Imported Upstream version 1.6.1
authorJohn L. Whiteman <john.l.whiteman@intel.com>
Thu, 14 Aug 2014 23:22:13 +0000 (16:22 -0700)
committerJohn L. Whiteman <john.l.whiteman@intel.com>
Thu, 14 Aug 2014 23:22:13 +0000 (16:22 -0700)
274 files changed:
AUTHORS
ChangeLog
ChangeLog-2011 [new file with mode: 0644]
LICENSES [new file with mode: 0644]
Makefile.am
Makefile.in
NEWS
README
README.GIT [moved from README.SVN with 82% similarity]
THANKS
VERSION
acinclude.m4
aclocal.m4
autogen.rc [new file with mode: 0644]
autogen.sh
build-aux/ChangeLog-2011 [new file with mode: 0644]
build-aux/compile [moved from compile with 100% similarity]
build-aux/config.guess [moved from config.guess with 90% similarity]
build-aux/config.rpath [moved from config.rpath with 100% similarity]
build-aux/config.sub [moved from config.sub with 92% similarity]
build-aux/depcomp [moved from depcomp with 100% similarity]
build-aux/git-log-fix [new file with mode: 0644]
build-aux/git-log-footer [new file with mode: 0644]
build-aux/install-sh [moved from install-sh with 74% similarity]
build-aux/ltmain.sh [moved from ltmain.sh with 67% similarity]
build-aux/mdate-sh [moved from doc/mdate-sh with 100% similarity]
build-aux/missing [moved from missing with 100% similarity]
build-aux/texinfo.tex [moved from doc/texinfo.tex with 99% similarity]
cipher/ChangeLog-2011 [moved from cipher/ChangeLog with 99% similarity]
cipher/Makefile.am
cipher/Makefile.in
cipher/ac.c [deleted file]
cipher/arcfour.c
cipher/bithelp.h
cipher/blowfish-amd64.S [new file with mode: 0644]
cipher/blowfish-arm.S [new file with mode: 0644]
cipher/blowfish.c
cipher/bufhelp.h [new file with mode: 0644]
cipher/camellia-aesni-avx-amd64.S [new file with mode: 0644]
cipher/camellia-aesni-avx2-amd64.S [new file with mode: 0644]
cipher/camellia-arm.S [new file with mode: 0644]
cipher/camellia-glue.c
cipher/camellia.c
cipher/camellia.h
cipher/cast5-amd64.S [new file with mode: 0644]
cipher/cast5-arm.S [new file with mode: 0644]
cipher/cast5.c
cipher/cipher-aeswrap.c [new file with mode: 0644]
cipher/cipher-cbc.c [new file with mode: 0644]
cipher/cipher-ccm.c [new file with mode: 0644]
cipher/cipher-cfb.c [new file with mode: 0644]
cipher/cipher-cmac.c [new file with mode: 0644]
cipher/cipher-ctr.c [new file with mode: 0644]
cipher/cipher-gcm.c [new file with mode: 0644]
cipher/cipher-internal.h [new file with mode: 0644]
cipher/cipher-ofb.c [new file with mode: 0644]
cipher/cipher-selftest.c [new file with mode: 0644]
cipher/cipher-selftest.h [new file with mode: 0644]
cipher/cipher.c
cipher/crc.c
cipher/des.c
cipher/dsa-common.c [new file with mode: 0644]
cipher/dsa.c
cipher/ecc-common.h [new file with mode: 0644]
cipher/ecc-curves.c [new file with mode: 0644]
cipher/ecc-ecdsa.c [new file with mode: 0644]
cipher/ecc-eddsa.c [new file with mode: 0644]
cipher/ecc-gost.c [new file with mode: 0644]
cipher/ecc-misc.c [new file with mode: 0644]
cipher/ecc.c
cipher/elgamal.c
cipher/gost.h [new file with mode: 0644]
cipher/gost28147.c [new file with mode: 0644]
cipher/gostr3411-94.c [new file with mode: 0644]
cipher/hash-common.c
cipher/hash-common.h
cipher/hmac-tests.c
cipher/idea.c [new file with mode: 0644]
cipher/kdf-internal.h [new file with mode: 0644]
cipher/kdf.c
cipher/mac-cmac.c [new file with mode: 0644]
cipher/mac-gmac.c [new file with mode: 0644]
cipher/mac-hmac.c [new file with mode: 0644]
cipher/mac-internal.h [new file with mode: 0644]
cipher/mac.c [new file with mode: 0644]
cipher/md.c
cipher/md4.c
cipher/md5.c
cipher/primegen.c
cipher/pubkey-internal.h [new file with mode: 0644]
cipher/pubkey-util.c [new file with mode: 0644]
cipher/pubkey.c
cipher/rfc2268.c
cipher/rijndael-amd64.S [new file with mode: 0644]
cipher/rijndael-arm.S [new file with mode: 0644]
cipher/rijndael.c
cipher/rmd.h
cipher/rmd160.c
cipher/rsa-common.c [new file with mode: 0644]
cipher/rsa.c
cipher/salsa20-amd64.S [new file with mode: 0644]
cipher/salsa20-armv7-neon.S [new file with mode: 0644]
cipher/salsa20.c [new file with mode: 0644]
cipher/scrypt.c [new file with mode: 0644]
cipher/seed.c
cipher/serpent-armv7-neon.S [new file with mode: 0644]
cipher/serpent-avx2-amd64.S [new file with mode: 0644]
cipher/serpent-sse2-amd64.S [new file with mode: 0644]
cipher/serpent.c
cipher/sha1-ssse3-amd64.S [new file with mode: 0644]
cipher/sha1.c
cipher/sha256-ssse3-amd64.S [new file with mode: 0644]
cipher/sha256.c
cipher/sha512-armv7-neon.S [new file with mode: 0644]
cipher/sha512-avx-amd64.S [new file with mode: 0644]
cipher/sha512-avx2-bmi2-amd64.S [new file with mode: 0644]
cipher/sha512-ssse3-amd64.S [new file with mode: 0644]
cipher/sha512.c
cipher/stribog.c [new file with mode: 0644]
cipher/tiger.c
cipher/twofish-amd64.S [new file with mode: 0644]
cipher/twofish-arm.S [new file with mode: 0644]
cipher/twofish.c
cipher/whirlpool.c
compat/Makefile.in
compat/compat.c
config.h.in
configure
configure.ac
doc/ChangeLog-2011 [moved from doc/ChangeLog with 95% similarity]
doc/DCO [new file with mode: 0644]
doc/HACKING
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
doc/gcrypt.info-2 [new file with mode: 0644]
doc/gcrypt.texi
doc/gpl.texi
doc/lgpl.texi
doc/libgcrypt-modules.eps
doc/libgcrypt-modules.pdf
doc/libgcrypt-modules.png
doc/stamp-vti
doc/version.texi
doc/yat2m.c [new file with mode: 0644]
m4/ChangeLog-2011 [moved from m4/ChangeLog with 73% similarity]
m4/Makefile.am
m4/Makefile.in
m4/gpg-error.m4
m4/libtool.m4
m4/lock.m4 [new file with mode: 0644]
m4/ltoptions.m4
m4/ltversion.m4
m4/lt~obsolete.m4
m4/threadlib.m4 [new file with mode: 0644]
mpi/ChangeLog-2011 [moved from mpi/ChangeLog with 97% similarity]
mpi/Makefile.am
mpi/Makefile.in
mpi/amd64/mpih-mul2.S
mpi/config.links
mpi/ec-ed25519.c [new file with mode: 0644]
mpi/ec-internal.h [new file with mode: 0644]
mpi/ec.c
mpi/longlong.h
mpi/mpi-add.c
mpi/mpi-bit.c
mpi/mpi-cmp.c
mpi/mpi-div.c
mpi/mpi-gcd.c
mpi/mpi-inline.h
mpi/mpi-internal.h
mpi/mpi-inv.c
mpi/mpi-mod.c
mpi/mpi-mpow.c
mpi/mpi-mul.c
mpi/mpi-pow.c
mpi/mpi-scan.c
mpi/mpicoder.c
mpi/mpih-div.c
mpi/mpih-mul.c
mpi/mpiutil.c
random/ChangeLog-2011 [moved from random/ChangeLog with 92% similarity]
random/Makefile.am
random/Makefile.in
random/rand-internal.h
random/random-csprng.c
random/random-daemon.c
random/random-fips.c
random/random-system.c [new file with mode: 0644]
random/random.c
random/random.h
random/rndegd.c
random/rndhw.c
random/rndlinux.c
random/rndunix.c
random/rndw32.c
src/ChangeLog-2011 [moved from src/ChangeLog with 96% similarity]
src/Makefile.am
src/Makefile.in
src/ath.c
src/ath.h
src/cipher-proto.h
src/cipher.h
src/context.c [new file with mode: 0644]
src/context.h [new file with mode: 0644]
src/ec-context.h [new file with mode: 0644]
src/fips.c
src/g10lib.h
src/gcrypt-int.h [new file with mode: 0644]
src/gcrypt-module.h [deleted file]
src/gcrypt.h
src/gcrypt.h.in
src/global.c
src/hmac256.c
src/hwf-arm.c [new file with mode: 0644]
src/hwf-common.h [new file with mode: 0644]
src/hwf-x86.c [new file with mode: 0644]
src/hwfeatures.c
src/libgcrypt.def
src/libgcrypt.m4
src/libgcrypt.vers
src/misc.c
src/module.c [deleted file]
src/mpi.h
src/mpicalc.c [new file with mode: 0644]
src/secmem.c
src/secmem.h
src/sexp.c
src/versioninfo.rc.in
src/visibility.c
src/visibility.h
tests/ChangeLog-2011 [moved from tests/ChangeLog with 97% similarity]
tests/Makefile.am
tests/Makefile.in
tests/ac-data.c [deleted file]
tests/ac-schemes.c [deleted file]
tests/ac.c [deleted file]
tests/aeswrap.c
tests/basic.c
tests/bench-slope.c [new file with mode: 0644]
tests/benchmark.c
tests/curves.c
tests/dsa-rfc6979.c [new file with mode: 0644]
tests/fips186-dsa.c
tests/fipsdrv.c
tests/genhashdata.c [new file with mode: 0644]
tests/hashtest-256g.in [new file with mode: 0755]
tests/hashtest.c [new file with mode: 0644]
tests/hmac.c
tests/keygen.c
tests/keygrip.c
tests/mpitests.c
tests/pkcs1v2.c
tests/prime.c
tests/pubkey.c
tests/random.c
tests/register.c [deleted file]
tests/rsacvt.c
tests/stopwatch.h [new file with mode: 0644]
tests/t-common.h [new file with mode: 0644]
tests/t-convert.c [new file with mode: 0644]
tests/t-ed25519.c [new file with mode: 0644]
tests/t-ed25519.inp [new file with mode: 0644]
tests/t-kdf.c
tests/t-lock.c [new file with mode: 0644]
tests/t-mpi-bit.c
tests/t-mpi-point.c [new file with mode: 0644]
tests/testapi.c
tests/tsexp.c
tests/version.c

diff --git a/AUTHORS b/AUTHORS
index 0685a4e..7c3c671 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,22 +1,47 @@
 Library: Libgcrypt
 Homepage: http://www.gnu.org/software/libgcrypt/
 Maintainer: Werner Koch <wk@gnupg.org>
-Bug reports: <bug-libgcrypt@gnupg.org>  or http://bugs.gnupg.org
+Bug reports: http://bugs.gnupg.org
 Security related bug reports: <security@gnupg.org>
 License (library): LGPLv2.1+
 License (manual and tools): GPLv2+
 
-Libgcrypt used to be part of GnuPG but has been taken out into its own
-package on 2000-12-21.
-
-
-Authors of Libgcrypt
-====================
-
-GNUPG  Werner Koch               1998-02-23
-Assigns GNU Privacy Guard and future changes.
+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
+copyright years may be listed using range notation, e.g., 2000-2013,
+indicating that every year in the range, inclusive, is a copyrightable
+year that would otherwise be listed individually.
+
+
+List of Copyright holders
+=========================
+
+  Copyright (C) 1989,1991-2012 Free Software Foundation, Inc.
+  Copyright (C) 1994 X Consortium
+  Copyright (C) 1996 L. Peter Deutsch
+  Copyright (C) 1997 Werner Koch
+  Copyright (C) 1998 The Internet Society
+  Copyright (C) 1996-1999 Peter Gutmann, Paul Kendall, and Chris Wedgwood
+  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 Simon Josefsson, Niels Möller
+  Copyright (c) 2012 Intel Corporation
+  Copyright (C) 2013 Christian Grothoff
+  Copyright (C) 2013-2014 Jussi Kivilinna
+  Copyright (C) 2013-2014 Dmitry Eremin-Solenikov
+
+
+Authors with a FSF copyright assignment
+=======================================
+
+LIBGCRYPT       Werner Koch    2001-06-07
+Assigns past and future changes.
+Assignment for future changes terminated on 2012-12-04.
 wk@gnupg.org
-Designed and implemented GnuPG.
+Designed and implemented Libgcrypt.
 
 GNUPG  Matthew Skala              1998-08-10
 Disclaims changes.
@@ -37,12 +62,13 @@ Disclaims changes.
 nh@df.lth.se
 Weak key patches.
 
-GNUPG  Rémi Guyomarch          1999-05-25
+GNUPG  Rémi Guyomarch         1999-05-25
 Assigns past and future changes. (g10/compress.c, g10/encr-data.c,
 g10/free-packet.c, g10/mdfilter.c, g10/plaintext.c, util/iobuf.c)
 rguyom@mail.dotcom.fr
 
 ANY     g10 Code GmbH           2001-06-07
+Assignment for future changes terminated on 2012-12-04.
 Code marked with ChangeLog entries of g10 Code employees.
 
 LIBGCRYPT Timo Schulz           2001-08-31
@@ -96,9 +122,57 @@ Assigns Past and Future Changes
 openpgp@brainhub.org
 (cipher/ecc.c and related files)
 
+LIBGCRYPT       Ulrich Müller    2012-02-15
+Assigns Past and Future Changes
+ulm@gentoo.org
+(Changes to cipher/idea.c and related files)
+
+LIBGCRYPT       Vladimir Serbinenko  2012-04-26
+Assigns Past and Future Changes
+phcoder@gmail.com
+(cipher/serpent.c)
+
+
+Authors with a DCO
+==================
+
+Christian Aistleitner <christian@quelltextlich.at>
+2013-02-26:20130226110144.GA12678@quelltextlich.at:
+
+Christian Grothoff <christian@grothoff.org>
+2013-03-21:514B5D8A.6040705@grothoff.org:
+
+Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+2013-07-13:20130713144407.GA27334@fangorn.rup.mentorg.com:
+
+Dmitry Kasatkin <dmitry.kasatkin@intel.com>
+2012-12-14:50CAE2DB.80302@intel.com:
+
+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:
+
+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:
+
+Tomáš Mráz <tm@t8m.info>
+2012-04-16:1334571250.5056.52.camel@vespa.frost.loc:
+
+Werner Koch <wk@gnupg.org> (g10 Code GmbH)
+2012-12-05:87obi8u4h2.fsf@vigenere.g10code.de:
+
 
 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.
@@ -121,9 +195,9 @@ a part of libgcrypt proper.  We distribute it merely for convenience.
 It has a permissive license and is copyrighted by atsec information
 security corporation.  See the file for details.
 
+The file salsa20.c is based on D.J. Bernstein's public domain code and
+taken from Nettle.  Copyright 2012 Simon Josefsson and Niels Möller.
 
- Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2006,
-           2007, 2008, 2009, 2011 Free Software Foundation, Inc.
 
  This file is free software; as a special exception the author gives
  unlimited permission to copy and/or distribute it, with or without
index 2c56e2a..8b46e29 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
-2011-06-29  Werner Koch  <wk@g10code.com>
-
-       Release 1.5.0.
-
-       * configure.ac: Keep LT version at C18/A7/R0 because it has
-       already been bumped up at 2010-07-09.
-
-       * config.guess, config.sub: Update to 2011-06-03.
-
-2011-04-06  Werner Koch  <wk@g10code.com>
-
-       * configure.ac (emacs_local_vars_begin): Move more to the top to
-       avoid Emacs warnings.
-
-2011-03-30  Werner Koch  <wk@g10code.com>
-
-       * compat/compat.c (_gcry_compat_identification): Add version string.
-
-2011-03-08  Werner Koch  <wk@g10code.com>
-
-       * configure.ac (BUILD_REVISION): Use new git_brevis macro.
-
-2011-02-23  Werner Koch  <wk@g10code.com>
-
-       * configure.ac (LIBGCRYPT_CONFIG_HOST): New.
-
-       * acinclude.m4 (AM_PATH_GPG_ERROR): Remove.
-
-2011-02-21  Werner Koch  <wk@g10code.com>
-
-       Release 1.5.0-beta1.
-
-2011-02-18  Werner Koch  <wk@g10code.com>
-
-       * configure.ac [GCC]: Remove the use of -fno-strict-aliasing.
-
-2011-02-11  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Add option --disbale-aesni-support.
-       (ENABLE_AESNI_SUPPORT): New macro.
-
-2011-02-04  Werner Koch  <wk@g10code.com>
-
-       * autogen.sh: Install the git pre-commit if not yet done.
-
-2010-12-23  Werner Koch  <wk@g10code.com>
-
-       * configure.ac (BUILD_REVISION): Use git_revision.
-
-2010-08-19  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Define GPG_ERR_ENABLE_ERRNO_MACROS. Remove
-       definition of _GNU_SOURCE.
-       (AC_GNU_SOURCE): New.
-
-2010-08-16  Werner Koch  <wk@g10code.com>
-
-       * configure.ac (INSERT_SYS_SELECT_H): New.
-
-2010-07-09  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Bump LT version to C18/A7/R0 to prepare a backport
-       of a new API to the 1.4 series.
-
-2010-04-19  Marcus Brinkmann  <marcus@g10code.de>
-
-       * configure.ac: Check for -fno-strict-aliasing.
-
-2010-04-12  Brad Hards  <bradh@frogmouth.net>  (wk)
-
-       * configure.ac: Print more verbose info at the end.
-
-2010-03-24  Werner Koch  <wk@g10code.com>
-
-       * configure.ac (USE_RNDW32CE): New.
-
-2010-03-15  Werner Koch  <wk@g10code.com>
-
-       * configure.ac (emacs_local_vars_begin)
-       (emacs_local_vars_read_only, emacs_local_vars_end): New.
-
-2010-01-21  Werner Koch  <wk@g10code.com>
-
-       * compat/Makefile.am: New.
-       * compat/compat.c: New.
-       * compat/libcompat.h: New.
-       * compat/getpid.c, compat/clock.c: New.
-
-       * configure.ac: Require libgpg-error 1.8.
-       (HAVE_W32CE_SYSTEM): New am_defines and am_conditionals.
-       (getpid): Check for replacement function.
-       (AC_CONFIG_LIBOBJ_DIR): New.
-       (AC_TYPE_PID_T): New.
-       (AM_INIT_AUTOMAKE): Use modern variant.
-       (AC_CONFIG_FILES): Add compat/Makfile.
-       * autogen.sh: Support W32CE.
-       * ltmain.sh: Update to 2.2.6b
-       (wrappers_required): Don't set for mingw32ce.
-       * Makefile.am (DIST_SUBDIRS, SUBDIRS): Add compat.
-
-2009-12-10  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Add option --disable-O-flag-munging.
-
-2009-12-08  Marcus Brinkmann  <marcus@g10code.de>
-
-       Update to libtool 2.2.6a.
-       * configure.ac: Invoke AC_CONFIG_MACRO_DIR.
-       (AC_LIBTOOL_WIN32_DLL, AC_LIBTOOL_RC): Replace by ...
-       (LT_PREREQ, LT_INIT, LT_LANG): ... these.
-       * config.guess, config.sub, install-sh, ltmain.sh, m4/libtool.m4:
-       Updated to libtool 2.2.6a.
-       * m4/ltoptions.m4, m4/ltsugar.m4, m4/ltversion.m4,
-       m4/lt~obsolete.m4: New files from libtool 2.2.6a.
-
-2009-08-05  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Test for sys/msg.h.
-
-2009-04-23  Werner Koch  <wk@g10code.com>
-
-       * README: Add a section on build problems.
-
-2009-01-22  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Bump LT version to C17/A6/R0 to mark the start of
-       a new development series.
-
-2009-01-22  Werner Koch  <wk@g10code.com>
-
-       Release 1.4.4.
-
-       * configure.ac: Bump LT version to C16/A5/R2.
-
-2008-10-30  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Remove option --enable-gcc-warnings.  Autodetect
-       useful gcc warnings in maintainer mode.
-
-2008-09-18  Werner Koch  <wk@g10code.com>
-
-       Release 1.4.3.
-
-       * configure.ac: Bump LT version to C16/A5/R1.
-
-2008-09-15  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Cehck for syslog.
-
-2008-09-08  Werner Koch  <wk@g10code.com>
-
-       Release 1.4.2.
-
-2008-09-01  Werner Koch  <wk@g10code.com>
-
-       Release 1.4.2rc2.
-
-       * configure.ac: Update svn_revision macro.
-
-2008-08-22  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Add option --enable-hmac-binary-check.
-       (DL_LIBS): Check whether -ldl is required.
-
-2008-08-19  Werner Koch  <wk@g10code.com>
-
-       Release 1.4.2rc1.
-
-       * configure.ac: Bump LT version to C16/A5/R0.
-
-2008-08-18  Werner Koch  <wk@g10code.com>
-
-       * Makefile.am (EXTRA_DIST): Remove the unused BUGS file.
-
-2008-08-15  Werner Koch  <wk@g10code.com>
-
-       * configure.ac (AH_BOTTOM): Define GCRY_GPG_ERR_NOT_OPERATIONAL.
-
-2008-07-05  Werner Koch  <wk@g10code.com>
-
-       * random/: New.
-       * Makefile.am (DIST_SUBDIRS): Add random.
-       * configure.ac (AC_CONFIG_FILES): Add random/Makefile.
-
-2008-04-25  Werner Koch  <wk@g10code.com>
-
-       Release 1.4.1.
-
-       * configure.ac: Bump LT version to C15/A4/R4.
-
-2008-04-22  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Set version to 1.4.1rc1.
-
-2008-04-18  Werner Koch  <wk@g10code.com>
-
-       * configure.ac (AH_BOTTOM): Add CAMELLIA_EXT_SYM_PREFIX.
-       (NAME_OF_DEV_RANDOM):  Remove special cases for Solaris etc.  This
-       matches the gnupg 1.4.9 version.
-
-2008-04-01  Werner Koch  <wk@g10code.com>
-
-       * configure.ac (AC_INIT): Fix quoting.
-
-2008-03-19  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Fix the tests for USE_<algo> to either define or
-       undef the macros.  Suggested by Dirk Stoecker.
-
-2008-03-18  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Test for uintptr_t.
-
-2008-02-18  Werner Koch  <wk@g10code.com>
-
-       * configure.ac (IS_DEVELOPMENT_VERSION): Set depending on the my_svn.
-
-2007-12-11  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: We actually require libgpg-error 1.4.  Reported by
-       Tim Mooney.
-
-2007-12-10  Werner Koch  <wk@g10code.com>
-
-       Released 1.4.0.
-
-       * configure.ac: Set LT to C15/A4/R3.
-
-2007-12-05  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Add option --disable-padlock-support.
-
-2007-12-03  Werner Koch  <wk@g10code.com>
-
-       Released 1.3.2.
-
-       * configure.ac: Set LT to C15/A4/R2.
-
-       * config.sub, config.guess: Update to version 2007-11-19.
-
-2007-10-30  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Protect config.h against double inclusion.
-
-2007-10-26  Werner Koch  <wk@g10code.com>
-
-       Released 1.3.1.
-
-       * configure.ac: Set LT to C15/A4/R1.
-
-2007-08-22  Werner Koch  <wk@g10code.com>
-
-       * README: Rewrite the license description.
-       * configure.ac (USE_RNDW32, USE_RNDUNIX): Unmark as GPL modules.
-
-2007-08-08  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Use $host and not $target.
-
-2007-07-26  Werner Koch  <wk@g10code.com>
-
-       * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Fix a syntax error
-       in the test program which lurked there for 4 years.  Adjusted name
-       of libtools global_system_pipe variable and add extra cut stage.
-       Reported by Gregor Riepl.
-
-2007-06-15  Werner Koch  <wk@g10code.com>
-
-       * autogen.sh (FORCE): Use = and not == in test to be POSIXly correct.
-
-2007-05-30  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Camellia is no longer GPL.
-
-2007-05-24  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Try to use -Wpointer-arith.
-
-2007-05-19  Marcus Brinkmann  <marcus@g10code.de>
-
-       * configure.ac: Fix test for optional UDIV and UDIV_QRNND MPI
-       modules.
-
-2007-05-09  Marcus Brinkmann  <marcus@g10code.de>
-
-       * configure.ac (ac_cv_mpi_config_done): Unused variable removed.
-       (ac_cv_mpi_mod_list, MPI_MOD_LIST_LO, MPI_MOD_LIST_O): Removed.
-       (MPI_MOD_ASM_MPIH_ADD1, MPI_MOD_ASM_MPIH_SUB1,
-       MPI_MOD_ASM_MPIH_MUL1, MPI_MOD_ASM_MPIH_MUL2,
-       MPI_MOD_ASM_MPIH_MUL3, MPI_MOD_ASM_MPIH_LSHIFT,
-       MPI_MOD_ASM_MPIH_RSHIFT, MPI_MOD_ASM_MPIH_UDIV,
-       MPI_MOD_ASM_MPIH_UDIV_QRNND, MPI_MOD_C_MPIH_ADD1,
-       MPI_MOD_C_MPIH_SUB1, MPI_MOD_C_MPIH_MUL1, MPI_MOD_C_MPIH_MUL2,
-       MPI_MOD_C_MPIH_MUL3, MPI_MOD_C_MPIH_LSHIFT, MPI_MOD_C_MPIH_RSHIFT,
-       MPI_MOD_C_MPIH_UDIV, MPI_MOD_C_MPIH_UDIV_QRNND): New automake
-       variables.
-
-2007-05-04  Werner Koch  <wk@g10code.com>
-
-       Released 1.3.0.
-
-       * configure.ac: Set LT to C15/A4/R0.
-
-       * configure.ac: Require automake 1.10
-       (AM_PROG_CC_C_O): New.
-
-2007-05-03  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Fix detection of GPLed random modules.
-
-2007-05-02  Werner Koch  <wk@g10code.com>
-
-       * configure.ac (LIBGCRYPT_DIGESTS, LIBGCRYPT_CIPHERS)
-       (LIBGCRYPT_PUBKEY_CIPHERS): Ac_define lists of algorithms.
-       (default_ciphers): Don't make camellia a default.
-
-2007-05-02  David Shaw  <dshaw@jabberwocky.com>
-
-       * NEWS, configure.ac: Add Camellia.
-
-2007-04-30  Werner Koch  <wk@g10code.com>
-
-       * README.apichanges: Move to doc/.
-       * Makefile.am (EXTRA_DIST): Removed that file.
-
-2007-04-28  Marcus Brinkmann  <marcus@g10code.de>
-
-       * configure.ac: Allow to specify additional search directories
-       with --enable-mpi-path.
-
-2007-04-16  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Check for sysconf.
-       * acinclude.m4 (GNUPG_CHECK_MLOCK): Try to use sysconf to get the
-       page size and use getpagesize only then if available.
-
-2007-03-22  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Add support for ECC.
-
-2007-02-22  Werner Koch  <wk@g10code.com>
-
-       * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Use
-       --enable-random-daemon.
-
-       * configure.ac: New option --enable-random-daemon.
-       Create versioninfo.rc and provide the build information.
-
-2007-02-21  Werner Koch  <wk@g10code.com>
-
-       * Makefile.am, configure.ac: Ignore w32-dll/.
-
-2007-02-20  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Bump LT version to C14/A3/R0 in preparation for a
-       release.
-
-       * autogen.sh: Add option --force.
-       * configure.ac: New option --disable-endian-check.  Use a real
-       noexecstack test instead of requiring an option.  Add SVN version
-       magic.
-
-2007-02-02  Werner Koch  <wk@g10code.com>
-
-       * configure.ac (FALLBACK_SOCKLEN_T): Special case for mingw32.
-
-2006-11-15  Werner Koch  <wk@g10code.com>
-
-       * autogen.sh: Add convenience option --build-amd64.
-
-2006-10-20  Werner Koch  <wk@g10code.com>
-
-       * Makefile.am (stowinstall): New convenience target.
-
-2006-10-12  Marcus Brinkmann  <marcus@g10code.de>
-
-       * configure.ac (FALLBACK_SOCKLEN_T): Third time is a charm.
-       Define gcry_socklen_t, to avoid conflicts with socklen_t
-       definitions by autoconf.
-
-2006-10-11  Marcus Brinkmann  <marcus@g10code.de>
-
-       * configure.ac (FALLBACK_SOCKLEN_T): Rewrite in terms of
-       socklen.m4.
-
-2006-10-11  Marcus Brinkmann  <marcus@g10code.de>
-
-       * acinclude.m4 (GNUPG_FIX_HDR_VERSION): Removed.
-       * configure.ac: Do not call GNUPG_FIX_HDR_VERSION.
-
-2006-10-10  Marcus Brinkmann  <marcus@g10code.de>
-
-       * configure.ac: Invoke AC_CHECK_SOCKLEN_TYPE.
-       (AC_CONFIG_FILES): Add src/gcrypt.h.
-       (AC_CONFIG_SRCDIR): Change to src/libgcrypt.vers.
-
-2006-10-02  Werner Koch  <wk@g10code.com>
-
-       * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Test on HOST and not
-       TARGET.  Hardwire for mingw32. Allow setting via command line when
-       cross compiling.
-
-2006-08-29  Werner Koch  <wk@g10code.com>
-
-       * configure.ac (USE_SEED): New.
-
-2006-07-26  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: New options --enable-noexecstack and
-       --disable-optimization.
-
-2006-07-04  Marcus Brinkmann  <marcus@g10code.de>
-
-       * configure.ac: Call AC_LIBTOO_WIN32_DLL and AC_LIBTOOL_RC.
-
-       * configure.ac: Call gl_TYPE_SOCKLEN_T instead of the other
-       socklen_t checks.
-
-2006-06-08  Marcus Brinkmann  <marcus@g10code.de>
-
-       * configure.ac (PTH_LIBS): Add --all to pth-config invocation.
-
-2006-03-14  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Check for fctnl and ftruncate.
-       (HAVE_PTH): Check for GNU Pth.
-       (HAVE_W32_SYSTEM): Define it.
-       * acinclude.m4 (GNUPG_PTH_VERSION_CHECK): New. Taken from GnuPG 1.4.
-
-2005-12-08  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Changed the random device names for netbsd.  From
-       Christian Biere.
-
-2005-11-02  Moritz Schulte  <moritz@g10code.com>
-
-       * NEWS: Documented minor API changes.
-
-2005-09-15  Moritz Schulte  <moritz@g10code.com>
-
-       * Makefile.am (EXTRA_DIST): Depend on README.SVN, not on README.CVS.
-
-2005-06-25  Moritz Schulte  <moritz@g10code.com>
-
-       * configure.ac: Removed src/libgcrypt.pc from AC_CONFIG_FILES.
-
-2005-06-10  Werner Koch  <wk@g10code.com>
-
-       * configure.ac: Move detection of basic stuff to the top.  For
-       example we need to know whether gcc is used before testing for it.
-       Reported by Ralf Fassel.
-
-2005-04-23  Moritz Schulte  <moritz@g10code.com>
-
-       * acinclude.m4 (TYPE_SOCKLEN_T): New type definition test;
-       provided by Albert Chin.
-       * configure.ac: Don't use $(CMD) as it's not portable; use CMD in
-       backticks instead.  Simpler -lnsl/-lsocket test.  Use
-       TYPE_SOCKLEN_T test.  Don't forget to set `random_modules'
-       correctly.
-
-2005-04-22  Moritz Schulte  <moritz@g10code.com>
-
-       * configure.ac: Added support for pkgconfig; provided by Albert
-       Chin.
-
-2005-04-11  Moritz Schulte  <moritz@g10code.com>
-
-       * configure.ac: Integrate Whirlpool.
-
-2005-01-04  Werner Koch  <wk@g10code.com>
-
-       Updated to automake 1.9.
-
-       * acinclude.m4: Updated for use with automake 1.9.
-
-       * configure.ac: Require libgpg-error 1.0; not really needed but
-       that is the first stable version.
-
-       * Makefile.am (ACLOCAL_AMFLAGS): New for -I m4.
-       (AUTOMAKE_OPTIONS): New to create a bzip archive.
-
-2005-02-03  Moritz Schulte  <moritz@g10code.com>
-
-       * THANKS: Updated.
-
-2004-08-09  Moritz Schulte  <moritz@g10code.com>
-
-       * THANKS: Updated.
-
-2004-07-04  Moritz Schulte  <moritz@g10code.com>
-
-       * THANKS: Updated.
-
-2004-04-21  Werner Koch  <wk@gnupg.org>
-
-       * configure.ac: Don't print a warning if GNU make was not found.
-
-2004-05-07  Moritz Schulte  <moritz@g10code.de>
-
-       * THANKS: Updated.
-
-2004-04-02  Thomas Schwinge  <schwinge@nic-nac-project.de>
-
-       * autogen.sh: Added ACLOCAL_FLAGS.
-
-2004-04-15  Werner Koch  <wk@gnupg.org>
-
-       Released 1.2.0.
-
-       * configure.ac: Set LT to C12/A1/R1.
-
-2004-04-06  Werner Koch  <wk@gnupg.org>
-
-       * config.guess, config.sub, ltmain.sh: Updated to those from
-       libtools 1.5.4.
-
-2004-03-29  Werner Koch  <wk@gnupg.org>
-
-       Released 1.1.94.
-
-       * configure.ac: Set LT to C12/A1/R0.
-
-2004-03-10  Marcus Brinkmann  <marcus@g10code.de>
-
-       * configure.ac (LIBGCRYPT_CONFIG_LIBS_PTHREAD,
-       LIBGCRYPT_CONFIG_CFLAGS_PTHREAD, LIBGCRYPT_CONFIG_LIBS_PTH,
-       LIBGCRYPT_CONFIG_CFLAGS_PTH, have_pth, have_pthread, AC_CHECK_PTH,
-       AC_CHECK_LIB(pthread), HAVE_PTH, HAVE_PTHREAD): Removed.
-
-2004-03-06  Werner Koch  <wk@gnupg.org>
-
-       Released 1.1.93.
-
-       * configure.ac (LIBGCRYPT_CONFIG_SONAME_NUMBER): Replaced by
-       LIBGCRYPT_CONPIG_API_VERSION.  Set it to 1.  Set LT to C11/A0/R1.
-
-2004-03-05  Werner Koch  <wk@gnupg.org>
-
-       * configure.ac (LIBGCRYPT_CONFIG_SONAME_NUMBER): New.
-
-2004-02-20  Werner Koch  <wk@gnupg.org>
-
-        Released 1.1.92.
-
-       * configure.ac: Set LT to C11/A0/R0.
-
-2004-02-11  Werner Koch  <wk@gnupg.org>
-
-       * autogen.sh (check_version): Removed bashism and simplified.
-
-2004-02-06  Werner Koch  <wk@gnupg.org>
-
-       * configure.ac: Add rfc2268 cipher algorithm.
-
-2004-01-25  Moritz Schulte  <mo@g10code.com>
-
-       * THANKS: Updated.
-
-2003-12-19  Werner Koch  <wk@gnupg.org>
-
-       Released 1.1.91.
-
-       * configure.ac: Bumbed LT version to C10/A3/R1.
-
-2003-12-08  Werner Koch  <wk@gnupg.org>
-
-       * Makefile.am (dist-hook): Don't distribute stuff from the now
-       obsolete scripts dir.
-       (EXTRA_DIST): Remove README_alpha
-       * README-alpha: Removed.
-       * configure.ac (AM_CONFIG_AUX_DIR): Removed.
-
-       * COPYING.DOC: Removed.
-       * Makefile.am (EXTRA_DIST): Added README.CVS and
-       autogen.sh. Removed COPYING.DOC.
-
-2003-11-14  Werner Koch  <wk@gnupg.org>
-
-       Released 1.1.90.
-
-       * configure.ac: Bumbed LT version to C10/A3/R0.
-
-       * configure.ac (have_ld_version_script): Set the default in
-       a separate test.
-       (PRINTABLE_OS_NAME): Don't handle the Hurd extra, this leads to
-       conflicts with BSD based GNU systems.  The Hurd has now a working
-       uname.
-
-2003-11-04  Werner Koch  <wk@gnupg.org>
-
-       * configure.ac (USE_SHA1): Make sure it is always included.
-       (USE_RMD160): Removed this AM conditional.
-
-2003-10-31  Werner Koch  <wk@gnupg.org>
-
-       * configure.ac: Bumbed version number to 1.1.90-cvs for futher
-       development
-
-       Released 1.1.44.
-
-       * acinclude.m4 (AC_CHECK_PTH): Added.
-       * configure.ac: Use it here instead of the generic lib test.
-       Bumbed LT vesion to C9/A2/R0.
-
-2003-10-27  Werner Koch  <wk@gnupg.org>
-
-       * configure.ac: Give a hint on where libgpg-error is available.
-       Reformatted long lines.  Don't include gcrypt-defs.h.
-       (--enable-gcc-warnings): New option.
-
-2003-10-24  Moritz Schulte  <mo@g10code.com>
-
-       * configure.ac: Check for socklen_t.
-
-2003-10-11  Moritz Schulte  <mo@g10code.com>
-
-       * acinclude.m4: Update AM_PATH_GPG_ERROR macro.
-
-2003-09-04  Werner Koch  <wk@gnupg.org>
-
-       Released 1.1.43.
-
-       * configure.ac: Require libgpg-error 0.4 due to the prime interface.
-
-2003-08-29  Werner Koch  <wk@gnupg.org>
-
-       * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Re-implemented.
-       * configure.ac: Use it here.
-
-2003-08-27  Moritz Schulte  <mo@g10code.com>
-
-       * configure.ac: Substitute: LIBGCRYPT_CONFIG_LIBS_PTHREAD,
-       LIBGCRYPT_CONFIG_CFLAGS_PTHREAD, LIBGCRYPT_CONFIG_LIBS_PTH,
-       LIBGCRYPT_CONFIG_CFLAGS_PTH, LIBGCRYPT_THREAD_MODULES.
-
-2003-08-07  Moritz Schulte  <moritz@g10code.com>
-
-       * configure.ac: Fail, if libgpg-error could not be found.
-
-2003-07-31  Werner Koch  <wk@gnupg.org>
-
-       Released 1.1.42.
-
-       * configure.ac: Set LT version to 7/0/0.
-
-2003-07-30  Werner Koch  <wk@gnupg.org>
-
-       * AUTHORS (Maintainer): Assigned Moritz as Maintainer.
-
-2003-07-30  Moritz Schulte  <moritz@g10code.com>
-
-       * NEWS: Include much more complete list of `Interface changes
-       relative to the 1.1.12 release'.
-
-2003-07-14  Moritz Schulte  <moritz@g10code.com>
-
-       * configure.ac: Bumbed version number up to 1.1.42-cvs.
-
-2003-07-09  Moritz Schulte  <moritz@g10code.com>
-
-       * configure.ac: Reintroduce --disable-asm, since it is needed by
-       mpi/config.links.
-
-2003-07-05  Moritz Schulte  <moritz@g10code.com>
-
-       * README: Few changes, mention libgpg-error.
-
-2003-06-18  Moritz Schulte  <moritz@g10code.com>
-
-       * configure.ac (available_ciphers): Removed Serpent, hrrm.
-
-2003-06-17  Moritz Schulte  <moritz@g10code.com>
-
-       * acinclude.m4: Removed macro definitions: GNUPG_CHECK_FAQPROG,
-       GNUPG_CHECK_ENDIAN, GNUPG_CHECK_CACHE, GNUPG_CHECK_PIC,
-       GNUPG_CHECK_EXPORTDYNAMIC, GNUPG_CHECK_IPC, GNUPG_PROG_NM,
-       GNUPG_SYS_SYMBOL_UNDERSCORE, GNUPG_FUNC_MKDIR_TAKES_ONE_ARG,
-       GPH_PROG_DB2ANY.
-       Added macro definitions: AM_PATH_GPG_ERROR.
-
-       * configure.ac: Use alternative approach for building based on
-       conditional sources, which does not make automake eat all your
-       memory, etc.
-       Removed unused tests.
-       Renamed --enable-static-rnd to --enable-random.
-       Use Autoconf's AC_C_BIGENDIAN macro instead of our own.
-       Re-organized the whole file.
-
-2003-06-16  Moritz Schulte  <moritz@g10code.com>
-
-       * configure.ac (AC_CONFIG_FILES): Removed doc/version.sgml.
-
-2003-06-11  Moritz Schulte  <moritz@g10code.com>
-
-       * configure.ac: Remove --enable-libgpg-error flag.
-       Ue AC_PATH_GPG_ERROR.
-
-2003-06-09  Moritz Schulte  <moritz@g10code.com>
-
-       * NEWS: Mention API changes and libgpg-error.
-
-2003-05-25  Moritz Schulte  <moritz@g10code.com>
-
-       * configure.ac (USE_LIBGPG_ERROR): Implementation of the
-       --enable-libgpg-error switch.
-       Define USE_LIBGPG_ERROR in LIBGCRYPT_CONFIG_FLAGS, in case
-       libgpg-error is used.
-
-2003-05-22  Moritz Schulte  <moritz@g10code.com>
-
-       * configure.ac (AC_CHECK_HEADERS): Removed unused headers:
-       termio.h, langinfo.h.
-       (AC_CHECK_FUNCS): Removed unused functions: strsep, strlwr,
-       tcgetattr, setrlimit, strftime, nl_langinfo, sigaction,
-       sigprocmask, fopen64, fstat64.
-
-2003-04-27  Moritz Schulte  <moritz@g10code.com>
-
-       * README: Documented new configure switches.
-       Mention the --enable-maintainer-switch.
-
-       * configure.ac: Merged some code from GnuPG's configure.ac for
-       disabling sha512/tiger in case no 64 data types are available.
-
-2003-04-17  Moritz Schulte  <moritz@g10code.com>
-
-       * configure.ac: Include support for sha512.
-
-2003-04-17  Moritz Schulte  <moritz@g10code.com>
-
-       * AUTHORS: Updated.
-
-2003-04-16  Moritz Schulte  <moritz@g10code.com>
-
-       * configure.ac: Implement command line switches: --enable-ciphers,
-       --enable-pubkey-ciphers and --enable-digests.
-       Set Automake conditionals and config.h symbols depending on the
-       selected ciphers, pubkey-ciphers, digests and random-modules.
-
-       * acinclude.m4 (LIST_MEMBER): New macro.
-
-       * configure.ac: Simplified, removed code for parsing
-       EXTRA_PROGRAMS from Makefile.am.
-
-2003-04-08  Moritz Schulte  <moritz@g10code.com>
-
-       * configure.ac: Merged random-module selection code from GnuPG's
-       configure.ac.
-
-2003-04-07  Moritz Schulte  <moritz@g10code.com>
-
-       * configure.ac: Removed code for generating contruct.c.
-       Remove digest modules from the static_modules list, only handle
-       random module selection.
-
-
-2003-03-24  Moritz Schulte  <moritz@g10code.com>
-
-       * NEWS: Mention new CBC_MAC flag.
-
-       * AUTHORS (Maintainer): Update entry for Simon Josefsson.
-
-2003-03-04  Moritz Schulte  <moritz@g10code.com>
-
-       * TODO: Remove item about resetting handles, since
-       gcry_cipher_reset is implemented by now.
-
-       * NEWS: Mentioned gcry_cipher_reset.
-
-2003-01-21  Werner Koch  <wk@gnupg.org>
-
-       * README (Configure options): New.
-       * configure.ac (have_ld_version_script): New option
-       --enable-ld-version-script.
-
-2003-01-20  Simon Josefsson  <jas@extundo.com>
-
-       * configure.ac (MODULES_IN_CIPHER): Add crc.
-
-2003-01-20  Werner Koch  <wk@gnupg.org>
-
-       Released 1.1.12.
-
-       * configure.ac (LIBGCRYPT_LT_REVISION): Bumbed up.
-
-2002-12-21  Werner Koch  <wk@gnupg.org>
-
-       Released 1.1.11.
-
-       * configure.ac (LIBGCRYPT_LT_CURRENT: Bumbed to 6/5/0 due to a new
-       interface
-
-2002-12-19  Werner Koch  <wk@gnupg.org>
-
-       * configure.ac (have_pthread): Check for pthreads in libc.
-       (have_ld_version_script): New.
-
-2002-11-10  Werner Koch  <wk@gnupg.org>
-
-       * configure.ac (MODULES_IN_CIPHER): Add md4.c.  By Simon Josefsson.
-
-2002-09-20  Werner Koch  <wk@gnupg.org>
-
-       Released 1.1.10.
-
-       * configure.ac (HAVE_DEV_RANDOM_IOCTL): Don't check for it; it is
-       not used.
-       (AS_CHECK_HEADERS): Check for sys/select.h.
-       * Makefile.am (DIST_SUBDIRS): New to include the w32-dll directory
-
-2002-09-18  Timo Schulz  <ts@winpt.org>
-
-       * configure.ac: Added makefile for the W32 DLL.
-
-2002-09-17  Werner Koch  <wk@gnupg.org>
-
-       * configure.ac: Check for Pth and Pthreads.
-
-2002-08-23  Werner Koch  <wk@gnupg.org>
-
-       Released 1.1.9.
-
-       * configure.ac (LIBGCRYPT_CONFIG_CFLAGS): Renamed from
-       LIBGCRYPT_CFLAGS and removed the libpath because it is set by the
-       config script.
-       (LIBGCRYPT_LT_REVISION): Set LT version to 5/4/1.
-
-2002-06-25  Werner Koch  <wk@gnupg.org>
-
-       Released 1.1.8.
-
-       * configure.ac: Set LT version to 5/4/0.
-
-2002-05-21  Werner Koch  <wk@gnupg.org>
-
-       Released 1.1.7.
-
-       * configure.ac: Set LT version to 4/3/0.
-
-2002-05-17  Werner Koch  <wk@gnupg.org>
-
-       * configure.ac: Removed all the dynamic loading stuff.
-
-2002-05-16  Werner Koch  <wk@gnupg.org>
-
-       * configure.ac: Reordered the C_CHECK_FUNCS.
-
-2002-05-15  Werner Koch  <wk@gnupg.org>
-
-       * configure.ac: Adjusted for new MPI module stuff.
-
-2002-05-14  Werner Koch  <wk@gnupg.org>
-
-       Changed license to the LGPL.
-
-2002-05-02  Werner Koch  <wk@gnupg.org>
-
-       * jnlib/: Removed.
-       * Makefile.am (SUBDIRS): Removed jnlib.
-       * configure.ac (jnlib/Makefile): Removed.
-
-       * configure.ac: Define _REENTRANT.
-
-2002-02-18  Werner Koch  <wk@gnupg.org>
-
-       * configure.ac (MPI_EXTRA_ASM_OBJS): Use .lo suffix.
-       (AC_CANONICAL_TARGET): Added.
-
-2002-02-07  Werner Koch  <wk@gnupg.org>
-
-       Released 1.1.6.
-
-2002-01-24  Werner Koch  <wk@gnupg.org>
-
-       * jnlib/: Replaced by a fresh copy from GnuPG (actually the NewPG
-       development branch).  Adjusted Makefile.am and jnlib-config.h
+2014-01-29  Werner Koch  <wk@gnupg.org>
+
+       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>
+
+       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.
+       (main): Run new test.
+
+2014-01-27  Werner Koch  <wk@gnupg.org>
+
+       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>
+
+       tests: Pass -no-install to libtool.
+       * tests/Makefile.am: add AM_LDFLAGS = -no-install
+
+       Fix most of memory leaks in tests code.
+       * tests/basic.c (check_ccm_cipher): Close cipher after use.
+       * tests/basic.c (check_one_cipher): Correct length of used buffer.
+       * tests/benchmark.c (cipher_bench): Use xcalloc to make buffer
+         initialized.
+       * tests/keygen.c (check_ecc_keys): Release generated key.
+       * tests/t-mpi-point.c (context_param): Release mpi Q.
+       * tests/t-sexp.c (check_extract_param): Release extracted number.
+
+       Fix memory leaks in ecc code.
+       * cipher/ecc-curves.c (_gcry_ecc_update_curve_param): Release passed mpi
+         values.
+       * cipher/ecc.c (compute_keygrip): Fix potential memory leak in error
+         path.
+       * cipher/ecc.c (_gcry_ecc_get_curve): Release temporary mpi.
+
+2014-01-24  Werner Koch  <wk@gnupg.org>
+
+       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-24  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.
+
+       (cherry picked from commit 9edcf1090e0485f9f383b6c54b18ea8ca3d4a225)
+
+2014-01-24  Werner Koch  <wk@gnupg.org>
+
+       Support locking under Windows.
+       * src/ath.c: Add support for Windows.
+       * src/global.c (external_lock_test): New.
+       (_gcry_vcontrol): Call new function with formerly reserved code 61.
+
+       * tests/t-common.h: New. Taken from current libgpg-error.
+       * tests/t-lock.c: New.  Based on t-lock.c from libgpg-error.
+       * configure.ac (HAVE_PTHREAD): Set macro to 1 if defined.
+       (AC_CHECK_FUNCS): Check for flockfile.
+       * tests/Makefile.am (tests_bin): Add t-lock.
+       (noinst_HEADERS): Add t-common.h
+       (LDADD): Move value to ...
+       (default_ldadd): new.
+       (t_lock_LDADD): New.
+
+2014-01-20  Werner Koch  <wk@gnupg.org>
+
+       cipher: Fix commit 77f28793.
+       * cipher/tiger.c (tiger_init): Add arg FLAGS.
+       (tiger1_init, tiger2_init): Ditto.
+
+       (cherry picked from commit dad06e4d1b835bac778b87090b1d3894b7535b14)
+
+       md: Add Whirlpool bug emulation feature.
+       * src/gcrypt.h.in (GCRY_MD_FLAG_BUGEMU1): New.
+       * src/cipher-proto.h (gcry_md_init_t): Add arg FLAGS.  Change all code
+       to implement that flag.
+       * cipher/md.c (gcry_md_context):  Replace SECURE and FINALIZED by bit
+       field FLAGS.  Add flag BUGEMU1.  Change all users.
+       (md_open): Replace args SECURE and HMAC by FLAGS.  Init flags.bugemu1.
+       (_gcry_md_open): Add for GCRY_MD_FLAG_BUGEMU1.
+       (md_enable): Pass bugemu1 flag to the hash init function.
+       (_gcry_md_reset): Ditto.
+
+2014-01-14  Milan Broz  <gmazyland@gmail.com>
+
+       PBKDF2: Use gcry_md_reset to speed up calculation.
+       * cipher/kdf.c (_gcry_kdf_pkdf2): Use gcry_md_reset
+       to speed up calculation.
+
+2014-01-13  Werner Koch  <wk@gnupg.org>
+
+       Fix macro conflict in NetBSD.
+       * cipher/bithelp.h (bswap32): Rename to _gcry_bswap32.
+       (bswap64): Rename to _gcry_bswap64.
+
+2014-01-13  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
+
+       Fix typo in search_oid.
+       * cipher/md.c (search_oid): Invert condition on oid comparison.
+
+       Correct formatting of gcry_mac_get_algo_keylen documentation.
+       * doc/gcrypt.texi: add braces near gcry_mac_get_algo_keylen
+         documentation.
+
+       Use braces around unsigned int in gcry_mac_get_algo_keylen
+       documentation, otherwise texinfo breaks that and uses 'int' as a
+       function definition.
+
+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
+
+       (cherry picked from commit 7fef7f481c0a1542be34d1dc831f58d41846ac29)
+
+       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.
+
+2014-01-10  Werner Koch  <wk@gnupg.org>
+
+       Use the generic autogen.sh script.
+       * autogen.rc: New.
+       * 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
+       * depcomp, doc/mdate-sh, doc/texinfo.tex
+       * install-sh, ltmain.sh, missing: Move to build-aux/.
+       * Makefile.am (EXTRA_DIST): Adjust.
+       * configure.ac (AC_CONFIG_AUX_DIR): New.
+       (AM_SILENT_RULES): New.
+
+       (cherry picked from commit df9b4eabf52faee6f289a4bc62219684442ae383)
+
+2013-12-16  Werner Koch  <wk@gnupg.org>
+
+       Release 1.6.0.
+
+       doc: Change yat2m to allow arbitrary condition names.
+       * doc/yat2m.c (MAX_CONDITION_NESTING): New.
+       (gpgone_defined): Remove.
+       (condition_s, condition_stack, condition_stack_idx): New.
+       (cond_is_active, cond_in_verbatim): New.
+       (add_predefined_macro, set_macro, macro_set_p): New.
+       (evaluate_conditions, push_condition, pop_condition): New.
+       (parse_file): Rewrite to use the condition stack.
+       (top_parse_file): Set prefined macros.
+       (main): Change -D to define arbitrary macros.
+
+       tests: Add SHA-512 to the long hash test.
+       * tests/hashtest.c (testvectors): Add vectors for 256GiB SHA-512.
+       * tests/hashtest-256g.in (algos): Add test for SHA-512.
+
+       Add configure option --enable-large-data-tests.
+       * configure.ac: Add option --enable-large-data-tests.
+       * tests/hashtest-256g.in: New.
+       * tests/Makefile.am (EXTRA_DIST): Add hashtest-256g.in.
+       (TESTS): Split up into tests_bin, tests_bin_last, tests_sh, and
+       tests_sh_last.
+       (tests_sh_last): Add hashtest-256g
+       (noinst_PROGRAMS): Add only tests_bin and tests_bin_last.
+       (bench-slope.log, hashtest-256g.log): New rules to enforce serial run.
+
+       random: Call random progress handler more often.
+       * random/rndlinux.c (_gcry_rndlinux_gather_random): Update progress
+       indicator earlier.
+
+       cipher: Normalize the MPIs used as input to secret key functions.
+       * cipher/dsa.c (sign): Normalize INPUT.
+       * cipher/elgamal.c (decrypt): Normalize A and B.
+       * cipher/rsa.c (secret): Normalize the INPUT.
+       (rsa_decrypt): Reduce DATA before passing to secret.
+
+2013-12-16  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Change dummy variable in mpih-div.c to mpi_limb_t type.
+       * mpi/mpih-div.c (_gcry_mpih_mod_1, _gcry_mpih_divmod_1): Change dummy
+       variable to 'mpi_limb_t' type from 'int'.
+
+       Remove duplicate gcry_mac_hd_t typedef.
+       * cipher/mac-internal.h (gcry_mac_hd_t): Remove.
+
+2013-12-15  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Use u64 for CCM data lengths.
+       * cipher/cipher-ccm.c: Move code inside [HAVE_U64_TYPEDEF].
+       [HAVE_U64_TYPEDEF] (_gcry_cipher_ccm_set_lengths): Use 'u64' for
+       data lengths.
+       [!HAVE_U64_TYPEDEF] (_gcry_cipher_ccm_encrypt)
+       (_gcry_cipher_ccm_decrypt, _gcry_cipher_ccm_set_nonce)
+       (_gcry_cipher_ccm_authenticate, _gcry_cipher_ccm_get_tag)
+       (_gcry_cipher_ccm_check_tag): Dummy functions returning
+       GPG_ERROR_NOT_SUPPORTED.
+       * cipher/cipher-internal.h (gcry_cipher_handle.u_mode.ccm)
+       (_gcry_cipher_ccm_set_lengths): Move inside [HAVE_U64_TYPEDEF] and use
+       u64 instead of size_t for CCM data lengths.
+       * cipher/cipher.c (_gcry_cipher_open_internal, cipher_reset)
+       (_gcry_cipher_ctl) [!HAVE_U64_TYPEDEF]: Return GPG_ERR_NOT_SUPPORTED
+       for CCM.
+       (_gcry_cipher_ctl) [HAVE_U64_TYPEDEF]: Use u64 for
+       GCRYCTL_SET_CCM_LENGTHS length parameters.
+       * tests/basic.c: Do not use CCM if !HAVE_U64_TYPEDEF.
+       * tests/bench-slope.c: Ditto.
+       * tests/benchmark.c: Ditto.
+
+2013-12-14  Werner Koch  <wk@gnupg.org>
+
+       tests: Prevent rare failure of gcry_pk_decrypt test.
+       * tests/basic.c (check_pubkey_crypt): Add special mode 1.
+       (main): Add option --loop.
+
+2013-12-14  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Minor fixes to SHA assembly implementations.
+       * cipher/Makefile.am: Correct 'sha256-avx*.S' to 'sha512-avx*.S'.
+       * cipher/sha1-ssse3-amd64.S: First line, correct filename.
+       * cipher/sha256-ssse3-amd64.S: Return correct stack burn depth.
+       * cipher/sha512-avx-amd64.S: Use 'vzeroall' to clear registers.
+       * cipher/sha512-avx2-bmi2-amd64.S: Ditto and return correct stack burn
+       depth.
+
+       SHA-1/SSSE3: Do not check for Intel syntax assembly support.
+       * cipher/sha1-ssse3-amd64.S: Remove check for
+       HAVE_INTEL_SYNTAX_PLATFORM_AS.
+       * cipher/sha1.c [USE_SSSE3]: Ditto.
+
+2013-12-13  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Convert SHA-1 SSSE3 implementation from mixed asm&C to pure asm.
+       * cipher/Makefile.am: Change 'sha1-ssse3-amd64.c' to
+       'sha1-ssse3-amd64.S'.
+       * cipher/sha1-ssse3-amd64.c: Remove.
+       * cipher/sha1-ssse3-amd64.S: New.
+
+       SHA-1: Add SSSE3 implementation.
+       * cipher/Makefile.am: Add 'sha1-ssse3-amd64.c'.
+       * cipher/sha1-ssse3-amd64.c: New.
+       * cipher/sha1.c (USE_SSSE3): New.
+       (SHA1_CONTEXT) [USE_SSSE3]: Add 'use_ssse3'.
+       (sha1_init) [USE_SSSE3]: Initialize 'use_ssse3'.
+       (transform): Rename to...
+       (_transform): this.
+       (transform): New.
+       * configure.ac [host=x86_64]: Add 'sha1-ssse3-amd64.lo'.
+
+       Add missing register clearing in to SHA-256 and SHA-512 assembly.
+       * cipher/sha256-ssse3-amd64.S: Clear used XMM/YMM registers at return.
+       * cipher/sha512-avx-amd64.S: Ditto.
+       * cipher/sha512-avx2-bmi2-amd64.S: Ditto.
+       * cipher/sha512-ssse3-amd64.S: Ditto.
+
+2013-12-13  Werner Koch  <wk@gnupg.org>
+
+       Update license information.
+       * LICENSES: New.
+       * Makefile.am (EXTRA_DIST): Add LICENSES.
+       * AUTHORS: Add list of copyright holders.
+       * README: Reference AUTHORS.
+
+2013-12-13  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Fix empty clobber in AVX2 assembly check.
+       * configure.ac (gcry_cv_gcc_inline_asm_avx2): Add "cc" as assembly
+       globber.
+
+       Fix W32 build.
+       * random/rndw32.c (register_poll, slow_gatherer): Change gcry_xmalloc to
+       xmalloc, and gcry_xrealloc to xrealloc.
+
+2013-12-12  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       SHA-512: Add AVX and AVX2 implementations for x86-64.
+       * cipher/Makefile.am: Add 'sha512-avx-amd64.S' and
+       'sha512-avx2-bmi2-amd64.S'.
+       * cipher/sha512-avx-amd64.S: New.
+       * cipher/sha512-avx2-bmi2-amd64.S: New.
+       * cipher/sha512.c (USE_AVX, USE_AVX2): New.
+       (SHA512_CONTEXT) [USE_AVX]: Add 'use_avx'.
+       (SHA512_CONTEXT) [USE_AVX2]: Add 'use_avx2'.
+       (sha512_init, sha384_init) [USE_AVX]: Initialize 'use_avx'.
+       (sha512_init, sha384_init) [USE_AVX2]: Initialize 'use_avx2'.
+       [USE_AVX] (_gcry_sha512_transform_amd64_avx): New.
+       [USE_AVX2] (_gcry_sha512_transform_amd64_avx2): New.
+       (transform) [USE_AVX2]: Add call for AVX2 implementation.
+       (transform) [USE_AVX]: Add call for AVX implementation.
+       * configure.ac (HAVE_GCC_INLINE_ASM_BMI2): New check.
+       (sha512): Add 'sha512-avx-amd64.lo' and 'sha512-avx2-bmi2-amd64.lo'.
+       * doc/gcrypt.texi: Document 'intel-cpu' and 'intel-bmi2'.
+       * src/g10lib.h (HWF_INTEL_CPU, HWF_INTEL_BMI2): New.
+       * src/hwfeatures.c (hwflist): Add "intel-cpu" and "intel-bmi2".
+       * src/hwf-x86.c (detect_x86_gnuc): Check for HWF_INTEL_CPU and
+       HWF_INTEL_BMI2.
+
+       SHA-512: Add SSSE3 implementation for x86-64.
+       * cipher/Makefile.am: Add 'sha512-ssse3-amd64.S'.
+       * cipher/sha512-ssse3-amd64.S: New.
+       * cipher/sha512.c (USE_SSSE3): New.
+       (SHA512_CONTEXT) [USE_SSSE3]: Add 'use_ssse3'.
+       (sha512_init, sha384_init) [USE_SSSE3]: Initialize 'use_ssse3'.
+       [USE_SSSE3] (_gcry_sha512_transform_amd64_ssse3): New.
+       (transform) [USE_SSSE3]: Call SSSE3 implementation.
+       * configure.ac (sha512): Add 'sha512-ssse3-amd64.lo'.
+
+       SHA-256: Add SSSE3 implementation for x86-64.
+       * cipher/Makefile.am: Add 'sha256-ssse3-amd64.S'.
+       * cipher/sha256-ssse3-amd64.S: New.
+       * cipher/sha256.c (USE_SSSE3): New.
+       (SHA256_CONTEXT) [USE_SSSE3]: Add 'use_ssse3'.
+       (sha256_init, sha224_init) [USE_SSSE3]: Initialize 'use_ssse3'.
+       (transform): Rename to...
+       (_transform): This.
+       [USE_SSSE3] (_gcry_sha256_transform_amd64_ssse3): New.
+       (transform): New.
+       * configure.ac (HAVE_INTEL_SYNTAX_PLATFORM_AS): New check.
+       (sha256): Add 'sha256-ssse3-amd64.lo'.
+       * doc/gcrypt.texi: Document 'intel-ssse3'.
+       * src/g10lib.h (HWF_INTEL_SSSE3): New.
+       * src/hwfeatures.c (hwflist): Add "intel-ssse3".
+       * src/hwf-x86.c (detect_x86_gnuc): Test for SSSE3.
+
+2013-12-12  Werner Koch  <wk@gnupg.org>
+
+       Add a configuration file to disable hardware features.
+       * src/hwfeatures.c: Inclyde syslog.h and ctype.h.
+       (HWF_DENY_FILE): New.
+       (my_isascii): New.
+       (parse_hwf_deny_file): New.
+       (_gcry_detect_hw_features): Call it.
+
+       * src/mpicalc.c (main): Correctly initialize Libgcrypt.  Add options
+       "--print-config" and "--disable-hwf".
+
+       Move list of hardware features to hwfeatures.c.
+       * src/global.c (hwflist, disabled_hw_features): Move to ..
+       * src/hwfeatures.c: here.
+       (_gcry_disable_hw_feature): New.
+       (_gcry_enum_hw_features): New.
+       (_gcry_detect_hw_features): Remove arg DISABLED_FEATURES.
+       * src/global.c (print_config, _gcry_vcontrol, global_init): Adjust
        accordingly.
 
-2001-12-18  Werner Koch  <wk@gnupg.org>
-
-       Released 1.1.5.
-
-       * Makefile.am (dist-hook): Only look in mpi and scripts for
-       distfiles; this way we don't include those of a stale "make dist"
-       directory.
-
-       * acinclude.m4 (GNUPG_FIX_HDR_VERSION): Make it work with the new
-       automake.
-       * configure.ac: Don't chmod db2any.
-
-2001-08-06  Werner Koch  <wk@gnupg.org>
-
-       * configure.ac: Removed cross compiling hacks.
-
-2001-08-03  Werner Koch  <wk@gnupg.org>
-
-       Released 1.1.4.
-
-       * acinclude.m4 (GNUPG_CHECK_TYPEDEF): Define GNU Source.
-
-        Migrated to autoconf 2.52.
-       * acinclude.m4: Removed GNUPG_LINK_FILES and converted.
-       * acconfig.h: Removed
-       * configure.in: Replaced by...
-       * configure.ac: and modified for use with autoconf 2.52.  Replaced
-       GNUPG_LINK_FILES with AC_CONFIG_LINKS and moved some informational
-       messages to the end. Removed --enable-m-debug
-
-       * tests/: New.
-       * Makefile.am: Included tests directory
-
-       * configure.in (DYNLINK_MOD_CFLAGS): Use -shared with dec-osf.
-       Reported by Chris Adams.  Merged some cases.
-
-2001-05-31  Werner Koch  <wk@gnupg.org>
-
-       Released 1.1.3.
-
-       * configure.in: Use _gcry_ prefix when creating the cipher constructor.
-
-       * acconfig.h (_GCRYPT_IN_LIBGCRYPT): Define it here.
-
-2001-05-28  Werner Koch  <wk@gnupg.org>
-
-       * acinclude.m4 (GPH_PROG_DOCBOOK): Removed.
-       (GPH_PROG_DB2ANY): New. Taken from GPH.
-       * configure.in: Use it here.
-
-2000-12-19  Werner Koch  <wk@gnupg.org>
-
-       Major change:
-       Removed all GnuPG stuff and renamed this piece of software
-       to gcrypt.  The directory gcrypt has been renamed to src.
-
-2000-11-14  Werner Koch  <wk@gnupg.org>
-
-       Version 1.1.2 released.
-
-2000-11-13  Werner Koch  <wk@gnupg.org>
-
-       * acinclude.m4 (GNUPG_FIX_HDR_VERSION): VPATH build fix.
-
-2000-10-10  Werner Koch  <wk@gnupg.org>
-
-       * Makefile.am (dist-hook): Create the version file.
-       * configure.in: Set the libtool version here, removed the need
-       for the version file.
-
-Mon Sep 18 16:35:45 CEST 2000  Werner Koch  <wk@openit.de>
-
-        * acinclude.m4 (GNUPG_CHECK_MLOCK):  Removed that silly mkdir().
-
-        * configure.in:  Changes to allow for Solaris random device.
-        By Nils Ellmenreich.
-        (--with-egd-socket): New.
-
-        * configure.in (GNUPG_HOMEDIR): New.
-
-        * configure.in: Check for fstat64 and fopen64
-
-        * acinclude.m4 (GNUPG_CHECK_FAQPROG): New.
-        * configure.in: Test for this.
-
-        * configure.in (DYNLINK_MOD_CFLAGS): Fix by David Champion.
-
-Tue Aug 22 14:31:15 CEST 2000  Werner Koch  <wk@openit.de>
-
-        Version 1.1.1
-
-Fri Aug 18 14:27:14 CEST 2000  Werner Koch  <wk@openit.de>
-
-  * agent/: New.
-  * Makefile.am, configure.in: Support for the new directory.
-
-Mon Jul 17 16:35:47 CEST 2000  Werner Koch  <wk@>
-
-  * configure.in (mingw32): Changes to allow for mingw32msvc
-
-Fri Jul 14 19:38:23 CEST 2000  Werner Koch  <wk@>
-
-  The big merge between this one and the stable branch 1.0.  Still need
-  to merge TNANKS, AUTHORS and such.  It probaly does not compile yet.
-
-  * acinclude.m4 (GNUPG_CHECK_MLOCK): Fixed syntax error in C code.
-
-  * configure.in: Add check for termio.h, wait unctiosn and sigaction.
-
-  * acinclude.m4, configure.in (GNUPG_CHECK_GNUMAKE): New.
-
-  * acinclude.m4 (MKDIR_TAKES_ONE_ARG): Check some headers. By Gaël Quéri.
-
-  * configure.in (AM_INIT_AUTOMAKE): Use this now. By Gaël.
-
-  * acinclude.m4 (GNUPG_CHECK_EXPORTDYNAMIC): Replacement for
-  GNUPG_CHECK_RDYNAMIC which should handle gcc with non GNU ld nicer.
-  Contributed by Dave Dykstra.
-  * configure.in (GNYPG_CHECK_RDYNAMIC): Replaced by the new check.
-
-  * configure.in: Add a test for unisgned long long.
-
-  * configure.in (DYNLINK_MOD_CFLAGS): Set different for NetBSD.
-
-  * configure.in: Add check for clock_gettime
-
-  * configure.in (ALL_LINGUAS): Add nl.
-  * configure.in (ALL_LINGUAS): Add Esperanto.
-  * configure.in (ALL_LINGUAS): Add sv and ja.
-
-  * configure.in: Use /usr/local for CFLAGS and LDFLAGS when
-  target is freebsd.  By Rémi.
-
-  * configure.in: Do not set development version when the version has
-  a dash in it.  Suggested by Dave Dykstra.
-
-  * configure.in: Removed substitution for doc/gph/Makefile.
-  Do all the gcc warning only in maintainer mode.
-
-  * configure.in (dlopen): Use CHECK_FUNC for a test of dlopen in libc.
-  Suggested by Alexandre Oliva.
-  (-Wall): Moved the settting of gcc warning options near to the end
-  so that tests don't get confused.  Suggested by Paul D. Smith.
-
-  * acinclude.m4 (GNUPG_SYS_NM_PARSE): Added BSDI support.
-  (GNUPG_CHECK_RDYNAMIC): Ditto.
-
-  * acinclude.m4 (GNUPG_CHECK_MLOCK): Changed the way to test for
-  librt.  Test suggested by Jeff Long.
-
-  * acinclude.m4 (GNUPG_CHECK_MLOCK): Do librt check only when
-  we can't link a test program.  This way GNU systems don't need
-  to link against linrt.
-  (GNUPG_CHECK_IPC): Fixed use of TRY_COMPILE macro.  From Tim Mooney.
-
-  * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Add support for
-  DJGPP.
-  (GNUPG_CHECK_MLOCK): Check whether mlock sits in librt.
-
-  * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Add NetBSD. By Thomas Klausner.
-
-  * acconfig.h (HAVE_MLOCK): Added
-
-Mon Mar 13 19:22:46 CET 2000  Werner Koch  <wk@openit.de>
-
-       * configure.in: Now uses the Docbook M4s from GPH.
-
-Mon Jan 31 17:46:35 CET 2000  Werner Koch  <wk@>
-
-       * Makefile.am: Re-added tools. By Rémi.
-
-Mon Jan 31 16:37:34 CET 2000  Werner Koch  <wk@gnupg.de>
-
-       * configure.in: Create a symlink for types.h in gcrypt/.
-
-Thu Jan 27 18:00:44 CET 2000  Werner Koch  <wk@gnupg.de>
-
-       * configure.in (g10defs.h): Replaced by gnupg-defs.h
-
-Mon Jan 24 13:04:28 CET 2000  Werner Koch  <wk@gnupg.de>
-
-       * jnlib/ : New.
-
-       * configure.in: Do set development version when the version has
-       a dash in it.  Suggested by Dave Dykstra.
-
-Thu Dec  9 17:22:27 CET 1999  Werner Koch  <wk@gnupg.de>
-
-       * acinclude.m4 (GNUPG_FIX_HDR_VERSION): New.
-       * configure.in: Check and fix the version number of gcrypt/gcrypt.h
-       so that it is always the save as VERSION.
-
-Thu Oct 28 16:17:46 CEST 1999  Werner Koch  <wk@gnupg.de>
-
-       * Started with development series 1.1 on 1999-10-26
-
-Tue Oct 26 14:10:21 CEST 1999  Werner Koch  <wk@gnupg.de>
-
-       * README-alpha: New
-
-       * configure.in: Fixed quoting in test for development version.
-
-       * THANKS: Add entries for Michael, Brenno and J Horacio who did
-       very nice Howto documents - I apoligize for forgetting to mention them
-       earlier.
-
-Fri Sep 17 12:56:42 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-
-       * configure.in: Add "-lcap" when capabilities are requested.
-       Add the conditional CROSS_COMPILING.
-       * Makefile.am: Don't use checks when CROSS_COMPILING.
-
-
-Wed Sep 15 16:22:17 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-
-       * configure.in (ALL_LINGUAS): Add pt_PT.
-
-       * configure.in: Some tweaks for cross compiling under MingW32
-       * acconfig.h (USE_STATIC_RNDW32): New.
-
-Tue Sep  7 17:08:10 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-
-       * VERSION: Set to 1.0.0.
-
-Mon Sep  6 19:59:08 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-
-       * configure.in: Create makefile in doc/gph
-
-       * acinclude.m4 (GNUPG_FUNC_MKDIR_TAKES_ONE_ARG): New
-       * configure.in: use the above.
-
-Thu Sep  2 16:40:55 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-
-       * VERSION: Set to 0.9.11.
-
-Tue Aug 31 17:20:44 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * configure.in: Minor changes to the OS/2 and Mingw32 system labels.
-       Add a printable name for Hurd.
-
-Mon Aug 30 20:38:33 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * configure.in: Some support for DJGPP (Mark Elbrecht)
-
-Wed Aug  4 10:34:46 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * VERSION: Set to 0.9.10.
-
-Mon Jul 26 09:34:46 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): remove init of ac_cv_...
-
-       * Makefile.am (DISCLEANFILES): New
-
-Fri Jul 23 13:53:03 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * VERSION: Set to 0.9.9.
-
-       * configure.in: Print a notice when rndunix is used.
-
-Thu Jul 15 10:15:35 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Fixed last modification.
-
-Wed Jul  7 13:08:40 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * Makefile.am: Support for libtool.
-       * configure.in: Ditto.
-
-Tue Jun 29 21:44:25 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * configure.in (use_local_zlib): The lost dollar is back.
-
-       * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Add EMX case.
-       * configure.in: Another variant of the MX vendor string
-
-       * configure.in (--with-capabilities): Some test code (Remi).
-
-Sat Jun 26 12:15:59 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Support for HPUX and IRIX.
-       * configure.in (HAVE_DL_SHL_LOAD): New for HPUX (Dave Dykstra).
-
-       * VERSION: Now 0.9.8
-
-Wed Jun 16 20:16:21 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * configure.in: Add test for docbook-to-man
-
-Tue Jun 15 12:21:08 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * acinclude.m4 (GNUPG_SYS_NM_PARSE): Support for {net,free}bsd,
-
-Thu Jun 10 14:18:23 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * configure.in (ZLIB,GDBM): Check both, header and lib.
-
-Sat Jun  5 15:30:33 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * pkclist.c (key_present_in_pk_list): New (Michael).
-
-Tue May 25 19:50:32 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * configure.in (IS_DEVELOPMENT_VERSION): Fixed detection.
-
-Sun May 23 14:20:22 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): assume yes when
-       cross-compiling.
-
-Mon May 17 21:54:43 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * configure.in (socket): Fix for Unisys by Katsuhiro Kondou.
-
-Sat May  8 19:28:08 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * NEWS: Add a marker line which I forgot to do for 0.9.6.
-
-Thu May  6 14:18:17 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * README: Minor updates
-
-       * VERSION: Now 0.9.6
-
-Thu Apr  8 09:35:53 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Fix for
-                                              amiga-openbsd (Peter Reich)
-       (GNUPG_PROG_NM): Ditto
-
-Wed Apr  7 20:51:39 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * Makefile.am (g10defs.h): Removed.
-       * configure.in (AC_OUTPUT_COMMANDS): Create g10defs.h
-
-Sat Mar 20 12:55:33 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * VERSION: Now 0.9.5
-
-Sun Mar 14 19:34:36 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * acinclude.m4 (AM_SYS_SYMBOL_UNDERSCORE): Removed because it is
-       now in the latest libtool.
-
-Thu Mar 11 16:39:46 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * configure.in: Removed the need for libtool
-
-Mon Mar  8 20:47:17 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * configure.in (DLSYM_NEEDS_UNDERSCORE): Replaced.
-       * acinclude.in (AM_SYS_SYMBOL_UNDERSCORE): New.
-
-       * VERSION: Now 0.9.4
-
-Sun Feb 28 19:11:00 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * configure.in (dld): Test disabled.
-
-Fri Feb 26 17:55:41 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * encode.c (encode_simple): temporary fix.
-
-Wed Feb 24 11:07:27 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * configure.in: New option --enable-static-rnd.
-
-Mon Feb 22 20:04:00 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * BUGS: Now we assign bug numbers.
-       * OBUGS: New to keep rack o fixed bugs (CVS only)
-
-Fri Feb 19 18:01:54 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * VERSION: Released 0.9.3
-
-Fri Feb 19 15:49:15 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * acinclude.m4: Removed gettext macros.
-
-Tue Feb 16 14:10:02 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * configure.in (socket): Check for -lsocket and -lnsl.
-       (osf4): Disable all warnings for DEC's cc.
-       (-Wall): Add more warning options for gcc
-
-Sat Feb 13 12:04:43 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * configure.in: Changed detection of compiler flags.
-       * intl/ : Removed directory
-
-Wed Feb 10 17:15:39 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Fix for freebsd 2.2
-
-       * configure.in: a lot of changes to allow selection of modules.
-       Add support for OS/2.
-
-       * acinclude.m4: add some more caching
-
-       * README: Spelling and grammar corrections (John A. Martin)
-       * INSTALL: Ditto.
-
-Wed Jan 20 21:40:21 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * configure.in: --enable-m-guard is now default
-
-Wed Jan 13 12:49:36 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * INSTALL: Applied new information how to build rpms by Fabio Coatti
-       * Makefile.in (gnupg.spec): Changed the names.
-
-Tue Jan 12 11:17:18 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * config.links (m68k-atari-mint): New
-
-Tue Jan 12 09:17:19 CET 1999  Gaël Quéri <gqueri@mail.dotcom.fr>
-
-       * all: Fixed typos all over the place
-
-Sat Jan  9 16:02:23 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * configure.in: Add a way to statically link rndunix
-
-Sun Jan  3 15:28:44 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): New.
-       * configure.in (DYNLOAD_CFLAGS): Use result from CHECK_RDYNAMIC
-
-Wed Dec 23 13:18:14 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * README: Replaced the command overview with a short intro.
-
-Sat Dec 12 18:40:32 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * configure.in: Add check for dlopen in libc (Greg Troxel)
-       and a new define
-       * acconfig.h (DLSYM_NEEDS_UNDERSCORE): New.
-
-Thu Dec 10 20:15:36 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * acinclude.m (GNUPG_CHECK_PIC): New
-       * configure.in, acinclude.m4: Renamed all WK_ to GNUPG_
-
-Tue Dec  8 15:09:29 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
-
-       * VERSION: Set to 0.4.5
-
-Wed Nov 25 12:38:29 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * configure.in (USE_RNDLINUX): New.
-
-Fri Nov 20 19:34:57 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * VERSION: Released 0.4.4
-
-       * configure.in (try_asm_modules): For option --disable-asm
-
-Tue Nov 10 19:32:40 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * configure.in (MPI_SFLAGS): New.
-
-Tue Nov 10 13:44:53 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * ABOUT-NLS: New
-       * configure.in (AC_REVISION): New.
-
-Sun Nov  8 18:20:35 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * VERSION: Set to 0.4.3
-
-Sun Oct 25 19:49:37 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * Makefile.am (g10defs.h): New macro GNUPG_DATADIR.
-
-Wed Oct 21 17:24:24 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * configure.in: Removed gettext kludge
-       * acinclude.m4: Add patched AM_WITH_NKS macro
-
-Tue Oct 20 19:03:36 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * configure.in: Kludge to make AM_GNU_GETTEXT work,
-       changed some macors to more modern versions. Also
-       changeg the all makefiles to remove duplicate ../intl.
-       * acinclude.m4: Removed the gettext stuff, as this
-       already comes with automake now.
-
-Wed Oct 14 12:11:34 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * configure.in (NAME_OF_DEV_RANDOM): New.
-       (DYNLINK_MOD_CFLAGS): New.
-
-Thu Oct  8 10:55:15 1998  Werner Koch  (wk@isil.d.shuttle.de)
-
-       * Makefile.am (g10defs.h): creates include file
-       * acconfig.h: now includes g10defs.h
-       * configure.in: Removed G10_LOCALEDIR and GNUPG_LIB
-
-Thu Sep 17 18:49:40 1998  Werner Koch  (wk@(none))
-
-       * Makefile.am (dist-hook): Now creates RPM file.
-       * scripts/gnupg.spec: New template file for RPMs
-
-Thu Jul 30 19:17:07 1998  Werner Koch  (wk@(none))
-
-       * acinclude.h (WK_CHECK_IPC): New
-       * configure.in : Add checks for SysV IPC
+       Remove macro hacks for internal vs. external functions.  Part 2 and last.
+       * src/visibility.h: Remove remaining define/undef hacks for symbol
+       visibility.  Add macros to detect the use of the public functions.
+       Change all affected functions by replacing them by the x-macros.
+       * src/g10lib.h: Add internal prototypes.
+       (xtrymalloc, xtrycalloc, xtrymalloc_secure, xtrycalloc_secure)
+       (xtryrealloc, xtrystrdup, xmalloc, xcalloc, xmalloc_secure)
+       (xcalloc_secure, xrealloc, xstrdup, xfree): New macros.
+
+2013-12-11  Werner Koch  <wk@gnupg.org>
+
+       random: Add a feature to close device file descriptors.
+       * src/gcrypt.h.in (GCRYCTL_CLOSE_RANDOM_DEVICE): New.
+       * src/global.c (_gcry_vcontrol): Call _gcry_random_close_fds.
+       * random/random.c (_gcry_random_close_fds): New.
+       * random/random-csprng.c (_gcry_rngcsprng_close_fds): New.
+       * random/random-fips.c (_gcry_rngfips_close_fds): New.
+       * random/random-system.c (_gcry_rngsystem_close_fds): New.
+       * random/rndlinux.c (open_device): Add arg retry.
+       (_gcry_rndlinux_gather_random): Add mode to close open fds.
+
+       * tests/random.c (check_close_random_device): New.
+       (main): Call new test.
+
+2013-12-10  Werner Koch  <wk@gnupg.org>
+
+       Fix last commit (9a37470c)
+       * src/secmem.c (lock_pool): Remove remaining line.  Reported by Ian
+       Goldberg.
+
+2013-12-09  Werner Koch  <wk@gnupg.org>
+
+       Fix one-off memory leak when build with Linux capability support.
+       * src/secmem.c (lock_pool, secmem_init): Use cap_free.  Reported by
+       Mike Crowe <mac@mcrowe.com>.
+
+2013-12-09  David 'Digit' Turner  <digit@google.com>
+
+       Update libtool to support Android.
+       * m4/libtool.m4: Add "linux*android*" case.  Taken from the libtool
+       repository.
+
+2013-12-09  Werner Koch  <wk@gnupg.org>
+
+       tests: Speed up benchmarks in regression test mode.
+       * tests/tsexp.c (check_extract_param): Fix compiler warning.
+       * tests/Makefile.am (TESTS_ENVIRONMENT): Set GCRYPT_IN_REGRESSION_TEST.
+       * tests/bench-slope.c (main): Speed up if in regression test mode.
+       * tests/benchmark.c (main): Ditto.
+
+       tests: Add --csv option to bench-slope.
+       * tests/bench-slope.c (STR, STR2): New.
+       (cvs_mode): New.
+       (num_measurement_repetitions): New.  Replace use of
+       NUM_MEASUREMENT_REPETITIONS by this.
+       (current_section_name, current_algo_name, current_mode_name): New.
+       (bench_print_result_csv): New.
+       (bench_print_result_std): Rename from bench_print_result.
+       (bench_print_result): New. Divert depending on CSV_MODE.
+       (bench_print_header, bench_print_footer): take care of CSV_MODE.
+       (bench_print_algo, bench_print_mode): New.  Use them instead of
+       explicit printfs.
+       (main): Add options --csv and --repetitions.
+
+2013-12-07  Werner Koch  <wk@gnupg.org>
+
+       sexp: Allow long names and white space in gcry_sexp_extract_param.
+       * src/sexp.c (_gcry_sexp_vextract_param): Skip white space.  Support
+       long parameter names.
+       * tests/tsexp.c (check_extract_param): Add test cases for long parameter
+       names and white space.
+
+2013-12-06  Werner Koch  <wk@gnupg.org>
+
+       ecc: Merge partly duplicated code.
+       * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_sign): Factor A hashing out to ...
+       (_gcry_ecc_eddsa_compute_h_d): new function.
+       * cipher/ecc-misc.c (_gcry_ecc_compute_public): Use new function.
+       (reverse_buffer): Remove.
+
+       ecc: Remove unused internal function.
+       * src/cipher-proto.h (gcry_pk_spec): Remove get_param.
+       * cipher/ecc-curves.c (_gcry_ecc_get_param_sexp): Merge in code from
+       _gcry_ecc_get_param.
+       (_gcry_ecc_get_param): Remove.
+       * cipher/ecc.c (_gcry_pubkey_spec_ecc): Remove _gcry_ecc_get_param.
+
+2013-12-06  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Fix building on mingw32.
+       * src/gcrypt-int.h: Include <types.h>.
+
+2013-12-05  Werner Koch  <wk@gnupg.org>
+
+       ecc: Change OID for Ed25519.
+       * cipher/ecc-curves.c (curve_aliased): Add more suitable OID for
+       Ed25519.
+
+       Remove macro hacks for internal vs. external functions.  Part 1.
+       * src/visibility.h: Remove almost all define/undef hacks for symbol
+       visibility.  Add macros to detect the use of the public functions.
+       Change all affected functions by prefixing them explicitly with an
+       underscore and change all internal callers to call the underscore
+       prefixed versions.  Provide convenience macros from sexp and mpi
+       functions.
+       * src/visibility.c: Change all functions to use only gpg_err_code_t
+       and translate to gpg_error_t only in visibility.c.
+
+2013-12-04  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       mpi: add inline assembly for x86-64.
+       * mpi/longlong.h [__x86_64] (add_ssaaaa, sub_ddmmss, umul_ppmm)
+       (udiv_qrnnd, count_leading_zeros, count_trailing_zeros): New.
+
+2013-12-04  NIIBE Yutaka  <gniibe@fsij.org>
+
+       mpi: fix gcry_mpi_powm for negative base.
+       * mpi/mpi-pow.c (gcry_mpi_powm) [USE_ALGORITHM_SIMPLE_EXPONENTIATION]:
+       Fix for the case where BASE is negative.
+       * tests/mpitests.c (test_powm): Add a test case of (-17)^6 mod 19.
+
+2013-12-03  Werner Koch  <wk@gnupg.org>
+
+       Add build support for ppc64le.
+       * config.guess, config.sub: Update to latest version (2013-11-29).
+       * m4/libtool.m4: Add patches for ppc64le.
+
+2013-12-03  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       rijndael: fix compiler warning on aarch64.
+       * cipher/rijndael.c (do_setkey): Use braces for empty if statement
+       instead of semicolon.
+
+       Add aarch64 (arm64) mpi assembly.
+       * mpi/aarch64/mpi-asm-defs.h: New.
+       * mpi/aarch64/mpih-add1.S: New.
+       * mpi/aarch64/mpih-mul1.S: New.
+       * mpi/aarch64/mpih-mul2.S: New.
+       * mpi/aarch64/mpih-mul3.S: New.
+       * mpi/aarch64/mpih-sub1.S: New.
+       * mpi/config.links [host=aarch64-*-*]: Add configguration for aarch64
+       assembly.
+       * mpi/longlong.h [__aarch64__] (add_ssaaaa, sub_ddmmss, umul_ppmm)
+       (count_leading_zeros): New.
+
+2013-12-02  Werner Koch  <wk@gnupg.org>
+
+       ecc: Use constant time point operation for Twisted Edwards.
+       * mpi/ec.c (_gcry_mpi_ec_mul_point): Try to do a constant time
+       operation if needed.
+       * tests/benchmark.c (main): Add option --use-secmem.
+
+       ecc: Make gcry_pk_testkey work for Ed25519.
+       * cipher/ecc-misc.c (_gcry_ecc_compute_public): Add optional args G
+       and d.  Change all callers.
+       * cipher/ecc.c (gen_y_2): Remove.
+       (check_secret_key): Use generic public key compute function.  Adjust
+       for use with Ed25519 and EdDSA.
+       (nist_generate_key): Do not use the compliant key thingy for Ed25519.
+       (ecc_check_secret_key): Make parameter parsing similar to the other
+       functions.
+       * cipher/ecc-curves.c (domain_parms): Zero prefix some parameters so
+       that _gcry_ecc_update_curve_param works correctly.
+       * tests/keygen.c (check_ecc_keys): Add "param" flag.  Check all
+       Ed25519 keys.
+
+       ecc: Fix eddsa point decompression.
+       * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_recover_x): Fix the negative
+       case.
+
+       ecc: Fix gcry_mpi_ec_curve_point for Weierstrass.
+       * mpi/ec.c (_gcry_mpi_ec_curve_point): Use correct equation.
+       (ec_pow3): New.
+       (ec_p_init): Always copy B.
+
+       mpi: Introduce 4 user flags for gcry_mpi_t.
+       * src/gcrypt.h.in (GCRYMPI_FLAG_USER1, GCRYMPI_FLAG_USER2)
+       (GCRYMPI_FLAG_USER3, GCRYMPI_FLAG_USER4): New.
+       * mpi/mpiutil.c (gcry_mpi_set_flag, gcry_mpi_clear_flag)
+       (gcry_mpi_get_flag, _gcry_mpi_free): Implement them.
+       (gcry_mpi_set_opaque): Keep user flags.
+
+2013-11-29  Vladimir 'φ-coder/phcoder' Serbinenko  <phcoder@gmail.com>
+
+       Fix armv3 compile error.
+       * mpi/longlong.h [__arm__ && __ARM_ARCH < 4] (umul_ppmm): Use
+       __AND_CLOBBER_CC instead of __CLOBBER_CC.
+
+       longlong.h on mips with clang.
+       * mpi/longlong.h [__mips__]: Use C-language version with clang.
+
+2013-11-24  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Camellia: Tweaks for AES-NI implementations.
+       * cipher/camellia-aesni-avx-amd64.S: Align stack to 16 bytes; tweak
+       key-setup for small speed up.
+       * cipher/camellia-aesni-avx2-amd64.S: Use vmovdqu even with aligned
+       stack; reorder vinsert128 instructions; use rbp for stack frame.
+
+2013-11-21  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Add GMAC to MAC API.
+       * cipher/Makefile.am: Add 'mac-gmac.c'.
+       * cipher/mac-gmac.c: New.
+       * cipher/mac-internal.h (gcry_mac_handle): Add 'u.gcm'.
+       (_gcry_mac_type_spec_gmac_aes, _gcry_mac_type_spec_gmac_twofish)
+       (_gcry_mac_type_spec_gmac_serpent, _gcry_mac_type_spec_gmac_seed)
+       (_gcry_mac_type_spec_gmac_camellia): New externs.
+       * cipher/mac.c (mac_list): Add GMAC specifications.
+       * doc/gcrypt.texi: Add mention of GMAC.
+       * src/gcrypt.h.in (gcry_mac_algos): Add GCM algorithms.
+       * tests/basic.c (check_one_mac): Add support for MAC IVs.
+       (check_mac): Add support for MAC IVs and add GMAC test vectors.
+       * tests/bench-slope.c (mac_bench): Iterate algorithm numbers to 499.
+       * tests/benchmark.c (mac_bench): Iterate algorithm numbers to 499.
+
+       GCM: Move gcm_table initialization to setkey.
+       * cipher/cipher-gcm.c: Change all 'c->u_iv.iv' to
+       'c->u_mode.gcm.u_ghash_key.key'.
+       (_gcry_cipher_gcm_setkey): New.
+       (_gcry_cipher_gcm_initiv): Move ghash initialization to function above.
+       * cipher/cipher-internal.h (gcry_cipher_handle): Add
+       'u_mode.gcm.u_ghash_key'; Reorder 'u_mode.gcm' members for partial
+       clearing in gcry_cipher_reset.
+       (_gcry_cipher_gcm_setkey): New prototype.
+       * cipher/cipher.c (cipher_setkey): Add GCM setkey.
+       (cipher_reset): Clear 'u_mode' only partially for GCM.
+
+2013-11-20  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       GCM: Add support for split data buffers and online operation.
+       * cipher/cipher-gcm.c (do_ghash_buf): Add buffering for less than
+       blocksize length input and padding handling.
+       (_gcry_cipher_gcm_encrypt, _gcry_cipher_gcm_decrypt): Add handling
+       for AAD padding and check if data has already being padded.
+       (_gcry_cipher_gcm_authenticate): Check that AAD or data has not being
+       padded yet.
+       (_gcry_cipher_gcm_initiv): Clear padding marks.
+       (_gcry_cipher_gcm_tag): Add finalization and padding; Clear sensitive
+       data from cipher handle, since they are not used after generating tag.
+       * cipher/cipher-internal.h (gcry_cipher_handle): Add 'u_mode.gcm.macbuf',
+       'u_mode.gcm.mac_unused', 'u_mode.gcm.ghash_data_finalized' and
+       'u_mode.gcm.ghash_aad_finalized'.
+       * tests/basic.c (check_gcm_cipher): Rename to...
+       (_check_gcm_cipher): ...this and add handling for different buffer step
+       lengths; Enable per byte buffer testing.
+       (check_gcm_cipher): Call _check_gcm_cipher with different buffer step
+       sizes.
+
+       GCM: Use size_t for buffer sizes.
+       * cipher/cipher-gcm.c (ghash, gcm_bytecounter_add, do_ghash_buf)
+       (_gcry_cipher_gcm_encrypt, _gcry_cipher_gcm_decrypt)
+       (_gcry_cipher_gcm_authenticate, _gcry_cipher_gcm_geniv)
+       (_gcry_cipher_gcm_tag): Use size_t for buffer lengths.
+       * cipher/cipher-internal.h (_gcry_cipher_gcm_encrypt)
+       (_gcry_cipher_gcm_decrypt, _gcry_cipher_gcm_authenticate): Use size_t
+       for buffer lengths.
+
+       GCM: add FIPS mode restrictions.
+       * cipher/cipher-gcm.c (_gcry_cipher_gcm_encrypt)
+       (_gcry_cipher_gcm_get_tag): Do not allow using in FIPS mode is setiv
+       was invocated directly.
+       (_gcry_cipher_gcm_setiv): Rename to...
+       (_gcry_cipher_gcm_initiv): ...this.
+       (_gcry_cipher_gcm_setiv): New setiv function with check for FIPS mode.
+       [TODO] (_gcry_cipher_gcm_getiv): New.
+       * cipher/cipher-internal.h (gcry_cipher_handle): Add
+       'u_mode.gcm.disallow_encryption_because_of_setiv_in_fips_mode'.
+
+       GCM: Add clearing and checking of marks.tag.
+       * cipher/cipher-gcm.c (_gcry_cipher_gcm_encrypt)
+       (_gcry_cipher_gcm_decrypt, _gcry_cipher_gcm_authenticate): Make sure
+       that tag has not been finalized yet.
+       (_gcry_cipher_gcm_setiv): Clear 'marks.tag'.
+
+       GCM: Add stack burning.
+       * cipher/cipher-gcm.c (do_ghash, ghash): Return stack burn depth.
+       (setupM): Wipe 'tmp' buffer.
+       (do_ghash_buf): Wipe 'tmp' buffer and add stack burning.
+
+       Add aggregated bulk processing for GCM on x86-64.
+       * cipher/cipher-gcm.c [__x86_64__] (gfmul_pclmul_aggr4): New.
+       (ghash) [GCM_USE_INTEL_PCLMUL]: Add aggregated bulk processing
+       for __x86_64__.
+       (setupM) [__x86_64__]: Add initialization for aggregated bulk
+       processing.
+
+       GCM: Tweak Intel PCLMUL ghash loop for small speed-up.
+       * cipher/cipher-gcm.c (do_ghash): Mark 'inline'.
+       [GCM_USE_INTEL_PCLMUL] (do_ghash_pclmul): Rename to...
+       [GCM_USE_INTEL_PCLMUL] (gfmul_pclmul): ..this and make inline function.
+       (ghash) [GCM_USE_INTEL_PCLMUL]: Preload data before ghash-pclmul loop.
+
+       GCM: Use counter mode code for speed-up.
+       * cipher/cipher-gcm.c (ghash): Add process for multiple blocks.
+       (gcm_bytecounter_add, gcm_add32_be128, gcm_check_datalen)
+       (gcm_check_aadlen_or_ivlen, do_ghash_buf): New functions.
+       (_gcry_cipher_gcm_encrypt, _gcry_cipher_gcm_decrypt)
+       (_gcry_cipher_gcm_authenticate, _gcry_cipher_gcm_set_iv)
+       (_gcry_cipher_gcm_tag): Adjust to use above new functions and
+       counter mode functions for encryption/decryption.
+       * cipher/cipher-internal.h (gcry_cipher_handle): Remove 'length'; Add
+       'u_mode.gcm.(addlen|datalen|tagiv|datalen_over_limits)'.
+       (_gcry_cipher_gcm_setiv): Return gcry_err_code_t.
+       * cipher/cipher.c (cipher_setiv): Return error code.
+       (_gcry_cipher_setiv): Handle error code from 'cipher_setiv'.
+
+       Add Intel PCLMUL acceleration for GCM.
+       * cipher/cipher-gcm.c (fillM): Rename...
+       (do_fillM): ...to this.
+       (ghash): Remove.
+       (fillM): New macro.
+       (GHASH): Use 'do_ghash' instead of 'ghash'.
+       [GCM_USE_INTEL_PCLMUL] (do_ghash_pclmul): New.
+       (ghash): New.
+       (setupM): New.
+       (_gcry_cipher_gcm_encrypt, _gcry_cipher_gcm_decrypt)
+       (_gcry_cipher_gcm_authenticate, _gcry_cipher_gcm_setiv)
+       (_gcry_cipher_gcm_tag): Use 'ghash' instead of 'GHASH' and
+       'c->u_mode.gcm.u_tag.tag' instead of 'c->u_tag.tag'.
+       * cipher/cipher-internal.h (GCM_USE_INTEL_PCLMUL): New.
+       (gcry_cipher_handle): Move 'u_tag' and 'gcm_table' under
+       'u_mode.gcm'.
+       * configure.ac (pclmulsupport, gcry_cv_gcc_inline_asm_pclmul): New.
+       * src/g10lib.h (HWF_INTEL_PCLMUL): New.
+       * src/global.c: Add "intel-pclmul".
+       * src/hwf-x86.c (detect_x86_gnuc): Add check for Intel PCLMUL.
+
+       GCM: GHASH optimizations.
+       * cipher/cipher-gcm.c [GCM_USE_TABLES] (gcmR, ghash): Replace with new.
+       [GCM_USE_TABLES] [GCM_TABLES_USE_U64] (bshift, fillM, do_ghash): New.
+       [GCM_USE_TABLES] [!GCM_TABLES_USE_U64] (bshift, fillM): Replace with
+       new.
+       [GCM_USE_TABLES] [!GCM_TABLES_USE_U64] (do_ghash): New.
+       (_gcry_cipher_gcm_tag): Remove extra memcpy to outbuf and use
+       buf_eq_const for comparing authentication tag.
+       * cipher/cipher-internal.h (gcry_cipher_handle): Different 'gcm_table'
+       for 32-bit and 64-bit platforms.
+
+       Add some documentation for GCM mode.
+       * doc/gcrypt.texi: Add mention of GCM mode.
+
+2013-11-19  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
+
+       Initial implementation of GCM.
+       * cipher/Makefile.am: Add 'cipher-gcm.c'.
+       * cipher/cipher-ccm.c (_gcry_ciphert_ccm_set_lengths)
+       (_gcry_cipher_ccm_authenticate, _gcry_cipher_ccm_tag)
+       (_gcry_cipher_ccm_encrypt, _gcry_cipher_ccm_decrypt): Change
+       'c->u_mode.ccm.tag' to 'c->marks.tag'.
+       * cipher/cipher-gcm.c: New.
+       * cipher/cipher-internal.h (GCM_USE_TABLES): New.
+       (gcry_cipher_handle): Add 'marks.tag', 'u_tag', 'length' and
+       'gcm_table'; Remove 'u_mode.ccm.tag'.
+       (_gcry_cipher_gcm_encrypt, _gcry_cipher_gcm_decrypt)
+       (_gcry_cipher_gcm_setiv, _gcry_cipher_gcm_authenticate)
+       (_gcry_cipher_gcm_get_tag, _gcry_cipher_gcm_check_tag): New.
+       * cipher/cipher.c (_gcry_cipher_open_internal, cipher_setkey)
+       (cipher_encrypt, cipher_decrypt, _gcry_cipher_authenticate)
+       (_gcry_cipher_gettag, _gcry_cipher_checktag): Add GCM mode handling.
+       * src/gcrypt.h.in (gcry_cipher_modes): Add GCRY_CIPHER_MODE_GCM.
+       (GCRY_GCM_BLOCK_LEN): New.
+       * tests/basic.c (check_gcm_cipher): New.
+       (check_ciphers): Add GCM check.
+       (check_cipher_modes): Call 'check_gcm_cipher'.
+       * tests/bench-slope.c (bench_gcm_encrypt_do_bench)
+       (bench_gcm_decrypt_do_bench, bench_gcm_authenticate_do_bench)
+       (gcm_encrypt_ops, gcm_decrypt_ops, gcm_authenticate_ops): New.
+       (cipher_modes): Add GCM enc/dec/auth.
+       (cipher_bench_one): Limit GCM to block ciphers with 16 byte block-size.
+       * tests/benchmark.c (cipher_bench): Add GCM.
+
+2013-11-19  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Camellia: fix compiler warning.
+       * cipher/camellia-glue.c (camellia_setkey): Use braces around empty if
+       statement.
+
+       Tweak Camellia-AVX key-setup for small speed-up.
+       * cipher/camellia-aesni-avx-amd64.S (camellia_f): Merge S-function output
+       rotation with P-function.
+
+       Add CMAC (Cipher-based MAC) to MAC API.
+       * cipher/Makefile.am: Add 'cipher-cmac.c' and 'mac-cmac.c'.
+       * cipher/cipher-cmac.c: New.
+       * cipher/cipher-internal.h (gcry_cipher_handle.u_mode): Add 'cmac'.
+       * cipher/cipher.c (gcry_cipher_open): Rename to...
+       (_gcry_cipher_open_internal): ...this and add CMAC.
+       (gcry_cipher_open): New wrapper that disallows use of internal
+       modes (CMAC) from outside.
+       (cipher_setkey, cipher_encrypt, cipher_decrypt)
+       (_gcry_cipher_authenticate, _gcry_cipher_gettag)
+       (_gcry_cipher_checktag): Add handling for CMAC mode.
+       (cipher_reset): Do not reset 'marks.key' and do not clear subkeys in
+       'u_mode' in CMAC mode.
+       * cipher/mac-cmac.c: New.
+       * cipher/mac-internal.h: Add CMAC support and algorithms.
+       * cipher/mac.c: Add CMAC algorithms.
+       * doc/gcrypt.texi: Add documentation for CMAC.
+       * src/cipher.h (gcry_cipher_internal_modes): New.
+       (_gcry_cipher_open_internal, _gcry_cipher_cmac_authenticate)
+       (_gcry_cipher_cmac_get_tag, _gcry_cipher_cmac_check_tag)
+       (_gcry_cipher_cmac_set_subkeys): New prototypes.
+       * src/gcrypt.h.in (gcry_mac_algos): Add CMAC algorithms.
+       * tests/basic.c (check_mac): Add CMAC test vectors.
+
+2013-11-16  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Add new MAC API, initially with HMAC.
+       * cipher/Makefile.am: Add 'mac.c', 'mac-internal.h' and 'mac-hmac.c'.
+       * cipher/bufhelp.h (buf_eq_const): New.
+       * cipher/cipher-ccm.c (_gcry_cipher_ccm_tag): Use 'buf_eq_const' for
+       constant-time compare.
+       * cipher/mac-hmac.c: New.
+       * cipher/mac-internal.h: New.
+       * cipher/mac.c: New.
+       * doc/gcrypt.texi: Add documentation for MAC API.
+       * src/gcrypt-int.h [GPG_ERROR_VERSION_NUMBER < 1.13]
+       (GPG_ERR_MAC_ALGO): New.
+       * src/gcrypt.h.in (gcry_mac_handle, gcry_mac_hd_t, gcry_mac_algos)
+       (gcry_mac_flags, gcry_mac_open, gcry_mac_close, gcry_mac_ctl)
+       (gcry_mac_algo_info, gcry_mac_setkey, gcry_mac_setiv, gcry_mac_write)
+       (gcry_mac_read, gcry_mac_verify, gcry_mac_get_algo_maclen)
+       (gcry_mac_get_algo_keylen, gcry_mac_algo_name, gcry_mac_map_name)
+       (gcry_mac_reset, gcry_mac_test_algo): New.
+       * src/libgcrypt.def (gcry_mac_open, gcry_mac_close, gcry_mac_ctl)
+       (gcry_mac_algo_info, gcry_mac_setkey, gcry_mac_setiv, gcry_mac_write)
+       (gcry_mac_read, gcry_mac_verify, gcry_mac_get_algo_maclen)
+       (gcry_mac_get_algo_keylen, gcry_mac_algo_name, gcry_mac_map_name): New.
+       * src/libgcrypt.vers (gcry_mac_open, gcry_mac_close, gcry_mac_ctl)
+       (gcry_mac_algo_info, gcry_mac_setkey, gcry_mac_setiv, gcry_mac_write)
+       (gcry_mac_read, gcry_mac_verify, gcry_mac_get_algo_maclen)
+       (gcry_mac_get_algo_keylen, gcry_mac_algo_name, gcry_mac_map_name): New.
+       * src/visibility.c (gcry_mac_open, gcry_mac_close, gcry_mac_ctl)
+       (gcry_mac_algo_info, gcry_mac_setkey, gcry_mac_setiv, gcry_mac_write)
+       (gcry_mac_read, gcry_mac_verify, gcry_mac_get_algo_maclen)
+       (gcry_mac_get_algo_keylen, gcry_mac_algo_name, gcry_mac_map_name): New.
+       * src/visibility.h (gcry_mac_open, gcry_mac_close, gcry_mac_ctl)
+       (gcry_mac_algo_info, gcry_mac_setkey, gcry_mac_setiv, gcry_mac_write)
+       (gcry_mac_read, gcry_mac_verify, gcry_mac_get_algo_maclen)
+       (gcry_mac_get_algo_keylen, gcry_mac_algo_name, gcry_mac_map_name): New.
+       * tests/basic.c (check_one_mac, check_mac): New.
+       (main): Call 'check_mac'.
+       * tests/bench-slope.c (bench_print_header, bench_print_footer): Allow
+       variable algorithm name width.
+       (_cipher_bench, hash_bench): Update to above change.
+       (bench_hash_do_bench): Add 'gcry_md_reset'.
+       (bench_mac_mode, bench_mac_init, bench_mac_free, bench_mac_do_bench)
+       (mac_ops, mac_modes, mac_bench_one, _mac_bench, mac_bench): New.
+       (main): Add 'mac' benchmark options.
+       * tests/benchmark.c (mac_repetitions, mac_bench): New.
+       (main): Add 'mac' benchmark options.
+
+       Use correct blocksize of 32 bytes for GOSTR3411-94 HMAC.
+       * cipher/md.c (md_open): Set macpads_Bsize to 32 for
+       GCRY_MD_GOST24311_94.
+
+2013-11-15  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       cipher: use size_t for internal buffer lengths.
+       * cipher/arcfour.c (do_encrypt_stream, encrypt_stream): Use 'size_t'
+       for buffer lengths.
+       * cipher/blowfish.c (_gcry_blowfish_ctr_enc, _gcry_blowfish_cbc_dec)
+       (_gcry_blowfish_cfb_dec): Ditto.
+       * cipher/camellia-glue.c (_gcry_camellia_ctr_enc)
+       (_gcry_camellia_cbc_dec, _gcry_blowfish_cfb_dec): Ditto.
+       * cipher/cast5.c (_gcry_cast5_ctr_enc, _gcry_cast5_cbc_dec)
+       (_gcry_cast5_cfb_dec): Ditto.
+       * cipher/cipher-aeswrap.c (_gcry_cipher_aeswrap_encrypt)
+       (_gcry_cipher_aeswrap_decrypt): Ditto.
+       * cipher/cipher-cbc.c (_gcry_cipher_cbc_encrypt)
+       (_gcry_cipher_cbc_decrypt): Ditto.
+       * cipher/cipher-ccm.c (_gcry_cipher_ccm_encrypt)
+       (_gcry_cipher_ccm_decrypt): Ditto.
+       * cipher/cipher-cfb.c (_gcry_cipher_cfb_encrypt)
+       (_gcry_cipher_cfb_decrypt): Ditto.
+       * cipher/cipher-ctr.c (_gcry_cipher_ctr_encrypt): Ditto.
+       * cipher/cipher-internal.h (gcry_cipher_handle->bulk)
+       (_gcry_cipher_cbc_encrypt, _gcry_cipher_cbc_decrypt)
+       (_gcry_cipher_cfb_encrypt, _gcry_cipher_cfb_decrypt)
+       (_gcry_cipher_ofb_encrypt, _gcry_cipher_ctr_encrypt)
+       (_gcry_cipher_aeswrap_encrypt, _gcry_cipher_aeswrap_decrypt)
+       (_gcry_cipher_ccm_encrypt, _gcry_cipher_ccm_decrypt): Ditto.
+       * cipher/cipher-ofb.c (_gcry_cipher_cbc_encrypt): Ditto.
+       * cipher/cipher-selftest.h (gcry_cipher_bulk_cbc_dec_t)
+       (gcry_cipher_bulk_cfb_dec_t, gcry_cipher_bulk_ctr_enc_t): Ditto.
+       * cipher/cipher.c (cipher_setkey, cipher_setiv, do_ecb_crypt)
+       (do_ecb_encrypt, do_ecb_decrypt, cipher_encrypt)
+       (cipher_decrypt): Ditto.
+       * cipher/rijndael.c (_gcry_aes_ctr_enc, _gcry_aes_cbc_dec)
+       (_gcry_aes_cfb_dec, _gcry_aes_cbc_enc, _gcry_aes_cfb_enc): Ditto.
+       * cipher/salsa20.c (salsa20_setiv, salsa20_do_encrypt_stream)
+       (salsa20_encrypt_stream, salsa20r12_encrypt_stream): Ditto.
+       * cipher/serpent.c (_gcry_serpent_ctr_enc, _gcry_serpent_cbc_dec)
+       (_gcry_serpent_cfb_dec): Ditto.
+       * cipher/twofish.c (_gcry_twofish_ctr_enc, _gcry_twofish_cbc_dec)
+       (_gcry_twofish_cfb_dec): Ditto.
+       * src/cipher-proto.h (gcry_cipher_stencrypt_t)
+       (gcry_cipher_stdecrypt_t, cipher_setiv_fuct_t): Ditto.
+       * src/cipher.h (_gcry_aes_cfb_enc, _gcry_aes_cfb_dec)
+       (_gcry_aes_cbc_enc, _gcry_aes_cbc_dec, _gcry_aes_ctr_enc)
+       (_gcry_blowfish_cfb_dec, _gcry_blowfish_cbc_dec)
+       (_gcry_blowfish_ctr_enc, _gcry_cast5_cfb_dec, _gcry_cast5_cbc_dec)
+       (_gcry_cast5_ctr_enc, _gcry_camellia_cfb_dec, _gcry_camellia_cbc_dec)
+       (_gcry_camellia_ctr_enc, _gcry_serpent_cfb_dec, _gcry_serpent_cbc_dec)
+       (_gcry_serpent_ctr_enc, _gcry_twofish_cfb_dec, _gcry_twofish_cbc_dec)
+       (_gcry_twofish_ctr_enc): Ditto.
+
+       Camellia: Add AVX/AES-NI key setup.
+       * cipher/camellia-aesni-avx-amd64.S (key_bitlength, key_table): New
+       order of fields in ctx.
+       (camellia_f, vec_rol128, vec_ror128): New macros.
+       (__camellia_avx_setup128, __camellia_avx_setup256)
+       (_gcry_camellia_aesni_avx_keygen): New functions.
+       * cipher/camellia-aesni-avx2-amd64.S (key_bitlength, key_table): New
+       order of fields in ctx.
+       * cipher/camellia-arm.S (CAMELLIA_TABLE_BYTE_LEN, key_length): Remove
+       unused macros.
+       * cipher/camellia-glue.c (CAMELLIA_context): Move keytable to head for
+       better alignment; Make 'use_aesni_avx' and 'use_aesni_avx2' bitfield
+       members.
+       [USE_AESNI_AVX] (_gcry_camellia_aesni_avx_keygen): New prototype.
+       (camellia_setkey) [USE_AESNI_AVX || USE_AESNI_AVX2]: Read hw features
+       to variable 'hwf' and match features from it.
+       (camellia_setkey) [USE_AESNI_AVX]: Use AES-NI/AVX key setup if
+       available.
+
+       Avoid unneeded stack burning with AES-NI and reduce number of 'decryption_prepared' checks
+       * cipher/rijndael.c (RIJNDAEL_context): Make 'decryption_prepared',
+       'use_padlock' and 'use_aesni' 1-bit members in bitfield.
+       (do_setkey): Move 'hwfeatures' inside [USE_AESNI || USE_PADLOCK].
+       (do_aesni_enc_aligned): Rename to...
+       (do_aesni_enc): ...this, as function does not require aligned input.
+       (do_aesni_dec_aligned): Rename to...
+       (do_aesni_dec): ...this, as function does not require aligned input.
+       (do_aesni): Remove.
+       (rijndael_encrypt): Call 'do_aesni_enc' instead of 'do_aesni'.
+       (rijndael_decrypt): Call 'do_aesni_dec' instead of 'do_aesni'.
+       (check_decryption_preparation): New.
+       (do_decrypt): Remove 'decryption_prepared' check.
+       (rijndael_decrypt): Ditto and call 'check_decryption_preparation'.
+       (_gcry_aes_cbc_dec): Ditto.
+       (_gcry_aes_cfb_enc): Add 'burn_depth' and burn stack only when needed.
+       (_gcry_aes_cbc_enc): Ditto.
+       (_gcry_aes_ctr_enc): Ditto.
+       (_gcry_aes_cfb_dec): Ditto.
+       (_gcry_aes_cbc_dec): Ditto and correct clearing of 'savebuf'.
+
+2013-11-14  Werner Koch  <wk@gnupg.org>
+
+       md: Fix hashing for data >= 256 GB.
+       * cipher/hash-common.h (gcry_md_block_ctx): Add "nblocks_high".
+       * cipher/hash-common.c (_gcry_md_block_write): Bump NBLOCKS_HIGH.
+       * cipher/md4.c (md4_init, md4_final): Take care of NBLOCKS_HIGH.
+       * cipher/md5.c (md5_init, md5_final): Ditto.
+       * cipher/rmd160.c (_gcry_rmd160_init, rmd160_final): Ditto.
+       * cipher/sha1.c (sha1_init, sha1_final): Ditto.
+       * cipher/sha256.c (sha256_init, sha224_init, sha256_final): Ditto.
+       * cipher/sha512.c (sha512_init, sha384_init, sha512_final): Ditto.
+       * cipher/tiger.c (do_init, tiger_final): Ditto.
+       * cipher/whirlpool.c (whirlpool_final): Ditto.
+
+       * cipher/md.c (gcry_md_algo_info): Add GCRYCTL_SELFTEST.
+       (_gcry_md_selftest): Return "not implemented" as required.
+       * tests/hashtest.c: New.
+       * tests/genhashdata.c: New.
+       * tests/Makefile.am (TESTS): Add hashtest.
+       (noinst_PROGRAMS): Add genhashdata
+
+2013-11-13  Christian Grothoff  <christian@grothoff.org>
+
+       ecc: Fix key generation for a plain Ed25519 key.
+       * cipher/ecc.c (nist_generate_key): Use custom code for ED25519.
+
+       ecc: Fix some memory leaks.
+       * cipher/ecc-curves.c (_gcry_mpi_ec_new): Free ec->b before assigning.
+       * cipher/ecc.c (nist_generate_key): Release Q.
+       * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_genkey): Ditto.
+
+2013-11-11  Werner Koch  <wk@gnupg.org>
+
+       ecc: Change keygrip computation for Ed25519+EdDSA.
+       * cipher/ecc.c (compute_keygrip): Rework.
+       * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_ensure_compact): New.
+       * cipher/ecc-curves.c (_gcry_ecc_update_curve_param): New.
+       * tests/keygrip.c (key_grips): Add flag param and test cases for
+       Ed25519.
+
+       mpi: Add special format GCRYMPI_FMT_OPAQUE.
+       * src/gcrypt.h.in (GCRYMPI_FMT_OPAQUE): New.
+       (_gcry_sexp_nth_opaque_mpi): Remove.
+       * src/sexp.c (gcry_sexp_nth_mpi): Add support for GCRYMPI_FMT_OPAQUE.
+       (_gcry_sexp_vextract_param): Replace removed function by
+       GCRYMPI_FMT_OPAQUE.
+
+2013-11-10  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Fix error output in CTR selftest.
+       * cipher/cipher-selftest.c (_gcry_selftest_helper_ctr): Change
+       fprintf(stderr,...) to syslog(); Correct error output for bulk
+       IV check, plaintext mismatch => ciphertext mismatch.
+
+2013-11-09  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Fix Serpent-AVX2 and Camellia-AVX2 counter modes.
+       * cipher/camellia-aesni-avx2-amd64.S
+       (_gcry_camellia_aesni_avx2_ctr_enc): Byte-swap before checking for
+       overflow handling.
+       * cipher/camellia-glue.c (selftest_ctr_128, selftest_cfb_128)
+       (selftest_cbc_128): Add 16 to nblocks.
+       * cipher/cipher-selftest.c (_gcry_selftest_helper_ctr): Add test with
+       non-overflowing IV and modify overflow IV to detect broken endianness
+       handling.
+       * cipher/serpent-avx2-amd64.S (_gcry_serpent_avx2_ctr_enc): Byte-swap
+       before checking for overflow handling; Fix crazy-mixed-endian IV
+       construction to big-endian.
+       * cipher/serpent.c (selftest_ctr_128, selftest_cfb_128)
+       (selftest_cbc_128): Add 8 to nblocks.
+
+2013-11-09  Sergey V  <sftp.mtuci@gmail.com>
+
+       cipher/gost28147: optimization: use precomputed S-box tables.
+       * cipher/gost.h (GOST28147_context): Remove unneeded subst and
+       subst_set members.
+       * cipher/gost28147.c (max): Remove unneeded macro.
+       (test_sbox): Replace with new precomputed tables.
+       (gost_set_subst): Remove function.
+       (gost_val): Use new S-box tables.
+       (gost_encrypt_block, gost_decrypt_block): Tweak to use new ctx and
+       S-box tables.
+
+2013-11-09  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Fix tail handling for AES-NI counter mode.
+       * cipher/rijndael.c (do_aesni_ctr): Fix outputting of updated
+       counter-IV.
+
+2013-11-08  Werner Koch  <wk@gnupg.org>
+
+       ecc: Improve gcry_pk_get_curve.
+       * cipher/ecc-curves.c (_gcry_ecc_fill_in_curve): Factor some code out
+       to ..
+       (find_domain_parms_idx): new.
+       (_gcry_ecc_get_curve): Find by curve name on error.
+
+       cipher: Avoid signed divisions in idea.c.
+       * cipher/idea.c (mul_inv): Use unsigned division.
+
+       ecc: Implement the "nocomp" flag for key generation.
+       * cipher/ecc.c (ecc_generate): Support the "nocomp" flag.
+       * tests/keygen.c (check_ecc_keys): Add a test for it.
+
+       ecc: Make "noparam" the default and replace by "param".
+       * src/cipher.h (PUBKEY_FLAG_NOCOMP): New.
+       (PUBKEY_FLAG_NOPARAM): Remove.
+       (PUBKEY_FLAG_PARAM): New.
+       * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Support the new
+       flags and ignore the obsolete "noparam" flag.
+       * cipher/ecc-curves.c (_gcry_ecc_fill_in_curve): Return the curve name
+       also for curves selected by NBITS.
+       (_gcry_mpi_ec_new): Support the "param" flag.
+       * cipher/ecc.c (ecc_generate, ecc_sign, ecc_verify): Ditto.
+       * tests/keygen.c (check_ecc_keys): Remove the "noparam" flag.
+
+2013-11-07  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Fix decryption function size in AES AMD64 assembly.
+       * cipher/rijndael-amd64.S (_gcry_aes_amd64_decrypt_block): Set '.size'
+       for '_gcry_aes_amd64_decrypt_block', not '..._encrypt_block'.
+
+       Change 64-bit shift to 32-bit in AES AMD64 assembly.
+       * cipher/rijndael-amd64.S (do16bit_shr): Change 'shrq' to 'shrl'.
+
+2013-11-06  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Speed-up AES-NI key setup.
+       * cipher/rijndael.c [USE_AESNI] (m128i_t): Remove.
+       [USE_AESNI] (u128_t): New.
+       [USE_AESNI] (aesni_do_setkey): New.
+       (do_setkey) [USE_AESNI]: Move AES-NI accelerated key setup to
+       'aesni_do_setkey'.
+       (do_setkey): Call _gcry_get_hw_features only once. Clear stack after
+       use in generic key setup part.
+       (rijndael_setkey): Remove stack burning.
+       (prepare_decryption) [USE_AESNI]: Use 'u128_t' instead of 'm128i_t' to
+       avoid compiler generated SSE2 instructions and XMM register usage,
+       unroll 'aesimc' setup loop
+       (prepare_decryption): Clear stack after use.
+       [USE_AESNI] (do_aesni_enc_aligned): Update comment about alignment.
+       (do_decrypt): Do not burning stack after prepare_decryption.
+
+       Avoid burn stack in Arcfour setkey.
+       * cipher/arcfour.c (arcfour_setkey): Remove stack burning.
+
+       Avoid burn_stack in CAST5 setkey.
+       * cipher/cast5.c (do_cast_setkey): Use wipememory instead of memset.
+       (cast_setkey): Remove stack burning.
+
+       Improve Serpent key setup speed.
+       * cipher/serpent.c (SBOX, SBOX_INVERSE): Remove index argument.
+       (serpent_subkeys_generate): Use smaller temporary arrays for subkey
+       generation and perform stack clearing locally.
+       (serpent_setkey_internal): Use wipememory to clear stack and remove
+       _gcry_burn_stack.
+       (serpent_setkey): Remove unneeded _gcry_burn_stack.
+
+       Modify encrypt/decrypt arguments for in-place.
+       * cipher/cipher.c (gcry_cipher_encrypt, gcry_cipher_decrypt): Modify
+       local arguments if in-place operation.
+
+       Speed up Stribog.
+       * cipher/stribog.c (STRIBOG_TABLES): Remove.
+       (Pi): Remove.
+       [!STRIBOG_TABLES] (A, strido): Remove.
+       (stribog_table): New table pre-reordered with Pi values.
+       (strido): Rewrite for new table.
+       (LPSX): Rewrite for new table.
+       (xor): Remove.
+       (g): Small tweaks.
+
+       Tweak AES-NI bulk CTR mode slightly.
+       * cipher/rijndael.c [USE_AESNI] (aesni_cleanup_2_5): Rename to...
+       (aesni_cleanup_2_6): ...this and clear also 'xmm6'.
+       [USE_AESNI && __i386__] (do_aesni_ctr, do_aesni_ctr_4): Prevent
+       inlining only on i386, allow on AMD64.
+       [USE_AESNI] (do_aesni_ctr, do_aesni_ctr_4): Use counter block from
+       'xmm5' and byte-swap mask from 'xmm6'.
+       (_gcry_aes_ctr_enc) [USE_AESNI]: Preload counter block to 'xmm5' and
+       byte-swap mask to 'xmm6'.
+       (_gcry_aes_ctr_enc, _gcry_aes_cfb_dec, _gcry_aes_cbc_dec): Use
+       'aesni_cleanup_2_6'.
+
+       Tweak bench-slope parameters.
+       * tests/bench-slope.c (BUF_STEP_SIZE): Half step size to 64.
+       (NUM_MEASUREMENT_REPETITIONS): Double repetitions to 64.
+
+       Optimize Blowfish weak key check.
+       * cipher/blowfish.c (hashset_elem, val_to_hidx, add_val): New.
+       (do_bf_setkey): Use faster algorithm for detecting weak keys.
+       (bf_setkey): Move stack burning to do_bf_setkey.
+
+       Fix __builtin_bswap32/64 checks.
+       * configure.ac (gcry_cv_have_builtin_bswap32)
+       (gcry_cv_have_builtin_bswap64): Change compile checks to link checks.
+
+       Fix 'u32' build error with Camellia.
+       * cipher/camellia.c: Add include for <config.h> and "types.h".
+       (u32): Remove.
+       (u8): Typedef as 'byte'.
+
+2013-11-06  Werner Koch  <wk@gnupg.org>
+
+       pubkey: Add forward compatibility feature.
+       * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Add
+       "igninvflag".
+
+2013-11-05  Werner Koch  <wk@gnupg.org>
+
+       ecc: Require "eddsa" flag for curve Ed25519.
+       * src/cipher.h (PUBKEY_FLAG_ECDSA): Remove.
+       * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Remove "ecdsa".
+       * cipher/ecc.c (ecc_generate, ecc_sign, ecc_verify): Require "eddsa" flag.
+       * cipher/ecc-misc.c (_gcry_ecc_compute_public): Depend "eddsa" flag.
+       * tests/benchmark.c, tests/keygen.c, tests/pubkey.c
+       * tests/t-ed25519.c, tests/t-mpi-point.c: Adjust for changed flags.
+
+       ecc: Fully implement Ed25519 compression in ECDSA mode.
+       * src/ec-context.h (mpi_ec_ctx_s): Add field FLAGS.
+       * mpi/ec.c (ec_p_init): Add arg FLAGS.  Change all callers to pass it.
+       * cipher/ecc-curves.c (point_from_keyparam): Add arg EC, parse as
+        opaque mpi and use eddsa decoding depending on the flag.
+       (_gcry_mpi_ec_new): Rearrange to parse Q and D after knowing the
+       curve.
+
+       mpi: Add function gcry_mpi_set_opaque_copy.
+       * src/gcrypt.h.in (gcry_mpi_set_opaque_copy): New.
+       * src/visibility.c (gcry_mpi_set_opaque_copy): New.
+       * src/visibility.h (gcry_mpi_set_opaque_copy): Mark visible.
+       * src/libgcrypt.def, src/libgcrypt.vers: Add new API.
+       * tests/mpitests.c (test_opaque): Add test.
+
+2013-11-04  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Make test vectors 'static const'
+       * cipher/arcfour.c (selftest): Change test vectors to 'static const'.
+       * cipher/blowfish.c (selftest): Ditto.
+       * cipher/camellia-glue.c (selftest): Ditto.
+       * cipher/cast5.c (selftest): Ditto.
+       * cipher/des.c (selftest): Ditto.
+       * cipher/rijndael.c (selftest): Ditto.
+       * tests/basic.c (cipher_cbc_mac_cipher, check_aes128_cbc_cts_cipher)
+       (check_ctr_cipher, check_cfb_cipher, check_ofb_cipher)
+       (check_ccm_cipher, check_stream_cipher)
+       (check_stream_cipher_large_block, check_bulk_cipher_modes)
+       (check_ciphers, check_digests, check_hmac, check_pubkey_sign)
+       (check_pubkey_sign_ecdsa, check_pubkey_crypt, check_pubkey): Ditto.
+
+2013-11-03  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Make jump labels local in Salsa20 assembly.
+       * cipher/salsa20-amd64.S: Rename '._labels' to '.L_labels'.
+       * cipher/salsa20-armv7-neon.S: Ditto.
+
+2013-10-30  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       bithelp: fix undefined behaviour with rol and ror.
+       * cipher/bithelp.h (rol, ror): Mask shift with 31.
+
+2013-10-29  Werner Koch  <wk@gnupg.org>
+
+       tests: Add feature to skip benchmarks.
+       * tests/benchmark.c (main): Add feature to skip the test.
+       * tests/bench-slope.c (main): Ditto.
+       (get_slope): Repace C++ style comment.
+       (double_cmp, cipher_bench, _hash_bench): Repalce system reserved
+       symbols.
+
+       ecc: Finish Ed25519/ECDSA hack.
+       * cipher/ecc.c (ecc_generate): Fix Ed25519/ECDSA case.
+       (ecc_verify): Implement ED25519/ECDSA uncompression.
+
+       ecc: Add flags "noparam" and "comp".
+       * src/cipher.h (PUBKEY_FLAG_NOPARAM, PUBKEY_FLAG_COMP): New.
+       * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Parse new flags
+       and change code for possible faster parsing.
+       * cipher/ecc.c (ecc_generate): Implement the "noparam" flag.
+       (ecc_sign): Ditto.
+       (ecc_verify): Ditto.
+       * tests/keygen.c (check_ecc_keys): Use the "noparam" flag.
+
+       * cipher/ecc.c (ecc_generate): Fix parsing of the deprecated
+       transient-flag parameter.
+       (ecc_verify): Do not make Q optional in the extract-param call.
+
+2013-10-28  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Fix typos in documentation.
+       * doc/gcrypt.texi: Fix some typos.
+
+       Add ARM NEON assembly implementation of Serpent.
+       * cipher/Makefile.am: Add 'serpent-armv7-neon.S'.
+       * cipher/serpent-armv7-neon.S: New.
+       * cipher/serpent.c (USE_NEON): New macro.
+       (serpent_context_t) [USE_NEON]: Add 'use_neon'.
+       [USE_NEON] (_gcry_serpent_neon_ctr_enc, _gcry_serpent_neon_cfb_dec)
+       (_gcry_serpent_neon_cbc_dec): New prototypes.
+       (serpent_setkey_internal) [USE_NEON]: Detect NEON support.
+       (_gcry_serpent_neon_ctr_enc, _gcry_serpent_neon_cfb_dec)
+       (_gcry_serpent_neon_cbc_dec) [USE_NEON]: Use NEON implementations
+       to process eight blocks in parallel.
+       * configure.ac [neonsupport]: Add 'serpent-armv7-neon.lo'.
+
+       Add ARM NEON assembly implementation of Salsa20.
+       * cipher/Makefile.am: Add 'salsa20-armv7-neon.S'.
+       * cipher/salsa20-armv7-neon.S: New.
+       * cipher/salsa20.c [USE_ARM_NEON_ASM]: New macro.
+       (struct SALSA20_context_s, salsa20_core_t, salsa20_keysetup_t)
+       (salsa20_ivsetup_t): New.
+       (SALSA20_context_t) [USE_ARM_NEON_ASM]: Add 'use_neon'.
+       (SALSA20_context_t): Add 'keysetup', 'ivsetup' and 'core'.
+       (salsa20_core): Change 'src' argument to 'ctx'.
+       [USE_ARM_NEON_ASM] (_gcry_arm_neon_salsa20_encrypt): New prototype.
+       [USE_ARM_NEON_ASM] (salsa20_core_neon, salsa20_keysetup_neon)
+       (salsa20_ivsetup_neon): New.
+       (salsa20_do_setkey): Setup keysetup, ivsetup and core with default
+       functions.
+       (salsa20_do_setkey) [USE_ARM_NEON_ASM]: When NEON support detect,
+       set keysetup, ivsetup and core with ARM NEON functions.
+       (salsa20_do_setkey): Call 'ctx->keysetup'.
+       (salsa20_setiv): Call 'ctx->ivsetup'.
+       (salsa20_do_encrypt_stream) [USE_ARM_NEON_ASM]: Process large buffers
+       in ARM NEON implementation.
+       (salsa20_do_encrypt_stream): Call 'ctx->core' instead of directly
+       calling 'salsa20_core'.
+       (selftest): Add test to check large buffer processing and block counter
+       updating.
+       * configure.ac [neonsupport]: 'Add salsa20-armv7-neon.lo'.
+
+       Add AMD64 assembly implementation of Salsa20.
+       * cipher/Makefile.am: Add 'salsa20-amd64.S'.
+       * cipher/salsa20-amd64.S: New.
+       * cipher/salsa20.c (USE_AMD64): New macro.
+       [USE_AMD64] (_gcry_salsa20_amd64_keysetup, _gcry_salsa20_amd64_ivsetup)
+       (_gcry_salsa20_amd64_encrypt_blocks): New prototypes.
+       [USE_AMD64] (salsa20_keysetup, salsa20_ivsetup, salsa20_core): New.
+       [!USE_AMD64] (salsa20_core): Change 'src' to non-constant, update block
+       counter in 'salsa20_core' and return burn stack depth.
+       [!USE_AMD64] (salsa20_keysetup, salsa20_ivsetup): New.
+       (salsa20_do_setkey): Move generic key setup to 'salsa20_keysetup'.
+       (salsa20_setkey): Fix burn stack depth.
+       (salsa20_setiv): Move generic IV setup to 'salsa20_ivsetup'.
+       (salsa20_do_encrypt_stream) [USE_AMD64]: Process large buffers in AMD64
+       implementation.
+       (salsa20_do_encrypt_stream): Move stack burning to this function...
+       (salsa20_encrypt_stream, salsa20r12_encrypt_stream): ...from these
+       functions.
+       * configure.ac [x86-64]: Add 'salsa20-amd64.lo'.
+
+       Add new benchmarking utility, bench-slope.
+       * tests/Makefile.am (TESTS): Add 'bench-slope'.
+       * tests/bench-slope.c: New.
+
+       Change .global to .globl in assembly files.
+       * cipher/blowfish-arm.S: Change '.global' to '.globl'.
+       * 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/rijndael-amd64.S: Ditto.
+       * cipher/rijndael-arm.S: Ditto.
+       * cipher/serpent-avx2-amd64.S: Ditto.
+       * cipher/serpent-sse2-amd64.S: Ditto.
+       * cipher/twofish-amd64.S: Ditto.
+       * cipher/twofish-arm.S: Ditto.
+
+2013-10-26  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Deduplicate code for ECB encryption and decryption.
+       * cipher/cipher.c (do_ecb_crypt): New, based on old 'do_ecb_encrypt'.
+       (do_ecb_encrypt): Use 'do_ecb_crypt', pass encryption function.
+       (do_ecb_decrypt): Use 'do_ecb_crypt', pass decryption function.
+
+2013-10-26  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
+
+       Drop _gcry_cipher_ofb_decrypt as it duplicates _gcry_cipher_ofb_encrypt.
+       * cipher/cipher.c (cipher_decrypt): Use _gcry_cipher_ofb_encrypt for OFB
+         decryption.
+       * cipher/cipher-internal.h: Remove _gcry_cipher_ofb_decrypt declaration.
+       * cipher/cipher-ofb.c (_gcry_cipher_ofb_decrypt): Remove.
+         (_gcry_cipher_ofb_encrypt): remove copying of IV to lastiv, it's
+         unused there.
+
+2013-10-25  Werner Koch  <wk@gnupg.org>
+
+       tests: Add tests for mpi_cmp.
+       * tests/mpitests.c (die): Modernize.
+       (fail): New.
+       (test_opaque, test_add, test_sub, test_mul): Use gcry_log_xx
+       (main): Return error count.
+       (test_cmp): New.
+
+2013-10-24  Werner Koch  <wk@gnupg.org>
+
+       ecc: Change algorithm for Ed25519 x recovery.
+       * cipher/ecc-eddsa.c (scanval): Add as temporary hack.
+       (_gcry_ecc_eddsa_recover_x): Use the algorithm from page 15 of the
+       paper.  Return an error code.
+       (_gcry_ecc_eddsa_decodepoint): Take care of the error code.
+       * mpi/mpi-mul.c (gcry_mpi_mulm): Use truncated division.
+
+       ecc: Refactor _gcry_ecc_eddsa_decodepoint.
+       * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_decodepoint): Factor some code
+       out to ..
+       (_gcry_ecc_eddsa_recover_x): new.
+
+2013-10-24  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       ecc-gost: Add missing include.
+       * ecc-gost.c: Include "pubkey-internal.h".
+
+2013-10-23  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Replace architecture specific fast_wipememory2 with generic.
+       * src/g10lib.h (fast_wipememory2): Remove architecture specific
+       implementations and add generic implementation.
+
+       Improve the speed of the cipher mode code.
+       * cipher/bufhelp.h (buf_cpy): New.
+       (buf_xor, buf_xor_2dst): If buffers unaligned, always jump to per-byte
+       processing.
+       (buf_xor_n_copy_2): New.
+       (buf_xor_n_copy): Use 'buf_xor_n_copy_2'.
+       * cipher/blowfish.c (_gcry_blowfish_cbc_dec): Avoid extra memory copy
+       and use new 'buf_xor_n_copy_2'.
+       * cipher/camellia-glue.c (_gcry_camellia_cbc_dec): Ditto.
+       * cipher/cast5.c (_gcry_cast_cbc_dec): Ditto.
+       * cipher/serpent.c (_gcry_serpent_cbc_dec): Ditto.
+       * cipher/twofish.c (_gcry_twofish_cbc_dec): Ditto.
+       * cipher/rijndael.c (_gcry_aes_cbc_dec): Ditto.
+       (do_encrypt, do_decrypt): Use 'buf_cpy' instead of 'memcpy'.
+       (_gcry_aes_cbc_enc): Avoid copying IV, use 'last_iv' pointer instead.
+       * cipher/cipher-cbc.c (_gcry_cipher_cbc_encrypt): Avoid copying IV,
+       update pointer to IV instead.
+       (_gcry_cipher_cbc_decrypt): Avoid extra memory copy and use new
+       'buf_xor_n_copy_2'.
+       (_gcry_cipher_cbc_encrypt, _gcry_cipher_cbc_decrypt): Avoid extra
+       accesses to c->spec, use 'buf_cpy' instead of memcpy.
+       * cipher/cipher-ccm.c (do_cbc_mac): Ditto.
+       * cipher/cipher-cfb.c (_gcry_cipher_cfb_encrypt)
+       (_gcry_cipher_cfb_decrypt): Ditto.
+       * cipher/cipher-ctr.c (_gcry_cipher_ctr_encrypt): Ditto.
+       * cipher/cipher-ofb.c (_gcry_cipher_ofb_encrypt)
+       (_gcry_cipher_ofb_decrypt): Ditto.
+       * cipher/cipher.c (do_ecb_encrypt, do_ecb_decrypt): Ditto.
+
+       bufhelp: enable unaligned memory accesses for AArch64 (64-bit ARM)
+       * cipher/bufhelp.h [__aarch64__] (BUFHELP_FAST_UNALIGNED_ACCESS): Set
+       macro on AArch64.
+
+2013-10-23  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
+
+       Enable assembler optimizations on earlier ARM cores.
+       * cipher/blowfish-armv6.S => cipher/blowfish-arm.S: adapt to pre-armv6 CPUs.
+       * cipher/blowfish.c: enable assembly on armv4/armv5 little-endian CPUs.
+       * cipher/camellia-armv6.S => cipher/camellia-arm.S: adapt to pre-armv6 CPUs.
+       * cipher/camellia.c, cipher-camellia-glue.c: enable assembly on armv4/armv5
+         little-endian CPUs.
+       * cipher/cast5-armv6.S => cipher/cast5-arm.S: adapt to pre-armv6 CPUs.
+       * cipher/cast5.c: enable assembly on armv4/armv5 little-endian CPUs.
+       * cipher/rijndael-armv6.S => cipher/rijndael-arm.S: adapt to pre-armv6 CPUs.
+       * cipher/rijndael.c: enable assembly on armv4/armv5 little-endian CPUs.
+       * cipher/twofish-armv6.S => cipher/twofish-arm.S: adapt to pre-armv6 CPUs.
+       * cipher/twofish.c: enable assembly on armv4/armv5 little-endian CPUs.
+
+       mpi: enable assembler on all arm architectures.
+       * mpi/config.links: remove check for arm >= v6
+       * mpi/armv6 => mpi/arm: rename directory to reflect that is is generic
+         enough
+
+       Correct ASM assembly test in configure.ac.
+       * configure.ac: correct HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS test to
+         require neither ARMv6, nor thumb mode. Our assembly code works
+         perfectly even on ARMv4 now.
+
+2013-10-23  Werner Koch  <wk@gnupg.org>
+
+       ecc: Refactor ecc.c.
+       * cipher/ecc-ecdsa.c, cipher/ecc-eddsa.c, cipher/ecc-gost.c: New.
+       * cipher/Makefile.am (EXTRA_libcipher_la_SOURCES): Add new files.
+       * configure.ac (GCRYPT_PUBKEY_CIPHERS): Add new files.
+       * cipher/ecc.c (point_init, point_free): Move to ecc-common.h.
+       (sign_ecdsa): Move to ecc-ecdsa.c as _gcry_ecc_ecdsa_sign.
+       (verify_ecdsa): Move to ecc-ecdsa.c as _gcry_ecc_ecdsa_verify.
+       (sign_gost): Move to ecc-gots.c as _gcry_ecc_gost_sign.
+       (verify_gost): Move to ecc-gost.c as _gcry_ecc_gost_verify.
+       (sign_eddsa): Move to ecc-eddsa.c as _gcry_ecc_eddsa_sign.
+       (verify_eddsa): Move to ecc-eddsa.c as _gcry_ecc_eddsa_verify.
+       (eddsa_generate_key): Move to ecc-eddsa.c as _gcry_ecc_eddsa_genkey.
+       (reverse_buffer): Move to ecc-eddsa.c.
+       (eddsa_encodempi, eddsa_encode_x_y): Ditto.
+       (_gcry_ecc_eddsa_encodepoint, _gcry_ecc_eddsa_decodepoint): Ditto.
+
+       mpi: Fix scanning of negative SSH formats and add more tests.
+       * mpi/mpicoder.c (gcry_mpi_scan): Fix sign setting for SSH format.
+       * tests/t-convert.c (negative_zero): Test all formats.
+       (check_formats): Add tests for PGP and scan tests for SSH and USG.
+
+       * src/gcrypt.h.in (mpi_is_neg): Fix macro.
+
+       * mpi/mpi-scan.c (_gcry_mpi_getbyte, _gcry_mpi_putbyte): Comment out
+       these unused functions.
+
+2013-10-22  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       twofish: add ARMv6 assembly implementation.
+       * cipher/Makefile.am: Add 'twofish-armv6.S'.
+       * cipher/twofish-armv6.S: New.
+       * cipher/twofish.c (USE_ARMV6_ASM): New macro.
+       [USE_ARMV6_ASM] (_gcry_twofish_armv6_encrypt_block)
+       (_gcry_twofish_armv6_decrypt_block): New prototypes.
+       [USE_AMDV6_ASM] (twofish_encrypt, twofish_decrypt): Add.
+       [USE_AMD64_ASM] (do_twofish_encrypt, do_twofish_decrypt): Remove.
+       (_gcry_twofish_ctr_enc, _gcry_twofish_cfb_dec): Use 'twofish_encrypt'
+       instead of 'do_twofish_encrypt'.
+       (_gcry_twofish_cbc_dec): Use 'twofish_decrypt' instead of
+       'do_twofish_decrypt'.
+       * configure.ac [arm]: Add 'twofish-armv6.lo'.
+
+       mpi: allow building with clang on ARM.
+       * mpi/longlong.h [__arm__] (add_ssaaaa, sub_ddmmss, umul_ppmm)
+       (count_leading_zeros): Do not cast assembly output arguments.
+       [__arm__] (umul_ppmm): Remove the extra '%' ahead of assembly comment.
+       [_ARM_ARCH >= 4] (umul_ppmm): Use correct inputs and outputs instead of
+       registers.
+
+       serpent-amd64: do not use GAS macros.
+       * cipher/serpent-avx2-amd64.S: Remove use of GAS macros.
+       * cipher/serpent-sse2-amd64.S: Ditto.
+       * configure.ac [HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS]: Do not check
+       for GAS macros.
+
+       Add Counter with CBC-MAC mode (CCM)
+       * cipher/Makefile.am: Add 'cipher-ccm.c'.
+       * cipher/cipher-ccm.c: New.
+       * cipher/cipher-internal.h (gcry_cipher_handle): Add 'u_mode'.
+       (_gcry_cipher_ccm_encrypt, _gcry_cipher_ccm_decrypt)
+       (_gcry_cipher_ccm_set_nonce, _gcry_cipher_ccm_authenticate)
+       (_gcry_cipher_ccm_get_tag, _gcry_cipher_ccm_check_tag)
+       (_gcry_cipher_ccm_set_lengths): New prototypes.
+       * cipher/cipher.c (gcry_cipher_open, cipher_encrypt, cipher_decrypt)
+       (_gcry_cipher_setiv, _gcry_cipher_authenticate, _gcry_cipher_gettag)
+       (_gcry_cipher_checktag, gry_cipher_ctl): Add handling for CCM mode.
+       * doc/gcrypt.texi: Add documentation for GCRY_CIPHER_MODE_CCM.
+       * src/gcrypt.h.in (gcry_cipher_modes): Add 'GCRY_CIPHER_MODE_CCM'.
+       (gcry_ctl_cmds): Add 'GCRYCTL_SET_CCM_LENGTHS'.
+       (GCRY_CCM_BLOCK_LEN): New.
+       * tests/basic.c (check_ccm_cipher): New.
+       (check_cipher_modes): Call 'check_ccm_cipher'.
+       * tests/benchmark.c (ccm_aead_init): New.
+       (cipher_bench): Add handling for AEAD modes and add CCM benchmarking.
+
+       Add API to support AEAD cipher modes.
+       * cipher/cipher.c (_gcry_cipher_authenticate, _gcry_cipher_checktag)
+       (_gcry_cipher_gettag): New.
+       * doc/gcrypt.texi: Add documentation for new API functions.
+       * src/visibility.c (gcry_cipher_authenticate, gcry_cipher_checktag)
+       (gcry_cipher_gettag): New.
+       * src/gcrypt.h.in, src/visibility.h: add declarations of these
+       functions.
+       * src/libgcrypt.defs, src/libgcrypt.vers: export functions.
+
+2013-10-22  NIIBE Yutaka  <gniibe@fsij.org>
+
+       ecc: Correct compliant key generation for Edwards curves.
+       * cipher/ecc.c: Add case for Edwards curves.
+
+2013-10-17  Werner Koch  <wk@gnupg.org>
+
+       tests: Add test options to keygen.
+       * tests/keygen.c (usage): New.
+       (main): Print usage info.  Allow running just one algo.
+
+       mpi: Do not clear the sign of the mpi_mod result.
+       * mpi/mpi-mod.c (_gcry_mpi_mod): Remove sign setting.
+
+       ecc: Put the curve name again into the output of gcry_pk_genkey.
+       * cipher/ecc.c (ecc_generate): Use the correct var.  Release
+       CURVE_FLAGS.
+
+       ecc: Support Weierstrass curves in gcry_mpi_ec_curve_point.
+       * mpi/ec.c (_gcry_mpi_ec_curve_point): Support MPI_EC_WEIERSTRASS.
+
+2013-10-16  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       arcfour: more optimized version for non-i386 architectures.
+       * cipher/arcfour.c (ARCFOUR_context): Reorder members.
+       (do_encrypt_stream) [!__i386__]: Faster implementation for non-i386.
+       (do_arcfour_setkey): Avoid modulo operations.
+
+       Avoid void* pointer arithmetic.
+       * tests/tsexp.c (check_extract_param): Cast void* pointers to char*
+       before doing arithmetics.
+
+2013-10-16  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
+
+       ecc: Add support for GOST R 34.10-2001/-2012 signatures.
+       * src/cipher.h: define PUBKEY_FLAG_GOST
+       * cipher/ecc-curves.c: Add GOST2001-test and GOST2012-test curves
+         defined in standards. Typical applications would use either those
+         curves, or curves defined in RFC 4357 (will be added later).
+       * cipher/ecc.c (sign_gost, verify_gost): New.
+         (ecc_sign, ecc_verify): use sign_gost/verify_gost if PUBKEY_FLAG_GOST
+         is set.
+         (ecc_names): add "gost" for gost signatures.
+       * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist,
+         _gcry_pk_util_preparse_sigval): set PUBKEY_FLAG_GOST if gost flag
+         is present in s-exp.
+       * tests/benchmark.c (ecc_bench): also benchmark GOST signatures.
+       * tests/basic.c (check_pubkey): add two public keys from
+         GOST R 34.10-2012 standard.
+         (check_pubkey_sign_ecdsa): add two data sets to check gost signatures.
+       * tests/curves.c: correct N_CURVES as we now have 2 more curves.
+
+
+       Removed some comments from the new curve definitions in ecc-curves.c
+       to avoid line wrapping.  Eventually we will develop a precompiler to
+       avoid parsing those hex strings. -wk
+
+       Fix 256-bit ecdsa test key definition.
+       * tests/basic.c (check_pubkey): fix nistp256 testing key declaration -
+         add missing comma.
+
+2013-10-16  Werner Koch  <wk@gnupg.org>
+
+       sexp: Add function gcry_sexp_extract_param.
+       * src/gcrypt.h.in (_GCRY_GCC_ATTR_SENTINEL): New.
+       (gcry_sexp_extract_param): New.
+       * src/visibility.c (gcry_sexp_extract_param): New.
+       * src/visibility.h (gcry_sexp_extract_param): Add hack to detect
+       internal use.
+       * cipher/pubkey-util.c (_gcry_pk_util_extract_mpis): Move and split
+       into ...
+       * src/sexp.c (_gcry_sexp_vextract_param)
+       (_gcry_sexp_extract_param): this.  Change all callers.  Add support for buffer
+       descriptors and a path option/
+
+       * tests/tsexp.c (die, hex2buffer, hex2mpi, hex2mpiopa): New.
+       (cmp_mpihex, cmp_bufhex): New.
+       (check_extract_param): New.
+
+2013-10-16  NIIBE Yutaka  <gniibe@fsij.org>
+
+       mpi: mpi-pow improvement.
+       * mpi/mpi-pow.c (gcry_mpi_powm): New implementation of left-to-right
+       k-ary exponentiation.
+
+2013-10-15  Werner Koch  <wk@gnupg.org>
+
+       ecc:  Support use of Ed25519 with ECDSA.
+       * src/cipher.h (PUBKEY_FLAG_ECDSA): New.
+       * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Add flag "ecdsa".
+       * cipher/ecc.c (verify_ecdsa, verify_eddsa): Remove some debug output.
+       (ecc_generate, ecc_sign, ecc_verify): Support Ed25519 with ECDSA.
+       * tests/keygen.c (check_ecc_keys): Create such a test key.
+       * tests/pubkey.c (fail, info, data_from_hex, extract_cmp_data): New.
+       Take from dsa-6979.c
+       (check_ed25519ecdsa_sample_key): new.
+       (main): Call new test.
+
+2013-10-14  Werner Koch  <wk@gnupg.org>
+
+       pubkey: Support flags list in gcry_pk_genkey.
+       * src/cipher.h (PUBKEY_FLAG_TRANSIENT_KEY): New.
+       (PUBKEY_FLAG_USE_X931): New.
+       (PUBKEY_FLAG_USE_FIPS186): New.
+       (PUBKEY_FLAG_USE_FIPS186_2): New.
+       * cipher/pubkey-util.c (_gcry_pk_util_parse_flaglist): Rename from
+       parse_flags_list.  Parse new flags.
+       * cipher/dsa.c (dsa_generate): Support flag list.
+       * cipher/ecc.c (ecc_generate): Ditto.
+       * cipher/rsa.c (rsa_generate): Ditto.
+
+       pubkey: Remove duplicated flag parsing code.
+       * cipher/pubkey-util.c (_gcry_pk_util_preparse_encval)
+       (_gcry_pk_util_data_to_mpi): Factor flag parsing code out to ..
+       (parse_flag_list): New.
+       * src/cipher.h (PUBKEY_FLAG_RAW_FLAG): New.
+
+       mpicalc: Accept lowercase hex digits.
+       * src/mpicalc.c (main): Test for lowercase hex digits.
+
+2013-10-11  Werner Koch  <wk@gnupg.org>
+
+       pubkey: Move sexp parsing of remaining fucntions to the modules.
+       * cipher/pubkey.c (release_mpi_array): Remove.
+       (pubkey_check_secret_key): Remove.
+       (sexp_elements_extract): Remove.
+       (sexp_elements_extract_ecc): Remove.
+       (sexp_to_key): Remove.
+       (get_hash_algo): Remove.
+       (gcry_pk_testkey): Revamp.
+       (gcry_pk_get_curve): Revamp.
+       * cipher/rsa.c (rsa_check_secret_key): Revamp.
+       * cipher/elgamal.c (elg_check_secret_key): Revamp.
+       * cipher/dsa.c (dsa_check_secret_key): Revamp.
+       * cipher/ecc.c (ecc_check_secret_key): Revamp.
+       * cipher/ecc-curves.c: Include cipher.h and pubkey-internal.h
+       (_gcry_ecc_get_curve): Revamp.
+
+       * cipher/pubkey-util.c (_gcry_pk_util_extract_mpis): Set passed and
+       used parameters on error to NULL.
+
+       pubkey: Move sexp parsing for gcry_pk_decrypt to the modules.
+       * cipher/rsa.c (rsa_decrypt): Revamp.
+       * cipher/elgamal.c (elg_decrypt): Revamp.
+       * cipher/ecc.c (ecc_decrypt_raw): Revamp.
+       * cipher/pubkey.c (gcry_pk_decrypt): Simplify.
+       (sexp_to_enc): Remove.
+       * cipher/pubkey-util.c (_gcry_pk_util_preparse_encval): New.
+
+       pubkey: Move sexp parsing for gcry_pk_encrypt to the modules.
+       * cipher/rsa.c (rsa_encrypt): Revamp.
+       * cipher/elgamal.c (elg_encrypt): Revamp.
+       * cipher/ecc.c (ecc_encrypt_raw): Revamp.
+       * cipher/pubkey.c (gcry_pk_encrypt): Simplify.
+
+       * tests/basic.c (check_pubkey_crypt): Init plain, ciph, and data so
+       that they are initialized even after an encrypt failure.
+
+       pubkey: Move sexp parsing for gcry_pk_sign to the modules.
+       * cipher/rsa.c (rsa_sign): Revamp.
+       * cipher/dsa.c (dsa_sign): Revamp.
+       * cipher/elgamal.c (elg_sign): Revamp.
+       * cipher/ecc.c (ecc_sign): Revamp.
+       * cipher/pubkey.c (gcry_pk_sign): Simplify.
+
+2013-10-10  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Prevent tail call optimization with _gcry_burn_stack.
+       * configure.ac: New check, HAVE_GCC_ASM_VOLATILE_MEMORY.
+       * src/g10lib.h (_gcry_burn_stack): Rename to __gcry_burn_stack.
+       (__gcry_burn_stack_dummy): New.
+       (_gcry_burn_stack): New macro.
+       * src/misc.c (_gcry_burn_stack): Rename to __gcry_burn_stack.
+       (__gcry_burn_stack_dummy): New.
+
+2013-10-09  Werner Koch  <wk@gnupg.org>
+
+       pubkey: Move sexp parsing for gcry_pk_verify to the modules.
+       * cipher/rsa.c (rsa_verify): Revamp.
+       * cipher/dsa.c (dsa_verify): Revamp.
+       * cipher/elgamal.c (elg_verify): Revamp.
+       * cipher/ecc.c (ecc_verify): Revamp.
+       * cipher/pubkey.c (sexp_to_sig): Remove.
+       (pss_verify_cmp): Move to pubkey-util.c
+       (sexp_data_to_mpi): Ditto.
+       (init_encoding_ctx): Ditto.
+       (gcry_pk_verify): Simplify.
+       * cipher/pubkey-util.c (_gcry_pk_util_init_encoding_ctx): Add. Take
+       from pubkey.c
+       (get_hash_algo): Ditto.
+       (_gcry_pk_util_data_to_mpi): Ditto.
+       (pss_verify_cmp): Ditto.
+       (_gcry_pk_util_extract_mpis): New.
+       (_gcry_pk_util_preparse_sigval): New.
+       (_gcry_pk_util_free_encoding_ctx): New.
+       * cipher/ecc-curves.c (_gcry_ecc_fill_in_curve): Make curve init
+       optional.
+
+       * src/g10lib.h (GCC_ATTR_SENTINEL): New.
+
+       * tests/basic.c (check_pubkey_sign): Print the algo name.
+       (main): Add option --pubkey.
+
+2013-10-08  Werner Koch  <wk@gnupg.org>
+
+       pubkey: Move sexp parsing for gcry_pk_get_nbits to the modules.
+       * cipher/pubkey.c (spec_from_sexp): New.
+       (gcry_pk_get_nbits): Simplify.
+       * cipher/rsa.c (rsa_get_nbits): Take only PARMS as args and do sexp
+       parsing here.
+       * cipher/dsa.c (dsa_get_nbits): Ditto.
+       * cipher/elgamal.c (elg_get_nbits): Ditto.
+       * cipher/ecc.c (ecc_get_nbits): Ditto.
+       * cipher/ecc-curves.c (_gcry_ecc_fill_in_curve): Allow NULL for arg
+       CURVE.
+
+       pubkey: Move sexp parsing for gcry_pk_getkey to the modules.
+       * cipher/pubkey-util.c: New.
+       (_gcry_pk_util_get_nbits): New.  Based on code from gcry_pk_genkey.
+       (_gcry_pk_util_get_rsa_use_e): Ditto.
+       * cipher/pubkey.c (gcry_pk_genkey): Strip most code and pass.
+       * cipher/rsa.c (rsa_generate): Remove args ALGO, NBITS and EVALUE.
+       Call new fucntions to get these values.
+       * cipher/dsa.c (dsa_generate): Remove args ALGO, NBITS and EVALUE.
+       Call _gcry_pk_util_get_nbits to get nbits.  Always parse genparms.
+       * cipher/elgamal.c (elg_generate): Ditto.
+       * cipher/ecc.c (ecc_generate): Ditto.
+
+       cipher: Deprecate GCRY_PK_ELG_E.
+       * cipher/elgamal.c (_gcry_pubkey_spec_elg_e): Remove.
+       * cipher/pubkey.c (pubkey_list): Remove double included
+       _gcry_pubkey_spec_elg.
+       (map_algo): MAke ELG_E to ELG.
+
+2013-10-02  Werner Koch  <wk@gnupg.org>
+
+       Provide Pth compatiblity for use with GnuPG 2.0.
+       * src/ath.c (ath_install): Call ath_init and declare Pth as
+       compatible.
+
+2013-10-02  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       sha512: fix building on ARM.
+       * cipher/sha512.c (transform) [USE_ARM_NEON_ASM]: Fix 'hd' to 'ctx'.
+
+2013-10-02  Werner Koch  <wk@gnupg.org>
+
+       Remove deprecated control codes.
+       * src/gcrypt.h.in (GCRYCTL_SET_KEY): Remove.
+       (GCRYCTL_SET_IV): Remove.
+       (GCRYCTL_SET_CTR): Remove.
+       * cipher/md.c (gcry_md_ctl): Remove deprecated GCRYCTL_SET_KEY.
+       * cipher/cipher.c (gcry_cipher_ctl): Remove deprecated
+       GCRYCTL_SET_KEY, GCRYCTL_SET_IV, GCRYCTL_SET_CTR.
+
+2013-10-02  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
+
+       Fix errors when building with Clang on PPC.
+       * mpi/longlong.h (add_ssaaaa, sub_ddmmss, count_leading_zeros,
+         umul_ppmm): Do not cast asm output to USItype.
+
+2013-10-02  Werner Koch  <wk@gnupg.org>
+
+       Remove last remains of the former module system.
+       * src/gcrypt-module.h, src/module.c: Remove.
+       * src/visibility.h: Do not include gcrypt-module.h.
+       * src/g10lib.h: Remove all prototypes from module.c
+       (gcry_module): Remove.
+       * cipher/cipher-internal.h (gcry_cipher_handle): Remove unused field.
+
+       Fix missing prototype warning in visibility.c.
+       * src/ec-context.h (_gcry_mpi_ec_new): Move prototype to mpi.h.
+
+       md: Simplify the message digest dispatcher md.c.
+       * src/gcrypt-module.h (gcry_md_spec_t):  Move to ...
+       * src/cipher-proto.h: here.  Merge with md_extra_spec_t.  Add fields
+       ALGO and FLAGS.  Set these fields in all digest modules.
+       * cipher/md.c: Change most code to replace the former module
+       system by a simpler system to gain information about the algorithms.
+
+2013-10-01  Werner Koch  <wk@gnupg.org>
+
+       cipher: Simplify the cipher dispatcher cipher.c.
+       * src/gcrypt-module.h (gcry_cipher_spec_t):  Move to ...
+       * src/cipher-proto.h (gcry_cipher_spec_t): here.  Merge with
+       cipher_extra_spec_t.  Add fields ALGO and FLAGS.  Set these fields in
+       all cipher modules.
+       * cipher/cipher.c: Change most code to replace the former module
+       system by a simpler system to gain information about the algorithms.
+       (disable_pubkey_algo): Simplified.  Not anymore thread-safe, though.
+
+       * cipher/md.c (_gcry_md_selftest): Use correct structure.  Not a real
+       problem because both define the same function as their first field.
+
+       * cipher/pubkey.c (_gcry_pk_selftest): Take care of the disabled flag.
+
+       mpi: Fix gcry_mpi_neg.
+       * mpi/mpiutil.c (_gcry_mpi_neg): Copy U to W.
+
+2013-10-01  Peter Wu  <lekensteyn@gmail.com>
+
+       cipher: Add support for 128-bit keys in RC2.
+       * cipher/rfc2268.c (oids_rfc2268_128): New
+       (_gcry_cipher_spec_rfc2268_128): New.
+       * cipher/cipher.c (cipher_table_entry): Add GCRY_CIPHER_RFC2268_128.
+
+2013-09-30  Werner Koch  <wk@gnupg.org>
+
+       ecc: Use faster b parameter for Ed25519.
+       * cipher/ecc-curves.c (domain_parms): Replace b.
+       * tests/t-mpi-point.c (test_curve): Ditto.
+
+       ecc: Prepare for future Ed25519 optimization.
+       * mpi/ec-ed25519.c: New but empty file.
+       * mpi/ec-internal.h: New.
+       * mpi/ec.c: Include ec-internal.h.
+       (ec_mod): New.
+       (ec_addm): Use ec_mod.
+       (ec_mulm): Remove commented code.  Use ec_mod.
+       (ec_subm): Call simple sub.
+       (ec_pow2): Use ec_mulm.
+       (ec_mul2): New.
+       (dup_point_weierstrass): Use ec_mul2.
+       (dup_point_twistededwards): Add special case for a == -1.  Use
+       ec_mul2.
+       (add_points_weierstrass): Use ec_mul2.
+       (add_points_twistededwards): Add special case for a == -1.
+       (_gcry_mpi_ec_curve_point): Ditto.
+       (ec_p_init): Add hack to test Barrett functions.
+       * src/ec-context.h (mpi_ec_ctx_s): Add P_BARRETT.
+
+       * mpi/mpi-mod.c (_gcry_mpi_mod_barrett): Fix sign problem.
+
+       ecc: Fix recomputing of Q for Ed25519.
+       * cipher/ecc-misc.c (reverse_buffer): New.
+       (_gcry_ecc_compute_public): Add ED255519 specific code.
+       * cipher/ecc.c (sign_eddsa): Allocate DIGEST in secure memory.  Get
+       rid of HASH_D.
+       * tests/t-mpi-point.c (context_param): Test recomputing of Q for
+       Ed25519.
+
+       log: Try to print s-expressions in a more compact format.
+       * src/misc.c (count_closing_parens): New.
+       (_gcry_log_printsxp): Use new function.
+       * mpi/ec.c (_gcry_mpi_point_log): Take care of a NULL point.
+
+2013-09-30  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Make Whirlpool use the _gcry_md_block_write helper.
+       * cipher/whirlpool.c (whirlpool_context_t): Add 'bctx', remove
+       'buffer', 'count' and 'nblocks'.
+       (whirlpool_init): Initialize 'bctx'.
+       (whirlpool_transform): Adjust context argument type and burn stack
+       depth.
+       (whirlpool_add): Remove.
+       (whirlpool_write): Use _gcry_md_block_write.
+       (whirlpool_final, whirlpool_read): Adjust for 'bctx' usage.
+
+       whirlpool: add stack burning after transform.
+       * cipher/whirlpool.c (whirlpool_transform): Return burn stack depth.
+       (whirlpool_add): Do burn_stack.
+
+       whirlpool: do bitcount calculation in finalization part.
+       * cipher/whirlpool.c (whirlpool_context_t): Remove 'length', add
+       'nblocks'.
+       (whirlpool_add): Update 'nblocks' instead of 'length', and add early
+       return at one spot.
+       (whirlpool_write): Check for 'nblocks' overflow.
+       (whirlpool_final): Convert 'nblocks' to bit-counter, and use
+       whirlpool_write instead of whirlpool_add.
+
+2013-09-30  Werner Koch  <wk@gnupg.org>
+
+       Add logging functions to the API.
+       * src/gcrypt.h.in (_GCRY_GCC_ATTR_PRINTF): New.
+       (gcry_log_debug, gcry_log_debughex, gcry_log_debugmpi): New.
+       (gcry_log_debugpnt, gcry_log_debugsxp): New.
+       * src/visibility.c (gcry_log_debug): New.
+       (gcry_log_debughex, gcry_log_debugmpi, gcry_log_debugpnt): New.
+       (gcry_log_debugsxp): New.
+       * src/libgcrypt.def, src/libgcrypt.vers: Add new functions.
+       * src/misc.c (_gcry_logv): Make public.
+       (_gcry_log_printsxp): New.
+       * src/g10lib.h (log_printsxp): New macro.
+
+2013-09-26  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Make libgcrypt build with Clang on i386.
+       * cipher/longlong.h [__i386__] (add_ssaaaa, sub_ddmmss)
+       (umul_ppmm, udiv_qrnnd): Do not cast asm output to USItype.
+
+2013-09-25  Werner Koch  <wk@gnupg.org>
+
+       mpi: Change not yet used _gcry_mpi_set_opaque_copy.
+       * mpi/mpiutil.c (_gcry_mpi_set_opaque_copy): Change prototype.
+       (_gcry_mpi_get_opaque_copy): Take care of gcry_malloc failure.
+
+       sexp: Improve printing of data with a leading zero.
+       * src/sexp.c (suitable_encoding): Detect leading zero byte.
+
+       ecc: Allow the name "q@eddsa" to get/set the public key.
+       * cipher/ecc-curves.c (_gcry_ecc_get_mpi): Support "q@eddsa".
+       (_gcry_ecc_set_mpi): Support "q".
+       * cipher/ecc.c (eddsa_encodepoint): Rename to ...
+       (_gcry_ecc_eddsa_encodepoint): this and make global.  Remove arg
+       MINLEN and take from context.
+       (eddsa_decodepoint): Rename to
+       (_gcry_ecc_eddsa_decodepoint): this and make global. Remove arg LEN
+       and take from context.
+       (sign_eddsa, verify_eddsa): Take B from context.
+       (ecc_sign, ecc_verify): Add hack to set DIALECT.
+       (_gcry_pk_ecc_get_sexp): Use _gcry_ecc_compute_public.  Handle EdDSA.
+       * src/ec-context.h (mpi_ec_ctx_s): Add field NBITS.
+       * mpi/ec.c (ec_p_init): Init NBITS.
+       * tests/t-mpi-point.c (test_curve): Add Ed25519.
+       (sample_ed25519_q): New.
+       (context_param): Check new sample key.
+       (hex2buffer, hex2mpiopa): New.
+       (cmp_mpihex): Take care of opaque MPIs.
+
+       mpicalc: Add statement to compute the number of bits.
+       * src/mpicalc.c (do_nbits): New.
+       (main): Add statement 'b'.
+
+       ecc: Refactor low-level access functions.
+       * mpi/ec.c (point_copy): Move to cipher/ecc-curves.c.
+       (ec_get_reset): Rename to _gcry_mpi_ec_get_reset and make global.
+       (_gcry_mpi_ec_get_mpi): Factor most code out to _gcry_ecc_get_mpi.
+       (_gcry_mpi_ec_get_point): Factor most code out to _gcry_ecc_get_point.
+       (_gcry_mpi_ec_set_mpi): Factor most code out to _gcry_ecc_set_mpi.
+       (_gcry_mpi_ec_set_point): Factor most code out to _gcry_ecc_set_point.
+       * cipher/ecc-curves.c (_gcry_ecc_get_mpi): New.
+       (_gcry_ecc_get_point, _gcry_ecc_set_mpi, _gcry_ecc_set_point): New.
+       * cipher/ecc-misc.c (_gcry_ecc_compute_public): New.
+
+       ecc: Fix highly unlikely endless loop in sign_ecdsa.
+       * cipher/ecc.c (sign_ecdsa): Turn while-do into do-while loops.
+
+2013-09-24  Werner Koch  <wk@gnupg.org>
+
+       ecc: Allow the use of an uncompressed public key.
+       * cipher/ecc.c (eddsa_encodepoint): Factor most code out to ...
+       (eddsa_encode_x_y): new fucntion.
+       (eddsa_decodepoint): Allow use of an uncompressed public key.
+       * tests/t-ed25519.c (N_TESTS): Adjust.
+       * tests/t-ed25519.inp: Add test 1025.
+
+2013-09-23  Werner Koch  <wk@gnupg.org>
+
+       pk: Add algo id GCRY_PK_ECC and deprecate ECDSA and ECDH.
+       * src/gcrypt.h.in (GCRY_PK_ECC): New.
+       * cipher/pubkey.c (map_algo): New.
+       (spec_from_algo, gcry_pk_get_param, _gcry_pk_selftest): Use it.
+       * cipher/ecc.c (selftests_ecdsa): Report using GCRY_PK_ECC.
+       (run_selftests): Simplify.
+       (ecdh_names, ecdsa_names): Merge into a new ecc_names.
+       (_gcry_pubkey_spec_ecdh, _gcry_pubkey_spec_ecdsa): Merge into new
+       _gcry_pubkey_spec_ecc.
+
+       ec: Use mpi_mulm instead of mpi_powm.
+       * mpi/ec.c (ec_pow2): New.
+       (ec_powm): Remove call to mpi_abs.
+       (dup_point_weierstrass, dup_point_twistededwards)
+       (add_points_weierstrass, add_points_twistededwards)
+       (_gcry_mpi_ec_curve_point): Use ec_pow2.
+
+2013-09-21  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       bufhelp: enable fast unaligned memory accesses on powerpc.
+       * cipher/bufhelp.h [__powerpc__] (BUFHELP_FAST_UNALIGNED_ACCESS): Set
+       macro enabled.
+       [__powerpc64__] (BUFHELP_FAST_UNALIGNED_ACCESS): Ditto.
+
+       Remove i386 inline assembly version of rotation functions.
+       * cipher/bithelp.h (rol, ror): Remove i386 version, change
+       macros to inline functions.
+       * src/hmac256.c (ror): Ditto.
+
+       Optimize and cleanup 32-bit and 64-bit endianess transforms.
+       * cipher/bithelp.h (bswap32, bswap64, le_bswap32, be_bswap32)
+       (le_bswap64, be_bswap64): New.
+       * cipher/bufhelp.h (buf_get_be32, buf_get_le32, buf_put_le32)
+       (buf_put_be32, buf_get_be64, buf_get_le64, buf_put_be64)
+       (buf_put_le64): New.
+       * cipher/blowfish.c (do_encrypt_block, do_decrypt_block): Use new
+       endian conversion helpers.
+       (do_bf_setkey): Turn endian specific code to generic.
+       * cipher/camellia.c (GETU32, PUTU32): Use new endian conversion
+       helpers.
+       * cipher/cast5.c (rol): Remove, use rol from bithelp.
+       (F1, F2, F3): Fix to use rol from bithelp.
+       (do_encrypt_block, do_decrypt_block, do_cast_setkey): Use new endian
+       conversion helpers.
+       * cipher/des.c (READ_64BIT_DATA, WRITE_64BIT_DATA): Ditto.
+       * cipher/md4.c (transform, md4_final): Ditto.
+       * cipher/md5.c (transform, md5_final): Ditto.
+       * cipher/rmd160.c (transform, rmd160_final): Ditto.
+       * cipher/salsa20.c (LE_SWAP32, LE_READ_UINT32): Ditto.
+       * cipher/scrypt.c (READ_UINT64, LE_READ_UINT64, LE_SWAP32): Ditto.
+       * cipher/seed.c (GETU32, PUTU32): Ditto.
+       * cipher/serpent.c (byte_swap_32): Remove.
+       (serpent_key_prepare, serpent_encrypt_internal)
+       (serpent_decrypt_internal): Use new endian conversion helpers.
+       * cipher/sha1.c (transform, sha1_final): Ditto.
+       * cipher/sha256.c (transform, sha256_final): Ditto.
+       * cipher/sha512.c (__transform, sha512_final): Ditto.
+       * cipher/stribog.c (transform, stribog_final): Ditto.
+       * cipher/tiger.c (transform, tiger_final): Ditto.
+       * cipher/twofish.c (INPACK, OUTUNPACK): Ditto.
+       * cipher/whirlpool.c (buffer_to_block, block_to_buffer): Ditto.
+       * configure.ac (gcry_cv_have_builtin_bswap32): Check for compiler
+       provided __builtin_bswap32.
+       (gcry_cv_have_builtin_bswap64): Check for compiler provided
+       __builtin_bswap64.
+
+       gostr3411_94: set better burn stack depth estimate.
+       * cipher/gost28147.c (_gcry_gost_enc_one): Account function stack to
+       burn stack depth.
+       * cipher/gostr3411-94.c (max): New macro.
+       (do_hash_step, transform): Return stack burn depth.
+
+       Use hash transform function return type for passing burn stack depth.
+       * cipher/gostr4311-94.c (transform): Return stack burn depth.
+       * cipher/hash-common.c (_gcry_md_block_write): Use stack burn depth
+       returned by 'hd->bwrite'.
+       * cipher/hash-common.h (_gcry_md_block_write_t): Change return type to
+       'unsigned int'.
+       (gry_md_block_ctx_t): Remove 'stack_burn'.
+       * cipher/md4.c (transform): Return stack burn depth.
+       (md4_final): Use stack burn depth from transform.
+       * cipher/md5.c (transform): Return stack burn depth.
+       (md5_final): Use stack burn depth from transform.
+       * cipher/rmd160.c (transform): Return stack burn depth.
+       (rmd160_final): Use stack burn depth from transform.
+       * cipher/sha1.c (transform): Return stack burn depth.
+       (sha1_final): Use stack burn depth from transform.
+       * cipher/sha256.c (transform): Return stack burn depth.
+       (sha256_final): Use stack burn depth from transform.
+       * cipher/sha512.c (__transform, transform): Return stack burn depth.
+       (sha512_final): Use stack burn depth from transform.
+       * cipher/stribog.c (transform64): Return stack burn depth.
+       * cipher/tiger.c (transform): Return stack burn depth.
+       (tiger_final): Use stack burn depth from transform.
+
+       Make STRIBOG use the new _gcry_md_block_write helper.
+       * cipher/stribog.c (STRIBOG_STRUCT): Add 'bctx' and remove 'buf' and
+       'count'.
+       (stribog_init_512): Initialize 'bctx'.
+       (transform64): New function.
+       (stribog_write): Remove.
+       (stribog_final): Use _gcry_md_block_write and bctx.
+       (_gcry_digest_spec_stribog_256, _gcry_digest_spec_stribog_512): Use
+       _gcry_md_block_write.
+
+       Make SHA-512 use the new _gcry_md_block_write helper.
+       * cipher/hash-common.c (_gcry_md_block_write): Check that hd->buf is
+       large enough.
+       * cipher/hash-common.h (MD_BLOCK_MAX_BLOCKSIZE, MD_NBLOCKS_TYPE): New
+       macros.
+       (gcry_md_block_ctx_t): Use above macros for 'nblocks' and 'buf'.
+       * cipher/sha512.c (SHA512_STATE): New struct.
+       (SHA512_CONTEXT): Add 'bctx' and 'state'.
+       (sha512_init, sha384_init): Initialize 'bctx'.
+       (__transform, _gcry_sha512_transform_armv7_neon): Use SHA512_STATE for
+       'hd'.
+       (transform): For now, do not return burn stack.
+       (sha512_write): Remove.
+       (sha512_final): Use _gcry_md_block_write and bctx.
+       (_gcry_digest_spec_sha512, _gcry_digest_spec_sha384): Use
+       _gcry_md_block_write.
+
+2013-09-20  Werner Koch  <wk@gnupg.org>
+
+       sexp: Change internal versions to always use gpg_err_code_t.
+       * src/sexp.c (gcry_sexp_new, gcry_sexp_create, gcry_sexp_build)
+       (gcry_sexp_build_array, gcry_sexp_canon_len): Change error return type
+       from gpg_error_t to gpg_err_code_t.  Remove all calls to gpg_error.
+       * src/visibility.c (gcry_sexp_new, gcry_sexp_create, gcry_sexp_sscan)
+       (gcry_sexp_build, gcry_sexp_build_array, gcry_sexp_canon_len): Map
+       error codes via gpg_error.
+       * cipher/dsa.c, cipher/ecc.c, cipher/elgamal.c, cipher/rsa.c: Remove
+       use gpg_err_code wrappers.
+
+       pk: Move s-exp creation for gcry_pk_decrypt to the modules.
+       * cipher/pubkey.c (sexp_to_enc): Remove RET_MODERN arg and merge it
+       into FLAGS.
+       (gcry_pk_decrypt): Move result s-exp building into the modules.
+       * src/cipher-proto.h (gcry_pk_decrypt_t): Add some args.
+       * cipher/ecc.c (ecc_decrypt_raw): Change to return an s-exp.
+       * cipher/elgamal.c (elg_decrypt): Ditto.
+       * cipher/rsa.c (rsa_decrypt): Ditto.
+       (rsa_blind, rsa_unblind): Merge into rsa_decrypt.  This saves several
+       extra MPI allocations.
+
+       pk: Remove unused function.
+       * cipher/pubkey.c (_gcry_pk_aliased_algo_name): Remove
+
+2013-09-19  Werner Koch  <wk@gnupg.org>
+
+       Beautify debug output of the prime generator.
+       * cipher/primegen.c: Adjust output of log_mpidump to recently changed
+       log_mpidump code changes.
+
+       pk: Move s-expr creation for genkey to the modules.
+       * cipher/pubkey.c (pubkey_generate): Fold into gcry_pk_genkey
+       (gcry_pk_genkey): Move result s-exp creation into the modules.
+       * cipher/dsa.c (dsa_generate): Create result as s-exp.
+       * cipher/elgamal.c (elg_generate): Ditto.
+       * cipher/rsa.c (rsa_generate): Ditto.
+       * cipher/ecc.c (ecc_generate): Ditto.
+       * src/cipher-proto.h (pk_ext_generate_t): Remove type
+       (gcry_pk_spec): and remove from struct.
+
+       tests: Beautify some diagnostics.
+       * tests/benchmark.c (ecc_bench): Print the key sexp in very verbose
+       mode.
+       (main): Add option --pk-count.
+       * tests/keygen.c: Add Elgamal generation and improved diagnostics.
+       * tests/t-ed25519.c (check_ed25519): Print running number of tests
+       done.
+
+       sexp: Improve printing data representing a negative number.
+       * src/sexp.c (suitable_encoding): Detect a negative number.
+
+       pk: Move RSA encoding functions to a new file.
+       * cipher/rsa-common: New.
+       * cipher/pubkey.c (pkcs1_encode_for_encryption): Move to rsa-common.c
+       and rename to _gcry_rsa_pkcs1_encode_for_enc.
+       (pkcs1_decode_for_encryption): Move to rsa-common.c and rename to
+       _gcry_rsa_pkcs1_decode_for_enc.
+       (pkcs1_encode_for_signature): Move to rsa-common.c and rename to
+       _gcry_rsa_pkcs1_encode_for_sig.
+       (oaep_encode): Move to rsa-common.c and rename to
+       _gcry_rsa_oaep_encode.
+       (oaep_decode): Move to rsa-common.c and rename to
+       _gcry_rsa_oaep_decode.
+       (pss_encode): Move to rsa-common.c and rename to _gcry_rsa_pss_encode.
+       (pss_verify): Move to rsa-common.c and rename to _gcry_rsa_pss_decode.
+       (octet_string_from_mpi, mgf1): Move to rsa-common.c.
+
+       pk: Move s-expr creation for sign and encrypt to the modules.
+       * cipher/pubkey.c (pubkey_encrypt): Fold into gcry_pk_encrypt.
+       (pubkey_decrypt): Fold into gcry_pk_decrypt.
+       (pubkey_sign): Fold into gcry_pk_sign.
+       (pubkey_verify): Fold into gcry_pk_verify.
+       (octet_string_from_mpi): Make it a wrapper and factor code out to ...
+       * mpi/mpicoder.c (_gcry_mpi_to_octet_string): New function.
+
+       * src/cipher.h (PUBKEY_FLAG_FIXEDLEN): New.
+       * cipher/pubkey.c (sexp_data_to_mpi): Set flag for some encodings.
+       (gcry_pk_encrypt): Simply by moving the s-expr generation to the modules.
+       (gcry_pk_sign): Ditto.
+       * cipher/dsa.c (dsa_sign): Create s-expr.
+       * cipher/elgamal.c (elg_encrypt, elg_sign): Ditto.
+       * cipher/rsa.c (rsa_encrypt, rsa_sign): Ditto.
+       * cipher/ecc.c (ecc_sign, ecc_encrypt_raw): Ditto.
+       (ecdsa_names): Add "eddsa".
+       * tests/t-ed25519.c (one_test): Expect "eddsa" token.
+
+2013-09-19  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
+
+       Fix Stribog digest on bigendian platforms.
+       * cipher/stribog.c (stribog_final): swap bytes in the result of digest
+       calculations.
+
+2013-09-18  Werner Koch  <wk@gnupg.org>
+
+       pk: Simplify the public key dispatcher pubkey.c.
+       * src/cipher-proto.h (gcry_pk_spec_t): Add fields ALGO and FLAGS.
+       * cipher/dsa.c (_gcry_pubkey_spec_dsa): Set these fields.
+       * cipher/ecc.c (_gcry_pubkey_spec_ecdsa): Ditto.
+       (_gcry_pubkey_spec_ecdh): Ditto.
+       * cipher/rsa.c (_gcry_pubkey_spec_rsa): Ditto.
+       * cipher/elgamal.c (_gcry_pubkey_spec_elg): Ditto
+       (_gcry_pubkey_spec_elg_e): New.
+       * cipher/pubkey.c: Change most code to replace the former module
+       system by a simpler system to gain information about the algorithms.
+       (disable_pubkey_algo): SImplified.  Not anymore thread-safe, though.
+
+       pk: Merge extraspecs struct with standard specs struct.
+       * src/gcrypt-module.h (gcry_pk_spec_t): Move this typedef and the
+       corresponding function typedefs to ...
+       * src/cipher-proto.h: here.
+       (pk_extra_spec_t): Remove typedef and merge fields into
+       gcry_pk_spec_t.
+       * cipher/rsa.c, cipher/dsa.c, cipher/elg.c, cipher/ecc.c: Ditto.
+       * cipher/pubkey.c: Change accordingly.
+       * src/cipher.h (_gcry_pubkey_extraspec_rsa): Remove.
+       (_gcry_pubkey_extraspec_dsa): Remove.
+       (_gcry_pubkey_extraspec_elg): Remove.
+       (_gcry_pubkey_extraspec_ecdsa): Remove.
+
+2013-09-18  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Fix encryption/decryption return type for GOST28147.
+       * cipher/gost.h (_gcry_gost_enc_one): Change return type to
+       'unsigned int'.
+       * cipher/gost28147.c (max): New macro.
+       (gost_encrypt_block, gost_decrypt_block): Return burn stack depth.
+       (_gcry_gost_enc_one): Return burn stack depth from gost_encrypt_block.
+
+2013-09-18  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
+
+       doc: fix building of ps and pdf documentation.
+       * doc/gcrypt.texi, doc/gpl.texi, doc/lgpl.texi: fix texinfo errors.
+
+       Add GOST R 34.11-2012 implementation (Stribog)
+       * src/gcrypt.h.in (GCRY_MD_GOSTR3411_12_256)
+       (GCRY_MD_GOSTR3411_12_512): New.
+       * cipher/stribog.c: New.
+       * configure.ac (available_digests_64): Add stribog.
+       * src/cipher.h: Declare Stribog declarations.
+       * cipher/md.c: Register Stribog digest.
+       * tests/basic.c (check_digests) Add 4 testcases for Stribog from
+       standard.
+       * doc/gcrypt.texi: Document new constants.
+
+       Add basic implementation of GOST R 34.11-94 message digest.
+       * src/gcrypt.h.in (GCRY_MD_GOSTR3411_94): New.
+       * cipher/gostr3411-94.c: New.
+       * configure.ac (available_digests): Add gostr3411-94.
+       * src/cipher.h: Add gostr3411-94 definitions.
+       * cipher/md.c: Register GOST R 34.11-94.
+       * tests/basic.c (check_digests): Add 4 tests for GOST R 34.11-94
+         hash algo. Two are  defined in the standard itself, two other are
+         more or less common tests - an empty string an exclamation mark.
+       * doc/gcrypt.texi: Add an entry describing GOST R 34.11-94 to the MD
+         algorithms table.
+
+       Separate common md block code.
+       * cipher/hash-common.c (_gcry_md_block_write): New function to handle
+       block md operations.  The current implementation is limited to 64 byte
+       buffer and u32 block counter.
+
+       * cipher/md4.c, cipher/md5.c, cipher/rmd.h, cipher/rmd160.c
+       *cipher/sha1.c, cipher/sha256.c, cipher/tiger.c: Convert to use
+       _gcry_md_block_write.
+
+       Add limited implementation of GOST 28147-89 cipher.
+       * src/gcrypt.h.in (GCRY_CIPHER_GOST28147): New.
+       * cipher/gost.h, cipher/gost28147.c: New.
+       * configure.ac (available_ciphers): Add gost28147.
+       * src/cipher.h: Add gost28147 definitions.
+       * cipher/cipher.c: Register gost28147.
+       * tests/basic.c (check_ciphers): Enable simple test for gost28147.
+       * doc/gcrypt.texi: document GCRY_CIPHER_GOST28147.
+
+2013-09-18  Werner Koch  <wk@gnupg.org>
+
+       ecc: Add Ed25519 key generation and prepare for optimizations.
+       * src/mpi.h (enum ecc_dialects): New.
+       * src/ec-context.h (mpi_ec_ctx_s): Add field DIALECT.
+       * cipher/ecc-common.h (elliptic_curve_t): Ditto.
+       * cipher/ecc-curves.c (ecc_domain_parms_t): Ditto.
+       (domain_parms): Add dialect values.
+       (_gcry_ecc_fill_in_curve): Set dialect.
+       (_gcry_ecc_get_curve): Ditto.
+       (_gcry_mpi_ec_new): Ditto.
+       (_gcry_ecc_get_param): Use ECC_DIALECT_STANDARD for now.
+       * cipher/ecc-misc.c (_gcry_ecc_curve_copy): Copy dialect.
+       (_gcry_ecc_dialect2str): New.
+       * mpi/ec.c (ec_p_init): Add arg DIALECT.
+       (_gcry_mpi_ec_p_internal_new): Ditto.
+       (_gcry_mpi_ec_p_new): Ditto.
+
+       * mpi/mpiutil.c (gcry_mpi_set_opaque): Set the secure flag.
+       (_gcry_mpi_set_opaque_copy): New.
+
+       * cipher/ecc-misc.c (_gcry_ecc_os2ec): Take care of an opaque MPI.
+       * cipher/ecc.c (eddsa_generate_key): New.
+       (generate_key): Rename to nist_generate_key and factor some code out
+       to ...
+       (ecc_generate_ext): here.  Divert to eddsa_generate_key if desired.
+       (eddsa_decodepoint): Take care of an opaque MPI.
+       (ecc_check_secret_key): Ditto.
+       (ecc_sign): Ditto.
+       * cipher/pubkey.c (sexp_elements_extract_ecc): Store public and secret
+       key as opaque MPIs.
+       (gcry_pk_genkey): Add the curve_name also to the private key part of
+       the result.
+
+       * tests/benchmark.c (ecc_bench): Support Ed25519.
+       (main): Add option --debug.
+       * tests/curves.c (sample_key_2): Make sure that P and N are positive.
+       * tests/keygen.c (show): New.
+       (check_ecc_keys): Support Ed25519.
+
+2013-09-17  Werner Koch  <wk@gnupg.org>
+
+       mpi: Support printing of negative numbers.
+       * mpi/mpicoder.c (twocompl, onecompl): New.
+       (gcry_mpi_print): Use it for STD and SSH.
+       (gcry_mpi_scan): Use it for STD and SSH.  Always set NSCANNED.
+       (gcry_mpi_aprint): Clear the extra allocated byte.
+       * tests/t-convert.c (showhex, showmpi): New.
+       (mpi2bitstr_nlz): New.
+       (check_formats): New.
+       (main): Call new test.
+
+2013-09-16  Werner Koch  <wk@gnupg.org>
+
+       Fix bug in _gcry_mpi_tdiv_q_2exp.
+       * mpi/mpi-internal.h (MPN_COPY_INCR): Make it work.
+
+       ecc: Implement Curve Ed25519 signing and verification.
+       * cipher/ecc-curves.c (domain_parms): Add curve "Ed25519".
+       * cipher/ecc.c (reverse_buffer): New.
+       (eddsa_encodempi): New.
+       (eddsa_encodepoint): New.
+       (eddsa_decodepoint): New.
+       (sign_eddsa): Implement.
+       (verify_eddsa): Implement.
+       (ecc_sign): Init unused Q.  Pass public key to sign_eddsa.
+       (ecc_verify): Init pk.Q if not used.  Pass public key verbatim to
+       verify_eddsa.
+       * cipher/pubkey.c (sexp_elements_extract): Add arg OPAQUE.  Change all
+       callers to pass 0.
+       (sexp_to_sig): Add arg OPAQUE and pass it to sexp_elements_extract.
+       (sexp_data_to_mpi): Allow for a zero length "value".
+       (gcry_pk_verify): Reorder parameter processing.  Pass OPAQUE flag as
+       required.
+       * mpi/ec.c (ec_invm): Print a warning if the inverse does not exist.
+       (_gcry_mpi_ec_get_affine): Implement for our Twisted Edwards curve
+       model.
+       (dup_point_twistededwards): Implement.
+       (add_points_twistededwards): Implement.
+       (_gcry_mpi_ec_mul_point): Support Twisted Edwards.
+
+       * mpi/mpicoder.c (do_get_buffer): Add arg FILL_LE.
+       (_gcry_mpi_get_buffer): Ditto.  Change all callers.
+       (_gcry_mpi_get_secure_buffer): Ditto.
+
+       * src/sexp.c (_gcry_sexp_nth_opaque_mpi): New.
+
+       * tests/t-ed25519.c: New.
+       * tests/t-ed25519.inp: New.
+       * tests/t-mpi-point.c (basic_ec_math_simplified): Print some output
+       only in debug mode.
+       (twistededwards_math): New test.
+       (main): Call new test.
+
+       mpi: Add internal convenience function.
+       * mpi/mpiutil.c (_gcry_mpi_get_opaque_copy): New.
+
+       mpi: Add debug function to print a point.
+       * mpi/ec.c (_gcry_mpi_point_log): New.
+       * src/mpi.h (log_printpnt): new macro.
+
+       tests: Factor time measurement code out.
+       * tests/benchmark.c (started_at, stopped_at, start_timer, stop_timer)
+       (elapsed time): Factor out to ..
+       * tests/stopwatch.h: new file.
+
+2013-09-12  Werner Koch  <wk@gnupg.org>
+
+       Fix _gcry_log_printmpi to print 00 instead of a sole sign.
+       * src/misc.c: Special case an mpi length of 0.
+
+2013-09-11  Werner Koch  <wk@gnupg.org>
+
+       Streamline the use of the internal mpi and hex debug functions.
+       * mpi/mpicoder.c (gcry_mpi_dump): Remove.
+       (_gcry_log_mpidump): Remove.
+       * src/misc.c (_gcry_log_printhex): Factor all code out to ...
+       (do_printhex): new.  Add line wrapping a and compact printing.
+       (_gcry_log_printmpi): New.
+       * src/mpi.h (log_mpidump): Remove macro.
+       * src/g10lib.h (log_mpidump): Add compatibility macro.
+       (log_printmpi): New macro
+       * src/visibility.c (gcry_mpi_dump): Call _gcry_log_printmpi.
+       * cipher/primegen.c (prime_generate_internal): Replace gcry_mpi_dump
+       by log_printmpi.
+       (gcry_prime_group_generator): Ditto.
+       * cipher/pubkey.c: Remove extra colons from log_mpidump call.
+       * cipher/rsa.c (stronger_key_check): Use log_printmpi.
+
+2013-09-10  Werner Koch  <wk@gnupg.org>
+
+       md: Add function gcry_md_hash_buffers.
+       * src/gcrypt.h.in (gcry_buffer_t): new.
+       (gcry_md_hash_buffers): New.
+       * src/visibility.c, src/visibility.h: Add wrapper for new function.
+       * src/libgcrypt.def, src/libgcrypt.vers: Export new function.
+       * cipher/md.c (gcry_md_hash_buffers): New.
+       * cipher/sha1.c (_gcry_sha1_hash_buffers): New.
+       * tests/basic.c (check_one_md_multi): New.
+       (check_digests): Run that test.
+       * tests/hmac.c (check_hmac_multi): New.
+       (main): Run that test.
+
+       md: Fix Whirlpool flaw.
+       * cipher/whirlpool.c (whirlpool_add): Remove shortcut return so that
+       byte counter is always properly updated.
+
+2013-09-07  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Fix static build on AMD64.
+       * cipher/rijndael-amd64.S: Correct 'RIP' macro for non-PIC build.
+
+       scrypt: fix for big-endian systems.
+       * cipher/scrypt.c (_salsa20_core): Fix endianess issues.
+
+2013-09-07  Werner Koch  <wk@gnupg.org>
+
+       Use gcc "unused" attribute only with gcc >= 3.5.
+       * src/g10lib.h (GCC_ATTR_UNUSED): Fix gcc version detection.
+
+2013-09-07  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
+
+       Add support for Salsa20/12 - 12 round version of Salsa20.
+       * src/gcrypt.h.in (GCRY_CIPHER_SALSA20R12): New.
+       * src/salsa20.c (salsa20_core, salsa20_do_encrypt_stream): Add support
+       for reduced round versions.
+         (salsa20r12_encrypt_stream, _gcry_cipher_spec_salsa20r12): Implement
+       Salsa20/12 - a 12 round version of Salsa20 selected by eStream.
+       * src/cipher.h: Declsare Salsa20/12 definition.
+       * cipher/cipher.c: Register Salsa20/12
+       * tests/basic.c: (check_stream_cipher, check_stream_cipher_large_block):
+       Populate Salsa20/12 tests with test vectors from ecrypt
+       (check_ciphers): Add simple test for Salsa20/12
+
+2013-09-07  Werner Koch  <wk@gnupg.org>
+
+       Add configure option --disable-amd64-as-feature-detection.
+       * configure.ac: Implement new disable flag.
+
+       mpi: Improve support for non-Weierstrass support.
+       * mpi/ec.c (ec_p_init): Add args MODEL and P.  Change all callers.
+       (_gcry_mpi_ec_p_internal_new): Ditto.
+       (_gcry_mpi_ec_p_new): Ditto.
+       * cipher/ecc-curves.c (_gcry_ecc_fill_in_curve): Return
+       GPG_ERR_UNKNOWN_CURVE instead of invalid value.  Init curve model.
+       * cipher/ecc.c (ecc_verify, ecc_encrypt_raw): Ditto.
+       * cipher/pubkey.c (sexp_data_to_mpi): Fix EDDSA flag error checking.
+
+       mpi: Add gcry_mpi_ec_curve_point.
+       * mpi/ec.c (_gcry_mpi_ec_curve_point): New.
+       (ec_powm): Return the absolute value.
+       * src/visibility.c, src/visibility.c: Add wrappers.
+       * src/libgcrypt.def, src/libgcrypt.vers: Export them.
+
+       mpi: Add functions to manipulate the sign.
+       * src/gcrypt.h.in (gcry_mpi_is_neg): New.
+       (gcry_mpi_neg, gcry_mpi_abs): New.
+       * mpi/mpiutil.c (_gcry_mpi_is_neg): New.
+       (_gcry_mpi_neg, _gcry_mpi_abs): New.
+       * src/visibility.c, src/visibility.h: Add wrappers.
+       * src/libgcrypt.def, src/libgcrypt.vers: Export them.
+       * src/mpi.h (mpi_is_neg): New.  Rename old macro to mpi_has_sign.
+       * mpi/mpi-mod.c (_gcry_mpi_mod_barrett): Use mpi_has_sign.
+       * mpi/mpi-mpow.c (calc_barrett): Ditto.
+       * cipher/primegen.c (_gcry_derive_x931_prime): Ditto
+       * cipher/rsa.c (secret): Ditto.
+
+2013-09-06  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Tune armv6 mpi assembly.
+       * mpi/armv6/mpih-mul1.S: Tune assembly for Cortex-A8.
+       * mpi/armv6/mpih-mul2.S: Ditto.
+       * mpi/armv6/mpih-mul3.S: Ditto.
+
+2013-09-05  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Change _gcry_burn_stack take burn depth as unsigned integer.
+       * src/misc.c (_gcry_burn_stack): Change to handle 'unsigned int' bytes.
+
+       mpicalc: fix building on linux and win32.
+       * src/Makefile.am (mpicalc): Adjust CFLAGS and LDADD.
+
+2013-09-04  Werner Koch  <wk@gnupg.org>
+
+       Change mpicalc to use Libgcrypt and install it.
+       * src/mpicalc.c: Make use of gcry_ functions.
+       (MPICALC_VERSION): New.  Set to 2.0.
+       (strusage): Remove.
+       (scan_mpi): New.  Replaces mpi_fromstr.
+       (print_mpi): New.  Replaces mpi_print.
+       (my_getc): New.
+       (print_help): New.
+       (main): Use simple option parser and print version info.
+       * src/Makefile.am (bin_PROGRAMS): Add mpicalc.
+       (mpicalc_SOURCES, mpicalc_CFLAGS, mpicalc_LDADD): New.
+
+       Add mpicalc.c to help with testing.
+       * src/mpicalc.c: Take from GnuPG 1.4
+
+       Prepare support for EdDSA.
+       * src/cipher.h (PUBKEY_FLAG_EDDSA): New.
+       * cipher/pubkey.c (pubkey_verify): Repalce args CMP and OPAQUEV by
+       CTX.  Pass flags and hash algo to the verify function.  Change all
+       verify functions to accept these args.
+       (sexp_data_to_mpi): Implement new flag "eddsa".
+       (gcry_pk_verify): Pass CTX instead of the compare function to
+       pubkey_verify.
+       * cipher/ecc.c (sign): Rename to sign_ecdsa.  Change all callers.
+       (verify): Rename to verify_ecdsa.  Change all callers.
+       (sign_eddsa, verify_eddsa): New stub functions.
+       (ecc_sign): Divert to sign_ecdsa or sign_eddsa.
+       (ecc_verify): Divert to verify_ecdsa or verify_eddsa.
+
+       Prepare support for non-Weierstrass EC equations.
+       * src/mpi.h (gcry_mpi_ec_models): New.
+       * src/ec-context.h (mpi_ec_ctx_s): Add MODEL.
+       * cipher/ecc-common.h (elliptic_curve_t): Ditto.
+       * cipher/ecc-curves.c (ecc_domain_parms_t): Ditto.
+       (domain_parms): Mark als as Weierstrass.
+       (_gcry_ecc_fill_in_curve): Check model.
+       (_gcry_ecc_get_curve): Set model to Weierstrass.
+       * cipher/ecc-misc.c (_gcry_ecc_model2str): New.
+       * cipher/ecc.c (generate_key, ecc_generate_ext): Print model in the
+       debug output.
+
+       * mpi/ec.c (_gcry_mpi_ec_dup_point): Switch depending on model.
+       Factor code out to ...
+       (dup_point_weierstrass): new.
+       (dup_point_montgomery, dup_point_twistededwards): New stub functions.
+       (_gcry_mpi_ec_add_points): Switch depending on model.  Factor code out
+       to ...
+       (add_points_weierstrass): new.
+       (add_points_montgomery, add_points_twistededwards): New stub
+       functions.
+
+       * tests/Makefile.am (TESTS): Reorder tests.
+
+       mpi: Suppress newer gcc warnings.
+       * src/g10lib.h (GCC_ATTR_UNUSED): Define for gcc >= 3.5.
+       * mpi/mpih-div.c (_gcry_mpih_mod_1, _gcry_mpih_divmod_1): Mark dummy
+       as unused.
+       * mpi/mpi-internal.h (UDIV_QRNND_PREINV): Mark _ql as unused.
+
+       Do not check with cpp for typedefed constants.
+       * src/gcrypt-int.h: Include error code replacements depeding on the
+       version of libgpg-error.
+
+2013-09-04  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Make _gcry_burn_stack use variable length array.
+       * configure.ac (HAVE_VLA): Add check.
+       * src/misc.c (_gcry_burn_stack) [HAVE_VLA]: Add VLA code.
+
+       Move stack burning from block ciphers to cipher modes.
+       * src/gcrypt-module.h (gcry_cipher_encrypt_t)
+       (gcry_cipher_decrypt_t): Return 'unsigned int'.
+       * cipher/cipher.c (dummy_encrypt_block, dummy_decrypt_block): Return
+       zero.
+       (do_ecb_encrypt, do_ecb_decrypt): Get largest stack burn depth from
+       block cipher crypt function and burn stack at end.
+       * cipher/cipher-aeswrap.c (_gcry_cipher_aeswrap_encrypt)
+       (_gcry_cipher_aeswrap_decrypt): Ditto.
+       * cipher/cipher-cbc.c (_gcry_cipher_cbc_encrypt)
+       (_gcry_cipher_cbc_decrypt): Ditto.
+       * cipher/cipher-cfb.c (_gcry_cipher_cfb_encrypt)
+       (_gcry_cipher_cfb_decrypt): Ditto.
+       * cipher/cipher-ctr.c (_gcry_cipher_cbc_encrypt): Ditto.
+       * cipher/cipher-ofb.c (_gcry_cipher_ofb_encrypt)
+       (_gcry_cipher_ofb_decrypt): Ditto.
+       * cipher/blowfish.c (encrypt_block, decrypt_block): Return burn stack
+       depth.
+       * cipher/camellia-glue.c (camellia_encrypt, camellia_decrypt): Ditto.
+       * cipher/cast5.c (encrypt_block, decrypt_block): Ditto.
+       * cipher/des.c (do_tripledes_encrypt, do_tripledes_decrypt)
+       (do_des_encrypt, do_des_decrypt): Ditto.
+       * cipher/idea.c (idea_encrypt, idea_decrypt): Ditto.
+       * cipher/rijndael.c (rijndael_encrypt, rijndael_decrypt): Ditto.
+       * cipher/seed.c (seed_encrypt, seed_decrypt): Ditto.
+       * cipher/serpent.c (serpent_encrypt, serpent_decrypt): Ditto.
+       * cipher/twofish.c (twofish_encrypt, twofish_decrypt): Ditto.
+       * cipher/rfc2268.c (encrypt_block, decrypt_block): New.
+       (_gcry_cipher_spec_rfc2268_40): Use encrypt_block and decrypt_block.
+
+2013-09-01  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       camellia-aesni-avx2-amd64: Move register clearing to assembly functions.
+       * cipher/camellia-aesni-avx2-amd64.S
+       (_gcry_camellia_aesni_avx2_ctr_enc): Add 'vzeroall'.
+       (_gcry_camellia_aesni_avx2_cbc_dec)
+       (_gcry_camellia_aesni_avx2_cfb_dec): Add 'vzeroupper' at head and
+       'vzeroall' at tail.
+       * cipher/camellia-glue.c (_gcry_serpent_ctr_enc, _gcry_serpent_cbc_dec)
+       (_gcry_serpent_avx2_cfb_dec) [USE_AESNI_AVX2]: Remove register
+       clearing.
+
+       camellia-aesni-avx-amd64: Move register clearing to assembly functions.
+       * cipher/camellia-aesni-avx-amd64.S (_gcry_camellia_aesni_avx_ctr_enc)
+       (_gcry_camellia_aesni_avx_cbc_dec)
+       (_gcry_camellia_aesni_avx_cfb_dec): Add 'vzeroupper' at head and
+       'vzeroall' at tail.
+       * cipher/camellia-glue.c (_gcry_serpent_ctr_enc, _gcry_serpent_cbc_dec)
+       (_gcry_serpent_avx2_cfb_dec) [USE_AESNI_AVX]: Remove register clearing.
+
+       serpent-avx2-amd64: Move register clearing to assembly.
+       * cipher/serpent-avx2-amd64.S (_gcry_serpent_avx2_ctr_enc)
+       (_gcry_serpent_avx2_cbc_dec, _gcry_serpent_avx2_cfb_dec): Change last
+       'vzeroupper' to 'vzeroall'.
+       * cipher/serpent.c (_gcry_serpent_ctr_enc, _gcry_serpent_cbc_dec)
+       (_gcry_serpent_avx2_cfb_dec) [USE_AVX2]: Remove register clearing with
+       'vzeroall'.
+
+       Fix building for x32 target.
+       * mpi/amd64/mpi-asm-defs.h: New file.
+       * random/rndhw.c (poll_padlock) [__x86_64__]: Also check if __LP64__ is
+       defined.
+       [USE_DRNG, __x86_64__]: Also check if __LP64__ is defined.
+
+2013-08-31  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       sha512: add ARM/NEON assembly version of transform function.
+       * cipher/Makefile.am: Add 'sha512-armv7-neon.S'.
+       * cipher/sha512-armv7-neon.S: New file.
+       * cipher/sha512.c (USE_ARM_NEON_ASM): New macro.
+       (SHA512_CONTEXT) [USE_ARM_NEON_ASM]: Add 'use_neon'.
+       (sha512_init, sha384_init) [USE_ARM_NEON_ASM]: Enable 'use_neon' if
+       CPU support NEON instructions.
+       (k): Round constant array moved outside of 'transform' function.
+       (__transform): Renamed from 'tranform' function.
+       [USE_ARM_NEON_ASM] (_gcry_sha512_transform_armv7_neon): New prototype.
+       (transform): New wrapper function for different transform versions.
+       (sha512_write, sha512_final): Burn stack by the amount returned by
+       transform function.
+       * configure.ac (sha512) [neonsupport]: Add 'sha512-armv7-neon.lo'.
+
+       sha512: reduce stack use in transform function by 512 bytes.
+       * cipher/sha512.c (transform): Change 'u64 w[80]' to 'u64 w[16]' and
+       inline input expansion to first 64 rounds.
+       (sha512_write, sha512_final): Reduce burn_stack depth by 512 bytes.
+
+       Add ARM HW feature detection module and add NEON detection.
+       * configure.ac: Add option --disable-neon-support.
+       (HAVE_GCC_INLINE_ASM_NEON): New.
+       (ENABLE_NEON_SUPPORT): New.
+       [arm]: Add 'hwf-arm.lo' as HW feature module.
+       * src/Makefile.am: Add 'hwf-arm.c'.
+       * src/g10lib.h (HWF_ARM_NEON): New macro.
+       * src/global.c (hwflist): Add HWF_ARM_NEON entry.
+       * src/hwf-arm.c: New file.
+       * src/hwf-common.h (_gcry_hwf_detect_arm): New prototype.
+       * src/hwfeatures.c (_gcry_detect_hw_features) [HAVE_CPU_ARCH_ARM]: Add
+       call to _gcry_hwf_detect_arm.
+
+       Correct mpi_cpu_arch for ARMv6.
+       * mpi/config.links [armv6]: Set mpi_cpu_arch to "arm", instead of
+       "armv6".
+
+2013-08-30  Werner Koch  <wk@gnupg.org>
+
+       mpi: Make gcry_mpi_print work with negative zeroes.
+       * mpi/mpicoder.c (gcry_mpi_print): Take care of negative zero.
+       (gcry_mpi_aprint): Allocate at least 1 byte.
+       * tests/t-convert.c: New.
+       * tests/Makefile.am (TESTS): Add t-convert.
+
+       Refactor the ECC code into 3 files.
+       * cipher/ecc-common.h, cipher/ecc-curves.c, cipher/ecc-misc.c: New.
+       * cipher/Makefile.am (EXTRA_libcipher_la_SOURCES): Add new files.
+       * configure.ac (GCRYPT_PUBKEY_CIPHERS): Add new .c files.
+       * cipher/ecc.c (curve_aliases, ecc_domain_parms_t, domain_parms)
+       (scanval): Move to ecc-curves.c.
+       (fill_in_curve): Move to ecc-curve.c as _gcry_ecc_fill_in_curve.
+       (ecc_get_curve): Move to ecc-curve.c as _gcry_ecc_get_curve.
+       (_gcry_mpi_ec_ec2os): Move to ecc-misc.c.
+       (ec2os): Move to ecc-misc.c as _gcry_ecc_ec2os.
+       (os2ec): Move to ecc-misc.c as _gcry_ecc_os2ec.
+       (point_set): Move as inline function to ecc-common.h.
+       (_gcry_ecc_curve_free): Move to ecc-misc.c as _gcry_ecc_curve_free.
+       (_gcry_ecc_curve_copy): Move to ecc-misc.c as _gcry_ecc_curve_copy.
+       (mpi_from_keyparam, point_from_keyparam): Move to ecc-curves.c.
+       (_gcry_mpi_ec_new): Move to ecc-curves.c.
+       (ecc_get_param): Move to ecc-curves.c as _gcry_ecc_get_param.
+       (ecc_get_param_sexp): Move to ecc-curves.c as _gcry_ecc_get_param_sexp.
+
+2013-08-22  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       serpent-sse2-amd64: Move register clearing to assembly functions.
+       cipher/serpent-sse2-amd64.S (_gcry_serpent_sse2_ctr_enc)
+       (_gcry_serpent_sse2_cbc_dec, _gcry_serpent_sse2_cfb_dec): Clear used
+       XMM registers.
+       cipher/serpent.c (_gcry_serpent_ctr_enc, _gcry_serpent_cbc_dec)
+       ( _gcry_serpent_cfb_dec) [USE_SSE2]: Remove XMM register clearing from
+       bulk functions.
+
+       twofish-amd64: do not make __twofish_dec_blk3 global.
+       * cipher/twofish-amd64.S (__twofish_dec_blk3): Do not export symbol as
+       global.
+       (__twofish_dec_blk3): Mark symbol as function.
+
+2013-08-20  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       mpi: add ARMv6 assembly.
+       * mpi/armv6/mpi-asm-defs.h: New.
+       * mpi/armv6/mpih-add1.S: New.
+       * mpi/armv6/mpih-mul1.S: New.
+       * mpi/armv6/mpih-mul2.S: New.
+       * mpi/armv6/mpih-mul3.S: New.
+       * mpi/armv6/mpih-sub1.S: New.
+       * mpi/config.links [arm]: Enable ARMv6 assembly.
+
+       Move ARMv6 detection to configure.ac.
+       * cipher/blowfish-armv6.S: Replace __ARM_ARCH >= 6 checks with
+       HAVE_ARM_ARCH_V6.
+       * cipher/blowfish.c: Ditto.
+       * cipher/camellia-armv6.S: Ditto.
+       * cipher/camellia.h: Ditto.
+       * cipher/cast5-armv6.S: Ditto.
+       * cipher/cast5.c: Ditto.
+       * cipher/rijndael-armv6.S: Ditto.
+       * cipher/rijndael.c: Ditto.
+       * configure.ac: Add HAVE_ARM_ARCH_V6 check.
+
+2013-08-19  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Add optimized wipememory for ARM.
+       src/g10lib.h [__arm__] (fast_wipememory2_unaligned_head)
+       (fast_wipememory2): New macros.
+
+       cipher: bufhelp: allow unaligned memory accesses on ARM.
+       * cipher/bufhelp.h [__arm__ && __ARM_FEATURE_UNALIGNED]: Enable
+       BUFHELP_FAST_UNALIGNED_ACCESS.
+
+2013-08-17  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Remove burn_stack optimization.
+       * src/misc.c (_gcry_burn_stack): Remove SIZEOF_UNSIGNED_LONG == 4 or 8
+       optimization.
+
+2013-08-16  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       camellia: add ARMv6 assembly implementation.
+       * cipher/Makefile.am: Add 'camellia-armv6.S'.
+       * cipher/camellia-armv6.S: New file.
+       * cipher/camellia-glue.c [USE_ARMV6_ASM]
+       (_gcry_camellia_armv6_encrypt_block)
+       (_gcry_camellia_armv6_decrypt_block): New prototypes.
+       [USE_ARMV6_ASM] (Camellia_EncryptBlock, Camellia_DecryptBlock)
+       (camellia_encrypt, camellia_decrypt): New functions.
+       * cipher/camellia.c [!USE_ARMV6_ASM]: Compile encryption and decryption
+       routines if USE_ARMV6_ASM macro is _not_ defined.
+       * cipher/camellia.h (USE_ARMV6_ASM): New macro.
+       [!USE_ARMV6_ASM] (Camellia_EncryptBlock, Camellia_DecryptBlock): If
+       USE_ARMV6_ASM is defined, disable these function prototypes.
+       (camellia) [arm]: Add 'camellia-armv6.lo'.
+
+       blowfish: add ARMv6 assembly implementation.
+       * cipher/Makefile.am: Add 'blowfish-armv6.S'.
+       * cipher/blowfish-armv6.S: New file.
+       * cipher/blowfish.c (USE_ARMV6_ASM): New macro.
+       [USE_ARMV6_ASM] (_gcry_blowfish_armv6_do_encrypt)
+       (_gcry_blowfish_armv6_encrypt_block)
+       (_gcry_blowfish_armv6_decrypt_block, _gcry_blowfish_armv6_ctr_enc)
+       (_gcry_blowfish_armv6_cbc_dec, _gcry_blowfish_armv6_cfb_dec): New
+       prototypes.
+       [USE_ARMV6_ASM] (do_encrypt, do_encrypt_block, do_decrypt_block)
+       (encrypt_block, decrypt_block): New functions.
+       (_gcry_blowfish_ctr_enc) [USE_ARMV6_ASM]: Use ARMv6 assembly function.
+       (_gcry_blowfish_cbc_dec) [USE_ARMV6_ASM]: Use ARMv6 assembly function.
+       (_gcry_blowfish_cfb_dec) [USE_ARMV6_ASM]: Use ARMv6 assembly function.
+       * configure.ac (blowfish) [arm]: Add 'blowfish-armv6.lo'.
+
+       cast5: add ARMv6 assembly implementation.
+       * cipher/Makefile.am: Add 'cast5-armv6.S'.
+       * cipher/cast5-armv6.S: New file.
+       * cipher/cast5.c (USE_ARMV6_ASM): New macro.
+       (CAST5_context) [USE_ARMV6_ASM]: New members 'Kr_arm_enc' and
+       'Kr_arm_dec'.
+       [USE_ARMV6_ASM] (_gcry_cast5_armv6_encrypt_block)
+       (_gcry_cast5_armv6_decrypt_block, _gcry_cast5_armv6_ctr_enc)
+       (_gcry_cast5_armv6_cbc_dec, _gcry_cast5_armv6_cfb_dec): New prototypes.
+       [USE_ARMV6_ASM] (do_encrypt_block, do_decrypt_block, encrypt_block)
+       (decrypt_block): New functions.
+       (_gcry_cast5_ctr_enc) [USE_ARMV6_ASM]: Use ARMv6 assembly function.
+       (_gcry_cast5_cbc_dec) [USE_ARMV6_ASM]: Use ARMv6 assembly function.
+       (_gcry_cast5_cfb_dec) [USE_ARMV6_ASM]: Use ARMv6 assembly function.
+       (do_cast_setkey) [USE_ARMV6_ASM]: Initialize 'Kr_arm_enc' and
+       'Kr_arm_dec'.
+       * configure.ac (cast5) [arm]: Add 'cast5-armv6.lo'.
+
+2013-08-14  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       rijndael: add ARMv6 assembly implementation.
+       * cipher/Makefile.am: Add 'rijndael-armv6.S'.
+       * cipher/rijndael-armv6.S: New file.
+       * cipher/rijndael.c (USE_ARMV6_ASM): New macro.
+       [USE_ARMV6_ASM] (_gcry_aes_armv6_encrypt_block)
+       (_gcry_aes_armv6_decrypt_block): New prototypes.
+       (do_encrypt_aligned) [USE_ARMV6_ASM]: Use ARMv6 assembly function.
+       (do_encrypt): Disable input/output alignment when USE_ARMV6_ASM.
+       (do_decrypt_aligned) [USE_ARMV6_ASM]: Use ARMv6 assembly function.
+       (do_decrypt): Disable input/output alignment when USE_ARMV6_ASM.
+       * configure.ac (HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS): New check for
+       gcc/as compatibility with ARM assembly implementations.
+       (aes) [arm]: Add 'rijndael-armv6.lo'.
+
+2013-08-09  NIIBE Yutaka  <gniibe@fsij.org>
+
+       cipher: fix memory leak.
+       * cipher/pubkey.c (gcry_pk_sign): Handle the specific case of ECC,
+       where there is NULL whichi is not the sentinel.
+
+2013-08-08  Werner Koch  <wk@gnupg.org>
+
+       mpi: Clear immutable flag on the result of gcry_mpi_set.
+       * mpi/mpiutil.c (gcry_mpi_set): Reset immutable and const flags.
+       * tests/mpitests.c (test_const_and_immutable): Add a test for this.
+
+2013-08-07  NIIBE Yutaka  <gniibe@fsij.org>
+
+       tests: fix memory leaks.
+       * tests/benchmark.c (dsa_bench): Release SIG.
+
+       * tests/mpitests.c (test_powm): Release BASE, EXP, MOD, and RES.
+
+       * tests/prime.c (check_primes): Release PRIME.
+
+       * tests/tsexp.c (basic): Use intermediate variable M for constant.
+       Release S1, S2 and A.
+
+2013-08-07  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Fix building on W32 (cannot export symbol 'gcry_sexp_get_buffer')
+       * src/libgcrypt.def: Change 'gcry_sexp_get_buffer' to
+       'gcry_sexp_nth_buffer'.
+
+2013-08-06  NIIBE Yutaka  <gniibe@fsij.org>
+
+       cipher: fix another memory leak.
+       * cipher/ecc.c (ecc_get_curve): Free TMP.
+
+       tests: fix memory leaks.
+       * tests/pubkey.c (check_keys_crypt): Release L, X0, and X1.
+       (check_keys): Release X.
+
+       cipher: fix memory leaks.
+       * cipher/elgamal.c (elg_generate_ext): Free XVALUE.
+
+       * cipher/pubkey.c (sexp_elements_extract): Don't use IDX for loop.
+       Call mpi_free.
+       (sexp_elements_extract_ecc): Call mpi_free.
+
+2013-08-05  Werner Koch  <wk@gnupg.org>
+
+       mpi: Improve gcry_mpi_invm to detect bad input.
+       * mpi/mpi-inv.c (gcry_mpi_invm): Return 0 for bad input.
+
+2013-07-31  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
+
+       Correct checks for ecc secret key.
+       * cipher/ecc.c (check_secret_key): replace wrong comparison of Q and
+       sk->Q points with correct one.
+
+2013-07-29  Werner Koch  <wk@gnupg.org>
+
+       sexp: Allow white space anywhere in a hex format.
+       * src/sexp.c (hextobyte): Remove.
+       (hextonibble): New.
+       (vsexp_sscan): Skip whtespace between hex nibbles.
+
+       Implement deterministic ECDSA as specified by rfc-6979.
+       * cipher/ecc.c (sign): Add args FLAGS and HASHALGO.  Convert an opaque
+       MPI as INPUT.  Implement rfc-6979.
+       (ecc_sign): Remove the opaque MPI code and pass FLAGS to sign.
+       (verify): Do not allocate and compute Y; it is not used.
+       (ecc_verify): Truncate the hash value if needed.
+       * tests/dsa-rfc6979.c (check_dsa_rfc6979): Add ECDSA test cases.
+
+2013-07-26  Werner Koch  <wk@gnupg.org>
+
+       Implement deterministic DSA as specified by rfc-6979.
+       * cipher/dsa.c (dsa_sign): Move opaque mpi extraction to sign.
+       (sign): Add args FLAGS and HASHALGO.  Implement deterministic DSA.
+       Add code path for R==0 to comply with the standard.
+       (dsa_verify): Left fill opaque mpi based hash values.
+       * cipher/dsa-common.c (int2octets, bits2octets): New.
+       (_gcry_dsa_gen_rfc6979_k): New.
+       * tests/dsa-rfc6979.c: New.
+       * tests/Makefile.am (TESTS): Add dsa-rfc6979.
+
+       Allow the use of a private-key s-expression with gcry_pk_verify.
+       * cipher/pubkey.c (sexp_to_key): Fallback to private key.
+
+2013-07-25  Werner Koch  <wk@gnupg.org>
+
+       Mitigate a flush+reload cache attack on RSA secret exponents.
+       * mpi/mpi-pow.c (gcry_mpi_powm): Always perfrom the mpi_mul for
+       exponents in secure memory.
+
+2013-07-19  Werner Koch  <wk@gnupg.org>
+
+       pk: Allow the use of a hash element for DSA sign and verify.
+       * cipher/pubkey.c (pubkey_sign): Add arg ctx and pass it to the sign
+       module.
+       (gcry_pk_sign): Pass CTX to pubkey_sign.
+       (sexp_data_to_mpi): Add flag rfc6979 and code to alls hash with *DSA
+       * cipher/rsa.c (rsa_sign, rsa_verify): Return an error if an opaque
+       MPI is given for DATA/HASH.
+       * cipher/elgamal.c (elg_sign, elg_verify): Ditto.
+       * cipher/dsa.c (dsa_sign, dsa_verify): Convert a given opaque MPI.
+       * cipher/ecc.c (ecc_sign, ecc_verify): Ditto.
+       * tests/basic.c (check_pubkey_sign_ecdsa): Add a test for using a hash
+       element with DSA.
+
+       sexp: Add function gcry_sexp_nth_buffer.
+       * src/sexp.c (gcry_sexp_nth_buffer): New.
+       * src/visibility.c, src/visibility.h: Add function wrapper.
+       * src/libgcrypt.vers, src/libgcrypt.def: Add to API.
+       * src/gcrypt.h.in: Add prototype.
+
+2013-07-18  Werner Koch  <wk@gnupg.org>
+
+       Add support for Salsa20.
+       * src/gcrypt.h.in (GCRY_CIPHER_SALSA20): New.
+       * cipher/salsa20.c: New.
+       * configure.ac (available_ciphers): Add Salsa20.
+       * cipher/cipher.c: Register Salsa20.
+       (cipher_setiv): Allow to divert an IV to a cipher module.
+       * src/cipher-proto.h (cipher_setiv_func_t): New.
+       (cipher_extra_spec): Add field setiv.
+       * src/cipher.h: Declare Salsa20 definitions.
+       * tests/basic.c (check_stream_cipher): New.
+       (check_stream_cipher_large_block): New.
+       (check_cipher_modes): Run new test functions.
+       (check_ciphers): Add simple test for Salsa20.
+
+2013-07-17  Werner Koch  <wk@gnupg.org>
+
+       Allow gcry_mpi_dump to print opaque MPIs.
+       * mpi/mpicoder.c (gcry_mpi_dump): Detect abd print opaque MPIs.
+       * tests/mpitests.c (test_opaque): New.
+       (main): Call new test.
+
+       cipher: Prepare to pass extra info to the sign functions.
+       * src/gcrypt-module.h (gcry_pk_sign_t): Add parms flags and hashalgo.
+       * cipher/rsa.c (rsa_sign): Add parms and mark them as unused.
+       * cipher/dsa.c (dsa_sign): Ditto.
+       * cipher/elgamal.c (elg_sign): Ditto.
+       * cipher/pubkey.c (dummy_sign): Ditto.
+       (pubkey_sign): Pass 0 for the new args.
+
+       Fix a special case bug in mpi_powm for e==0.
+       * mpi/mpi-pow.c (gcry_mpi_powm): For a zero exponent, make sure that
+       the result has been allocated.
+
+2013-07-15  Dmitry Eremin-Solenikov  <dbaryshkov@gmail.com>
+
+       Fix memory leak in t-mpi-point test.
+       * tests/t-mpi-point.c (basic_ec_math, basic_ec_math_simplified): add
+       calls to gcry_ctx_release() to free contexts after they become unused.
+
+2013-07-10  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Fix 'Please include winsock2.h before windows.h' warnings with mingw32.
+       * random/rndw32.c: include winsock2.h before windows.h.
+       * src/ath.h [_WIN32]: Ditto.
+       * tests/benchmark.c [_WIN32]: Ditto.
+
+       Remove duplicate header from mpi/amd64/mpih-mul2.S.
+       * mpi/amd64/mpih-mul2.S: remove duplicated header.
+
+       Fix i386/amd64 inline assembly "cc" clobbers.
+       * cipher/bithelp.h [__GNUC__, __i386__] (rol, ror): add "cc" globber
+       for inline assembly.
+       * cipher/cast5.c [__GNUC__, __i386__] (rol): Ditto.
+       * random/rndhw.c [USE_DRNG] (rdrand_long): Ditto.
+       * src/hmac256.c [__GNUC__, __i386__] (ror): Ditto.
+       * mpi/longlong.c [__i386__] (add_ssaaaa, sub_ddmmss, umul_ppmm)
+       (udiv_qrnnd, count_leading_zeros, count_trailing_zeros): Ditto.
+
+       bufhelp: Suppress 'cast increases required alignment' warning.
+       * cipher/bufhelp.h (buf_xor, buf_xor_2dst, buf_xor_n_copy): Cast
+       to larger element pointer through (void *) to suppress -Wcast-error.
+
+       mpi: Add __ARM_ARCH for older GCC.
+       * mpi/longlong.h [__arm__]: Construct __ARM_ARCH if not provided by
+       compiler.
+
+       mpi: add missing "cc" clobber for ARM assembly.
+       * mpi/longlong.h [__arm__] (add_ssaaaa, sub_ddmmss): Add __CLOBBER_CC.
+       [__arm__][__ARM_ARCH <= 3] (umul_ppmm): Ditto.
+
+       Tweak ARM inline assembly for mpi.
+       mpi/longlong.h [__arm__]: Enable inline assembly if __thumb2__ is
+       defined.
+       [__arm__]: Use __ARCH_ARM when defined.
+       [__arm__] [__ARM_ARCH >= 5] (count_leading_zeros): New.
+
+2013-06-26  Werner Koch  <wk@gnupg.org>
+
+       Make gpg-error replacement defines more robust.
+       * configure.ac (AH_BOTTOM): Move GPG_ERR_ replacement defines to ...
+       * src/gcrypt-int.h: new file.
+       * src/visibility.h, src/cipher.h: Replace gcrypt.h by gcrypt-int.h.
+       * tests/: Ditto for all test files.
+
+2013-06-20  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Check if assembler is compatible with AMD64 assembly implementations.
+       * cipher/blowfish-amd64.S: Enable only if
+       HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS is defined.
+       * cipher/camellia-aesni-avx-amd64.S: Ditto.
+       * cipher/camellia-aesni-avx2-amd64.S: Ditto.
+       * cipher/cast5-amd64.S: Ditto.
+       * cipher/rinjdael-amd64.S: Ditto.
+       * cipher/serpent-avx2-amd64.S: Ditto.
+       * cipher/serpent-sse2-amd64.S: Ditto.
+       * cipher/twofish-amd64.S: Ditto.
+       * cipher/blowfish.c: Use AMD64 assembly implementation only if
+       HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS is defined
+       * cipher/camellia-glue.c: Ditto.
+       * cipher/cast5.c: Ditto.
+       * cipher/rijndael.c: Ditto.
+       * cipher/serpent.c: Ditto.
+       * cipher/twofish.c: Ditto.
+       * configure.ac: Check gcc/as compatibility with AMD64 assembly
+       implementations.
+
+2013-06-09  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Optimize _gcry_burn_stack for 32-bit and 64-bit architectures.
+       * src/misc.c (_gcry_burn_stack): Add optimization for 32-bit and 64-bit
+       architectures.
+
+       Add Camellia AES-NI/AVX2 implementation.
+       * cipher/Makefile.am: Add 'camellia-aesni-avx2-amd64.S'.
+       * cipher/camellia-aesni-avx2-amd64.S: New file.
+       * cipher/camellia-glue.c (USE_AESNI_AVX2): New macro.
+       (CAMELLIA_context) [USE_AESNI_AVX2]: Add 'use_aesni_avx2'.
+       [USE_AESNI_AVX2] (_gcry_camellia_aesni_avx2_ctr_enc)
+       (_gcry_camellia_aesni_avx2_cbc_dec)
+       (_gcry_camellia_aesni_avx2_cfb_dec): New prototypes.
+       (camellia_setkey) [USE_AESNI_AVX2]: Check AVX2+AES-NI capable hardware
+       and set 'ctx->use_aesni_avx2'.
+       (_gcry_camellia_ctr_enc) [USE_AESNI_AVX2]: Add AVX2 accelerated code.
+       (_gcry_camellia_cbc_dec) [USE_AESNI_AVX2]: Add AVX2 accelerated code.
+       (_gcry_camellia_cfb_dec) [USE_AESNI_AVX2]: Add AVX2 accelerated code.
+       (selftest_ctr_128, selftest_cbc_128, selftest_cfb_128): Grow 'nblocks'
+       so that AVX2 codepaths get tested.
+       * configure.ac (camellia) [avx2support, aesnisupport]: Add
+       'camellia-aesni-avx2-amd64.lo'.
+
+       Add Serpent AVX2 implementation.
+       * cipher/Makefile.am: Add 'serpent-avx2-amd64.S'.
+       * cipher/serpent-avx2-amd64.S: New file.
+       * cipher/serpent.c (USE_AVX2): New macro.
+       (serpent_context_t) [USE_AVX2]: Add 'use_avx2'.
+       [USE_AVX2] (_gcry_serpent_avx2_ctr_enc, _gcry_serpent_avx2_cbc_dec)
+       (_gcry_serpent_avx2_cfb_dec): New prototypes.
+       (serpent_setkey_internal) [USE_AVX2]: Check for AVX2 capable hardware
+       and set 'use_avx2'.
+       (_gcry_serpent_ctr_enc) [USE_AVX2]: Use AVX2 accelerated functions.
+       (_gcry_serpent_cbc_dec) [USE_AVX2]: Use AVX2 accelerated functions.
+       (_gcry_serpent_cfb_dec) [USE_AVX2]: Use AVX2 accelerated functions.
+       (selftest_ctr_128, selftest_cbc_128, selftest_cfb_128): Grow 'nblocks'
+       so that AVX2 codepaths are tested.
+       * configure.ac (serpent) [avx2support]: Add 'serpent-avx2-amd64.lo'.
+
+       Add detection for Intel AVX2 instruction set.
+       * configure.ac: Add option --disable-avx2-support.
+       (HAVE_GCC_INLINE_ASM_AVX2): New.
+       (ENABLE_AVX2_SUPPORT): New.
+       * src/g10lib.h (HWF_INTEL_AVX2): New.
+       * src/global.c (hwflist): Add HWF_INTEL_AVX2.
+       * src/hwf-x86.c [__i386__] (get_cpuid): Initialize registers to zero
+       before cpuid.
+       [__x86_64__] (get_cpuid): Initialize registers to zero before cpuid.
+       (detect_x86_gnuc): Store maximum cpuid level.
+       (detect_x86_gnuc) [ENABLE_AVX2_SUPPORT]: Add detection for AVX2.
+
+       twofish: add amd64 assembly implementation.
+       * cipher/Makefile.am: Add 'twofish-amd64.S'.
+       * cipher/twofish-amd64.S: New file.
+       * cipher/twofish.c (USE_AMD64_ASM): New macro.
+       [USE_AMD64_ASM] (_gcry_twofish_amd64_encrypt_block)
+       (_gcry_twofish_amd64_decrypt_block, _gcry_twofish_amd64_ctr_enc)
+       (_gcry_twofish_amd64_cbc_dec, _gcry_twofish_amd64_cfb_dec): New
+       prototypes.
+       [USE_AMD64_ASM] (do_twofish_encrypt, do_twofish_decrypt)
+       (twofish_encrypt, twofish_decrypt): New functions.
+       (_gcry_twofish_ctr_enc, _gcry_twofish_cbc_dec, _gcry_twofish_cfb_dec)
+       (selftest_ctr, selftest_cbc, selftest_cfb): New functions.
+       (selftest): Call new bulk selftests.
+       * cipher/cipher.c (gcry_cipher_open) [USE_TWOFISH]: Register Twofish
+       bulk functions for ctr-enc, cbc-dec and cfb-dec.
+       * configure.ac (twofish) [x86_64]: Add 'twofish-amd64.lo'.
+       * src/cipher.h (_gcry_twofish_ctr_enc, _gcry_twofish_cbc_dec)
+       (gcry_twofish_cfb_dec): New prototypes.
+
+2013-05-29  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       rinjdael: add amd64 assembly implementation.
+       * cipher/Makefile.am: Add 'rijndael-amd64.S'.
+       * cipher/rijndael-amd64.S: New file.
+       * cipher/rijndael.c (USE_AMD64_ASM): New macro.
+       [USE_AMD64_ASM] (_gcry_aes_amd64_encrypt_block)
+       (_gcry_aes_amd64_decrypt_block): New prototypes.
+       (do_encrypt_aligned) [USE_AMD64_ASM]: Use amd64 assembly function.
+       (do_encrypt): Disable input/output alignment when USE_AMD64_ASM is set.
+       (do_decrypt_aligned) [USE_AMD64_ASM]: Use amd64 assembly function.
+       (do_decrypt): Disable input/output alignment when USE_AMD64_AES is set.
+       * configure.ac (aes) [x86-64]: Add 'rijndael-amd64.lo'.
+
+       blowfish: add amd64 assembly implementation.
+       * cipher/Makefile.am: Add 'blowfish-amd64.S'.
+       * cipher/blowfish-amd64.S: New file.
+       * cipher/blowfish.c (USE_AMD64_ASM): New macro.
+       [USE_AMD64_ASM] (_gcry_blowfish_amd64_do_encrypt)
+       (_gcry_blowfish_amd64_encrypt_block)
+       (_gcry_blowfish_amd64_decrypt_block, _gcry_blowfish_amd64_ctr_enc)
+       (_gcry_blowfish_amd64_cbc_dec, _gcry_blowfish_amd64_cfb_dec): New
+       prototypes.
+       [USE_AMD64_ASM] (do_encrypt, do_encrypt_block, do_decrypt_block)
+       (encrypt_block, decrypt_block): New functions.
+       (_gcry_blowfish_ctr_enc, _gcry_blowfish_cbc_dec)
+       (_gcry_blowfish_cfb_dec, selftest_ctr, selftest_cbc, selftest_cfb): New
+       functions.
+       (selftest): Call new bulk selftests.
+       * cipher/cipher.c (gcry_cipher_open) [USE_BLOWFISH]: Register Blowfish
+       bulk functions for ctr-enc, cbc-dec and cfb-dec.
+       * configure.ac (blowfish) [x86_64]: Add 'blowfish-amd64.lo'.
+       * src/cipher.h (_gcry_blowfish_ctr_enc, _gcry_blowfish_cbc_dec)
+       (gcry_blowfish_cfb_dec): New prototypes.
+
+2013-05-24  Werner Koch  <wk@gnupg.org>
+
+       ecc: Simplify the compliant point generation.
+       * cipher/ecc.c (generate_key): Use point_snatch_set, replaces unneeded
+       variable copies, etc.
+
+       ecc: Fix a minor flaw in the generation of K.
+       * cipher/dsa.c (gen_k): Factor code out to ..
+       * cipher/dsa-common.c (_gcry_dsa_gen_k): new file and function.  Add
+       arg security_level and re-indent a bit.
+       * cipher/ecc.c (gen_k): Remove and change callers to _gcry_dsa_gen_k.
+       * cipher/dsa.c: Include pubkey-internal.
+       * cipher/Makefile.am (libcipher_la_SOURCES): Add dsa-common.c
+
+2013-05-24  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       cast5: add amd64 assembly implementation.
+       * cipher/Makefile.am: Add 'cast5-amd64.S'.
+       * cipher/cast5-amd64.S: New file.
+       * cipher/cast5.c (USE_AMD64_ASM): New macro.
+       (_gcry_cast5_s1tos4): Merge arrays s1, s2, s3, s4 to single array to
+       simplify access from assembly implementation.
+       (s1, s2, s3, s4): New macros pointing to subarrays in
+       _gcry_cast5_s1tos4.
+       [USE_AMD64_ASM] (_gcry_cast5_amd64_encrypt_block)
+       (_gcry_cast5_amd64_decrypt_block, _gcry_cast5_amd64_ctr_enc)
+       (_gcry_cast5_amd64_cbc_dec, _gcry_cast5_amd64_cfb_dec): New prototypes.
+       [USE_AMD64_ASM] (do_encrypt_block, do_decrypt_block, encrypt_block)
+       (decrypt_block): New functions.
+       (_gcry_cast5_ctr_enc, _gcry_cast5_cbc_dec, _gcry_cast5_cfb_dec)
+       (selftest_ctr, selftest_cbc, selftest_cfb): New functions.
+       (selftest): Call new bulk selftests.
+       * cipher/cipher.c (gcry_cipher_open) [USE_CAST5]: Register CAST5 bulk
+       functions for ctr-enc, cbc-dec and cfb-dec.
+       * configure.ac (cast5) [x86_64]: Add 'cast5-amd64.lo'.
+       * src/cipher.h (_gcry_cast5_ctr_enc, _gcry_cast5_cbc_dec)
+       (gcry_cast5_cfb_dec): New prototypes.
+
+       cipher-selftest: make selftest work with any block-size.
+       * cipher/cipher-selftest.c (_gcry_selftest_helper_cbc_128)
+       (_gcry_selftest_helper_cfb_128, _gcry_selftest_helper_ctr_128): Renamed
+       functions from '<name>_128' to '<name>'.
+       (_gcry_selftest_helper_cbc, _gcry_selftest_helper_cfb)
+       (_gcry_selftest_helper_ctr): Make work with different block sizes.
+       * cipher/cipher-selftest.h (_gcry_selftest_helper_cbc_128)
+       (_gcry_selftest_helper_cfb_128, _gcry_selftest_helper_ctr_128): Renamed
+       prototypes from '<name>_128' to '<name>'.
+       * cipher/camellia-glue.c (selftest_ctr_128, selftest_cfb_128)
+       (selftest_ctr_128): Change to use new function names.
+       * cipher/rijndael.c (selftest_ctr_128, selftest_cfb_128)
+       (selftest_ctr_128): Change to use new function names.
+       * cipher/serpent.c (selftest_ctr_128, selftest_cfb_128)
+       (selftest_ctr_128): Change to use new function names.
+
+2013-05-23  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       serpent: add parallel processing for CFB decryption.
+       * cipher/cipher.c (gcry_cipher_open): Add bulf CFB decryption function
+       for Serpent.
+       * cipher/serpent-sse2-amd64.S (_gcry_serpent_sse2_cfb_dec): New
+       function.
+       * cipher/serpent.c (_gcry_serpent_sse2_cfb_dec): New prototype.
+       (_gcry_serpent_cfb_dec) New function.
+       (selftest_cfb_128) New function.
+       (selftest) Call selftest_cfb_128.
+       * src/cipher.h (_gcry_serpent_cfb_dec): New prototype.
+
+       camellia: add parallel processing for CFB decryption.
+       * cipher/camellia-aesni-avx-amd64.S
+       (_gcry_camellia_aesni_avx_cfb_dec): New function.
+       * cipher/camellia-glue.c (_gcry_camellia_aesni_avx_cfb_dec): New
+       prototype.
+       (_gcry_camellia_cfb_dec): New function.
+       (selftest_cfb_128): New function.
+       (selftest): Call selftest_cfb_128.
+       * cipher/cipher.c (gry_cipher_open): Add bulk CFB decryption function
+       for Camellia.
+       * src/cipher.h (_gcry_camellia_cfb_dec): New prototype.
+
+       rinjdael: add parallel processing for CFB decryption with AES-NI.
+       * cipher/cipher-selftest.c (_gcry_selftest_helper_cfb_128): New
+       function for CFB selftests.
+       * cipher/cipher-selftest.h (_gcry_selftest_helper_cfb_128): New
+       prototype.
+       * cipher/rijndael.c [USE_AESNI] (do_aesni_enc_vec4): New function.
+       (_gcry_aes_cfb_dec) [USE_AESNI]: Add parallelized CFB decryption.
+       (selftest_cfb_128): New function.
+       (selftest): Call selftest_cfb_128.
+
+2013-05-23  Werner Koch  <wk@gnupg.org>
+
+       Avoid compiler warning due to the global symbol setkey.
+       * cipher/cipher-selftest.c (_gcry_selftest_helper_cbc_128)
+       (_gcry_selftest_helper_ctr_128): Rename setkey to setkey_func.
+
+2013-05-23  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       serpent: add SSE2 accelerated amd64 implementation.
+       * configure.ac (serpent): Add 'serpent-sse2-amd64.lo'.
+       * cipher/Makefile.am (EXTRA_libcipher_la_SOURCES): Add
+       'serpent-sse2-amd64.S'.
+       * cipher/cipher.c (gcry_cipher_open) [USE_SERPENT]: Register bulk
+       functions for CBC-decryption and CTR-mode.
+       * cipher/serpent.c (USE_SSE2): New macro.
+       [USE_SSE2] (_gcry_serpent_sse2_ctr_enc, _gcry_serpent_sse2_cbc_dec):
+       New prototypes to assembler functions.
+       (serpent_setkey): Set 'serpent_init_done' before calling serpent_test.
+       (_gcry_serpent_ctr_enc): New function.
+       (_gcry_serpent_cbc_dec): New function.
+       (selftest_ctr_128): New function.
+       (selftest_cbc_128): New function.
+       (selftest): Call selftest_ctr_128 and selftest_cbc_128.
+       * cipher/serpent-sse2-amd64.S: New file.
+       * src/cipher.h (_gcry_serpent_ctr_enc): New prototype.
+       (_gcry_serpent_cbc_dec): New prototype.
+
+       Serpent: faster S-box implementation.
+       * cipher/serpent.c (SBOX0, SBOX1, SBOX2, SBOX3, SBOX4, SBOX5, SBOX6)
+       (SBOX7, SBOX0_INVERSE, SBOX1_INVERSE, SBOX2_INVERSE, SBOX3_INVERSE)
+       (SBOX4_INVERSE, SBOX5_INVERSE, SBOX6_INVERSE, SBOX7_INVERSE): Replace
+       with new definitions.
+
+2013-05-22  Werner Koch  <wk@gnupg.org>
+
+       w32: Fix installing of .def file.
+       * src/Makefile.am (install-def-file): Create libdir first.
+
+       Add control commands to disable mlock and setuid dropping.
+       * src/gcrypt.h.in (GCRYCTL_DISABLE_LOCKED_SECMEM): New.
+       (GCRYCTL_DISABLE_PRIV_DROP): New.
+       * src/global.c (_gcry_vcontrol): Implement them.
+       * src/secmem.h (GCRY_SECMEM_FLAG_NO_MLOCK): New.
+       (GCRY_SECMEM_FLAG_NO_PRIV_DROP): New.
+       * src/secmem.c (no_mlock, no_priv_drop): New.
+       (_gcry_secmem_set_flags, _gcry_secmem_get_flags): Set and get them.
+       (lock_pool): Handle no_mlock and no_priv_drop.
+
+       Fix libtool 2.4.2 to correctly detect .def files.
+       * ltmain.sh (sed_uncomment_deffile): New.
+       (orig_export_symbols): Uncomment def file before testing for EXPORTS.
+       * m4/libtool.m4: Do the same for the generated code.
+
+2013-05-22  Jussi Kivilinna  <jussi.kivilinna@iki.fi>
+
+       Add AES bulk CBC decryption selftest.
+       * cipher/rinjdael.c (selftest_cbc_128): New.
+       (selftest): Call selftest_cbc_128.
+
+       Change AES bulk CTR encryption selftest use new selftest helper function
+       * cipher/rinjdael.c: (selftest_ctr_128): Change to use new selftest
+       helper function.
+
+       Convert bulk CTR and CBC selftest functions in Camellia to generic selftest helper functions
+       * cipher/Makefile.am (libcipher_la_SOURCES): Add cipher-selftest files.
+       * cipher/camellia-glue.c (selftest_ctr_128, selftest_cbc_128): Change
+       to use the new selftest helper functions.
+       * cipher/cipher-selftest.c: New.
+       * cipher/cipher-selftest.h: New.
+
+       camellia: add bulk CBC decryption selftest.
+       * cipher/camellia-glue.c: (selftest_cbc_128): New selftest function for
+       bulk CBC decryption.
+       (selftest): Add call to selftest_cbc_128.
+
+       camellia: Rename camellia_aesni_avx_x86-64.S to camellia-aesni-avx-amd64.S
+       * cipher/camellia_aesni_avx_x86-64.S: Remove.
+       * cipher/camellia-aesni-avx-amd64.S: New.
+       * cipher/Makefile.am: Use the new filename.
+       * configure.ac: Use the new filename.
+
+2013-05-21  Werner Koch  <wk@gnupg.org>
+
+       Fix indentation and save on string space.
+       * cipher/ecc.c (generate_key): Use the same string for both fatal
+       messages.
+
+2013-05-20  Andrey  <andrey@brainhub.org>
+
+       cipher: Fix segv in last ECC change.
+       * cipher/ecc.c (generate_key): Make sure R is initialized.
+
+2013-05-09  Andrey  <andrey@brainhub.org>
+
+       cipher: Generate compliant ECC keys.
+       * cipher/ecc.c (generate_key): Make sure a key is compliant for
+       using the compact representation.
+
+2013-04-18  Werner Koch  <wk@gnupg.org>
+
+       cipher: Fix regression in Padlock support.
+       * cipher/rijndael.c (do_setkey): Remove dummy padlock key generation case
+       and use the standard one.
+
+       mpi: Yet another fix to get option flag munging right.
+       * cipher/Makefile.am (o_flag_munging): Yet another fix.
+
+       mpi: Make using gcc's -Ofast easier.
+       * cipher/Makefile.am (o_flag_munging): Take -Ofast in account.
+
+       Fix alignment problem in idea.c.
+       * cipher/idea.c (cipher): Rework parameter use to fix alignment
+       problems.
+
+       * cipher/idea.c (FNCCAST_SETKEY, FNCCAST_CRYPT): Remove unused macros.
+
+       Fix alignment problem in idea.c.
+
+       * cipher/idea.c (cipher): Rework parameter use to fix alignment
+       problems.
+
+       * cipher/idea.c (FNCCAST_SETKEY, FNCCAST_CRYPT): Remove unused macros.
+
+
+       (cherry picked from 4cd279556777e02eda79973f68efaa4b741f9175)
+
+2013-04-18  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Add some const attributes.
+       * cipher/md4.c (transform): Add const attribute.
+       * cipher/md5.c (transform): Ditto.
+       * cipher/rmd160.c (transform): Ditto.
+
+       Fix alignment problem in serpent.c.
+       * cipher/serpent.c (serpent_key_prepare): Fix misaligned access.
+       (serpent_setkey): Likewise.
+       (serpent_encrypt_internal): Likewise.
+       (serpent_decrypt_internal): Likewise.
+       (serpent_encrypt): Don't put an alignment-increasing cast.
+       (serpent_decrypt): Likewise.
+       (serpent_test): Likewise.
+
+2013-04-16  Werner Koch  <wk@wheatstone.g10code.de>
+
+       Fix multiply by zero in gcry_mpi_ec_mul.
+       * mpi/ec.c (_gcry_mpi_ec_mul_point): Handle case of SCALAR == 0.
+       * tests/t-mpi-point.c (basic_ec_math): Add a test case for this.
+
+2013-04-15  Werner Koch  <wk@gnupg.org>
+
+       Add macros to return pre-defined MPIs.
+       * src/gcrypt.h.in (GCRYMPI_CONST_ONE, GCRYMPI_CONST_TWO)
+       (GCRYMPI_CONST_THREE, GCRYMPI_CONST_FOUR, GCRYMPI_CONST_EIGHT): New.
+       (_gcry_mpi_get_const): New private function.
+       * src/visibility.c (_gcry_mpi_get_const): New.
+       * src/visibility.h: Mark it visible.
+
+       Fix addition of EC points.
+       * mpi/ec.c (_gcry_mpi_ec_add_points): Fix case of P1 given in affine
+       coordinates.
+
+2013-04-12  Werner Koch  <wk@gnupg.org>
+
+       Add hack to allow using an "ecc" key for "ecdsa" or "ecdh".
+       * cipher/pubkey.c (sexp_to_key): Add optional arg USE.
+       (gcry_pk_encrypt, gcry_pk_decrypt): Call sexp_to_key with usage sign.
+       (gcry_pk_sign, gcry_pk_verify): Call sexp_to_key with usage encrypt.
+       * tests/basic.c (show_sexp): New.
+       (check_pubkey_sign): Print test number and add cases for ecc.
+       (check_pubkey_sign_ecdsa): New.
+       (do_check_one_pubkey): Divert to new function.
+
+2013-04-11  Werner Koch  <wk@gnupg.org>
+
+       Add gcry_pubkey_get_sexp.
+       * src/gcrypt.h.in (GCRY_PK_GET_PUBKEY): New.
+       (GCRY_PK_GET_SECKEY): New.
+       (gcry_pubkey_get_sexp): New.
+       * src/visibility.c (gcry_pubkey_get_sexp): New.
+       * src/visibility.h (gcry_pubkey_get_sexp): Mark visible.
+       * src/libgcrypt.def, src/libgcrypt.vers: Add new function.
+       * cipher/pubkey-internal.h: New.
+       * cipher/Makefile.am (libcipher_la_SOURCES): Add new file.
+       * cipher/ecc.c: Include pubkey-internal.h
+       (_gcry_pk_ecc_get_sexp): New.
+       * cipher/pubkey.c: Include pubkey-internal.h and context.h.
+       (_gcry_pubkey_get_sexp): New.
+       * src/context.c (_gcry_ctx_find_pointer): New.
+       * src/cipher-proto.h: Add _gcry_pubkey_get_sexp.
+       * tests/t-mpi-point.c (print_sexp): New.
+       (context_param, basic_ec_math_simplified): Add tests for the new
+       function.
+
+       * configure.ac (NEED_GPG_ERROR_VERSION): Set to 1.11.
+       (AH_BOTTOM) Add error codes from gpg-error 1.12
+       * src/g10lib.h (fips_not_operational): Use GPG_ERR_NOT_OPERATIONAL.
+
+       * mpi/ec.c (_gcry_mpi_ec_get_mpi): Fix computation of Q.
+       (_gcry_mpi_ec_get_point): Ditto.
+
+       Remove unused code.
+       * cipher/pubkey.c (_gcry_pk_module_lookup, _gcry_pk_module_release)
+       (_gcry_pk_get_elements): Remove.
+
+2013-04-05  Werner Koch  <wk@gnupg.org>
+
+       Make the Q parameter optional for ECC signing.
+       * cipher/ecc.c (ecc_sign): Remove the need for Q.
+       * cipher/pubkey.c (sexp_elements_extract_ecc): Make Q optional for a
+       private key.
+       (sexp_to_key): Add optional arg R_IS_ECC.
+       (gcry_pk_sign): Do not call gcry_pk_get_nbits for ECC keys.
+       * tests/pubkey.c (die): Make sure to print a LF.
+       (check_ecc_sample_key): New.
+       (main): Call new test.
+
+       Add test case for SCRYPT and rework the code.
+       * tests/t-kdf.c (check_scrypt): New.
+       (main): Call new test.
+
+       * configure.ac: Support disabling of the scrypt algorithm.  Make KDF
+       enabling similar to the other algorithm classes.  Disable scrypt if we
+       don't have a 64 bit type.
+       * cipher/memxor.c, cipher/memxor.h: Remove.
+       * cipher/scrypt.h: Remove.
+       * cipher/kdf-internal.h: New.
+       * cipher/Makefile.am: Remove files.  Add new file.  Move scrypt.c to
+       EXTRA_libcipher_la_SOURCES.
+       (GCRYPT_MODULES): Add GCRYPT_KDFS.
+       * src/gcrypt.h.in (GCRY_KDF_SCRYPT): Change value.
+       * cipher/kdf.c (pkdf2): Rename to _gcry_kdf_pkdf2.
+       (_gcry_kdf_pkdf2): Don't bail out for SALTLEN==0.
+       (gcry_kdf_derive): Allow for a passwordlen of zero for scrypt.  Check
+       for SALTLEN > 0 for GCRY_KDF_PBKDF2.  Pass algo to _gcry_kdf_scrypt.
+       (gcry_kdf_derive) [!USE_SCRYPT]: Return an error.
+       * cipher/scrypt.c: Replace memxor.h by bufhelp.h.  Replace scrypt.h by
+       kdf-internal.h.  Enable code only if HAVE_U64_TYPEDEF is defined.
+       Replace C99 types uint64_t, uint32_t, and uint8_t by libgcrypt types.
+       (_SALSA20_INPUT_LENGTH): Remove underscore from identifier.
+       (_scryptBlockMix): Replace memxor by buf_xor.
+       (_gcry_kdf_scrypt): Use gcry_malloc and gcry_free.  Check for integer
+       overflow.  Add hack to support blocksize of 1 for tests.  Return
+       errors from calls to _gcry_kdf_pkdf2.
+
+       * cipher/kdf.c (openpgp_s2k): Make static.
+
+2013-04-04  Christian Grothoff  <christian@grothoff.org>
+
+       Add the SCRYPT KDF function.
+       * scrypt.c, scrypt.h: New files.
+       * memxor.c, memxor.h: New files.
+       * cipher/Makefile.am: Add new files.
+       * cipher/kdf.c (gcry_kdf_derive): Support GCRY_KDF_SCRYPT.
+       * src/gcrypt.h.in (GCRY_KDF_SCRYPT): New.
+
+2013-03-22  Werner Koch  <wk@gnupg.org>
+
+       Replace deprecated AM_CONFIG_HEADER macro.
+       * configure.ac: s/AM_CONFIG_HEADER/AC_CONFIG_HEADER/
+
+       Disable AES-NI support if as does not support SSSE3.
+       * configure.ac (HAVE_GCC_INLINE_ASM_SSSE3): New test.
+       (ENABLE_AESNI_SUPPORT): Do not define without SSSE3 support.
+       (HAVE_GCC_INLINE_ASM_SSSE3, ENABLE_AVX_SUPPORT): Split up detection
+       and definition.
+
+2013-03-21  Werner Koch  <wk@gnupg.org>
+
+       Fix make dependency regression.
+       * src/Makefile.am (libgcrypt_la_DEPENDENCIES): Add missing backslash.
+       Reported by LRN.
+
+2013-03-20  Werner Koch  <wk@gnupg.org>
+
+       Use finer grained on-the-fly helper computations for EC.
+       * src/ec-context.h (mpi_ec_ctx_s): Replace NEED_SYNC by a bitfield.
+       * mpi/ec.c (ec_p_sync): Remove.
+       (ec_get_reset, ec_get_a_is_pminus3, ec_get_two_inv_p): New.
+       (ec_p_init): Use ec_get_reset.
+       (_gcry_mpi_ec_set_mpi, _gcry_mpi_ec_dup_point)
+       (_gcry_mpi_ec_add_points): Replace ec_p_sync by the ec_get_ accessors.
+
+       Allow building with w64-mingw32.
+       * autogen.sh <--build-w32>: Support the w64-mingw32 toolchain.  Also
+       prepare for 64 bit building.
+
+       Provide GCRYPT_VERSION_NUMBER macro, add build info to the binary.
+       * src/gcrypt.h.in (GCRYPT_VERSION_NUMBER): New.
+       * configure.ac (VERSION_NUMBER): New ac_subst.
+       * src/global.c (_gcry_vcontrol): Move call to above function ...
+       (gcry_check_version): .. here.
+
+       * configure.ac (BUILD_REVISION, BUILD_FILEVERSION)
+       (BUILD_TIMESTAMP): Define on all platforms.
+       * compat/compat.c (_gcry_compat_identification): Include revision and
+       timestamp.
+
+       Fix a memory leak in the new EC code.
+       * cipher/ecc.c (point_from_keyparam): Always call mpi_free on A.
+
+2013-03-19  Werner Koch  <wk@gnupg.org>
+
+       Extend the new EC interface and fix two bugs.
+       * src/ec-context.h (mpi_ec_ctx_s): Add field NEED_SYNC.
+       * mpi/ec.c (ec_p_sync): New.
+       (ec_p_init): Only set NEED_SYNC.
+       (_gcry_mpi_ec_set_mpi): Set NEED_SYNC for 'p' and 'a'.
+       (_gcry_mpi_ec_dup_point, _gcry_mpi_ec_add_points)
+       (_gcry_mpi_ec_mul_point): Call ec_p_sync.
+       (_gcry_mpi_ec_get_point): Recompute 'q' is needed.
+       (_gcry_mpi_ec_get_mpi): Ditto.  Also allow for names 'q', 'q.x',
+       'q.y', and 'g'.
+       * cipher/ecc.c (_gcry_mpi_ec_ec2os): New.
+
+       * cipher/ecc.c (_gcry_mpi_ec_new): Fix init from parameters 'Q'->'q',
+       'G'->'q'.
+
+2013-03-15  Werner Koch  <wk@gnupg.org>
+
+       mpi: Add functions to manipulate an EC context.
+       * src/gcrypt.h.in (gcry_mpi_ec_p_new): Remove.
+       (gcry_mpi_ec_new): New.
+       (gcry_mpi_ec_get_mpi): New.
+       (gcry_mpi_ec_get_point): New.
+       (gcry_mpi_ec_set_mpi): New.
+       (gcry_mpi_ec_set_point): New.
+       * src/visibility.c (gcry_mpi_ec_p_new): Remove.
+       * mpi/ec.c (_gcry_mpi_ec_p_new): Make it an internal function and
+       change to return an error code.
+       (_gcry_mpi_ec_get_mpi): New.
+       (_gcry_mpi_ec_get_point): New.
+       (_gcry_mpi_ec_set_mpi): New.
+       (_gcry_mpi_ec_set_point): New.
+       * src/mpi.h: Add new prototypes.
+       * src/ec-context.h: New.
+       * mpi/ec.c: Include that header.
+       (mpi_ec_ctx_s): Move to ec-context.h, add new fields, and put some
+       fields into an inner struct.
+       (point_copy): New.
+       * cipher/ecc.c (fill_in_curve): Allow passing NULL for R_NBITS.
+       (mpi_from_keyparam, point_from_keyparam): New.
+       (_gcry_mpi_ec_new): New.
+
+       * tests/t-mpi-point.c (test-curve): New.
+       (ec_p_new): New.  Use it instead of the removed gcry_mpi_ec_p_new.
+       (get_and_cmp_mpi, get_and_cmp_point): New.
+       (context_param): New test.
+       (basic_ec_math_simplified): New test.
+       (main): Call new tests.
+
+       * src/context.c (_gcry_ctx_get_pointer): Check for a NULL CTX.
+
+2013-03-13  Werner Koch  <wk@gnupg.org>
+
+       Add GCRYMPI_FLAG_CONST and make use constants.
+       * src/gcrypt.h.in (GCRYMPI_FLAG_CONST): New.
+       * src/mpi.h (mpi_is_const, mpi_const): New.
+       (enum gcry_mpi_constants, MPI_NUMBER_OF_CONSTANTS): New.
+       * mpi/mpiutil.c (_gcry_mpi_init): New.
+       (constants): New.
+       (_gcry_mpi_free): Do not release a constant flagged MPI.
+       (gcry_mpi_copy): Clear the const and immutable flags.
+       (gcry_mpi_set_flag, gcry_mpi_clear_flag, gcry_mpi_get_flag): Support
+       GCRYMPI_FLAG_CONST.
+       (_gcry_mpi_const): New.
+       * src/global.c (global_init): Call _gcry_mpi_init.
+       * mpi/ec.c (mpi_ec_ctx_s): Remove fields one, two, three, four, and
+       eight.  Change all users to call mpi_const() instead.
+
+       * src/mpiutils.c (gcry_mpi_set_opaque): Check the immutable flag.
+
+       Add GCRYMPI_FLAG_IMMUTABLE to help debugging.
+       * src/gcrypt.h.in (GCRYMPI_FLAG_IMMUTABLE): New.
+       * src/mpi.h (mpi_is_immutable): New macro.
+       * mpi/mpiutil.c (gcry_mpi_set_flag, gcry_mpi_clear_flag)
+       (gcry_mpi_get_flag): Implement new flag
+       (_gcry_mpi_immutable_failed): New.
+
+       * mpi/mpiutil.c (_gcry_mpi_clear, _gcry_mpi_free, gcry_mpi_snatch)
+       (gcry_mpi_set, gcry_mpi_randomize): Act upon the immutable flag.
+       * mpi/mpi-bit.c (gcry_mpi_set_bit, gcry_mpi_set_highbit)
+       (gcry_mpi_clear_highbit, gcry_mpi_clear_bit)
+       (_gcry_mpi_rshift_limbs, gcry_mpi_lshift): Ditto.
+       * mpi/mpicoder.c (_gcry_mpi_set_buffer): Ditto.
+
+2013-03-08  Werner Koch  <wk@gnupg.org>
+
+       mpi: Add an API for EC math.
+       * src/context.c, src/context.h: New.
+       * src/Makefile.am (libgcrypt_la_SOURCES): Add new files.
+       * src/gcrypt.h.in (struct gcry_context, gcry_ctx_t): New types.
+       (gcry_ctx_release): New prototype.
+       (gcry_mpi_ec_p_new, gcry_mpi_ec_get_affine, gcry_mpi_ec_dup)
+       (gcry_mpi_ec_add, gcry_mpi_ec_mul): New prototypes.
+       * mpi/ec.c: Include errno.h and context.h.
+       (_gcry_mpi_ec_init): Rename to ..
+       (ec_p_init): this, make static, remove allocation and add arg CTX.
+       (_gcry_mpi_ec_p_internal_new): New; to replace _gcry_mpi_ec_init.
+       Change all callers to use this func.
+       (_gcry_mpi_ec_free): Factor code out to ..
+       (ec_deinit): New func.
+       (gcry_mpi_ec_p_new): New.
+       * src/visibility.c: Include context.h and mpi.h.
+       (gcry_mpi_ec_p_new, gcry_mpi_ec_get_affine, gcry_mpi_ec_dup)
+       (gcry_mpi_ec_add, gcry_mpi_ec_mul)
+       (gcry_ctx_release): New wrapper functions.
+       * src/visibility.h: Mark new wrapper functions visible.
+       * src/libgcrypt.def, src/libgcrypt.vers: Add new symbols.
+       * tests/t-mpi-point.c (print_mpi, hex2mpi, cmp_mpihex): New.
+       (context_alloc): New.
+       (make_point, basic_ec_math): New.
+
+       mpi: Add an API for EC point operations.
+       * mpi/ec.c (gcry_mpi_point_new, gcry_mpi_point_release): New.
+       (gcry_mpi_point_get, gcry_mpi_point_snatch_get): New.
+       (gcry_mpi_point_set, gcry_mpi_point_snatch_set): New.
+       * src/visibility.h, src/visibility.c: Add corresponding macros and
+       wrappers.
+       * src/gcrypt.h.in (struct gcry_mpi_point, gcry_mpi_point_t): New.
+       (gcry_mpi_point_new, gcry_mpi_point_release, gcry_mpi_point_get)
+       (gcry_mpi_point_snatch_get, gcry_mpi_point_set)
+       (gcry_mpi_point_snatch_set): New prototypes.
+       (mpi_point_new, mpi_point_release, mpi_point_get, mpi_point_snatch_get)
+       (mpi_point_set, mpi_point_snatch_set): New macros.
+       * src/libgcrypt.vers (gcry_mpi_point_new, gcry_mpi_point_release)
+       (gcry_mpi_point_get, gcry_mpi_point_snatch_get, gcry_mpi_point_set)
+       (gcry_mpi_point_snatch_set): New symbols.
+       * src/libgcrypt.def: Ditto.
+       * tests/t-mpi-point.c: New.
+       * tests/Makefile.am (TESTS): Add t-mpi-point
+
+2013-03-07  Werner Koch  <wk@gnupg.org>
+
+       mpi: Add mpi_snatch and change an internal typedef.
+       * src/mpi.h (struct mpi_point_s): Rename to struct gcry_mpi_point.
+       (mpi_point_struct): New typedef.
+       (mpi_point_t): Change typedef to a pointer.  Replace all occurrences
+       to use mpi_point_struct.
+       * mpi/ec.c (_gcry_mpi_ec_point_init): Rename to ..
+       (_gcry_mpi_point_init): this.  Change all callers.
+       (_gcry_mpi_ec_point_free): Rename to ..
+       (_gcry_mpi_point_free_parts): this.  Change all callers.
+
+       * mpi/mpiutil.c (gcry_mpi_snatch): New function.
+       * src/gcrypt.h.in (gcry_mpi_snatch, mpi_snatch): Add protoype and
+       macro.
+       * src/visibility.c (gcry_mpi_snatch): Add wrapper.
+       * src/visibility.h (gcry_mpi_snatch): Add macro magic.
+       * src/libgcrypt.def, src/libgcrypt.vers: Add new function.
+
+       Pretty print the configure feedback.
+       * acinclude.m4 (GNUPG_MSG_PRINT): Remove.
+       (GCRY_MSG_SHOW, GCRY_MSG_WRAP): New.
+       * configure.ac: Use new macros for the feedback.
+
+2013-02-20  Werner Koch  <wk@gnupg.org>
+
+       Fix building of hwf-x86.c.
+       * src/Makefile.am (AM_CFLAGS): Set to GPG_ERROR_CFLAGS
+       (AM_CCASFLAGS): Set NOEXECSTACK_FLAGS.
+
+       Remove build hacks for FreeBSD.
+       * configure.ac [freebsd]: Do not add /usr/local to CPPFLAGS and
+       LDFLAGS.
+
+2013-02-19  Jussi Kivilinna  <jussi.kivilinna@mbnet.fi>
+
+       Rinjdael: Fix use of SSE2 outside USE_AESNI/ctx->use_aesni.
+       * cipher/rijndael.c (_gcry_aes_cbc_enc): Check if AES-NI is enabled before
+       calling aesni_prepare() and aesni_cleanup().
+
+       Add AES-NI/AVX accelerated Camellia implementation.
+       * configure.ac: Add option --disable-avx-support.
+       (HAVE_GCC_INLINE_ASM_AVX): New.
+       (ENABLE_AVX_SUPPORT): New.
+       (camellia) [ENABLE_AVX_SUPPORT, ENABLE_AESNI_SUPPORT]: Add
+       camellia_aesni_avx_x86-64.lo.
+       * cipher/Makefile.am (AM_CCASFLAGS): Add.
+       (EXTRA_libcipher_la_SOURCES): Add camellia_aesni_avx_x86-64.S
+       * cipher/camellia-glue.c [ENABLE_AESNI_SUPPORT, ENABLE_AVX_SUPPORT]
+       [__x86_64__] (USE_AESNI_AVX): Add macro.
+       (struct Camellia_context) [USE_AESNI_AVX]: Add use_aesni_avx.
+       [USE_AESNI_AVX] (_gcry_camellia_aesni_avx_ctr_enc)
+       (_gcry_camellia_aesni_avx_cbc_dec): New prototypes to assembly
+       functions.
+       (camellia_setkey) [USE_AESNI_AVX]: Enable AES-NI/AVX if hardware
+       support both.
+       (_gcry_camellia_ctr_enc) [USE_AESNI_AVX]: Add AES-NI/AVX code.
+       (_gcry_camellia_cbc_dec) [USE_AESNI_AVX]: Add AES-NI/AVX code.
+       * cipher/camellia_aesni_avx_x86-64.S: New.
+       * src/g10lib.h (HWF_INTEL_AVX): New.
+       * src/global.c (hwflist): Add HWF_INTEL_AVX.
+       * src/hwf-x86.c (detect_x86_gnuc) [ENABLE_AVX_SUPPORT]: Add detection
+       for AVX.
+
+       camellia.c: Prepare for AES-NI/AVX implementation.
+       * cipher/camellia-glue.c (CAMELLIA_encrypt_stack_burn_size)
+       (CAMELLIA_decrypt_stack_burn_size): Increase stack burn size.
+       * cipher/camellia.c (CAMELLIA_ROUNDSM): Move key-material mixing in
+       the front.
+       (camellia_setup128, camellia_setup256): Remove now unneeded
+       key-material mangling.
+       (camellia_encrypt128, camellia_decrypt128, amellia_encrypt256)
+       (camellia_decrypt256): Copy block to stack, so that compiler can
+       optimize it for register usage.
+
+       Camellia, prepare glue code for AES-NI/AVX implementation.
+       * cipher/camellia-glue.c (ATTR_ALIGNED_16): Add macro.
+       (CAMELLIA_encrypt_stack_burn_size): Add macro.
+       (camellia_encrypt): Use macro above for stack burn size.
+       (CAMELLIA_decrypt_stack_burn_size): Add macro.
+       (camellia_decrypt): Use macro above for stack burn size.
+       (_gcry_camellia_ctr_enc): New function.
+       (_gcry_camellia_cbc_dec): New function.
+       (selftest_ctr_128): New function.
+       (selftest): Call function above.
+       * cipher/cipher.c (gcry_cipher_open) [USE_CAMELLIA]: Register bulk
+       functions for CBC-decryption and CTR-mode.
+       * src/cipher.h (_gcry_camellia_ctr_enc): New prototype.
+       (_gcry_camellia_cbc_dec): New prototype.
+
+2012-12-21  Werner Koch  <wk@gnupg.org>
+
+       Prepare for hardware feature detection on other platforms.
+       * configure.ac (GCRYPT_HWF_MODULES): New.
+       (HAVE_CPU_ARCH_X86, HAVE_CPU_ARCH_ALPHA, HAVE_CPU_ARCH_SPARC)
+       (HAVE_CPU_ARCH_MIPS, HAVE_CPU_ARCH_M68K, HAVE_CPU_ARCH_PPC)
+       (HAVE_CPU_ARCH_ARM): New AC_DEFINEs.
+       * mpi/config.links (mpi_cpu_arch): New.
+       * src/global.c (print_config): Print new tag "cpu-arch".
+       * src/Makefile.am (libgcrypt_la_SOURCES): Add hwf-common.h
+       (EXTRA_libgcrypt_la_SOURCES): New.
+       (gcrypt_hwf_modules): New.
+       (libgcrypt_la_DEPENDENCIES, libgcrypt_la_LIBADD): Add that one.
+       * src/hwfeatures.c: Factor most code out to ...
+       * src/hwf-x86.c: New file.
+       (detect_x86_gnuc): Return the feature vector.
+       (_gcry_hwf_detect_x86): New.
+       * src/hwf-common.h: New.
+       * src/hwfeatures.c (_gcry_detect_hw_features): Dispatch using
+       HAVE_CPU_ARCH_ macros.
+
+2012-12-21  Jussi Kivilinna  <jussi.kivilinna@mbnet.fi>
+
+       Clean up i386/x86-64 cpuid usage in hwfeatures.c.
+       * src/hwfeatures.c [__i386__ && __GNUC__] (detect_ia32_gnuc): Remove.
+       [__x86_64__ && __GNUC__] (detect_x86_64_gnuc): Remove.
+       [__i386__ && __GNUC__] (is_cpuid_available, get_cpuid)
+       (HAS_X86_CPUID): New.
+       [__x86_64__ && __GNUC__] (is_cpuid_available, get_cpuid)
+       (HAS_X86_CPUID): New.
+       [HAS_X86_CPUID] (detect_x86_gnuc): New.
+       (_gcry_detect_hw_features) [__i386__ && GNUC]: Remove detect_ia32_gnuc
+       call.
+       (_gcry_detect_hw_features) [__x86_64__ && GNUC]: Remove
+       detect_x86_64_gnuc call.
+       (_gcry_detect_hw_features) [HAS_X86_CPUID]: Add detect_x86_gnuc call.
+
+2012-12-18  Dmitry Kasatkin  <dmitry.kasatkin@intel.com>
+
+       Add support for using DRNG random number generator.
+       * configure.ac: Add option --disable-drng-support.
+       (ENABLE_DRNG_SUPPORT): New.
+       * random/rndhw.c (USE_DRNG): New.
+       (rdrand_long, rdrand_nlong, poll_drng): New.
+       (_gcry_rndhw_poll_fast, _gcry_rndhw_poll_slow): Call poll function.
+       * src/g10lib.h (HWF_INTEL_RDRAND): New.
+       * src/global.c (hwflist): Add "intel-rdrand".
+       * src/hwfeatures.c (detect_x86_64_gnuc) [ENABLE_DRNG_SUPPORT]: Detect
+       RDRAND.
+       (detect_ia32_gnuc) [ENABLE_DRNG_SUPPORT]: Detect RDRAND.
+
+2012-12-03  Werner Koch  <wk@gnupg.org>
+
+       random: Add a RNG selection interface and system RNG wrapper.
+       * random/random-system.c: New.
+       * random/Makefile.am (librandom_la_SOURCES): Add new module.
+       * random/random.c (struct rng_types): New.
+       (_gcry_set_preferred_rng_type, _gcry_get_rng_type): New.
+       (_gcry_random_initialize, gcry_random_add_bytes, do_randomize)
+       (_gcry_set_random_seed_file, _gcry_update_random_seed_file)
+       (_gcry_fast_random_poll): Dispatch to the actual RNG.
+       * src/gcrypt.h.in (GCRYCTL_SET_PREFERRED_RNG_TYPE): New.
+       GCRYCTL_GET_CURRENT_RNG_TYPE): New.
+       (gcry_rng_types): New.
+       * src/global.c (print_config): Print the TNG type.
+       (global_init, _gcry_vcontrol): Implement the new control codes.
+       * doc/gcrypt.texi (Controlling the library): Document the new control
+       codes.
+
+       * tests/benchmark.c (main): Add options to test the RNG types.
+       * tests/random.c (main): Add new options.
+       (print_hex): Print to stderr.
+       (progress_cb, rng_type): New.
+       (check_rng_type_switching, check_early_rng_type_switching): New.
+       (run_all_rng_tests): New.
+
+       tests: Allow use of random.c under Windows.
+       * tests/Makefile.am (TESTS): Always include random.c
+       * tests/random.c [!W32]: Include sys/wait.h.
+       (inf): New.
+       (check_forking, check_nonce_forking): Print a notice what will be done.
+       (main) [W32]: Do not call signal.
+
+       Make random-fips.c work multi-threaded.
+       * random/random-fips.c (basic_initialization): Fix reversed logic.
+
+       Move nonce creation from csprng backend to random main module.
+       * random/random-csprng.c (_gcry_rngcsprng_create_nonce): Remove.
+       (nonce_buffer_lock): Remove.
+       (initialize_basics): Remove init of nonce_buffer_lock.
+       * random/random.c: Add a few header files.
+       (nonce_buffer_lock):  New.
+       (_gcry_random_initialize): Init nonce_buffer_lock.
+       (gcry_create_nonce): Add code from _gcry_rngcsprng_create_nonce.
+
+       * random/random-daemon.c (_gcry_daemon_create_nonce): Remove.
+
+2012-12-03  Jussi Kivilinna  <jussi.kivilinna@mbnet.fi>
+
+       Fix building with CC="gcc -std=c90".
+       * configure.ac: Add check for missing 'asm' keyword in C90 mode and
+       replacement with '__asm__'.
+
+2012-12-03  Werner Koch  <wk@gnupg.org>
+
+       Try to use inttypes.h if stdint.h is not available.
+       * cipher/bufhelp.h [HAVE_INTTYPES_H]: Include inttypes.h
+
+2012-12-03  Jussi Kivilinna  <jussi.kivilinna@mbnet.fi>
+
+       Optimize buffer xoring.
+       * cipher/Makefile.am (libcipher_la_SOURCES): Add 'bufhelp.h'.
+       * cipher/bufhelp.h: New.
+       * cipher/cipher-aeswrap.c (_gcry_cipher_aeswrap_encrypt)
+       (_gcry_cipher_aeswrap_decrypt): Use 'buf_xor' for buffer xoring.
+       * cipher/cipher-cbc.c (_gcry_cipher_cbc_encrypt)
+       (_gcry_cipher_cbc_decrypt): Use 'buf_xor' for buffer xoring and remove
+       resulting unused variables.
+       * cipher/cipher-cfb.c (_gcry_cipher_cfb_encrypt) Use 'buf_xor_2dst'
+       for buffer xoring and remove resulting unused variables.
+       (_gcry_cipher_cfb_decrypt): Use 'buf_xor_n_copy' for buffer xoring and
+       remove resulting unused variables.
+       * cipher/cipher-ctr.c (_gcry_cipher_ctr_encrypt): Use 'buf_xor' for
+       buffer xoring and remove resulting unused variables.
+       * cipher/cipher-ofb.c (_gcry_cipher_ofb_encrypt)
+       (_gcry_cipher_ofb_decrypt): Use 'buf_xor' for buffer xoring and remove
+       resulting used variables.
+       * cipher/rijndael.c (_gry_aes_cfb_enc): Use 'buf_xor_2dst' for buffer
+       xoring and remove resulting unused variables.
+       (_gry_aes_cfb_dev): Use 'buf_xor_n_copy' for buffer xoring and remove
+       resulting unused variables.
+       (_gry_aes_cbc_enc, _gry_aes_ctr_enc, _gry_aes_cbc_dec): Use 'buf_xor'
+       for buffer xoring and remove resulting unused variables.
+
+2012-11-29  Jussi Kivilinna  <jussi.kivilinna@mbnet.fi>
+
+       Optimize AES-NI CTR mode.
+       * cipher/rijndael.c [USE_AESNI] (do_aesni_ctr, do_aesni_ctr_4): Make
+       handling of 64-bit overflow and carry conditional. Avoid generic to
+       vector register passing of value '1'. Generate and use '-1' instead.
+
+2012-11-28  Werner Koch  <wk@gnupg.org>
+
+       Make a cpp conditional in rijndael.c better readable.
+       * cipher/rijndael.c (USE_AESNI): Modify cpp conditionals for better
+       readability.
+
+2012-11-28  Jussi Kivilinna  <jussi.kivilinna@mbnet.fi>
+
+       Fix building with Clang on x86-64 and i386.
+       * cipher/rijndael.c [USE_AESNI] (do_aesni_enc_aligned)
+       (do_aesni_dec_vec4, do_aesni_cfb, do_aesni_ctr, do_aesni_ctr_4): Add
+       explicit suffix to 'cmp' instructions.
+
+2012-11-26  Jussi Kivilinna  <jussi.kivilinna@mbnet.fi>
+
+       Optimize wipememory2 for i386 and x86-64.
+       * src/g10lib.h (wipememory2): Add call to fast_wipememory2.
+       (fast_wipememory2): New macros for i386 and x86-64 architectures.
+       Empty macro provided for other architectures.
+
+       Fix missing 64bit carry handling in AES-NI CTR mode.
+       * cipher/rijndael.c [USE_AESNI] (do_aesni_ctr, do_aesni_ctr_4): Add
+       carry handling to 64-bit addition.
+       (selftest_ctr_128): New function for testing IV handling in bulk CTR
+       function.
+       (selftest): Add call to selftest_ctr_128.
+
+       Add parallelized AES-NI CBC decryption.
+       * cipher/rijndael.c [USE_AESNI] (aesni_cleanup_5): New macro.
+       [USE_AESNI] (do_aesni_dec_vec4): New function.
+       (_gcry_aes_cbc_dec) [USE_AESNI]: Add parallelized CBC loop.
+       (_gcry_aes_cbc_dec) [USE_AESNI]: Change IV storage register from xmm3
+       to xmm5.
+
+       Clear xmm5 after use in AES-NI CTR mode.
+       * cipher/rijndael.c [USE_AESNI]: Rename aesni_cleanup_2_4 to
+       aesni_cleanup_2_5.
+       [USE_AESNI] (aesni_cleanup_2_5): Clear xmm5 register.
+       (_gcry_aes_ctr_enc, _gcry_aes_cbc_dec) [USE_AESNI]: Use
+       aesni_cleanup_2_5 instead of aesni_cleanup_2_4.
+
+       Optimize AES-NI CBC encryption.
+       * cipher/rijndeal.c (_gcry_aes_cbc_enc) [USE_AESNI]: Add AES-NI
+       spesific loop and use SSE2 assembler for xoring and copying of
+       blocks.
+
+       Improve parallelizability of CBC decryption for AES-NI.
+       * cipher/rijndael.c (_gcry_aes_cbc_dec) [USE_AESNI]: Add AES-NI
+       specific CBC mode loop with temporary block and IV stored in free SSE
+       registers.
+
+       Extend test of chained modes for 128bit ciphers.
+       * tests/basic.c (check_one_cipher_core, check_one_cipher): Increase
+       input and output buffer sizes from 16 bytes to 1024+16=1040 bytes.
+       (check_one_cipher_core): Add asserts to verify sizes of temporary
+       buffers.
+
+2012-11-21  Werner Koch  <wk@gnupg.org>
+
+       Fix for strict aliasing rules.
+       * cipher/rijndael.c (do_setkey, prepare_decryption): Use u32_a_t for
+       casting.
+
+       Do not detect AES-NI support if disabled by configure.
+       * src/hwfeatures.c (detect_ia32_gnuc): Detect AESNI support only if
+       that support has been enabled.
+
+2012-11-21  Jussi Kivilinna  <jussi.kivilinna@mbnet.fi>
+
+       Fix too large burn_stack in camellia-glue.c.
+       * cipher/camellia-glue.c (camellia_encrypt, camellia_decrypt): Do not
+       take full array size of KEY_TABLE_TYPE, but argument size instead.
+
+       Add x86_64 support for AES-NI.
+       * cipher/rijndael.c [ENABLE_AESNI_SUPPORT]: Enable USE_AESNI on x86-64.
+       (do_setkey) [USE_AESNI_is_disabled_here]: Use %[key] and %[ksch]
+       directly as registers instead of using temporary register %%esi.
+       [USE_AESNI] (do_aesni_enc_aligned, do_aesni_dec_aligned, do_aesni_cfb,
+       do_aesni_ctr, do_aesni_ctr_4): Use %[key] directly as register instead
+       of using temporary register %%esi.
+       [USE_AESNI] (do_aesni_cfb, do_aesni_ctr, do_aesni_ctr_4): Change %[key]
+       from generic "g" type to register "r".
+       * src/hwfeatures.c (_gcry_detect_hw_features) [__x86_64__]: Do not
+       clear AES-NI feature flag.
+
+       Fix cpuid vendor-id check for i386 and x86-64.
+       * src/hwfeatures.c (detect_x86_64_gnuc, detect_ia32_gnuc): Allow
+       Intel features be detect from CPU by other vendors too.
 
-Thu Jun 25 11:18:49 1998  Werner Koch  (wk@isil.d.shuttle.de)
+       Fix hwdetect assembler clobbers.
+       * src/hwfeatures.c (detect_x86_64_gnuc): Add missing %ebx assembler
+       clobbers.
+       (detect_x86_64_gnuc, detect_ia32_gnuc) [ENABLE_PADLOCK_SUPPORT]: Add
+       missing %ecx assembler clobbers.
 
-       * configure.in (--disable-dynload): New.
+2012-11-21  Werner Koch  <wk@gnupg.org>
 
-Wed Jun 10 07:48:59 1998  Werner Koch,mobil,,, (wk@tobold)
+       Use configure test for aligned attribute.
+       * configure.ac (HAVE_GCC_ATTRIBUTE_ALIGNED): New test and ac_define.
+       * cipher/cipher-internal.h, cipher/rijndael.c, random/rndhw.c: Use new
+       macro instead of a fixed test for __GNUC__.
 
-       * configure.in (GNUPG_LIBDIR): New.
+       Fix segv with AES-NI on some platforms.
+       * cipher/rijndael.c (RIJNDAEL_context): Align on 16 bytes.
 
-Mon May 25 19:10:59 1998  Werner Koch  (wk@isil.d.shuttle.de)
+2012-11-16  Werner Koch  <wk@gnupg.org>
 
-       * rand-unix.c (fast_random_poll): fixed syntax bug.
+       Improve parsing of the GIT revision number.
+       * configure.ac (mmm4_revision): Use git rev-parse.
 
-Mon May 11 10:21:31 1998  Werner Koch  (wk@isil.d.shuttle.de)
+2012-11-08  Werner Koch  <wk@gnupg.org>
 
-       * configure.in (PRINTABLE_OS_NAME): Linux is now GNU/Linux
+       Fix extern inline use for gcc > 4.3 in c99 mode.
+       * mpi/mpi-inline.h [!G10_MPI_INLINE_DECL]: Take care of changed extern
+       inline semantics in gcc.
 
-Tue Apr 14 19:08:05 1998  Werner Koch  (wk@isil.d.shuttle.de)
+2012-11-07  Werner Koch  <wk@gnupg.org>
 
-       * [all files]: Applied Matthew Skala's typo and grammar fixes.
+       Fix memory leak in gcry_pk_testkey for ECC.
+       * cipher/ecc.c (check_secret_key): Restructure for easier allocation
+       tracking.  Fix memory leak.
+
+2012-11-05  Werner Koch  <wk@gnupg.org>
 
-Wed Mar  4 10:32:40 1998  Werner Koch  (wk@isil.d.shuttle.de)
+       Prepare for a backported interface in 1.5.1.
+       * configure.ac: Bump LT version at C20/A0/R0 to adjust for a planned
+       API update in 1.5.1.
 
-       * configure.in (getrusage,gettimeofday): New tests.
+       Adjust for stricter autoconf requirements.
+       * configure.ac: Fix usage of AC_LANG_PROGRAM.
 
-Fri Feb 27 13:14:17 1998  Werner Koch  (wk@isil.d.shuttle.de)
+       Update build helper scripts.
+       * config.guess, config.sub: Update to version 2012-07-31.
+       * ltmain.sh: Update to version 2.4.2.
+       * install-sh, m4/libtool.m4, m4/ltoptions.m4, m4/ltversion.m4
+       * m4/lt~obsolete.m4: Update to autoconf 2.69 versions.
 
-       * configure.in (--disable-m-guard): New.
+       Do not distribute a copy of gitlog-to-changelog.
+       * Makefile.am (GITLOG_TO_CHANGELOG): New.
+       (gen-ChangeLog): Require an installed gitlog-to-changelog.
+       * scripts/gitlog-to-changelog: Remove.
 
-Thu Feb 26 17:09:27 1998  Werner Koch  (wk@isil.d.shuttle.de)
+       * README.SVN: Remove.
+       * REMOVE.GIT: New.
 
-       * configure.in, acinclude.m4, intl/, po/: New macros taken
-       from GNOME, switched to automake 1.2f
+       Allow building with w64-mingw32.
+       * autogen.sh <--build-w32>: Support the w64-mingw32 toolchain.  Also
+       prepare for 64 bit building.
+       <git-setup>: Remove option -c from chmod.
 
-Thu Feb 26 09:05:46 1998  Werner Koch  (wk@isil.d.shuttle.de)
+       Switch to the new automagic beta numbering scheme.
+       * configure.ac: Add all the required m4 magic.
 
-       * configure.in (doc/Makefile): New
+       Avoid dereferencing pointer right after the end.
+       * mpi/mpicoder.c (do_get_buffer): Check the length before derefing P.
 
-Thu Feb 26 07:40:47 1998  Werner Koch  (wk@isil.d.shuttle.de)
+2012-10-30  Werner Koch  <wk@gnupg.org>
 
-       * configure.in: Changed gettext stuff
+       Make ancient test program useful again.
+       * tests/testapi.c (test_sexp): Adjust to current API.  Print the
+       return code.  Mark unused args.
+       (test_genkey): Mark unused args.
+       (main): Do not pass NULL to printf.
 
-Wed Feb 25 11:44:10 1998  Werner Koch  (wk@isil.d.shuttle.de)
+       tests: Add ECC key generation tests.
+       * tests/keygen.c (check_generated_ecc_key): New.
+       (check_ecc_keys): New.
+       (main): Call simple ECC checks.
 
-       * checks/*test : restructured the directory.
+2012-10-30  Milan Broz  <mbroz@redhat.com>
+
+       PBKDF2: Allow empty passphrase.
+       * cipher/kdf.c (gcry_kdf_derive): Allow empty passphrase for PBKDF2.
+       * tests/t-kdf.c (check_pbkdf2): Add test case for above.
 
-Tue Feb 24 15:59:12 1998  Werner Koch  (wk@isil.d.shuttle.de)
+2012-08-16  Xi Wang  <xi.wang@gmail.com>
 
-       * configure.in: Changed the name of the package to GNUPG and
-       chnaged several other names too.
+       Replace deliberate division by zero with _gcry_divide_by_zero.
+       * mpi/mpi-pow.c: Replace 1 / msize.
+       * mpi/mpih-div.c: Replace 1 / dsize.
+       * src/misc.c: Add _gcry_divide_by_zero.
 
-Wed Feb 18 17:36:45 1998  Werner Koch  (wk@isil.d.shuttle.de)
+2012-06-21  Werner Koch  <wk@gnupg.org>
 
-       * Makefile.am (checks): New.
+       Clear AESNI feature flag for x86_64.
+       * src/hwfeatures.c (_gcry_detect_hw_features) [__x86_64__]: Clear
+       AESNI feature flag.
 
-Sat Feb 14 15:37:55 1998  Werner Koch  (wk@isil.d.shuttle.de)
+       Beautify last change.
+       * cipher/rijndael.c: Replace C99 feature from last patch.  Keep cpp
+       lines short.
+       * random/rndhw.c: Keep cpp lines short.
+       * src/hwfeatures.c (_gcry_detect_hw_features): Make cpp def chain
+       better readable.
 
-       * configure.in (mpi_config_done): Removed asm links caching.
+2012-06-21  Rafaël Carré  <funman@videolan.org>
 
-Sat Feb 14 14:02:20 1998  Werner Koch  (wk@isil.d.shuttle.de)
+       Enable VIA Padlock on x86_64 platforms.
+         * cipher/rijndael.c: Duplicate x86 assembly and convert to x86_64.
+         * random/rndhw.c: Likewise.
+         * src/hwfeatures.c: Likewise.
 
-       * configure.in (PRINTABLE_OS_NAME): New.
-       * acconfig.h: Likewise.
+2012-05-14  Werner Koch  <wk@gnupg.org>
 
-Fri Feb 13 19:43:41 1998  Werner Koch  (wk@isil.d.shuttle.de)
+       Add curve aliases from RFC-5656.
+       * cipher/ecc.c (curve_aliases): Add "nistp???" entries.
 
-       * configure.in : Fixed zlib stuff
-       * Makefile.am: Likewise
+2012-04-16  Werner Koch  <wk@gnupg.org>
 
+       State new contribution rules.
+       * doc/DCO: New.
+       * doc/HACKING: Document new rules.
+
+2012-04-04  Tomas Mraz  <tmraz@fedoraproject.org>
 
- Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006,
-          2007, 2008, 2009, 2011 Free Software Foundation, Inc.
+       Add GCRYCTL_SET_ENFORCED_FIPS_FLAG command.
+       * doc/gcrypt.texi: Add documentation of the new command.
+       * src/fips.c (_gcry_enforced_fips_mode): Report the enforced fips mode
+       only when fips mode is enabled.
+       (_gcry_set_enforced_fips_mode): New function.
+       * src/g10lib.h: Add the _gcry_set_enforced_fips_mode prototype.
+       * src/gcrypt.h.in: Add the GCRYCTL_SET_ENFORCED_FIPS_FLAG.
+       * src/global.c (_gcry_vcontrol): Handle the new command.
 
- 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.
+2012-02-17  Ulrich Müller  <ulm@gentoo.org>
+
+       Rework selftest in idea.c.
+       * cipher/idea.c (do_setkey): Execute selftest when first called.
+       (decrypt_block): Remove commented-out code.
+       (selftest): Execute all selftests. Return NULL on success, or
+       string in case of error.
+
+2012-02-16  Werner Koch  <wk@gnupg.org>
+
+       Fix missing prototype.
+       * src/g10lib.h (_gcry_secmem_module_init): Make it a real prototype.
 
- 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.
+2012-02-16  Ulrich Müller  <ulm@gentoo.org>
+
+       Add support for the IDEA cipher.
+       Adapt idea.c to the Libgcrypt framework.
+       Add IDEA to cipher_table and to the build system.
+
+       Patents on IDEA have expired:
+         Europe: EP0482154 on 2011-05-16,
+         Japan:  JP3225440 on 2011-05-16,
+         U.S.:   5,214,703 on 2012-01-07.
+
+       * configure.ac: Add idea to the list of available ciphers.
+       Define USE_IDEA if idea is enabled.
+       * cipher/cipher.c (cipher_table): Add entry for IDEA.
+       * cipher/idea.c: Update comment about patents.
+       Include proper header files and remove redundant declarations.
+       (expand_key, cipher, do_setkey, encrypt_block, decrypt_block):
+       Define function arguments as const where appropriate.
+       (cipher): Test for !WORDS_BIGENDIAN instead of LITTLE_ENDIAN_HOST.
+       (do_setkey, decrypt_block): Don't call selftest.
+       (idea_setkey): New function, wrapper for do_setkey.
+       (idea_encrypt): New function, wrapper for encrypt_block.
+       (_gcry_cipher_spec_idea): Define.
+       * cipher/Makefile.am (EXTRA_libcipher_la_SOURCES): Add idea.c.
+       * src/cipher.h (_gcry_cipher_spec_idea): Declare.
+       * tests/basic.c (check_ciphers): Add GCRY_CIPHER_IDEA.
+
+2012-01-09  Werner Koch  <wk@gnupg.org>
+
+       Include an IDEA implementation.
+       The code is the old IDEA test code, written by me back in 1997 and
+       distributed on a Danish FTP server.  This commit is only for
+       reference.  To use the code it has to be adjusted to the Libgcrypt
+       framework.
+
+2012-01-03  Marcus Brinkmann  <marcus.brinkmann@ruhr-uni-bochum.de>
+
+       Fix pthread locking and remove defunctional support for static lock init.
+       * src/ath.c: Include assert.h.
+       (ath_mutex_destroy, ath_mutex_lock, ath_mutex_unlock): Dereference LOCK.
+       * src/g10lib.h (_gcry_secmem_module_init): New declaration.
+       * src/global.c (global_init): Call _gcry_secmem_module_init.
+       * src/secmem.c (_gcry_secmem_module_init): New function.
+
+2011-12-16  Werner Koch  <wk@gnupg.org>
+
+       Add alignment tests for the cipher tests.
+       * tests/basic.c (check_one_cipher): Factor most code out to
+       check_one_cipher_core.  Call that core function several times using
+       different alignment settings.
+       (check_one_cipher_core): New.  Add extra args to allow alignment
+       testing.
+
+2011-12-07  Werner Koch  <wk@gnupg.org>
+
+       tests/prime: Add option to create a well known private key.
+       * tests/prime.c (print_mpi, create_42prime): New.
+       (main): Add option --42.
+
+2011-12-01  Werner Koch  <wk@gnupg.org>
+
+       Do not build the random-daemon by make distcheck.
+       * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Disable building of the
+       random daemon
+
+       Generate the ChangeLog from commit logs.
+       * scripts/gitlog-to-changelog: New script.  Taken from gnulib.
+       * scripts/git-log-fix: New file.
+       * scripts/git-log-footer: New file.
+       * doc/HACKING: Describe the ChangeLog policy
+       * ChangeLog: New file.
+       * Makefile.am (EXTRA_DIST): Add new files.
+       (gen-ChangeLog): New.
+       (dist-hook): Run gen-ChangeLog.
+
+       Rename all ChangeLog files to ChangeLog-2011.
+
+2011-12-01  Werner Koch  <wk@gnupg.org>
+
+       NB: Changes done before December 1st, 2011 are described in
+       per directory files named ChangeLog-2011.  See doc/HACKING for
+       details.
+
+        -----
+       Copyright (C) 2011 Free Software Foundation, Inc.
+
+       Copying and distribution of this file and/or the original GIT
+       commit log messages, with or without modification, are
+       permitted provided the copyright notice and this notice are
+       preserved.
diff --git a/ChangeLog-2011 b/ChangeLog-2011
new file mode 100644 (file)
index 0000000..3c70a1f
--- /dev/null
@@ -0,0 +1,1499 @@
+2011-12-01  Werner Koch  <wk@g10code.com>
+
+       NB: ChangeLog files are no longer manually maintained.  Starting
+       on December 1st, 2011 we put change information only in the GIT
+       commit log, and generate a top-level ChangeLog file from logs at
+       "make dist".  See doc/HACKING for details.
+
+2011-11-28  Jim Meyering  <meyering@redhat.com>
+
+       accept --with-libgpg-error-prefix as well as --with-gpg-error-prefix
+       * m4/gpg-error.m4: Update from git master.
+
+2011-09-16  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (HAVE_PTHREAD): New.
+
+2011-09-15  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Bump LT version at C19/A0/R0 due to the ABI change.
+
+       * configure.ac (CC_FOR_BUILD): New.
+
+2011-06-29  Werner Koch  <wk@g10code.com>
+
+       Release 1.5.0.
+
+       * configure.ac: Keep LT version at C18/A7/R0 because it has
+       already been bumped up at 2010-07-09.
+
+       * config.guess, config.sub: Update to 2011-06-03.
+
+2011-04-06  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (emacs_local_vars_begin): Move more to the top to
+       avoid Emacs warnings.
+
+2011-03-30  Werner Koch  <wk@g10code.com>
+
+       * compat/compat.c (_gcry_compat_identification): Add version string.
+
+2011-03-08  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (BUILD_REVISION): Use new git_brevis macro.
+
+2011-02-23  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (LIBGCRYPT_CONFIG_HOST): New.
+
+       * acinclude.m4 (AM_PATH_GPG_ERROR): Remove.
+
+2011-02-21  Werner Koch  <wk@g10code.com>
+
+       Release 1.5.0-beta1.
+
+2011-02-18  Werner Koch  <wk@g10code.com>
+
+       * configure.ac [GCC]: Remove the use of -fno-strict-aliasing.
+
+2011-02-11  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Add option --disbale-aesni-support.
+       (ENABLE_AESNI_SUPPORT): New macro.
+
+2011-02-04  Werner Koch  <wk@g10code.com>
+
+       * autogen.sh: Install the git pre-commit if not yet done.
+
+2010-12-23  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (BUILD_REVISION): Use git_revision.
+
+2010-08-19  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Define GPG_ERR_ENABLE_ERRNO_MACROS. Remove
+       definition of _GNU_SOURCE.
+       (AC_GNU_SOURCE): New.
+
+2010-08-16  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (INSERT_SYS_SELECT_H): New.
+
+2010-07-09  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Bump LT version to C18/A7/R0 to prepare a backport
+       of a new API to the 1.4 series.
+
+2010-04-19  Marcus Brinkmann  <marcus@g10code.de>
+
+       * configure.ac: Check for -fno-strict-aliasing.
+
+2010-04-12  Brad Hards  <bradh@frogmouth.net>  (wk)
+
+       * configure.ac: Print more verbose info at the end.
+
+2010-03-24  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (USE_RNDW32CE): New.
+
+2010-03-15  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (emacs_local_vars_begin)
+       (emacs_local_vars_read_only, emacs_local_vars_end): New.
+
+2010-01-21  Werner Koch  <wk@g10code.com>
+
+       * compat/Makefile.am: New.
+       * compat/compat.c: New.
+       * compat/libcompat.h: New.
+       * compat/getpid.c, compat/clock.c: New.
+
+       * configure.ac: Require libgpg-error 1.8.
+       (HAVE_W32CE_SYSTEM): New am_defines and am_conditionals.
+       (getpid): Check for replacement function.
+       (AC_CONFIG_LIBOBJ_DIR): New.
+       (AC_TYPE_PID_T): New.
+       (AM_INIT_AUTOMAKE): Use modern variant.
+       (AC_CONFIG_FILES): Add compat/Makfile.
+       * autogen.sh: Support W32CE.
+       * ltmain.sh: Update to 2.2.6b
+       (wrappers_required): Don't set for mingw32ce.
+       * Makefile.am (DIST_SUBDIRS, SUBDIRS): Add compat.
+
+2009-12-10  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Add option --disable-O-flag-munging.
+
+2009-12-08  Marcus Brinkmann  <marcus@g10code.de>
+
+       Update to libtool 2.2.6a.
+       * configure.ac: Invoke AC_CONFIG_MACRO_DIR.
+       (AC_LIBTOOL_WIN32_DLL, AC_LIBTOOL_RC): Replace by ...
+       (LT_PREREQ, LT_INIT, LT_LANG): ... these.
+       * config.guess, config.sub, install-sh, ltmain.sh, m4/libtool.m4:
+       Updated to libtool 2.2.6a.
+       * m4/ltoptions.m4, m4/ltsugar.m4, m4/ltversion.m4,
+       m4/lt~obsolete.m4: New files from libtool 2.2.6a.
+
+2009-08-05  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Test for sys/msg.h.
+
+2009-04-23  Werner Koch  <wk@g10code.com>
+
+       * README: Add a section on build problems.
+
+2009-01-22  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Bump LT version to C17/A6/R0 to mark the start of
+       a new development series.
+
+2009-01-22  Werner Koch  <wk@g10code.com>
+
+       Release 1.4.4.
+
+       * configure.ac: Bump LT version to C16/A5/R2.
+
+2008-10-30  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Remove option --enable-gcc-warnings.  Autodetect
+       useful gcc warnings in maintainer mode.
+
+2008-09-18  Werner Koch  <wk@g10code.com>
+
+       Release 1.4.3.
+
+       * configure.ac: Bump LT version to C16/A5/R1.
+
+2008-09-15  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Cehck for syslog.
+
+2008-09-08  Werner Koch  <wk@g10code.com>
+
+       Release 1.4.2.
+
+2008-09-01  Werner Koch  <wk@g10code.com>
+
+       Release 1.4.2rc2.
+
+       * configure.ac: Update svn_revision macro.
+
+2008-08-22  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Add option --enable-hmac-binary-check.
+       (DL_LIBS): Check whether -ldl is required.
+
+2008-08-19  Werner Koch  <wk@g10code.com>
+
+       Release 1.4.2rc1.
+
+       * configure.ac: Bump LT version to C16/A5/R0.
+
+2008-08-18  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (EXTRA_DIST): Remove the unused BUGS file.
+
+2008-08-15  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (AH_BOTTOM): Define GCRY_GPG_ERR_NOT_OPERATIONAL.
+
+2008-07-05  Werner Koch  <wk@g10code.com>
+
+       * random/: New.
+       * Makefile.am (DIST_SUBDIRS): Add random.
+       * configure.ac (AC_CONFIG_FILES): Add random/Makefile.
+
+2008-04-25  Werner Koch  <wk@g10code.com>
+
+       Release 1.4.1.
+
+       * configure.ac: Bump LT version to C15/A4/R4.
+
+2008-04-22  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Set version to 1.4.1rc1.
+
+2008-04-18  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (AH_BOTTOM): Add CAMELLIA_EXT_SYM_PREFIX.
+       (NAME_OF_DEV_RANDOM):  Remove special cases for Solaris etc.  This
+       matches the gnupg 1.4.9 version.
+
+2008-04-01  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (AC_INIT): Fix quoting.
+
+2008-03-19  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Fix the tests for USE_<algo> to either define or
+       undef the macros.  Suggested by Dirk Stoecker.
+
+2008-03-18  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Test for uintptr_t.
+
+2008-02-18  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (IS_DEVELOPMENT_VERSION): Set depending on the my_svn.
+
+2007-12-11  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: We actually require libgpg-error 1.4.  Reported by
+       Tim Mooney.
+
+2007-12-10  Werner Koch  <wk@g10code.com>
+
+       Released 1.4.0.
+
+       * configure.ac: Set LT to C15/A4/R3.
+
+2007-12-05  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Add option --disable-padlock-support.
+
+2007-12-03  Werner Koch  <wk@g10code.com>
+
+       Released 1.3.2.
+
+       * configure.ac: Set LT to C15/A4/R2.
+
+       * config.sub, config.guess: Update to version 2007-11-19.
+
+2007-10-30  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Protect config.h against double inclusion.
+
+2007-10-26  Werner Koch  <wk@g10code.com>
+
+       Released 1.3.1.
+
+       * configure.ac: Set LT to C15/A4/R1.
+
+2007-08-22  Werner Koch  <wk@g10code.com>
+
+       * README: Rewrite the license description.
+       * configure.ac (USE_RNDW32, USE_RNDUNIX): Unmark as GPL modules.
+
+2007-08-08  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Use $host and not $target.
+
+2007-07-26  Werner Koch  <wk@g10code.com>
+
+       * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Fix a syntax error
+       in the test program which lurked there for 4 years.  Adjusted name
+       of libtools global_system_pipe variable and add extra cut stage.
+       Reported by Gregor Riepl.
+
+2007-06-15  Werner Koch  <wk@g10code.com>
+
+       * autogen.sh (FORCE): Use = and not == in test to be POSIXly correct.
+
+2007-05-30  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Camellia is no longer GPL.
+
+2007-05-24  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Try to use -Wpointer-arith.
+
+2007-05-19  Marcus Brinkmann  <marcus@g10code.de>
+
+       * configure.ac: Fix test for optional UDIV and UDIV_QRNND MPI
+       modules.
+
+2007-05-09  Marcus Brinkmann  <marcus@g10code.de>
+
+       * configure.ac (ac_cv_mpi_config_done): Unused variable removed.
+       (ac_cv_mpi_mod_list, MPI_MOD_LIST_LO, MPI_MOD_LIST_O): Removed.
+       (MPI_MOD_ASM_MPIH_ADD1, MPI_MOD_ASM_MPIH_SUB1,
+       MPI_MOD_ASM_MPIH_MUL1, MPI_MOD_ASM_MPIH_MUL2,
+       MPI_MOD_ASM_MPIH_MUL3, MPI_MOD_ASM_MPIH_LSHIFT,
+       MPI_MOD_ASM_MPIH_RSHIFT, MPI_MOD_ASM_MPIH_UDIV,
+       MPI_MOD_ASM_MPIH_UDIV_QRNND, MPI_MOD_C_MPIH_ADD1,
+       MPI_MOD_C_MPIH_SUB1, MPI_MOD_C_MPIH_MUL1, MPI_MOD_C_MPIH_MUL2,
+       MPI_MOD_C_MPIH_MUL3, MPI_MOD_C_MPIH_LSHIFT, MPI_MOD_C_MPIH_RSHIFT,
+       MPI_MOD_C_MPIH_UDIV, MPI_MOD_C_MPIH_UDIV_QRNND): New automake
+       variables.
+
+2007-05-04  Werner Koch  <wk@g10code.com>
+
+       Released 1.3.0.
+
+       * configure.ac: Set LT to C15/A4/R0.
+
+       * configure.ac: Require automake 1.10
+       (AM_PROG_CC_C_O): New.
+
+2007-05-03  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Fix detection of GPLed random modules.
+
+2007-05-02  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (LIBGCRYPT_DIGESTS, LIBGCRYPT_CIPHERS)
+       (LIBGCRYPT_PUBKEY_CIPHERS): Ac_define lists of algorithms.
+       (default_ciphers): Don't make camellia a default.
+
+2007-05-02  David Shaw  <dshaw@jabberwocky.com>
+
+       * NEWS, configure.ac: Add Camellia.
+
+2007-04-30  Werner Koch  <wk@g10code.com>
+
+       * README.apichanges: Move to doc/.
+       * Makefile.am (EXTRA_DIST): Removed that file.
+
+2007-04-28  Marcus Brinkmann  <marcus@g10code.de>
+
+       * configure.ac: Allow to specify additional search directories
+       with --enable-mpi-path.
+
+2007-04-16  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Check for sysconf.
+       * acinclude.m4 (GNUPG_CHECK_MLOCK): Try to use sysconf to get the
+       page size and use getpagesize only then if available.
+
+2007-03-22  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Add support for ECC.
+
+2007-02-22  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (DISTCHECK_CONFIGURE_FLAGS): Use
+       --enable-random-daemon.
+
+       * configure.ac: New option --enable-random-daemon.
+       Create versioninfo.rc and provide the build information.
+
+2007-02-21  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am, configure.ac: Ignore w32-dll/.
+
+2007-02-20  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Bump LT version to C14/A3/R0 in preparation for a
+       release.
+
+       * autogen.sh: Add option --force.
+       * configure.ac: New option --disable-endian-check.  Use a real
+       noexecstack test instead of requiring an option.  Add SVN version
+       magic.
+
+2007-02-02  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (FALLBACK_SOCKLEN_T): Special case for mingw32.
+
+2006-11-15  Werner Koch  <wk@g10code.com>
+
+       * autogen.sh: Add convenience option --build-amd64.
+
+2006-10-20  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am (stowinstall): New convenience target.
+
+2006-10-12  Marcus Brinkmann  <marcus@g10code.de>
+
+       * configure.ac (FALLBACK_SOCKLEN_T): Third time is a charm.
+       Define gcry_socklen_t, to avoid conflicts with socklen_t
+       definitions by autoconf.
+
+2006-10-11  Marcus Brinkmann  <marcus@g10code.de>
+
+       * configure.ac (FALLBACK_SOCKLEN_T): Rewrite in terms of
+       socklen.m4.
+
+2006-10-11  Marcus Brinkmann  <marcus@g10code.de>
+
+       * acinclude.m4 (GNUPG_FIX_HDR_VERSION): Removed.
+       * configure.ac: Do not call GNUPG_FIX_HDR_VERSION.
+
+2006-10-10  Marcus Brinkmann  <marcus@g10code.de>
+
+       * configure.ac: Invoke AC_CHECK_SOCKLEN_TYPE.
+       (AC_CONFIG_FILES): Add src/gcrypt.h.
+       (AC_CONFIG_SRCDIR): Change to src/libgcrypt.vers.
+
+2006-10-02  Werner Koch  <wk@g10code.com>
+
+       * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Test on HOST and not
+       TARGET.  Hardwire for mingw32. Allow setting via command line when
+       cross compiling.
+
+2006-08-29  Werner Koch  <wk@g10code.com>
+
+       * configure.ac (USE_SEED): New.
+
+2006-07-26  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: New options --enable-noexecstack and
+       --disable-optimization.
+
+2006-07-04  Marcus Brinkmann  <marcus@g10code.de>
+
+       * configure.ac: Call AC_LIBTOO_WIN32_DLL and AC_LIBTOOL_RC.
+
+       * configure.ac: Call gl_TYPE_SOCKLEN_T instead of the other
+       socklen_t checks.
+
+2006-06-08  Marcus Brinkmann  <marcus@g10code.de>
+
+       * configure.ac (PTH_LIBS): Add --all to pth-config invocation.
+
+2006-03-14  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Check for fctnl and ftruncate.
+       (HAVE_PTH): Check for GNU Pth.
+       (HAVE_W32_SYSTEM): Define it.
+       * acinclude.m4 (GNUPG_PTH_VERSION_CHECK): New. Taken from GnuPG 1.4.
+
+2005-12-08  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Changed the random device names for netbsd.  From
+       Christian Biere.
+
+2005-11-02  Moritz Schulte  <moritz@g10code.com>
+
+       * NEWS: Documented minor API changes.
+
+2005-09-15  Moritz Schulte  <moritz@g10code.com>
+
+       * Makefile.am (EXTRA_DIST): Depend on README.SVN, not on README.CVS.
+
+2005-06-25  Moritz Schulte  <moritz@g10code.com>
+
+       * configure.ac: Removed src/libgcrypt.pc from AC_CONFIG_FILES.
+
+2005-06-10  Werner Koch  <wk@g10code.com>
+
+       * configure.ac: Move detection of basic stuff to the top.  For
+       example we need to know whether gcc is used before testing for it.
+       Reported by Ralf Fassel.
+
+2005-04-23  Moritz Schulte  <moritz@g10code.com>
+
+       * acinclude.m4 (TYPE_SOCKLEN_T): New type definition test;
+       provided by Albert Chin.
+       * configure.ac: Don't use $(CMD) as it's not portable; use CMD in
+       backticks instead.  Simpler -lnsl/-lsocket test.  Use
+       TYPE_SOCKLEN_T test.  Don't forget to set `random_modules'
+       correctly.
+
+2005-04-22  Moritz Schulte  <moritz@g10code.com>
+
+       * configure.ac: Added support for pkgconfig; provided by Albert
+       Chin.
+
+2005-04-11  Moritz Schulte  <moritz@g10code.com>
+
+       * configure.ac: Integrate Whirlpool.
+
+2005-01-04  Werner Koch  <wk@g10code.com>
+
+       Updated to automake 1.9.
+
+       * acinclude.m4: Updated for use with automake 1.9.
+
+       * configure.ac: Require libgpg-error 1.0; not really needed but
+       that is the first stable version.
+
+       * Makefile.am (ACLOCAL_AMFLAGS): New for -I m4.
+       (AUTOMAKE_OPTIONS): New to create a bzip archive.
+
+2005-02-03  Moritz Schulte  <moritz@g10code.com>
+
+       * THANKS: Updated.
+
+2004-08-09  Moritz Schulte  <moritz@g10code.com>
+
+       * THANKS: Updated.
+
+2004-07-04  Moritz Schulte  <moritz@g10code.com>
+
+       * THANKS: Updated.
+
+2004-04-21  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac: Don't print a warning if GNU make was not found.
+
+2004-05-07  Moritz Schulte  <moritz@g10code.de>
+
+       * THANKS: Updated.
+
+2004-04-02  Thomas Schwinge  <schwinge@nic-nac-project.de>
+
+       * autogen.sh: Added ACLOCAL_FLAGS.
+
+2004-04-15  Werner Koch  <wk@gnupg.org>
+
+       Released 1.2.0.
+
+       * configure.ac: Set LT to C12/A1/R1.
+
+2004-04-06  Werner Koch  <wk@gnupg.org>
+
+       * config.guess, config.sub, ltmain.sh: Updated to those from
+       libtools 1.5.4.
+
+2004-03-29  Werner Koch  <wk@gnupg.org>
+
+       Released 1.1.94.
+
+       * configure.ac: Set LT to C12/A1/R0.
+
+2004-03-10  Marcus Brinkmann  <marcus@g10code.de>
+
+       * configure.ac (LIBGCRYPT_CONFIG_LIBS_PTHREAD,
+       LIBGCRYPT_CONFIG_CFLAGS_PTHREAD, LIBGCRYPT_CONFIG_LIBS_PTH,
+       LIBGCRYPT_CONFIG_CFLAGS_PTH, have_pth, have_pthread, AC_CHECK_PTH,
+       AC_CHECK_LIB(pthread), HAVE_PTH, HAVE_PTHREAD): Removed.
+
+2004-03-06  Werner Koch  <wk@gnupg.org>
+
+       Released 1.1.93.
+
+       * configure.ac (LIBGCRYPT_CONFIG_SONAME_NUMBER): Replaced by
+       LIBGCRYPT_CONPIG_API_VERSION.  Set it to 1.  Set LT to C11/A0/R1.
+
+2004-03-05  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac (LIBGCRYPT_CONFIG_SONAME_NUMBER): New.
+
+2004-02-20  Werner Koch  <wk@gnupg.org>
+
+        Released 1.1.92.
+
+       * configure.ac: Set LT to C11/A0/R0.
+
+2004-02-11  Werner Koch  <wk@gnupg.org>
+
+       * autogen.sh (check_version): Removed bashism and simplified.
+
+2004-02-06  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac: Add rfc2268 cipher algorithm.
+
+2004-01-25  Moritz Schulte  <mo@g10code.com>
+
+       * THANKS: Updated.
+
+2003-12-19  Werner Koch  <wk@gnupg.org>
+
+       Released 1.1.91.
+
+       * configure.ac: Bumbed LT version to C10/A3/R1.
+
+2003-12-08  Werner Koch  <wk@gnupg.org>
+
+       * Makefile.am (dist-hook): Don't distribute stuff from the now
+       obsolete scripts dir.
+       (EXTRA_DIST): Remove README_alpha
+       * README-alpha: Removed.
+       * configure.ac (AM_CONFIG_AUX_DIR): Removed.
+
+       * COPYING.DOC: Removed.
+       * Makefile.am (EXTRA_DIST): Added README.CVS and
+       autogen.sh. Removed COPYING.DOC.
+
+2003-11-14  Werner Koch  <wk@gnupg.org>
+
+       Released 1.1.90.
+
+       * configure.ac: Bumbed LT version to C10/A3/R0.
+
+       * configure.ac (have_ld_version_script): Set the default in
+       a separate test.
+       (PRINTABLE_OS_NAME): Don't handle the Hurd extra, this leads to
+       conflicts with BSD based GNU systems.  The Hurd has now a working
+       uname.
+
+2003-11-04  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac (USE_SHA1): Make sure it is always included.
+       (USE_RMD160): Removed this AM conditional.
+
+2003-10-31  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac: Bumbed version number to 1.1.90-cvs for futher
+       development
+
+       Released 1.1.44.
+
+       * acinclude.m4 (AC_CHECK_PTH): Added.
+       * configure.ac: Use it here instead of the generic lib test.
+       Bumbed LT vesion to C9/A2/R0.
+
+2003-10-27  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac: Give a hint on where libgpg-error is available.
+       Reformatted long lines.  Don't include gcrypt-defs.h.
+       (--enable-gcc-warnings): New option.
+
+2003-10-24  Moritz Schulte  <mo@g10code.com>
+
+       * configure.ac: Check for socklen_t.
+
+2003-10-11  Moritz Schulte  <mo@g10code.com>
+
+       * acinclude.m4: Update AM_PATH_GPG_ERROR macro.
+
+2003-09-04  Werner Koch  <wk@gnupg.org>
+
+       Released 1.1.43.
+
+       * configure.ac: Require libgpg-error 0.4 due to the prime interface.
+
+2003-08-29  Werner Koch  <wk@gnupg.org>
+
+       * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Re-implemented.
+       * configure.ac: Use it here.
+
+2003-08-27  Moritz Schulte  <mo@g10code.com>
+
+       * configure.ac: Substitute: LIBGCRYPT_CONFIG_LIBS_PTHREAD,
+       LIBGCRYPT_CONFIG_CFLAGS_PTHREAD, LIBGCRYPT_CONFIG_LIBS_PTH,
+       LIBGCRYPT_CONFIG_CFLAGS_PTH, LIBGCRYPT_THREAD_MODULES.
+
+2003-08-07  Moritz Schulte  <moritz@g10code.com>
+
+       * configure.ac: Fail, if libgpg-error could not be found.
+
+2003-07-31  Werner Koch  <wk@gnupg.org>
+
+       Released 1.1.42.
+
+       * configure.ac: Set LT version to 7/0/0.
+
+2003-07-30  Werner Koch  <wk@gnupg.org>
+
+       * AUTHORS (Maintainer): Assigned Moritz as Maintainer.
+
+2003-07-30  Moritz Schulte  <moritz@g10code.com>
+
+       * NEWS: Include much more complete list of `Interface changes
+       relative to the 1.1.12 release'.
+
+2003-07-14  Moritz Schulte  <moritz@g10code.com>
+
+       * configure.ac: Bumbed version number up to 1.1.42-cvs.
+
+2003-07-09  Moritz Schulte  <moritz@g10code.com>
+
+       * configure.ac: Reintroduce --disable-asm, since it is needed by
+       mpi/config.links.
+
+2003-07-05  Moritz Schulte  <moritz@g10code.com>
+
+       * README: Few changes, mention libgpg-error.
+
+2003-06-18  Moritz Schulte  <moritz@g10code.com>
+
+       * configure.ac (available_ciphers): Removed Serpent, hrrm.
+
+2003-06-17  Moritz Schulte  <moritz@g10code.com>
+
+       * acinclude.m4: Removed macro definitions: GNUPG_CHECK_FAQPROG,
+       GNUPG_CHECK_ENDIAN, GNUPG_CHECK_CACHE, GNUPG_CHECK_PIC,
+       GNUPG_CHECK_EXPORTDYNAMIC, GNUPG_CHECK_IPC, GNUPG_PROG_NM,
+       GNUPG_SYS_SYMBOL_UNDERSCORE, GNUPG_FUNC_MKDIR_TAKES_ONE_ARG,
+       GPH_PROG_DB2ANY.
+       Added macro definitions: AM_PATH_GPG_ERROR.
+
+       * configure.ac: Use alternative approach for building based on
+       conditional sources, which does not make automake eat all your
+       memory, etc.
+       Removed unused tests.
+       Renamed --enable-static-rnd to --enable-random.
+       Use Autoconf's AC_C_BIGENDIAN macro instead of our own.
+       Re-organized the whole file.
+
+2003-06-16  Moritz Schulte  <moritz@g10code.com>
+
+       * configure.ac (AC_CONFIG_FILES): Removed doc/version.sgml.
+
+2003-06-11  Moritz Schulte  <moritz@g10code.com>
+
+       * configure.ac: Remove --enable-libgpg-error flag.
+       Ue AC_PATH_GPG_ERROR.
+
+2003-06-09  Moritz Schulte  <moritz@g10code.com>
+
+       * NEWS: Mention API changes and libgpg-error.
+
+2003-05-25  Moritz Schulte  <moritz@g10code.com>
+
+       * configure.ac (USE_LIBGPG_ERROR): Implementation of the
+       --enable-libgpg-error switch.
+       Define USE_LIBGPG_ERROR in LIBGCRYPT_CONFIG_FLAGS, in case
+       libgpg-error is used.
+
+2003-05-22  Moritz Schulte  <moritz@g10code.com>
+
+       * configure.ac (AC_CHECK_HEADERS): Removed unused headers:
+       termio.h, langinfo.h.
+       (AC_CHECK_FUNCS): Removed unused functions: strsep, strlwr,
+       tcgetattr, setrlimit, strftime, nl_langinfo, sigaction,
+       sigprocmask, fopen64, fstat64.
+
+2003-04-27  Moritz Schulte  <moritz@g10code.com>
+
+       * README: Documented new configure switches.
+       Mention the --enable-maintainer-switch.
+
+       * configure.ac: Merged some code from GnuPG's configure.ac for
+       disabling sha512/tiger in case no 64 data types are available.
+
+2003-04-17  Moritz Schulte  <moritz@g10code.com>
+
+       * configure.ac: Include support for sha512.
+
+2003-04-17  Moritz Schulte  <moritz@g10code.com>
+
+       * AUTHORS: Updated.
+
+2003-04-16  Moritz Schulte  <moritz@g10code.com>
+
+       * configure.ac: Implement command line switches: --enable-ciphers,
+       --enable-pubkey-ciphers and --enable-digests.
+       Set Automake conditionals and config.h symbols depending on the
+       selected ciphers, pubkey-ciphers, digests and random-modules.
+
+       * acinclude.m4 (LIST_MEMBER): New macro.
+
+       * configure.ac: Simplified, removed code for parsing
+       EXTRA_PROGRAMS from Makefile.am.
+
+2003-04-08  Moritz Schulte  <moritz@g10code.com>
+
+       * configure.ac: Merged random-module selection code from GnuPG's
+       configure.ac.
+
+2003-04-07  Moritz Schulte  <moritz@g10code.com>
+
+       * configure.ac: Removed code for generating contruct.c.
+       Remove digest modules from the static_modules list, only handle
+       random module selection.
+
+
+2003-03-24  Moritz Schulte  <moritz@g10code.com>
+
+       * NEWS: Mention new CBC_MAC flag.
+
+       * AUTHORS (Maintainer): Update entry for Simon Josefsson.
+
+2003-03-04  Moritz Schulte  <moritz@g10code.com>
+
+       * TODO: Remove item about resetting handles, since
+       gcry_cipher_reset is implemented by now.
+
+       * NEWS: Mentioned gcry_cipher_reset.
+
+2003-01-21  Werner Koch  <wk@gnupg.org>
+
+       * README (Configure options): New.
+       * configure.ac (have_ld_version_script): New option
+       --enable-ld-version-script.
+
+2003-01-20  Simon Josefsson  <jas@extundo.com>
+
+       * configure.ac (MODULES_IN_CIPHER): Add crc.
+
+2003-01-20  Werner Koch  <wk@gnupg.org>
+
+       Released 1.1.12.
+
+       * configure.ac (LIBGCRYPT_LT_REVISION): Bumbed up.
+
+2002-12-21  Werner Koch  <wk@gnupg.org>
+
+       Released 1.1.11.
+
+       * configure.ac (LIBGCRYPT_LT_CURRENT: Bumbed to 6/5/0 due to a new
+       interface
+
+2002-12-19  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac (have_pthread): Check for pthreads in libc.
+       (have_ld_version_script): New.
+
+2002-11-10  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac (MODULES_IN_CIPHER): Add md4.c.  By Simon Josefsson.
+
+2002-09-20  Werner Koch  <wk@gnupg.org>
+
+       Released 1.1.10.
+
+       * configure.ac (HAVE_DEV_RANDOM_IOCTL): Don't check for it; it is
+       not used.
+       (AS_CHECK_HEADERS): Check for sys/select.h.
+       * Makefile.am (DIST_SUBDIRS): New to include the w32-dll directory
+
+2002-09-18  Timo Schulz  <ts@winpt.org>
+
+       * configure.ac: Added makefile for the W32 DLL.
+
+2002-09-17  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac: Check for Pth and Pthreads.
+
+2002-08-23  Werner Koch  <wk@gnupg.org>
+
+       Released 1.1.9.
+
+       * configure.ac (LIBGCRYPT_CONFIG_CFLAGS): Renamed from
+       LIBGCRYPT_CFLAGS and removed the libpath because it is set by the
+       config script.
+       (LIBGCRYPT_LT_REVISION): Set LT version to 5/4/1.
+
+2002-06-25  Werner Koch  <wk@gnupg.org>
+
+       Released 1.1.8.
+
+       * configure.ac: Set LT version to 5/4/0.
+
+2002-05-21  Werner Koch  <wk@gnupg.org>
+
+       Released 1.1.7.
+
+       * configure.ac: Set LT version to 4/3/0.
+
+2002-05-17  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac: Removed all the dynamic loading stuff.
+
+2002-05-16  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac: Reordered the C_CHECK_FUNCS.
+
+2002-05-15  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac: Adjusted for new MPI module stuff.
+
+2002-05-14  Werner Koch  <wk@gnupg.org>
+
+       Changed license to the LGPL.
+
+2002-05-02  Werner Koch  <wk@gnupg.org>
+
+       * jnlib/: Removed.
+       * Makefile.am (SUBDIRS): Removed jnlib.
+       * configure.ac (jnlib/Makefile): Removed.
+
+       * configure.ac: Define _REENTRANT.
+
+2002-02-18  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac (MPI_EXTRA_ASM_OBJS): Use .lo suffix.
+       (AC_CANONICAL_TARGET): Added.
+
+2002-02-07  Werner Koch  <wk@gnupg.org>
+
+       Released 1.1.6.
+
+2002-01-24  Werner Koch  <wk@gnupg.org>
+
+       * jnlib/: Replaced by a fresh copy from GnuPG (actually the NewPG
+       development branch).  Adjusted Makefile.am and jnlib-config.h
+       accordingly.
+
+2001-12-18  Werner Koch  <wk@gnupg.org>
+
+       Released 1.1.5.
+
+       * Makefile.am (dist-hook): Only look in mpi and scripts for
+       distfiles; this way we don't include those of a stale "make dist"
+       directory.
+
+       * acinclude.m4 (GNUPG_FIX_HDR_VERSION): Make it work with the new
+       automake.
+       * configure.ac: Don't chmod db2any.
+
+2001-08-06  Werner Koch  <wk@gnupg.org>
+
+       * configure.ac: Removed cross compiling hacks.
+
+2001-08-03  Werner Koch  <wk@gnupg.org>
+
+       Released 1.1.4.
+
+       * acinclude.m4 (GNUPG_CHECK_TYPEDEF): Define GNU Source.
+
+        Migrated to autoconf 2.52.
+       * acinclude.m4: Removed GNUPG_LINK_FILES and converted.
+       * acconfig.h: Removed
+       * configure.in: Replaced by...
+       * configure.ac: and modified for use with autoconf 2.52.  Replaced
+       GNUPG_LINK_FILES with AC_CONFIG_LINKS and moved some informational
+       messages to the end. Removed --enable-m-debug
+
+       * tests/: New.
+       * Makefile.am: Included tests directory
+
+       * configure.in (DYNLINK_MOD_CFLAGS): Use -shared with dec-osf.
+       Reported by Chris Adams.  Merged some cases.
+
+2001-05-31  Werner Koch  <wk@gnupg.org>
+
+       Released 1.1.3.
+
+       * configure.in: Use _gcry_ prefix when creating the cipher constructor.
+
+       * acconfig.h (_GCRYPT_IN_LIBGCRYPT): Define it here.
+
+2001-05-28  Werner Koch  <wk@gnupg.org>
+
+       * acinclude.m4 (GPH_PROG_DOCBOOK): Removed.
+       (GPH_PROG_DB2ANY): New. Taken from GPH.
+       * configure.in: Use it here.
+
+2000-12-19  Werner Koch  <wk@gnupg.org>
+
+       Major change:
+       Removed all GnuPG stuff and renamed this piece of software
+       to gcrypt.  The directory gcrypt has been renamed to src.
+
+2000-11-14  Werner Koch  <wk@gnupg.org>
+
+       Version 1.1.2 released.
+
+2000-11-13  Werner Koch  <wk@gnupg.org>
+
+       * acinclude.m4 (GNUPG_FIX_HDR_VERSION): VPATH build fix.
+
+2000-10-10  Werner Koch  <wk@gnupg.org>
+
+       * Makefile.am (dist-hook): Create the version file.
+       * configure.in: Set the libtool version here, removed the need
+       for the version file.
+
+Mon Sep 18 16:35:45 CEST 2000  Werner Koch  <wk@openit.de>
+
+        * acinclude.m4 (GNUPG_CHECK_MLOCK):  Removed that silly mkdir().
+
+        * configure.in:  Changes to allow for Solaris random device.
+        By Nils Ellmenreich.
+        (--with-egd-socket): New.
+
+        * configure.in (GNUPG_HOMEDIR): New.
+
+        * configure.in: Check for fstat64 and fopen64
+
+        * acinclude.m4 (GNUPG_CHECK_FAQPROG): New.
+        * configure.in: Test for this.
+
+        * configure.in (DYNLINK_MOD_CFLAGS): Fix by David Champion.
+
+Tue Aug 22 14:31:15 CEST 2000  Werner Koch  <wk@openit.de>
+
+        Version 1.1.1
+
+Fri Aug 18 14:27:14 CEST 2000  Werner Koch  <wk@openit.de>
+
+  * agent/: New.
+  * Makefile.am, configure.in: Support for the new directory.
+
+Mon Jul 17 16:35:47 CEST 2000  Werner Koch  <wk@>
+
+  * configure.in (mingw32): Changes to allow for mingw32msvc
+
+Fri Jul 14 19:38:23 CEST 2000  Werner Koch  <wk@>
+
+  The big merge between this one and the stable branch 1.0.  Still need
+  to merge TNANKS, AUTHORS and such.  It probaly does not compile yet.
+
+  * acinclude.m4 (GNUPG_CHECK_MLOCK): Fixed syntax error in C code.
+
+  * configure.in: Add check for termio.h, wait unctiosn and sigaction.
+
+  * acinclude.m4, configure.in (GNUPG_CHECK_GNUMAKE): New.
+
+  * acinclude.m4 (MKDIR_TAKES_ONE_ARG): Check some headers. By Gaël Quéri.
+
+  * configure.in (AM_INIT_AUTOMAKE): Use this now. By Gaël.
+
+  * acinclude.m4 (GNUPG_CHECK_EXPORTDYNAMIC): Replacement for
+  GNUPG_CHECK_RDYNAMIC which should handle gcc with non GNU ld nicer.
+  Contributed by Dave Dykstra.
+  * configure.in (GNYPG_CHECK_RDYNAMIC): Replaced by the new check.
+
+  * configure.in: Add a test for unisgned long long.
+
+  * configure.in (DYNLINK_MOD_CFLAGS): Set different for NetBSD.
+
+  * configure.in: Add check for clock_gettime
+
+  * configure.in (ALL_LINGUAS): Add nl.
+  * configure.in (ALL_LINGUAS): Add Esperanto.
+  * configure.in (ALL_LINGUAS): Add sv and ja.
+
+  * configure.in: Use /usr/local for CFLAGS and LDFLAGS when
+  target is freebsd.  By Rémi.
+
+  * configure.in: Do not set development version when the version has
+  a dash in it.  Suggested by Dave Dykstra.
+
+  * configure.in: Removed substitution for doc/gph/Makefile.
+  Do all the gcc warning only in maintainer mode.
+
+  * configure.in (dlopen): Use CHECK_FUNC for a test of dlopen in libc.
+  Suggested by Alexandre Oliva.
+  (-Wall): Moved the settting of gcc warning options near to the end
+  so that tests don't get confused.  Suggested by Paul D. Smith.
+
+  * acinclude.m4 (GNUPG_SYS_NM_PARSE): Added BSDI support.
+  (GNUPG_CHECK_RDYNAMIC): Ditto.
+
+  * acinclude.m4 (GNUPG_CHECK_MLOCK): Changed the way to test for
+  librt.  Test suggested by Jeff Long.
+
+  * acinclude.m4 (GNUPG_CHECK_MLOCK): Do librt check only when
+  we can't link a test program.  This way GNU systems don't need
+  to link against linrt.
+  (GNUPG_CHECK_IPC): Fixed use of TRY_COMPILE macro.  From Tim Mooney.
+
+  * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Add support for
+  DJGPP.
+  (GNUPG_CHECK_MLOCK): Check whether mlock sits in librt.
+
+  * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Add NetBSD. By Thomas Klausner.
+
+  * acconfig.h (HAVE_MLOCK): Added
+
+Mon Mar 13 19:22:46 CET 2000  Werner Koch  <wk@openit.de>
+
+       * configure.in: Now uses the Docbook M4s from GPH.
+
+Mon Jan 31 17:46:35 CET 2000  Werner Koch  <wk@>
+
+       * Makefile.am: Re-added tools. By Rémi.
+
+Mon Jan 31 16:37:34 CET 2000  Werner Koch  <wk@gnupg.de>
+
+       * configure.in: Create a symlink for types.h in gcrypt/.
+
+Thu Jan 27 18:00:44 CET 2000  Werner Koch  <wk@gnupg.de>
+
+       * configure.in (g10defs.h): Replaced by gnupg-defs.h
+
+Mon Jan 24 13:04:28 CET 2000  Werner Koch  <wk@gnupg.de>
+
+       * jnlib/ : New.
+
+       * configure.in: Do set development version when the version has
+       a dash in it.  Suggested by Dave Dykstra.
+
+Thu Dec  9 17:22:27 CET 1999  Werner Koch  <wk@gnupg.de>
+
+       * acinclude.m4 (GNUPG_FIX_HDR_VERSION): New.
+       * configure.in: Check and fix the version number of gcrypt/gcrypt.h
+       so that it is always the save as VERSION.
+
+Thu Oct 28 16:17:46 CEST 1999  Werner Koch  <wk@gnupg.de>
+
+       * Started with development series 1.1 on 1999-10-26
+
+Tue Oct 26 14:10:21 CEST 1999  Werner Koch  <wk@gnupg.de>
+
+       * README-alpha: New
+
+       * configure.in: Fixed quoting in test for development version.
+
+       * THANKS: Add entries for Michael, Brenno and J Horacio who did
+       very nice Howto documents - I apoligize for forgetting to mention them
+       earlier.
+
+Fri Sep 17 12:56:42 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+
+       * configure.in: Add "-lcap" when capabilities are requested.
+       Add the conditional CROSS_COMPILING.
+       * Makefile.am: Don't use checks when CROSS_COMPILING.
+
+
+Wed Sep 15 16:22:17 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+
+       * configure.in (ALL_LINGUAS): Add pt_PT.
+
+       * configure.in: Some tweaks for cross compiling under MingW32
+       * acconfig.h (USE_STATIC_RNDW32): New.
+
+Tue Sep  7 17:08:10 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+
+       * VERSION: Set to 1.0.0.
+
+Mon Sep  6 19:59:08 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+
+       * configure.in: Create makefile in doc/gph
+
+       * acinclude.m4 (GNUPG_FUNC_MKDIR_TAKES_ONE_ARG): New
+       * configure.in: use the above.
+
+Thu Sep  2 16:40:55 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+
+       * VERSION: Set to 0.9.11.
+
+Tue Aug 31 17:20:44 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * configure.in: Minor changes to the OS/2 and Mingw32 system labels.
+       Add a printable name for Hurd.
+
+Mon Aug 30 20:38:33 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * configure.in: Some support for DJGPP (Mark Elbrecht)
+
+Wed Aug  4 10:34:46 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * VERSION: Set to 0.9.10.
+
+Mon Jul 26 09:34:46 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): remove init of ac_cv_...
+
+       * Makefile.am (DISCLEANFILES): New
+
+Fri Jul 23 13:53:03 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * VERSION: Set to 0.9.9.
+
+       * configure.in: Print a notice when rndunix is used.
+
+Thu Jul 15 10:15:35 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Fixed last modification.
+
+Wed Jul  7 13:08:40 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * Makefile.am: Support for libtool.
+       * configure.in: Ditto.
+
+Tue Jun 29 21:44:25 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * configure.in (use_local_zlib): The lost dollar is back.
+
+       * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): Add EMX case.
+       * configure.in: Another variant of the MX vendor string
+
+       * configure.in (--with-capabilities): Some test code (Remi).
+
+Sat Jun 26 12:15:59 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Support for HPUX and IRIX.
+       * configure.in (HAVE_DL_SHL_LOAD): New for HPUX (Dave Dykstra).
+
+       * VERSION: Now 0.9.8
+
+Wed Jun 16 20:16:21 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * configure.in: Add test for docbook-to-man
+
+Tue Jun 15 12:21:08 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * acinclude.m4 (GNUPG_SYS_NM_PARSE): Support for {net,free}bsd,
+
+Thu Jun 10 14:18:23 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * configure.in (ZLIB,GDBM): Check both, header and lib.
+
+Sat Jun  5 15:30:33 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * pkclist.c (key_present_in_pk_list): New (Michael).
+
+Tue May 25 19:50:32 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * configure.in (IS_DEVELOPMENT_VERSION): Fixed detection.
+
+Sun May 23 14:20:22 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * acinclude.m4 (GNUPG_SYS_SYMBOL_UNDERSCORE): assume yes when
+       cross-compiling.
+
+Mon May 17 21:54:43 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * configure.in (socket): Fix for Unisys by Katsuhiro Kondou.
+
+Sat May  8 19:28:08 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * NEWS: Add a marker line which I forgot to do for 0.9.6.
+
+Thu May  6 14:18:17 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * README: Minor updates
+
+       * VERSION: Now 0.9.6
+
+Thu Apr  8 09:35:53 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Fix for
+                                              amiga-openbsd (Peter Reich)
+       (GNUPG_PROG_NM): Ditto
+
+Wed Apr  7 20:51:39 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * Makefile.am (g10defs.h): Removed.
+       * configure.in (AC_OUTPUT_COMMANDS): Create g10defs.h
+
+Sat Mar 20 12:55:33 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * VERSION: Now 0.9.5
+
+Sun Mar 14 19:34:36 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * acinclude.m4 (AM_SYS_SYMBOL_UNDERSCORE): Removed because it is
+       now in the latest libtool.
+
+Thu Mar 11 16:39:46 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * configure.in: Removed the need for libtool
+
+Mon Mar  8 20:47:17 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * configure.in (DLSYM_NEEDS_UNDERSCORE): Replaced.
+       * acinclude.in (AM_SYS_SYMBOL_UNDERSCORE): New.
+
+       * VERSION: Now 0.9.4
+
+Sun Feb 28 19:11:00 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * configure.in (dld): Test disabled.
+
+Fri Feb 26 17:55:41 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * encode.c (encode_simple): temporary fix.
+
+Wed Feb 24 11:07:27 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * configure.in: New option --enable-static-rnd.
+
+Mon Feb 22 20:04:00 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * BUGS: Now we assign bug numbers.
+       * OBUGS: New to keep rack o fixed bugs (CVS only)
+
+Fri Feb 19 18:01:54 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * VERSION: Released 0.9.3
+
+Fri Feb 19 15:49:15 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * acinclude.m4: Removed gettext macros.
+
+Tue Feb 16 14:10:02 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * configure.in (socket): Check for -lsocket and -lnsl.
+       (osf4): Disable all warnings for DEC's cc.
+       (-Wall): Add more warning options for gcc
+
+Sat Feb 13 12:04:43 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * configure.in: Changed detection of compiler flags.
+       * intl/ : Removed directory
+
+Wed Feb 10 17:15:39 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): Fix for freebsd 2.2
+
+       * configure.in: a lot of changes to allow selection of modules.
+       Add support for OS/2.
+
+       * acinclude.m4: add some more caching
+
+       * README: Spelling and grammar corrections (John A. Martin)
+       * INSTALL: Ditto.
+
+Wed Jan 20 21:40:21 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * configure.in: --enable-m-guard is now default
+
+Wed Jan 13 12:49:36 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * INSTALL: Applied new information how to build rpms by Fabio Coatti
+       * Makefile.in (gnupg.spec): Changed the names.
+
+Tue Jan 12 11:17:18 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * config.links (m68k-atari-mint): New
+
+Tue Jan 12 09:17:19 CET 1999  Gaël Quéri <gqueri@mail.dotcom.fr>
+
+       * all: Fixed typos all over the place
+
+Sat Jan  9 16:02:23 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * configure.in: Add a way to statically link rndunix
+
+Sun Jan  3 15:28:44 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * acinclude.m4 (GNUPG_CHECK_RDYNAMIC): New.
+       * configure.in (DYNLOAD_CFLAGS): Use result from CHECK_RDYNAMIC
+
+Wed Dec 23 13:18:14 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * README: Replaced the command overview with a short intro.
+
+Sat Dec 12 18:40:32 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * configure.in: Add check for dlopen in libc (Greg Troxel)
+       and a new define
+       * acconfig.h (DLSYM_NEEDS_UNDERSCORE): New.
+
+Thu Dec 10 20:15:36 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * acinclude.m (GNUPG_CHECK_PIC): New
+       * configure.in, acinclude.m4: Renamed all WK_ to GNUPG_
+
+Tue Dec  8 15:09:29 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * VERSION: Set to 0.4.5
+
+Wed Nov 25 12:38:29 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * configure.in (USE_RNDLINUX): New.
+
+Fri Nov 20 19:34:57 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * VERSION: Released 0.4.4
+
+       * configure.in (try_asm_modules): For option --disable-asm
+
+Tue Nov 10 19:32:40 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * configure.in (MPI_SFLAGS): New.
+
+Tue Nov 10 13:44:53 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * ABOUT-NLS: New
+       * configure.in (AC_REVISION): New.
+
+Sun Nov  8 18:20:35 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * VERSION: Set to 0.4.3
+
+Sun Oct 25 19:49:37 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * Makefile.am (g10defs.h): New macro GNUPG_DATADIR.
+
+Wed Oct 21 17:24:24 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * configure.in: Removed gettext kludge
+       * acinclude.m4: Add patched AM_WITH_NKS macro
+
+Tue Oct 20 19:03:36 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * configure.in: Kludge to make AM_GNU_GETTEXT work,
+       changed some macors to more modern versions. Also
+       changeg the all makefiles to remove duplicate ../intl.
+       * acinclude.m4: Removed the gettext stuff, as this
+       already comes with automake now.
+
+Wed Oct 14 12:11:34 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * configure.in (NAME_OF_DEV_RANDOM): New.
+       (DYNLINK_MOD_CFLAGS): New.
+
+Thu Oct  8 10:55:15 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * Makefile.am (g10defs.h): creates include file
+       * acconfig.h: now includes g10defs.h
+       * configure.in: Removed G10_LOCALEDIR and GNUPG_LIB
+
+Thu Sep 17 18:49:40 1998  Werner Koch  (wk@(none))
+
+       * Makefile.am (dist-hook): Now creates RPM file.
+       * scripts/gnupg.spec: New template file for RPMs
+
+Thu Jul 30 19:17:07 1998  Werner Koch  (wk@(none))
+
+       * acinclude.h (WK_CHECK_IPC): New
+       * configure.in : Add checks for SysV IPC
+
+Thu Jun 25 11:18:49 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * configure.in (--disable-dynload): New.
+
+Wed Jun 10 07:48:59 1998  Werner Koch,mobil,,, (wk@tobold)
+
+       * configure.in (GNUPG_LIBDIR): New.
+
+Mon May 25 19:10:59 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * rand-unix.c (fast_random_poll): fixed syntax bug.
+
+Mon May 11 10:21:31 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * configure.in (PRINTABLE_OS_NAME): Linux is now GNU/Linux
+
+Tue Apr 14 19:08:05 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * [all files]: Applied Matthew Skala's typo and grammar fixes.
+
+Wed Mar  4 10:32:40 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * configure.in (getrusage,gettimeofday): New tests.
+
+Fri Feb 27 13:14:17 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * configure.in (--disable-m-guard): New.
+
+Thu Feb 26 17:09:27 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * configure.in, acinclude.m4, intl/, po/: New macros taken
+       from GNOME, switched to automake 1.2f
+
+Thu Feb 26 09:05:46 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * configure.in (doc/Makefile): New
+
+Thu Feb 26 07:40:47 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * configure.in: Changed gettext stuff
+
+Wed Feb 25 11:44:10 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * checks/*test : restructured the directory.
+
+Tue Feb 24 15:59:12 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * configure.in: Changed the name of the package to GNUPG and
+       chnaged several other names too.
+
+Wed Feb 18 17:36:45 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * Makefile.am (checks): New.
+
+Sat Feb 14 15:37:55 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * configure.in (mpi_config_done): Removed asm links caching.
+
+Sat Feb 14 14:02:20 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * configure.in (PRINTABLE_OS_NAME): New.
+       * acconfig.h: Likewise.
+
+Fri Feb 13 19:43:41 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * configure.in : Fixed zlib stuff
+       * Makefile.am: Likewise
+
+
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006,
+          2007, 2008, 2009, 2011 Free Software Foundation, Inc.
+
+ 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.
+
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/LICENSES b/LICENSES
new file mode 100644 (file)
index 0000000..8594cfd
--- /dev/null
+++ b/LICENSES
@@ -0,0 +1,134 @@
+Additional license notices for Libgcrypt.                    -*- org -*-
+
+This file contains the copying permission notices for various files in
+the Libgcrypt distribution which are not covered by the GNU Lesser
+General Public License (LGPL) or the GNU General Public License (GPL).
+
+These notices all require that a copy of the notice be included
+in the accompanying documentation and be distributed with binary
+distributions of the code, so be sure to include this file along
+with any binary distributions derived from the GNU C Library.
+
+* BSD_3Clause
+
+  For files:
+  - cipher/sha256-ssse3-amd64.S
+  - cipher/sha512-avx-amd64.S
+  - cipher/sha512-avx2-bmi2-amd64.S
+  - cipher/sha512-ssse3-amd64.S
+
+#+begin_quote
+  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.
+#+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:
+  - install.sh
+
+#+begin_quote
+  Copyright (C) 1994 X Consortium
+
+  Permission is hereby granted, free of charge, to any person obtaining a copy
+  of this software and associated documentation files (the "Software"), to
+  deal in the Software without restriction, including without limitation the
+  rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+  sell copies of the Software, and to permit persons to whom the Software is
+  furnished to do so, subject to the following conditions:
+
+  The above copyright notice and this permission notice shall be included in
+  all copies or substantial portions of the Software.
+
+  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+  X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+  AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+  TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+  Except as contained in this notice, the name of the X Consortium shall not
+  be used in advertising or otherwise to promote the sale, use or other deal-
+  ings in this Software without prior written authorization from the X Consor-
+  tium.
+#+end_quote
index fbb5744..937bdaf 100644 (file)
 
 ACLOCAL_AMFLAGS = -I m4
 AUTOMAKE_OPTIONS = dist-bzip2
-DISTCHECK_CONFIGURE_FLAGS = --enable-random-daemon \
+DISTCHECK_CONFIGURE_FLAGS = --disable-random-daemon \
   --enable-ciphers=arcfour:blowfish:cast5:des:aes:twofish:serpent:rfc2268:seed:camellia
 
+# (A suitable gitlog-to-changelog script can be found in GnuPG master.)
+GITLOG_TO_CHANGELOG=gitlog-to-changelog
+
 DIST_SUBDIRS = m4 compat mpi cipher random src doc tests
 SUBDIRS =         compat mpi cipher random src doc tests
-EXTRA_DIST = autogen.sh README.SVN
+
+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    \
+             random/ChangeLog-2011 tests/ChangeLog-2011 mpi/ChangeLog-2011 \
+             build-aux/git-log-footer build-aux/git-log-fix
+
 DISTCLEANFILES =
 
 
 # Add all the files listed in "distfiles" files to the distribution,
 # apply version number s to some files and create a VERSION file which
 # we need for the Prereq: patch file trick.
-dist-hook:
+dist-hook: gen-ChangeLog
        @set -e; \
         for file in `cd $(top_srcdir); \
              find mpi -type f -name distfiles`; do \
@@ -44,5 +53,21 @@ dist-hook:
        @set -e; \
        echo "$(VERSION)" > $(distdir)/VERSION
 
+
+gen_start_date = 2011-12-01T14:00:00
+.PHONY: gen-ChangeLog
+gen-ChangeLog:
+       if test -d $(top_srcdir)/.git; then                             \
+         (cd $(top_srcdir) &&                                          \
+           $(GITLOG_TO_CHANGELOG) --append-dot --tear-off              \
+           --amend=build-aux/git-log-fix                               \
+           --since=$(gen_start_date) ) > $(distdir)/cl-t;              \
+          cat $(top_srcdir)/build-aux/git-log-footer >> $(distdir)/cl-t;\
+         rm -f $(distdir)/ChangeLog;                                   \
+         mv $(distdir)/cl-t $(distdir)/ChangeLog;                      \
+       fi
+
+
+
 stowinstall:
        $(MAKE) $(AM_MAKEFLAGS) install prefix=/usr/local/stow/libgcrypt
index 77a3e3e..605bf5b 100644 (file)
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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; \
+    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;; \
+    esac; \
+    test $$am__dry = yes; \
+  }
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -55,24 +72,34 @@ 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 compile config.guess config.rpath \
-       config.sub depcomp install-sh ltmain.sh missing mkinstalldirs
+       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
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.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/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/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
        $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
-       $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+       $(top_srcdir)/m4/threadlib.m4 $(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 \
  configure.lineno config.status.lineno
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
+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_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
 SOURCES =
 DIST_SOURCES =
 RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
@@ -82,6 +109,11 @@ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
        install-pdf-recursive install-ps-recursive install-recursive \
        installcheck-recursive installdirs-recursive pdf-recursive \
        ps-recursive uninstall-recursive
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
 RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive        \
   distclean-recursive maintainer-clean-recursive
 AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
@@ -93,9 +125,11 @@ DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
 am__remove_distdir = \
-  { test ! -d "$(distdir)" \
-    || { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
-         && rm -fr "$(distdir)"; }; }
+  if test -d "$(distdir)"; then \
+    find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
+      && rm -rf "$(distdir)" \
+      || { sleep 5 && rm -rf "$(distdir)"; }; \
+  else :; fi
 am__relativize = \
   dir0=`pwd`; \
   sed_first='s,^\([^/]*\)/.*$$,\1,'; \
@@ -124,9 +158,12 @@ am__relativize = \
 DIST_ARCHIVES = $(distdir).tar.gz $(distdir).tar.bz2
 GZIP_ENV = --best
 distuninstallcheck_listfiles = find . -type f -print
+am__distuninstallcheck_listfiles = $(distuninstallcheck_listfiles) \
+  | sed 's|^\./|$(prefix)/|' | grep -v '$(infodir)/dir$$'
 distcleancheck_listfiles = find . -type f -print
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AR = @AR@
 AS = @AS@
 AUTOCONF = @AUTOCONF@
@@ -141,6 +178,7 @@ CCAS = @CCAS@
 CCASDEPMODE = @CCASDEPMODE@
 CCASFLAGS = @CCASFLAGS@
 CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
@@ -160,6 +198,8 @@ FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
 FGREP = @FGREP@
 GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
 GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_HWF_MODULES = @GCRYPT_HWF_MODULES@
+GCRYPT_KDFS = @GCRYPT_KDFS@
 GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
 GCRYPT_RANDOM = @GCRYPT_RANDOM@
 GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
@@ -185,14 +225,19 @@ 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@
 MKDIR_P = @MKDIR_P@
 MPI_SFLAGS = @MPI_SFLAGS@
 NM = @NM@
@@ -215,16 +260,19 @@ PTH_CONFIG = @PTH_CONFIG@
 PTH_LIBS = @PTH_LIBS@
 RANLIB = @RANLIB@
 RC = @RC@
+RUN_LARGE_DATA_TESTS = @RUN_LARGE_DATA_TESTS@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
 SYS_SOCKET_H = @SYS_SOCKET_H@
 VERSION = @VERSION@
+VERSION_NUMBER = @VERSION_NUMBER@
 abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
@@ -260,7 +308,6 @@ libdir = @libdir@
 libexecdir = @libexecdir@
 localedir = @localedir@
 localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 oldincludedir = @oldincludedir@
@@ -278,18 +325,27 @@ top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
 ACLOCAL_AMFLAGS = -I m4
 AUTOMAKE_OPTIONS = dist-bzip2
-DISTCHECK_CONFIGURE_FLAGS = --enable-random-daemon \
+DISTCHECK_CONFIGURE_FLAGS = --disable-random-daemon \
   --enable-ciphers=arcfour:blowfish:cast5:des:aes:twofish:serpent:rfc2268:seed:camellia
 
+
+# (A suitable gitlog-to-changelog script can be found in GnuPG master.)
+GITLOG_TO_CHANGELOG = gitlog-to-changelog
 DIST_SUBDIRS = m4 compat mpi cipher random src doc tests
 SUBDIRS = compat mpi cipher random src doc tests
-EXTRA_DIST = autogen.sh README.SVN
+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    \
+             random/ChangeLog-2011 tests/ChangeLog-2011 mpi/ChangeLog-2011 \
+             build-aux/git-log-footer build-aux/git-log-fix
+
 DISTCLEANFILES = 
+gen_start_date = 2011-12-01T14:00:00
 all: config.h
        $(MAKE) $(AM_MAKEFLAGS) all-recursive
 
 .SUFFIXES:
-am--refresh:
+am--refresh: Makefile
        @:
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
        @for dep in $?; do \
@@ -325,10 +381,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; \
-         $(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
-       else :; fi
+       @if test ! -f $@; then rm -f stamp-h1; else :; fi
+       @if test ! -f $@; then $(MAKE) $(AM_MAKEFLAGS) stamp-h1; else :; fi
 
 stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
        @rm -f stamp-h1
@@ -519,13 +573,10 @@ distdir: $(DISTFILES)
        done
        @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
          if test "$$subdir" = .; then :; else \
-           test -d "$(distdir)/$$subdir" \
-           || $(MKDIR_P) "$(distdir)/$$subdir" \
-           || exit 1; \
-         fi; \
-       done
-       @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
-         if test "$$subdir" = .; then :; else \
+           $(am__make_dryrun) \
+             || test -d "$(distdir)/$$subdir" \
+             || $(MKDIR_P) "$(distdir)/$$subdir" \
+             || exit 1; \
            dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
            $(am__relativize); \
            new_distdir=$$reldir; \
@@ -559,7 +610,11 @@ dist-gzip: distdir
        tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
        $(am__remove_distdir)
 dist-bzip2: distdir
-       tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+       tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
+       $(am__remove_distdir)
+
+dist-lzip: distdir
+       tardir=$(distdir) && $(am__tar) | lzip -c $${LZIP_OPT--9} >$(distdir).tar.lz
        $(am__remove_distdir)
 
 dist-lzma: distdir
@@ -567,7 +622,7 @@ dist-lzma: distdir
        $(am__remove_distdir)
 
 dist-xz: distdir
-       tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
+       tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
        $(am__remove_distdir)
 
 dist-tarZ: distdir
@@ -585,7 +640,7 @@ dist-zip: distdir
 
 dist dist-all: distdir
        tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
-       tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
+       tardir=$(distdir) && $(am__tar) | BZIP2=$${BZIP2--9} bzip2 -c >$(distdir).tar.bz2
        $(am__remove_distdir)
 
 # This target untars the dist file and tries a VPATH configuration.  Then
@@ -599,6 +654,8 @@ distcheck: dist
          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*) \
          xz -dc $(distdir).tar.xz | $(am__untar) ;;\
        *.tar.Z*) \
@@ -608,7 +665,7 @@ distcheck: dist
        *.zip*) \
          unzip $(distdir).zip ;;\
        esac
-       chmod -R a-w $(distdir); chmod a+w $(distdir)
+       chmod -R a-w $(distdir); chmod u+w $(distdir)
        mkdir $(distdir)/_build
        mkdir $(distdir)/_inst
        chmod a-w $(distdir)
@@ -618,6 +675,7 @@ distcheck: dist
          && am__cwd=`pwd` \
          && $(am__cd) $(distdir)/_build \
          && ../configure --srcdir=.. --prefix="$$dc_install_base" \
+           $(AM_DISTCHECK_CONFIGURE_FLAGS) \
            $(DISTCHECK_CONFIGURE_FLAGS) \
          && $(MAKE) $(AM_MAKEFLAGS) \
          && $(MAKE) $(AM_MAKEFLAGS) dvi \
@@ -646,8 +704,16 @@ distcheck: dist
          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'
 distuninstallcheck:
-       @$(am__cd) '$(distuninstallcheck_dir)' \
-       && test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
+       @test -n '$(distuninstallcheck_dir)' || { \
+         echo 'ERROR: trying to run $@ with an empty' \
+              '$$(distuninstallcheck_dir)' >&2; \
+         exit 1; \
+       }; \
+       $(am__cd) '$(distuninstallcheck_dir)' || { \
+         echo 'ERROR: cannot chdir into $(distuninstallcheck_dir)' >&2; \
+         exit 1; \
+       }; \
+       test `$(am__distuninstallcheck_listfiles) | wc -l` -eq 0 \
           || { echo "ERROR: files left after uninstall:" ; \
                if test -n "$(DESTDIR)"; then \
                  echo "  (check DESTDIR support)"; \
@@ -678,10 +744,15 @@ install-am: all-am
 
 installcheck: installcheck-recursive
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-         `test -z '$(STRIP)' || \
-           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+       if test -z '$(STRIP)'; then \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+             install; \
+       else \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+           "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+       fi
 mostlyclean-generic:
 
 clean-generic:
@@ -770,24 +841,25 @@ uninstall-am:
 .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-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
+       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
 
 
 # Add all the files listed in "distfiles" files to the distribution,
 # apply version number s to some files and create a VERSION file which
 # we need for the Prereq: patch file trick.
-dist-hook:
+dist-hook: gen-ChangeLog
        @set -e; \
         for file in `cd $(top_srcdir); \
              find mpi -type f -name distfiles`; do \
@@ -799,6 +871,17 @@ dist-hook:
        done
        @set -e; \
        echo "$(VERSION)" > $(distdir)/VERSION
+.PHONY: gen-ChangeLog
+gen-ChangeLog:
+       if test -d $(top_srcdir)/.git; then                             \
+         (cd $(top_srcdir) &&                                          \
+           $(GITLOG_TO_CHANGELOG) --append-dot --tear-off              \
+           --amend=build-aux/git-log-fix                               \
+           --since=$(gen_start_date) ) > $(distdir)/cl-t;              \
+          cat $(top_srcdir)/build-aux/git-log-footer >> $(distdir)/cl-t;\
+         rm -f $(distdir)/ChangeLog;                                   \
+         mv $(distdir)/cl-t $(distdir)/ChangeLog;                      \
+       fi
 
 stowinstall:
        $(MAKE) $(AM_MAKEFLAGS) install prefix=/usr/local/stow/libgcrypt
diff --git a/NEWS b/NEWS
index 32fb6de..074e9f2 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,169 @@
+Noteworthy changes in version 1.6.1 (2014-01-29)
+------------------------------------------------
+
+ * Added emulation for broken Whirlpool code prior to 1.6.0.
+
+ * Improved performance of KDF functions.
+
+ * Improved ECDSA compliance.
+
+ * Fixed locking for Windows and non-ELF Pthread systems (regression
+   in 1.6.0)
+
+ * 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).
+
+
+Noteworthy changes in version 1.6.0 (2013-12-16)
+------------------------------------------------
+
+ * Removed the long deprecated gcry_ac interface.  Thus Libgcrypt is
+   not anymore ABI compatible to previous versions if they used the ac
+   interface.
+
+ * Removed the module register subsystem.
+
+ * The deprecated message digest debug macros have been removed.  Use
+   gcry_md_debug instead.
+
+ * Removed deprecated control codes.
+
+ * Improved performance of most cipher algorithms as well as for the
+   SHA family of hash functions.
+
+ * Added support for the IDEA cipher algorithm.
+
+ * Added support for the Salsa20 and reduced Salsa20/12 stream ciphers.
+
+ * Added limited support for the GOST 28147-89 cipher algorithm.
+
+ * Added support for the GOST R 34.11-94 and R 34.11-2012 (Stribog)
+   hash algorithms.
+
+ * Added a random number generator to directly use the system's RNG.
+   Also added an interface to prefer the use of a specified RNG.
+
+ * Added support for the SCRYPT algorithm.
+
+ * 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 curve Ed25519.
+
+ * Added a scatter gather hash convenience function.
+
+ * Added several MPI amd SEXP helper functions.
+
+ * Added support for negative numbers to gcry_mpi_print,
+   gcry_mpi_aprint and gcry_mpi_scan.
+
+ * The algorithm ids GCRY_PK_ECDSA and GCRY_PK_ECDH are now
+   deprecated.  Use GCRY_PK_ECC if you need an algorithm id.
+
+ * Changed gcry_pk_genkey for "ecc" to only include the curve name and
+   not the parameters.  The flag "param" may be used to revert this.
+
+ * Added a feature to globally disable selected hardware features.
+
+ * Added debug helper functions.
+
+ * Interface changes relative to the 1.5.0 release:
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ gcry_ac_*                      REMOVED.
+ GCRY_AC_*                      REMOVED.
+ gcry_module_t                  REMOVED.
+ gcry_cipher_register           REMOVED.
+ gcry_cipher_unregister         REMOVED.
+ gcry_cipher_list               REMOVED.
+ gcry_pk_register               REMOVED.
+ gcry_pk_unregister             REMOVED.
+ gcry_pk_list                   REMOVED.
+ gcry_md_register               REMOVED.
+ gcry_md_unregister             REMOVED.
+ gcry_md_list                   REMOVED.
+ gcry_md_start_debug            REMOVED (macro).
+ gcry_md_stop_debug             REMOVED (macro).
+ GCRYCTL_SET_KEY                 REMOVED.
+ GCRYCTL_SET_IV                  REMOVED.
+ GCRYCTL_SET_CTR                 REMOVED.
+ GCRYCTL_DISABLE_ALGO            CHANGED: Not anymore thread-safe.
+ gcry_pk_genkey                  CHANGED: ECC curve params not returned.
+ gcry_md_hash_buffers            NEW.
+ gcry_buffer_t                   NEW.
+ GCRYCTL_SET_ENFORCED_FIPS_FLAG  NEW.
+ GCRYCTL_SET_PREFERRED_RNG_TYPE  NEW.
+ GCRYCTL_GET_CURRENT_RNG_TYPE    NEW.
+ GCRYCTL_CLOSE_RANDOM_DEVICE     NEW.
+ GCRY_RNG_TYPE_STANDARD          NEW.
+ GCRY_RNG_TYPE_FIPS              NEW.
+ GCRY_RNG_TYPE_SYSTEM            NEW.
+ gcry_mpi_is_neg                 NEW.
+ gcry_mpi_neg                    NEW.
+ gcry_mpi_abs                    NEW.
+ gcry_mpi_snatch                 NEW.
+ gcry_mpi_set_opaque_copy        NEW.
+ gcry_mpi_point_t                NEW.
+ gcry_mpi_point_new              NEW.
+ gcry_mpi_point_release          NEW.
+ gcry_mpi_point_get              NEW.
+ gcry_mpi_point_snatch_get       NEW.
+ gcry_mpi_point_set              NEW.
+ gcry_mpi_point_snatch_set       NEW.
+ gcry_ctx_t                      NEW.
+ gcry_ctx_release                NEW.
+ gcry_mpi_ec_new                 NEW.
+ gcry_mpi_ec_get_mpi             NEW.
+ gcry_mpi_ec_get_point           NEW.
+ gcry_mpi_ec_set_mpi             NEW.
+ gcry_mpi_ec_set_point           NEW.
+ gcry_mpi_ec_get_affine          NEW.
+ gcry_mpi_ec_dup                 NEW.
+ gcry_mpi_ec_add                 NEW.
+ gcry_mpi_ec_mul                 NEW.
+ gcry_mpi_ec_curve_point         NEW.
+ GCRYMPI_FLAG_IMMUTABLE          NEW.
+ GCRYMPI_FLAG_CONST              NEW.
+ GCRYMPI_FLAG_USER1              NEW.
+ GCRYMPI_FLAG_USER2              NEW.
+ GCRYMPI_FLAG_USER3              NEW.
+ GCRYMPI_FLAG_USER4              NEW.
+ GCRYMPI_CONST_ONE               NEW.
+ GCRYMPI_CONST_TWO               NEW.
+ GCRYMPI_CONST_THREE             NEW.
+ GCRYMPI_CONST_FOUR              NEW.
+ GCRYMPI_CONST_EIGHT             NEW.
+ GCRYMPI_FMT_OPAQUE              NEW.
+ GCRYPT_VERSION_NUMBER           NEW.
+ GCRY_KDF_SCRYPT                 NEW.
+ gcry_pubkey_get_sexp            NEW.
+ GCRYCTL_DISABLE_LOCKED_SECMEM   NEW.
+ GCRYCTL_DISABLE_PRIV_DROP       NEW.
+ GCRY_CIPHER_SALSA20             NEW.
+ gcry_sexp_nth_buffer            NEW.
+ gcry_sexp_extract_param         NEW.
+ GCRY_CIPHER_SALSA20R12          NEW.
+ GCRY_CIPHER_GOST28147           NEW.
+ GCRY_MD_GOSTR3411_94            NEW.
+ GCRY_MD_STRIBOG256              NEW.
+ GCRY_MD_STRIBOG512              NEW.
+ GCRY_PK_ECC                     NEW.
+ gcry_log_debug                  NEW.
+ gcry_log_debughex               NEW.
+ gcry_log_debugmpi               NEW.
+ gcry_log_debugpnt               NEW.
+
+
 Noteworthy changes in version 1.5.0 (2011-06-29)
 ------------------------------------------------
 
@@ -665,6 +831,7 @@ Noteworthy changes in version 1.1.3 (2001-05-31)
 
 Copyright 2001, 2002, 2003, 2004, 2007, 2008,
           2009, 2011 Free Software Foundation, Inc.
+Copyright 2013 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
diff --git a/README b/README
index a3abfa1..25ed18a 100644 (file)
--- a/README
+++ b/README
@@ -1,18 +1,14 @@
                    Libgcrypt - The GNU Crypto Library
                   ------------------------------------
-                             Version 1.5
+                             Version 1.6
 
-    Copyright 2000, 2002, 2003, 2004, 2007, 2008, 2009,
-              2011 Free Software Foundation, Inc.
-
-    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.
+       Copyright (C) 1989,1991-2012 Free Software Foundation, Inc.
+       Copyright (C) 2012-2014 g10 Code GmbH
+       Copyright (C) 2013-2014 Jussi Kivilinna
 
+    Libgcrypt is free software.  See the file AUTHORS for full copying
+    notices, and LICENSES for notices about contributions that require
+    these additional notices to be distributed.
 
 
     Overview
@@ -39,7 +35,7 @@
     You should get the latest versions of course.
 
     After building and installing the libgpg-error package, you may
-    continue with Libgcrypt installation As with allmost all GNU
+    continue with Libgcrypt installation as with allmost all GNU
     packages, you just have to do
 
        ./configure
     Here is a list of configure options which are sometimes useful
     for installation.
 
+     --enable-large-data-tests
+                     With this option a "make check" will take really
+                     long due to extra checks for the hash algorithms.
+
      --enable-m-guard
                      Enable the integrated malloc checking code. Please
                      note that this feature does not work on all CPUs
     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.
+    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
     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 .
+
 
   This file is Free Software; as a special exception the authors gives
   unlimited permission to copy and/or distribute it, with or without
similarity index 82%
rename from README.SVN
rename to README.GIT
index ae17923..ee2c638 100644 (file)
@@ -1,9 +1,11 @@
-If you are building from CVS, run the script
+If you are building from GIT, run the script
 
 ./autogen.sh
 
 first, to make sure that you have all the necessary maintainer tools
-are installed and to build the actual configuration files.  Then run
+are installed and to build the actual configuration files.  If you
+have just checked out from GIT, you should add the option "--force" to
+autogen.sh so that meta data is noticed by autom4te.cache.  Then run
 
 ./configure --enable-maintainer-mode
 
@@ -14,7 +16,7 @@ tools, or the tools are not installed, you may use environment
 variables to override the default tool names:
 
  AUTOMAKE_SUFFIX  is used as a suffix for all tools from the automake
-                  package.  For example 
+                  package.  For example
                      AUTOMAKE_SUFFIX="-1.7" ./autogen.sh
                   uses "automake-1.7" and "aclocal-1.7.
  AUTOMAKE_PREFIX  is used as a prefix for all tools from the automake
@@ -35,17 +37,13 @@ It is also possible to use the variable name AUTOMAKE, AUTOCONF,
 ACLOCAL, AUTOHEADER, GETTEXT and MSGMERGE to directly specify the name
 of the programs to run.  It is however better to use the suffix and
 prefix forms as described above because that does not require
-knowledge about the actual tools used by autgen.sh.
+knowledge about the actual tools used by autogen.sh.
 
 
 Please don't use autopoint, libtoolize or autoreconf unless you are
 the current maintainer and want to update the standard configuration
-files.  All those files should be in the CVS and only updated manually
+files.  All those files should be in GIT and only updated manually
 if the maintainer decides that newer versions are required.  The
 maintainer should also make sure that the required version of automake
 et al. are properly indicated at the top of configure.ac and take care
 to copy the files and not merely use symlinks.
-
-
-
-
diff --git a/THANKS b/THANKS
index 41f4c77..6a44ead 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -130,10 +130,12 @@ Stephan Müller             smueller at atsec com
 Stephane Corthesy          stephane@sente.ch
 Stefan Karrmann           S.Karrmann@gmx.net
 Stefan Keller             dres@cs.tu-berlin.de
+Stefan Krüger              stadtkind2 at gmx de
 Steffen Ullrich           ccrlphr@xensei.com
 Steffen Zahn              zahn@berlin.snafu.de
 Steven Bakker             steven@icoe.att.com
 Susanne Schultz           schultz@hsp.de
+Sven Bjorn
 Szakats Istvan             szaki.ms@gmail.com
 Thiago Jung Bauermann     jungmann@cwb.matrix.com.br
 Thomas Roessler           roessler@guug.de
diff --git a/VERSION b/VERSION
index bc80560..9c6d629 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.5.0
+1.6.1
index e69291a..fdb2d17 100644 (file)
@@ -1,6 +1,7 @@
 dnl macros to configure Libgcrypt
 dnl Copyright (C) 1998, 1999, 2000, 2001, 2002,
 dnl               2003 Free Software Foundation, Inc.
+dnl Copyright (C) 2013 g10 Code GmbH
 dnl
 dnl This file is part of Libgcrypt.
 dnl
@@ -18,13 +19,43 @@ dnl You should have received a copy of the GNU Lesser General Public
 dnl License along with this program; if not, write to the Free Software
 dnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
-dnl GNUPG_MSG_PRINT(STRING)
-dnl print a message
+dnl GCRY_MSG_SHOW(PREFIX,STRING)
+dnl Print a message with a prefix.
 dnl
-define([GNUPG_MSG_PRINT],
-  [ echo $ac_n "$1"" $ac_c" 1>&AS_MESSAGE_FD([])
+define([GCRY_MSG_SHOW],
+  [
+     echo "        $1 $2" 1>&AS_MESSAGE_FD([])
+  ])
+
+dnl GCRY_MSG_WRAP(PREFIX, ALGOLIST)
+dnl Print a nicely formatted list of algorithms
+dnl with an approriate line wrap.
+dnl
+define([GCRY_MSG_WRAP],
+  [
+    tmp="        $1"
+    tmpi="abc"
+    if test "${#tmpi}" -ne 3 >/dev/null 2>&1 ; then
+      dnl Without a POSIX shell, we don't botter to wrap it
+      echo "$tmp $2" 1>&AS_MESSAGE_FD([])
+    else
+      tmpi=`echo "$tmp"| sed 's/./ /g'`
+      echo $2 EOF | tr ' ' '\n' | \
+        while read word; do
+          if test "${#tmp}" -gt 70 ; then
+            echo "$tmp" 1>&AS_MESSAGE_FD([])
+            tmp="$tmpi"
+          fi
+          if test "$word" = "EOF" ; then
+            echo "$tmp" 1>&AS_MESSAGE_FD([])
+          else
+            tmp="$tmp $word"
+          fi
+        done
+    fi
   ])
 
+
 dnl GNUPG_CHECK_TYPEDEF(TYPE, HAVE_NAME)
 dnl Check whether a typedef exists and create a #define $2 if it exists
 dnl
index e409c1f..1ef2244 100644 (file)
@@ -1,7 +1,8 @@
-# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.11.6 -*- Autoconf -*-
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2007, 2008, 2009  Free Software Foundation, Inc.
+# 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.
 
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.64],,
-[m4_warning([this file was generated for autoconf 2.64.
+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'.])])
 
-# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008  Free Software Foundation, Inc.
+# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008, 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_AUTOMAKE_VERSION(VERSION)
 # ----------------------------
 # Automake X.Y traces this macro to ensure aclocal.m4 has been
@@ -34,7 +38,7 @@ AC_DEFUN([AM_AUTOMAKE_VERSION],
 [am__api_version='1.11'
 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.1], [],
+m4_if([$1], [1.11.6], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -50,7 +54,7 @@ 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.1])dnl
+[AM_AUTOMAKE_VERSION([1.11.6])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
@@ -79,12 +83,14 @@ _AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+# Copyright (C) 2001, 2003, 2005, 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
+
 # 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/../..'.
@@ -166,14 +172,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
-# Free Software Foundation, Inc.
+# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 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.
 
-# serial 10
+# serial 12
 
 # 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,
@@ -213,6 +219,7 @@ AC_CACHE_CHECK([dependency style of $depcc],
   # 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'.
+  rm -rf conftest.dir
   mkdir conftest.dir
   # Copy depcomp to subdir because otherwise we won't find it if we're
   # using a relative directory.
@@ -277,7 +284,7 @@ AC_CACHE_CHECK([dependency style of $depcc],
        break
       fi
       ;;
-    msvisualcpp | msvcmsys)
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
       # 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.
@@ -342,10 +349,13 @@ AC_DEFUN([AM_DEP_TRACK],
 if test "x$enable_dependency_tracking" != xno; then
   am_depcomp="$ac_aux_dir/depcomp"
   AMDEPBACKSLASH='\'
+  am__nodep='_no'
 fi
 AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
 AC_SUBST([AMDEPBACKSLASH])dnl
 _AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
+AC_SUBST([am__nodep])dnl
+_AM_SUBST_NOTMAKE([am__nodep])dnl
 ])
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
@@ -428,18 +438,6 @@ AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
      [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
 ])
 
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005
-# 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 8
-
-# AM_CONFIG_HEADER is obsolete.  It has been replaced by AC_CONFIG_HEADERS.
-AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
-
 # Do all the work for Automake.                             -*- Autoconf -*-
 
 # Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
@@ -579,12 +577,15 @@ 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  Free Software Foundation, Inc.
+# Copyright (C) 2001, 2003, 2005, 2008, 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_INSTALL_SH
 # ------------------
 # Define $install_sh.
@@ -624,8 +625,8 @@ 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
-# Free Software Foundation, Inc.
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008,
+# 2011 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -645,7 +646,7 @@ AC_DEFUN([AM_MAINTAINER_MODE],
        [disable], [m4_define([am_maintainer_other], [enable])],
        [m4_define([am_maintainer_other], [enable])
         m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
-AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
+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
@@ -791,12 +792,15 @@ else
 fi
 ])
 
-# Copyright (C) 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
+# 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'.
@@ -819,13 +823,14 @@ esac
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001, 2002, 2003, 2005, 2008  Free Software Foundation, Inc.
+# Copyright (C) 2001, 2002, 2003, 2005, 2008, 2010 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
+# serial 5
 
 # _AM_MANGLE_OPTION(NAME)
 # -----------------------
@@ -833,13 +838,13 @@ AC_DEFUN([_AM_MANGLE_OPTION],
 [[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
 
 # _AM_SET_OPTION(NAME)
-# ------------------------------
+# --------------------
 # 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)])
 
 # _AM_SET_OPTIONS(OPTIONS)
-# ----------------------------------
+# ------------------------
 # OPTIONS is a space-separated list of Automake options.
 AC_DEFUN([_AM_SET_OPTIONS],
 [m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
@@ -915,12 +920,71 @@ Check your system clock])
 fi
 AC_MSG_RESULT(yes)])
 
-# Copyright (C) 2001, 2003, 2005  Free Software Foundation, Inc.
+# Copyright (C) 2009, 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 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).
+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]);;
+esac
+dnl
+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}
+AC_CACHE_CHECK([whether $am_make supports nested variables],
+   [am_cv_make_support_nested_variables],
+   [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])
+if test $am_cv_make_support_nested_variables = yes; then
+  dnl Using `$V' instead of `$(V)' breaks IRIX make.
+  AM_V='$(V)'
+  AM_DEFAULT_V='$(AM_DEFAULT_VERBOSITY)'
+else
+  AM_V=$AM_DEFAULT_VERBOSITY
+  AM_DEFAULT_V=$AM_DEFAULT_VERBOSITY
+fi
+AC_SUBST([AM_V])dnl
+AM_SUBST_NOTMAKE([AM_V])dnl
+AC_SUBST([AM_DEFAULT_V])dnl
+AM_SUBST_NOTMAKE([AM_DEFAULT_V])dnl
+AC_SUBST([AM_DEFAULT_VERBOSITY])dnl
+AM_BACKSLASH='\'
+AC_SUBST([AM_BACKSLASH])dnl
+_AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
+])
+
+# Copyright (C) 2001, 2003, 2005, 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_INSTALL_STRIP
 # ---------------------
 # One issue with vendor `install' (even GNU) is that you can't
@@ -943,13 +1007,13 @@ fi
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006, 2008  Free Software Foundation, Inc.
+# Copyright (C) 2006, 2008, 2010 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
+# serial 3
 
 # _AM_SUBST_NOTMAKE(VARIABLE)
 # ---------------------------
@@ -958,13 +1022,13 @@ AC_SUBST([INSTALL_STRIP_PROGRAM])])
 AC_DEFUN([_AM_SUBST_NOTMAKE])
 
 # AM_SUBST_NOTMAKE(VARIABLE)
-# ---------------------------
+# --------------------------
 # Public sister of _AM_SUBST_NOTMAKE.
 AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004, 2005  Free Software Foundation, Inc.
+# Copyright (C) 2004, 2005, 2012 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -986,10 +1050,11 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
 # a tarball read from stdin.
 #     $(am__untar) < result.tar
 AC_DEFUN([_AM_PROG_TAR],
-[# Always define AMTAR for backward compatibility.
-AM_MISSING_PROG([AMTAR], [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='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
+     [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])
@@ -1060,6 +1125,7 @@ AC_SUBST([am__untar])
 
 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])
@@ -1068,4 +1134,5 @@ 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])
diff --git a/autogen.rc b/autogen.rc
new file mode 100644 (file)
index 0000000..09a9b9c
--- /dev/null
@@ -0,0 +1,17 @@
+# autogen.sh configuration for Libgcrypt                       -*- sh -*-
+
+case "$myhost" in
+  w32)
+    configure_opts="
+      --with-gpg-error-prefix=@SYSROOT@
+      "
+    ;;
+
+  amd64)
+    configure_opts="
+      --with-gpg-error-prefix=@SYSROOT@
+     "
+    ;;
+esac
+
+final_info="./configure --enable-maintainer-mode && make"
index d9a6586..471193c 100755 (executable)
@@ -1,7 +1,6 @@
 #! /bin/sh
-# Run this to generate all the initial makefiles, etc.
-#
-# Copyright (C) 2003 g10 Code GmbH
+# autogen.sh
+# Copyright (C) 2003, 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
@@ -10,6 +9,13 @@
 # This program 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.
+#
+# This is a generic script to create the configure script and handle cross
+# build environments.  It requires the presence of a autogen.rc file to
+# configure it for the respective package.  It is maintained as part of
+# GnuPG and source copied by other packages.
+#
+# Version: 2014-01-10
 
 configure_ac="configure.ac"
 
@@ -18,7 +24,7 @@ cvtver () {
 }
 
 check_version () {
-    if [ `("$1" --version || echo "0") | cvtver` -ge "$2" ]; then
+    if [ $(( `("$1" --version || echo "0") | cvtver` >= $2 )) = 1 ]; then
        return 0
     fi
     echo "**Error**: "\`$1\'" not installed or too old." >&2
@@ -28,79 +34,176 @@ check_version () {
     return 1
 }
 
+fatal () {
+    echo "autogen.sh:" "$*" >&2
+    DIE=yes
+}
+
+info () {
+    if [ -z "${SILENT}" ]; then
+      echo "autogen.sh:" "$*"
+    fi
+}
+
+die_p () {
+  if [ "$DIE" = "yes" ]; then
+    echo "autogen.sh: Stop." >&2
+    exit 1
+  fi
+}
+
+replace_sysroot () {
+    configure_opts=$(echo $configure_opts | sed "s#@SYSROOT@#${w32root}#g")
+    extraoptions=$(echo $extraoptions | sed "s#@SYSROOT@#${w32root}#g")
+}
+
+# Allow to override the default tool names
+AUTOCONF=${AUTOCONF_PREFIX}${AUTOCONF:-autoconf}${AUTOCONF_SUFFIX}
+AUTOHEADER=${AUTOCONF_PREFIX}${AUTOHEADER:-autoheader}${AUTOCONF_SUFFIX}
+
+AUTOMAKE=${AUTOMAKE_PREFIX}${AUTOMAKE:-automake}${AUTOMAKE_SUFFIX}
+ACLOCAL=${AUTOMAKE_PREFIX}${ACLOCAL:-aclocal}${AUTOMAKE_SUFFIX}
+
+GETTEXT=${GETTEXT_PREFIX}${GETTEXT:-gettext}${GETTEXT_SUFFIX}
+MSGMERGE=${GETTEXT_PREFIX}${MSGMERGE:-msgmerge}${GETTEXT_SUFFIX}
 
 DIE=no
 FORCE=
+SILENT=
+tmp=$(dirname "$0")
+tsdir=$(cd "${tmp}"; pwd)
+
+if [ -n "${AUTOGEN_SH_SILENT}" ]; then
+  SILENT=" --silent"
+fi
+if test x"$1" = x"--help"; then
+  echo "usage: ./autogen.sh [--silent] [--force] [--build-TYPE] [ARGS]"
+  exit 0
+fi
+if test x"$1" = x"--silent"; then
+  SILENT=" --silent"
+  shift
+fi
 if test x"$1" = x"--force"; then
   FORCE=" --force"
   shift
 fi
 
-# Begin list of optional variables sourced from ~/.gnupg-autogen.rc
+
+# Reject unsafe characters in $HOME, $tsdir and cwd.  We consider spaces
+# as unsafe because it is too easy to get scripts wrong in this regard.
+am_lf='
+'
+case `pwd` in
+  *[\;\\\"\#\$\&\'\`$am_lf\ \  ]*)
+    fatal "unsafe working directory name" ;;
+esac
+case $tsdir in
+  *[\;\\\"\#\$\&\'\`$am_lf\ \  ]*)
+    fatal "unsafe source directory: \`$tsdir'" ;;
+esac
+case $HOME in
+  *[\;\\\"\#\$\&\'\`$am_lf\ \  ]*)
+    fatal "unsafe home directory: \`$HOME'" ;;
+esac
+die_p
+
+
+# List of variables sourced from autogen.rc.  The strings '@SYSROOT@' in
+# these variables are replaced by the actual system root.
+configure_opts=
+extraoptions=
+# List of optional variables sourced from autogen.rc and ~/.gnupg-autogen.rc
 w32_toolprefixes=
 w32_extraoptions=
 w32ce_toolprefixes=
 w32ce_extraoptions=
+w64_toolprefixes=
+w64_extraoptions=
 amd64_toolprefixes=
 # End list of optional variables sourced from ~/.gnupg-autogen.rc
 # What follows are variables which are sourced but default to
 # environment variables or lacking them hardcoded values.
 #w32root=
 #w32ce_root=
+#w64root=
 #amd64root=
 
-if [ -f "$HOME/.gnupg-autogen.rc" ]; then
-    echo "sourcing extra definitions from $HOME/.gnupg-autogen.rc"
-    . "$HOME/.gnupg-autogen.rc"
-fi
-
 # Convenience option to use certain configure options for some hosts.
 myhost=""
 myhostsub=""
 case "$1" in
     --build-w32)
         myhost="w32"
+        shift
         ;;
     --build-w32ce)
         myhost="w32"
         myhostsub="ce"
+        shift
+        ;;
+    --build-w64)
+        myhost="w32"
+        myhostsub="64"
+        shift
         ;;
     --build-amd64)
         myhost="amd64"
+        shift
         ;;
     --build*)
-        echo "**Error**: invalid build option $1" >&2
-        exit 1
+        fatal "**Error**: invalid build option $1"
+        shift
         ;;
-     *)
+    *)
         ;;
 esac
+die_p
 
 
-# ***** W32 build script *******
-# Used to cross-compile for Windows.
+# Source our configuration
+if [ -f "${tsdir}/autogen.rc" ]; then
+    . "${tsdir}/autogen.rc"
+fi
+
+# Source optional site specific configuration
+if [ -f "$HOME/.gnupg-autogen.rc" ]; then
+    info "sourcing extra definitions from $HOME/.gnupg-autogen.rc"
+    . "$HOME/.gnupg-autogen.rc"
+fi
+
+# ******************
+#  W32 build script
+# ******************
 if [ "$myhost" = "w32" ]; then
-    tmp=`dirname $0`
-    tsdir=`cd "$tmp"; pwd`
-    shift
-    if [ ! -f $tsdir/config.guess ]; then
-        echo "$tsdir/config.guess not found" >&2
+    if [ ! -f "$tsdir/build-aux/config.guess" ]; then
+        fatal "$tsdir/build-aux/config.guess not found"
         exit 1
     fi
-    build=`$tsdir/config.guess`
+    build=`$tsdir/build-aux/config.guess`
 
     case $myhostsub in
         ce)
           w32root="$w32ce_root"
           [ -z "$w32root" ] && w32root="$HOME/w32ce_root"
-          toolprefixes="arm-mingw32ce"
+          toolprefixes="$w32ce_toolprefixes arm-mingw32ce"
+          extraoptions="$extraoptions $w32ce_extraoptions"
+          ;;
+        64)
+          w32root="$w64root"
+          [ -z "$w32root" ] && w32root="$HOME/w64root"
+          toolprefixes="$w64_toolprefixes x86_64-w64-mingw32"
+          extraoptions="$extraoptions $w64_extraoptions"
           ;;
         *)
           [ -z "$w32root" ] && w32root="$HOME/w32root"
-          toolprefixes="i586-mingw32msvc i386-mingw32msvc"
+          toolprefixes="$w32_toolprefixes i686-w64-mingw32 i586-mingw32msvc"
+          toolprefixes="$toolprefixes i386-mingw32msvc mingw32"
+          extraoptions="$extraoptions $w32_extraoptions"
           ;;
     esac
-    echo "Using $w32root as standard install directory" >&2
+    info "Using $w32root as standard install directory"
+    replace_sysroot
 
     # Locate the cross compiler
     crossbindir=
@@ -112,48 +215,49 @@ if [ "$myhost" = "w32" ]; then
         fi
     done
     if [ -z "$crossbindir" ]; then
-        echo "Cross compiler kit not installed" >&2
-        if [ -z "$sub" ]; then
-          echo "Under Debian GNU/Linux, you may install it using" >&2
-          echo "  apt-get install mingw32 mingw32-runtime mingw32-binutils" >&2
+        fatal "cross compiler kit not installed"
+        if [ -z "$myhostsub" ]; then
+          info "Under Debian GNU/Linux, you may install it using"
+          info "  apt-get install mingw32 mingw32-runtime mingw32-binutils"
         fi
-        echo "Stop." >&2
-        exit 1
+        die_p
     fi
 
     if [ -f "$tsdir/config.log" ]; then
         if ! head $tsdir/config.log | grep "$host" >/dev/null; then
-            echo "Pease run a 'make distclean' first" >&2
-            exit 1
+            fatal "Please run a 'make distclean' first"
+            die_p
         fi
     fi
 
-    $tsdir/configure --enable-maintainer-mode  --prefix=${w32root}  \
-            --host=${host} --build=${build} \
-            --with-gpg-error-prefix=${w32root}
-    exit $?
+    $tsdir/configure --enable-maintainer-mode ${SILENT} \
+             --prefix=${w32root}  \
+             --host=${host} --build=${build} \
+             ${configure_opts} ${extraoptions} "$@"
+    rc=$?
+    exit $rc
 fi
 # ***** end W32 build script *******
 
-
 # ***** AMD64 cross build script *******
 # Used to cross-compile for AMD64 (for testing)
 if [ "$myhost" = "amd64" ]; then
-    tmp=`dirname $0`
-    tsdir=`cd "$tmp"; pwd`
     shift
-    if [ ! -f $tsdir/config.guess ]; then
-        echo "$tsdir/config.guess not found" >&2
+    if [ ! -f $tsdir/build-aux/config.guess ]; then
+        echo "$tsdir/build-aux/config.guess not found" >&2
         exit 1
     fi
-    build=`$tsdir/config.guess`
+    build=`$tsdir/build-aux/config.guess`
 
     [ -z "$amd64root" ] && amd64root="$HOME/amd64root"
-    echo "Using $amd64root as standard install directory" >&2
+    info "Using $amd64root as standard install directory"
+    replace_sysroot
+
+    toolprefixes="$amd64_toolprefixes x86_64-linux-gnu amd64-linux-gnu"
 
     # Locate the cross compiler
     crossbindir=
-    for host in x86_64-linux-gnu amd64-linux-gnu; do
+    for host in $toolprefixes ; do
         if ${host}-gcc --version >/dev/null 2>&1 ; then
             crossbindir=/usr/${host}/bin
             conf_CC="CC=${host}-gcc"
@@ -173,15 +277,16 @@ if [ "$myhost" = "amd64" ]; then
         fi
     fi
 
-    $tsdir/configure --enable-maintainer-mode --prefix=${amd64root}  \
+    $tsdir/configure --enable-maintainer-mode ${SILENT} \
+             --prefix=${amd64root}  \
              --host=${host} --build=${build} \
-             --with-gpg-error-prefix=${amd64root}
-
+             ${configure_opts} ${extraoptions} "$@"
     rc=$?
     exit $rc
 fi
 # ***** end AMD64 cross build script *******
 
+
 # Grep the required versions from configure.ac
 autoconf_vers=`sed -n '/^AC_PREREQ(/ {
 s/^.*(\(.*\))/\1/p
@@ -195,29 +300,22 @@ q
 }' ${configure_ac}`
 automake_vers_num=`echo "$automake_vers" | cvtver`
 
-#gettext_vers=`sed -n '/^AM_GNU_GETTEXT_VERSION(/ {
-#s/^.*(\(.*\))/\1/p
-#q
-#}' ${configure_ac}`
-#gettext_vers_num=`echo "$gettext_vers" | cvtver`
-
+if [ -d "${tsdir}/po" ]; then
+  gettext_vers=`sed -n '/^AM_GNU_GETTEXT_VERSION(/ {
+s/^.*\[\(.*\)])/\1/p
+q
+}' ${configure_ac}`
+  gettext_vers_num=`echo "$gettext_vers" | cvtver`
+else
+  gettext_vers="n/a"
+fi
 
-if [ -z "$autoconf_vers" -o -z "$automake_vers" ]
+if [ -z "$autoconf_vers" -o -z "$automake_vers" -o -z "$gettext_vers" ]
 then
   echo "**Error**: version information not found in "\`${configure_ac}\'"." >&2
   exit 1
 fi
 
-# Allow to override the default tool names
-AUTOCONF=${AUTOCONF_PREFIX}${AUTOCONF:-autoconf}${AUTOCONF_SUFFIX}
-AUTOHEADER=${AUTOCONF_PREFIX}${AUTOHEADER:-autoheader}${AUTOCONF_SUFFIX}
-
-AUTOMAKE=${AUTOMAKE_PREFIX}${AUTOMAKE:-automake}${AUTOMAKE_SUFFIX}
-ACLOCAL=${AUTOMAKE_PREFIX}${ACLOCAL:-aclocal}${AUTOMAKE_SUFFIX}
-
-#GETTEXT=${GETTEXT_PREFIX}${GETTEXT:-gettext}${GETTEXT_SUFFIX}
-#MSGMERGE=${GETTEXT_PREFIX}${MSGMERGE:-msgmerge}${GETTEXT_SUFFIX}
-
 
 if check_version $AUTOCONF $autoconf_vers_num $autoconf_vers ; then
     check_version $AUTOHEADER $autoconf_vers_num $autoconf_vers autoconf
@@ -225,45 +323,71 @@ fi
 if check_version $AUTOMAKE $automake_vers_num $automake_vers; then
   check_version $ACLOCAL $automake_vers_num $autoconf_vers automake
 fi
-#if check_version $GETTEXT $gettext_vers_num $gettext_vers; then
-#  check_version $MSGMERGE $gettext_vers_num $gettext_vers gettext
-#fi
+if [ "$gettext_vers" != "n/a" ]; then
+  if check_version $GETTEXT $gettext_vers_num $gettext_vers; then
+    check_version $MSGMERGE $gettext_vers_num $gettext_vers gettext
+  fi
+fi
 
-if test "$DIE" = "yes"; then
+if [ "$DIE" = "yes" ]; then
     cat <<EOF
 
 Note that you may use alternative versions of the tools by setting
-the corresponding environment variables; see README.SVN for details.
+the corresponding environment variables; see README.GIT for details.
 
 EOF
-    exit 1
+    die_p
 fi
 
 # Check the git setup.
 if [ -d .git ]; then
+  CP="cp -a"
+  [ -z "${SILENT}" ] && CP="$CP -v"
   if [ -f .git/hooks/pre-commit.sample -a ! -f .git/hooks/pre-commit ] ; then
-    cat <<EOF >&2
+    [ -z "${SILENT}" ] && cat <<EOF
 *** Activating trailing whitespace git pre-commit hook. ***
     For more information see this thread:
       http://mail.gnome.org/archives/desktop-devel-list/2009-May/msg00084html
     To deactivate this pre-commit hook again move .git/hooks/pre-commit
     and .git/hooks/pre-commit.sample out of the way.
 EOF
-      cp -av .git/hooks/pre-commit.sample .git/hooks/pre-commit
-      chmod -c +x  .git/hooks/pre-commit
+      $CP .git/hooks/pre-commit.sample .git/hooks/pre-commit
+      chmod +x  .git/hooks/pre-commit
   fi
-fi
 
+  if [ "$gettext_vers" != "n/a" ]; then
+    tmp=$(git config --get filter.cleanpo.clean)
+    if [ "$tmp" != \
+          "awk '/^\"POT-Creation-Date:/&&!s{s=1;next};!/^#: /{print}'" ]
+    then
+      info "*** Adding GIT filter.cleanpo.clean configuration."
+      git config --add filter.cleanpo.clean \
+        "awk '/^\"POT-Creation-Date:/&&!s{s=1;next};!/^#: /{print}'"
+    fi
+  fi
+  if [ -f build-aux/git-hooks/commit-msg -a ! -f .git/hooks/commit-msg ] ; then
+      [ -z "${SILENT}" ] && cat <<EOF
+*** Activating commit log message check hook. ***
+EOF
+      $CP build-aux/git-hooks/commit-msg .git/hooks/commit-msg
+      chmod +x  .git/hooks/commit-msg
+  fi
+fi
 
-echo "Running aclocal -I m4 ${ACLOCAL_FLAGS:+$ACLOCAL_FLAGS }..."
-$ACLOCAL -I m4 $ACLOCAL_FLAGS
-echo "Running autoheader..."
+aclocal_flags="-I m4"
+if [ -n "${extra_aclocal_flags}" ]; then
+  aclocal_flags="${aclocal_flags} ${extra_aclocal_flags}"
+fi
+if [ -n "${ACLOCAL_FLAGS}" ]; then
+  aclocal_flags="${aclocal_flags} ${ACLOCAL_FLAGS}"
+fi
+info "Running $ACLOCAL ${aclocal_flags} ..."
+$ACLOCAL ${aclocal_flags}
+info "Running autoheader..."
 $AUTOHEADER
-echo "Running automake --gnu ..."
+info "Running automake --gnu ..."
 $AUTOMAKE --gnu;
-echo "Running autoconf${FORCE} ..."
+info "Running autoconf${FORCE} ..."
 $AUTOCONF${FORCE}
 
-echo "You may now run:
-  ./configure --enable-maintainer-mode && make
-"
+info "You may now run:${am_lf}  ${final_info}"
diff --git a/build-aux/ChangeLog-2011 b/build-aux/ChangeLog-2011
new file mode 100644 (file)
index 0000000..85032cd
--- /dev/null
@@ -0,0 +1,169 @@
+2011-12-01  Werner Koch  <wk@g10code.com>
+
+       NB: ChangeLog files are no longer manually maintained.  Starting
+       on December 1st, 2011 we put change information only in the GIT
+       commit log, and generate a top-level ChangeLog file from logs at
+       "make dist".  See doc/HACKING for details.
+
+2003-12-08  Werner Koch  <wk@gnupg.org>
+
+       * autogen.sh, config.sub, install-sh, mkinstalldirs, config.guess,
+       * missing: Removed
+
+2003-10-31  Werner Koch  <wk@gnupg.org>
+
+       * autogen.sh: Allow to override the tool name.  Do not run
+       libtoolize. Update required version numbers.
+
+2003-07-30  Werner Koch  <wk@gnupg.org>
+
+       * config.guess, config.sub: Updated from ftp.gnu.org/gnu/config/
+
+2003-07-07  Moritz Schulte  <moritz@g10code.com>
+
+       * autogen.sh: Undo last change.
+       * autogen.sh: Remove -a argument for automake.
+
+2003-03-06  Moritz Schulte  <mo@g10code.com>
+
+       * autogen.sh (run): New function.
+       Let automake run with -a for adding missing files automatically
+
+2002-11-12  Werner Koch  <wk@gnupg.org>
+
+       * config.sub, config.guess: Updated from ftp.gnu.org/gnu/config
+       to version 2002-11-08.
+
+2002-05-14  Werner Koch  <wk@gnupg.org>
+
+       * autogen.sh: Require version 2.53 of autoconf
+
+2001-12-18  Werner Koch  <wk@gnupg.org>
+
+       * distfiles: Remove files which are automatically added by automake.
+
+2001-08-06  Werner Koch  <wk@gnupg.org>
+
+       * autogen.sh: Added --build-w32 option.
+
+2001-05-28  Werner Koch  <wk@gnupg.org>
+
+       * db2html.in: Removed.
+       * db2any: New.  Taken from GPH
+
+Mon Jul 17 16:35:47 CEST 2000  Werner Koch  <wk@>
+
+        * config.gues, config.sub: Support for s390-ibm-linux-gnu; thanks
+        to Holger Smolinski.  Add support for QNX; by Sam Roberts.
+
+Tue Oct 26 14:10:21 CEST 1999  Werner Koch  <wk@gnupg.de>
+
+       * commit: Remove leading and trailing empty lines when copying
+       Changes to Changelog
+
+Wed Sep 15 16:22:17 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * gnupg.spec: Add Portuguese description
+
+Thu Sep  2 16:40:55 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * mkdiff: changed format of diff file name and made script more
+       general.
+
+Wed Aug  4 10:34:18 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * config.guess: Updated from gnu/common and applied my emx patch again.
+       * config.sub: Updated from gnu/common.
+
+Wed Jul 14 19:42:08 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * ltmain.sh, ltconfig.sh : Updated to libtool 1.3.3
+
+Mon Jul 12 14:55:34 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * autogen.sh: Run libtoolize
+
+Sat May 22 22:47:26 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * autogen.sh: Fixed the error message for a missing libtool.
+
+Sat May  8 19:28:08 CEST 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * mkinstalldirs, install-sh: New from GNU repository
+       * config.sub, config.guess: Merged with rep version.
+
+Sun Mar 14 19:34:36 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * autogen.sh: Add a check for libtool because some autoconf macros
+       are needed.
+
+Mon Feb 22 20:04:00 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * autogen.sh: Enhanced the version testing code (Philippe Laliberte)
+
+       * mkwebpage: Edits the buglist.
+
+Sat Feb 13 12:04:43 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * autogen.sh: Now uses gettextize
+
+Wed Feb 10 17:15:39 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * config.sub, config.guess: Support i386-emx-os2
+
+Sun Jan 17 11:04:33 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * autogen.sh: Now checks for installed gettext
+
+Sat Jan 16 09:27:30 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * config.guess (m68k-atari-mint): New.
+       * config.sub: Add support for atarist-MiNT
+
+Wed Jan 13 12:49:36 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * gnupg.spec.in: New
+       * gnupg.spec: Removed
+
+Wed Dec 23 13:18:14 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * gnupg.spec: Updated version by Fabio Coatti
+
+Thu Dec 17 18:31:15 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
+
+       * gnupg.spec: New version by Reuben Sumner and did some more
+       changes.
+
+Fri Nov 27 12:39:29 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
+
+
+       * commit: New
+
+
+Fri Nov 20 12:01:57 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * mkdiff: signs the patch file
+
+Sat Oct 17 16:10:16 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * autogen.sh: New.
+
+Wed Oct 14 09:55:25 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * config.guess (FreeBSD): Changes from Jun Kuriyama to support ELF
+       * config.sub: (freebsd): Add to maybe_os
+
+
+  Copyright 1998,1999,2000,2001,2002 Free Software Foundation, Inc.
+
+ 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.
+
+Local Variables:
+buffer-read-only: t
+End:
similarity index 100%
rename from compile
rename to build-aux/compile
similarity index 90%
rename from config.guess
rename to build-aux/config.guess
index b02565c..9afd676 100755 (executable)
@@ -1,14 +1,12 @@
 #! /bin/sh
 # Attempt to guess a canonical system name.
-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-#   2011 Free Software Foundation, Inc.
+#   Copyright 1992-2013 Free Software Foundation, Inc.
 
-timestamp='2011-06-03'
+timestamp='2013-11-29'
 
 # 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
-# the Free Software Foundation; either version 2 of the License, or
+# the Free Software Foundation; either version 3 of the License, or
 # (at your option) any later version.
 #
 # This program is distributed in the hope that it will be useful, but
@@ -17,26 +15,22 @@ timestamp='2011-06-03'
 # 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
 # configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Originally written by Per Bothner.  Please send patches (context
-# diff format) to <config-patches@gnu.org> and include a ChangeLog
-# entry.
+# the same distribution terms that you use for the rest of that
+# program.  This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
 #
-# This script attempts to guess a canonical system name similar to
-# config.sub.  If it succeeds, it prints the system name on stdout, and
-# exits with 0.  Otherwise, it exits with 1.
+# Originally written by Per Bothner.
 #
 # 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.
+
 
 me=`echo "$0" | sed -e 's,.*/,,'`
 
@@ -56,9 +50,7 @@ version="\
 GNU config.guess ($timestamp)
 
 Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
-Software Foundation, Inc.
+Copyright 1992-2013 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."
@@ -140,12 +132,33 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
 UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
 UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
 
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+       # If the system lacks a compiler, then just pick glibc.
+       # We could probably try harder.
+       LIBC=gnu
+
+       eval $set_cc_for_build
+       cat <<-EOF > $dummy.c
+       #include <features.h>
+       #if defined(__UCLIBC__)
+       LIBC=uclibc
+       #elif defined(__dietlibc__)
+       LIBC=dietlibc
+       #else
+       LIBC=gnu
+       #endif
+       EOF
+       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
+       ;;
+esac
+
 # Note: order is significant - the case branches are not exclusive.
 
 case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     *:NetBSD:*:*)
        # NetBSD (nbsd) targets should (where applicable) match one or
-       # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+       # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
        # *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
        # switched to ELF, *-*-netbsd* would select the old
        # object file format.  This provides both forward
@@ -202,6 +215,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
        # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
        echo "${machine}-${os}${release}"
        exit ;;
+    *:Bitrig:*:*)
+       UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+       echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+       exit ;;
     *:OpenBSD:*:*)
        UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
        echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
@@ -304,7 +321,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
     arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
        echo arm-acorn-riscix${UNAME_RELEASE}
        exit ;;
-    arm:riscos:*:*|arm:RISCOS:*:*)
+    arm*:riscos:*:*|arm*:RISCOS:*:*)
        echo arm-unknown-riscos
        exit ;;
     SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
@@ -792,21 +809,26 @@ EOF
        echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
        exit ;;
     *:FreeBSD:*:*)
-       case ${UNAME_MACHINE} in
-           pc98)
-               echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+       UNAME_PROCESSOR=`/usr/bin/uname -p`
+       case ${UNAME_PROCESSOR} in
            amd64)
                echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
            *)
-               echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+               echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
        esac
        exit ;;
     i*:CYGWIN*:*)
        echo ${UNAME_MACHINE}-pc-cygwin
        exit ;;
+    *:MINGW64*:*)
+       echo ${UNAME_MACHINE}-pc-mingw64
+       exit ;;
     *:MINGW*:*)
        echo ${UNAME_MACHINE}-pc-mingw32
        exit ;;
+    i*:MSYS*:*)
+       echo ${UNAME_MACHINE}-pc-msys
+       exit ;;
     i*:windows32*:*)
        # uname -m includes "-pc" on this system.
        echo ${UNAME_MACHINE}-mingw32
@@ -852,15 +874,22 @@ EOF
        exit ;;
     *:GNU:*:*)
        # the GNU system
-       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+       echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
        exit ;;
     *:GNU/*:*:*)
        # other systems with GNU libc and userland
-       echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+       echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
        exit ;;
     i*86:Minix:*:*)
        echo ${UNAME_MACHINE}-pc-minix
        exit ;;
+    aarch64:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       exit ;;
+    aarch64_be:Linux:*:*)
+       UNAME_MACHINE=aarch64_be
+       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       exit ;;
     alpha:Linux:*:*)
        case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
          EV5)   UNAME_MACHINE=alphaev5 ;;
@@ -872,56 +901,54 @@ EOF
          EV68*) UNAME_MACHINE=alphaev68 ;;
        esac
        objdump --private-headers /bin/sh | grep -q ld.so.1
-       if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
-       echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+       if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       exit ;;
+    arc:Linux:*:* | arceb:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
        exit ;;
     arm*:Linux:*:*)
        eval $set_cc_for_build
        if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
            | grep -q __ARM_EABI__
        then
-           echo ${UNAME_MACHINE}-unknown-linux-gnu
+           echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
        else
            if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
                | grep -q __ARM_PCS_VFP
            then
-               echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+               echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
            else
-               echo ${UNAME_MACHINE}-unknown-linux-gnueabihf
+               echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
            fi
        fi
        exit ;;
     avr32*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
        exit ;;
     cris:Linux:*:*)
-       echo cris-axis-linux-gnu
+       echo ${UNAME_MACHINE}-axis-linux-${LIBC}
        exit ;;
     crisv32:Linux:*:*)
-       echo crisv32-axis-linux-gnu
+       echo ${UNAME_MACHINE}-axis-linux-${LIBC}
        exit ;;
     frv:Linux:*:*)
-       echo frv-unknown-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       exit ;;
+    hexagon:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
        exit ;;
     i*86:Linux:*:*)
-       LIBC=gnu
-       eval $set_cc_for_build
-       sed 's/^        //' << EOF >$dummy.c
-       #ifdef __dietlibc__
-       LIBC=dietlibc
-       #endif
-EOF
-       eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
-       echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
+       echo ${UNAME_MACHINE}-pc-linux-${LIBC}
        exit ;;
     ia64:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
        exit ;;
     m32r*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
        exit ;;
     m68*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
        exit ;;
     mips:Linux:*:* | mips64:Linux:*:*)
        eval $set_cc_for_build
@@ -940,54 +967,63 @@ EOF
        #endif
 EOF
        eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
-       test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
+       test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
        ;;
+    or1k:Linux:*:*)
+       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+       exit ;;
     or32:Linux:*:*)
-       echo or32-unknown-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
        exit ;;
     padre:Linux:*:*)
-       echo sparc-unknown-linux-gnu
+       echo sparc-unknown-linux-${LIBC}
        exit ;;
     parisc64:Linux:*:* | hppa64:Linux:*:*)
-       echo hppa64-unknown-linux-gnu
+       echo hppa64-unknown-linux-${LIBC}
        exit ;;
     parisc:Linux:*:* | hppa:Linux:*:*)
        # Look for CPU level
        case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
-         PA7*) echo hppa1.1-unknown-linux-gnu ;;
-         PA8*) echo hppa2.0-unknown-linux-gnu ;;
-         *)    echo hppa-unknown-linux-gnu ;;
+         PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+         PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+         *)    echo hppa-unknown-linux-${LIBC} ;;
        esac
        exit ;;
     ppc64:Linux:*:*)
-       echo powerpc64-unknown-linux-gnu
+       echo powerpc64-unknown-linux-${LIBC}
        exit ;;
     ppc:Linux:*:*)
-       echo powerpc-unknown-linux-gnu
+       echo powerpc-unknown-linux-${LIBC}
+       exit ;;
+    ppc64le:Linux:*:*)
+       echo powerpc64le-unknown-linux-${LIBC}
+       exit ;;
+    ppcle:Linux:*:*)
+       echo powerpcle-unknown-linux-${LIBC}
        exit ;;
     s390:Linux:*:* | s390x:Linux:*:*)
-       echo ${UNAME_MACHINE}-ibm-linux
+       echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
        exit ;;
     sh64*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
        exit ;;
     sh*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
        exit ;;
     sparc:Linux:*:* | sparc64:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
        exit ;;
     tile*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
        exit ;;
     vax:Linux:*:*)
-       echo ${UNAME_MACHINE}-dec-linux-gnu
+       echo ${UNAME_MACHINE}-dec-linux-${LIBC}
        exit ;;
     x86_64:Linux:*:*)
-       echo x86_64-unknown-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
        exit ;;
     xtensa*:Linux:*:*)
-       echo ${UNAME_MACHINE}-unknown-linux-gnu
+       echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
        exit ;;
     i*86:DYNIX/ptx:4*:*)
        # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
@@ -1191,6 +1227,9 @@ EOF
     BePC:Haiku:*:*)    # Haiku running on Intel PC compatible.
        echo i586-pc-haiku
        exit ;;
+    x86_64:Haiku:*:*)
+       echo x86_64-unknown-haiku
+       exit ;;
     SX-4:SUPER-UX:*:*)
        echo sx4-nec-superux${UNAME_RELEASE}
        exit ;;
@@ -1217,19 +1256,31 @@ EOF
        exit ;;
     *:Darwin:*:*)
        UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
-       case $UNAME_PROCESSOR in
-           i386)
-               eval $set_cc_for_build
-               if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
-                 if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
-                     (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
-                     grep IS_64BIT_ARCH >/dev/null
-                 then
-                     UNAME_PROCESSOR="x86_64"
-                 fi
-               fi ;;
-           unknown) UNAME_PROCESSOR=powerpc ;;
-       esac
+       eval $set_cc_for_build
+       if test "$UNAME_PROCESSOR" = unknown ; then
+           UNAME_PROCESSOR=powerpc
+       fi
+       if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+           if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+               if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+                   (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+                   grep IS_64BIT_ARCH >/dev/null
+               then
+                   case $UNAME_PROCESSOR in
+                       i386) UNAME_PROCESSOR=x86_64 ;;
+                       powerpc) UNAME_PROCESSOR=powerpc64 ;;
+                   esac
+               fi
+           fi
+       elif test "$UNAME_PROCESSOR" = i386 ; then
+           # Avoid executing cc on OS X 10.9, as it ships with a stub
+           # that puts up a graphical alert prompting to install
+           # developer tools.  Any system running Mac OS X 10.7 or
+           # later (Darwin 11 and later) is required to have a 64-bit
+           # processor. This is not true of the ARM version of Darwin
+           # that Apple uses in portable devices.
+           UNAME_PROCESSOR=x86_64
+       fi
        echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
        exit ;;
     *:procnto*:*:* | *:QNX:[0123456789]*:*)
@@ -1246,7 +1297,7 @@ EOF
     NEO-?:NONSTOP_KERNEL:*:*)
        echo neo-tandem-nsk${UNAME_RELEASE}
        exit ;;
-    NSE-?:NONSTOP_KERNEL:*:*)
+    NSE-*:NONSTOP_KERNEL:*:*)
        echo nse-tandem-nsk${UNAME_RELEASE}
        exit ;;
     NSR-?:NONSTOP_KERNEL:*:*)
@@ -1315,11 +1366,11 @@ EOF
     i*86:AROS:*:*)
        echo ${UNAME_MACHINE}-pc-aros
        exit ;;
+    x86_64:VMkernel:*:*)
+       echo ${UNAME_MACHINE}-unknown-esx
+       exit ;;
 esac
 
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
 eval $set_cc_for_build
 cat >$dummy.c <<EOF
 #ifdef _SEQUENT_
similarity index 100%
rename from config.rpath
rename to build-aux/config.rpath
similarity index 92%
rename from config.sub
rename to build-aux/config.sub
index f9fcdc8..61cb4bc 100755 (executable)
@@ -1,38 +1,31 @@
 #! /bin/sh
 # Configuration validation subroutine script.
-#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-#   2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-#   2011 Free Software Foundation, Inc.
+#   Copyright 1992-2013 Free Software Foundation, Inc.
 
-timestamp='2011-06-03'
+timestamp='2013-10-01'
 
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine.  It does not imply ALL GNU software can.
-#
-# 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
-# the Free Software Foundation; either version 2 of the License, or
+# 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
+# the Free Software Foundation; either version 3 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.
+# 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., 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
 # configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
+# the same distribution terms that you use for the rest of that
+# program.  This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
 
 
-# Please send patches to <config-patches@gnu.org>.  Submit a context
-# diff and a properly formatted GNU ChangeLog entry.
+# Please send patches with a ChangeLog entry to config-patches@gnu.org.
 #
 # Configuration subroutine to validate and canonicalize a configuration type.
 # Supply the specified configuration type as an argument.
@@ -75,9 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>."
 version="\
 GNU config.sub ($timestamp)
 
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free
-Software Foundation, Inc.
+Copyright 1992-2013 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."
@@ -125,13 +116,17 @@ esac
 maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
   nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
-  linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+  linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
   knetbsd*-gnu* | netbsd*-gnu* | \
   kopensolaris*-gnu* | \
   storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
     basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
     ;;
+  android-linux)
+    os=-linux-android
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+    ;;
   *)
     basic_machine=`echo $1 | sed 's/-[^-]*$//'`
     if [ $basic_machine != $1 ]
@@ -154,7 +149,7 @@ case $os in
        -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
        -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
        -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-       -apple | -axis | -knuth | -cray | -microblaze)
+       -apple | -axis | -knuth | -cray | -microblaze*)
                os=
                basic_machine=$1
                ;;
@@ -223,6 +218,12 @@ case $os in
        -isc*)
                basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
                ;;
+       -lynx*178)
+               os=-lynxos178
+               ;;
+       -lynx*5)
+               os=-lynxos5
+               ;;
        -lynx*)
                os=-lynxos
                ;;
@@ -247,20 +248,28 @@ case $basic_machine in
        # Some are omitted here because they have special meanings below.
        1750a | 580 \
        | a29k \
+       | aarch64 | aarch64_be \
        | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
        | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
        | am33_2.0 \
-       | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
+       | arc | arceb \
+       | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+       | avr | avr32 \
+       | be32 | be64 \
        | bfin \
-       | c4x | clipper \
+       | c4x | c8051 | clipper \
        | d10v | d30v | dlx | dsp16xx \
+       | epiphany \
        | fido | fr30 | frv \
        | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+       | hexagon \
        | i370 | i860 | i960 | ia64 \
        | ip2k | iq2000 \
+       | k1om \
+       | le32 | le64 \
        | lm32 \
        | m32c | m32r | m32rle | m68000 | m68k | m88k \
-       | maxq | mb | microblaze | mcore | mep | metag \
+       | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
        | mips | mipsbe | mipseb | mipsel | mipsle \
        | mips16 \
        | mips64 | mips64el \
@@ -278,20 +287,21 @@ case $basic_machine in
        | mipsisa64r2 | mipsisa64r2el \
        | mipsisa64sb1 | mipsisa64sb1el \
        | mipsisa64sr71k | mipsisa64sr71kel \
+       | mipsr5900 | mipsr5900el \
        | mipstx39 | mipstx39el \
        | mn10200 | mn10300 \
        | moxie \
        | mt \
        | msp430 \
        | nds32 | nds32le | nds32be \
-       | nios | nios2 \
+       | nios | nios2 | nios2eb | nios2el \
        | ns16k | ns32k \
        | open8 \
-       | or32 \
+       | or1k | or32 \
        | pdp10 | pdp11 | pj | pjl \
        | powerpc | powerpc64 | powerpc64le | powerpcle \
        | pyramid \
-       | rx \
+       | 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 \
        | sh64 | sh64le \
@@ -315,8 +325,7 @@ case $basic_machine in
        c6x)
                basic_machine=tic6x-unknown
                ;;
-       m6811 | m68hc11 | m6812 | m68hc12 | picochip)
-               # Motorola 68HC11/12.
+       m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
                basic_machine=$basic_machine-unknown
                os=-none
                ;;
@@ -329,7 +338,10 @@ case $basic_machine in
        strongarm | thumb | xscale)
                basic_machine=arm-unknown
                ;;
-
+       xgate)
+               basic_machine=$basic_machine-unknown
+               os=-none
+               ;;
        xscaleeb)
                basic_machine=armeb-unknown
                ;;
@@ -352,25 +364,31 @@ case $basic_machine in
        # Recognize the basic CPU types with company name.
        580-* \
        | a29k-* \
+       | aarch64-* | aarch64_be-* \
        | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
        | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
-       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+       | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
        | arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
        | avr-* | avr32-* \
+       | be32-* | be64-* \
        | bfin-* | bs2000-* \
        | c[123]* | c30-* | [cjt]90-* | c4x-* \
-       | clipper-* | craynv-* | cydra-* \
+       | c8051-* | clipper-* | craynv-* | cydra-* \
        | d10v-* | d30v-* | dlx-* \
        | elxsi-* \
        | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
        | h8300-* | h8500-* \
        | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+       | hexagon-* \
        | i*86-* | i860-* | i960-* | ia64-* \
        | ip2k-* | iq2000-* \
+       | k1om-* \
+       | le32-* | le64-* \
        | lm32-* \
        | m32c-* | m32r-* | m32rle-* \
        | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
-       | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
+       | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+       | microblaze-* | microblazeel-* \
        | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
        | mips16-* \
        | mips64-* | mips64el-* \
@@ -388,19 +406,20 @@ case $basic_machine in
        | mipsisa64r2-* | mipsisa64r2el-* \
        | mipsisa64sb1-* | mipsisa64sb1el-* \
        | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+       | mipsr5900-* | mipsr5900el-* \
        | mipstx39-* | mipstx39el-* \
        | mmix-* \
        | mt-* \
        | msp430-* \
        | nds32-* | nds32le-* | nds32be-* \
-       | nios-* | nios2-* \
+       | nios-* | nios2-* | nios2eb-* | nios2el-* \
        | none-* | np1-* | ns16k-* | ns32k-* \
        | open8-* \
        | orion-* \
        | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
        | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
        | pyramid-* \
-       | romp-* | rs6000-* | rx-* \
+       | rl78-* | romp-* | rs6000-* | rx-* \
        | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
        | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
        | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
@@ -712,7 +731,6 @@ case $basic_machine in
        i370-ibm* | ibm*)
                basic_machine=i370-ibm
                ;;
-# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
        i*86v32)
                basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
                os=-sysv32
@@ -770,11 +788,15 @@ case $basic_machine in
                basic_machine=ns32k-utek
                os=-sysv
                ;;
-       microblaze)
+       microblaze*)
                basic_machine=microblaze-xilinx
                ;;
+       mingw64)
+               basic_machine=x86_64-pc
+               os=-mingw64
+               ;;
        mingw32)
-               basic_machine=i386-pc
+               basic_machine=i686-pc
                os=-mingw32
                ;;
        mingw32ce)
@@ -809,10 +831,18 @@ case $basic_machine in
        ms1-*)
                basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
                ;;
+       msys)
+               basic_machine=i686-pc
+               os=-msys
+               ;;
        mvs)
                basic_machine=i370-ibm
                os=-mvs
                ;;
+       nacl)
+               basic_machine=le32-unknown
+               os=-nacl
+               ;;
        ncr3000)
                basic_machine=i486-ncr
                os=-sysv4
@@ -993,7 +1023,11 @@ case $basic_machine in
                basic_machine=i586-unknown
                os=-pw32
                ;;
-       rdos)
+       rdos | rdos64)
+               basic_machine=x86_64-pc
+               os=-rdos
+               ;;
+       rdos32)
                basic_machine=i386-pc
                os=-rdos
                ;;
@@ -1320,21 +1354,21 @@ case $os in
        -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
              | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
              | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
-             | -sym* | -kopensolaris* \
+             | -sym* | -kopensolaris* | -plan9* \
              | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
              | -aos* | -aros* \
              | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
              | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
              | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
-             | -openbsd* | -solidbsd* \
+             | -bitrig* | -openbsd* | -solidbsd* \
              | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
              | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
              | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
              | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
              | -chorusos* | -chorusrdb* | -cegcc* \
-             | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-             | -mingw32* | -linux-gnu* | -linux-android* \
-             | -linux-newlib* | -linux-uclibc* \
+             | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+             | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+             | -linux-newlib* | -linux-musl* | -linux-uclibc* \
              | -uxpv* | -beos* | -mpeix* | -udk* \
              | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
              | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
@@ -1466,9 +1500,6 @@ case $os in
        -aros*)
                os=-aros
                ;;
-       -kaos*)
-               os=-kaos
-               ;;
        -zvmoe)
                os=-zvmoe
                ;;
@@ -1517,6 +1548,12 @@ case $basic_machine in
        c4x-* | tic4x-*)
                os=-coff
                ;;
+       c8051-*)
+               os=-elf
+               ;;
+       hexagon-*)
+               os=-elf
+               ;;
        tic54x-*)
                os=-coff
                ;;
@@ -1544,9 +1581,6 @@ case $basic_machine in
                ;;
        m68000-sun)
                os=-sunos3
-               # This also exists in the configure program, but was not the
-               # default.
-               # os=-sunos4
                ;;
        m68*-cisco)
                os=-aout
@@ -1560,6 +1594,9 @@ case $basic_machine in
        mips*-*)
                os=-elf
                ;;
+       or1k-*)
+               os=-elf
+               ;;
        or32-*)
                os=-coff
                ;;
similarity index 100%
rename from depcomp
rename to build-aux/depcomp
diff --git a/build-aux/git-log-fix b/build-aux/git-log-fix
new file mode 100644 (file)
index 0000000..3e3fd95
--- /dev/null
@@ -0,0 +1,14 @@
+# This file is expected to be used via gitlog-to-changelog's --amend=FILE
+# option.  It specifies what changes to make to each given SHA1's commit
+# log and metadata, using Perl-eval'able expressions.
+
+eb4937914db3fb7317502e97e4f0e40c1857f59d
+# Fix bad formatted entry dated 2013-05-20
+s/(?s)mpi_sub.*$/cipher: Fix segv in last ECC change.
+* cipher\/ecc.c (generate_key): Make sure R is initialized./
+
+296f38a2bd2e25788643a42e4881faed00884a40
+# Fix bad formatted entry dated 2013-05-09
+s/(?s)Generate ECC.*$/cipher: Generate compliant ECC keys.
+* cipher\/ecc.c (generate_key): Make sure a key is compliant for
+using the compact representation./
diff --git a/build-aux/git-log-footer b/build-aux/git-log-footer
new file mode 100644 (file)
index 0000000..c31fe93
--- /dev/null
@@ -0,0 +1,14 @@
+
+2011-12-01  Werner Koch  <wk@gnupg.org>
+
+       NB: Changes done before December 1st, 2011 are described in
+       per directory files named ChangeLog-2011.  See doc/HACKING for
+       details.
+
+        -----
+       Copyright (C) 2011 Free Software Foundation, Inc.
+
+       Copying and distribution of this file and/or the original GIT
+       commit log messages, with or without modification, are
+       permitted provided the copyright notice and this notice are
+       preserved.
similarity index 74%
rename from install-sh
rename to build-aux/install-sh
index 4fbbae7..6781b98 100755 (executable)
@@ -1,7 +1,7 @@
 #!/bin/sh
 # install - install a program, script, or datafile
 
-scriptversion=2006-10-14.15
+scriptversion=2009-04-28.21; # UTC
 
 # This originates from X11R5 (mit/util/scripts/install.sh), which was
 # later released in X11R6 (xc/config/util/install.sh) with the
@@ -48,7 +48,7 @@ IFS=" ""      $nl"
 # set DOITPROG to echo to test this script
 
 # Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
+doit=${DOITPROG-}
 if test -z "$doit"; then
   doit_exec=exec
 else
@@ -58,34 +58,49 @@ fi
 # Put in absolute file names if you don't have them in your path;
 # or use environment vars.
 
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_glob='?'
+initialize_posix_glob='
+  test "$posix_glob" != "?" || {
+    if (set -f) 2>/dev/null; then
+      posix_glob=
+    else
+      posix_glob=:
+    fi
+  }
+'
 
-posix_glob=
 posix_mkdir=
 
 # Desired mode of installed file.
 mode=0755
 
+chgrpcmd=
 chmodcmd=$chmodprog
 chowncmd=
-chgrpcmd=
-stripcmd=
+mvcmd=$mvprog
 rmcmd="$rmprog -f"
-mvcmd="$mvprog"
+stripcmd=
+
 src=
 dst=
 dir_arg=
-dstarg=
+dst_arg=
+
+copy_on_change=false
 no_target_directory=
 
-usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
    or: $0 [OPTION]... SRCFILES... DIRECTORY
    or: $0 [OPTION]... -t DIRECTORY SRCFILES...
    or: $0 [OPTION]... -d DIRECTORIES...
@@ -95,65 +110,55 @@ In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
 In the 4th, create DIRECTORIES.
 
 Options:
--c         (ignored)
--d         create directories instead of installing files.
--g GROUP   $chgrpprog installed files to GROUP.
--m MODE    $chmodprog installed files to MODE.
--o USER    $chownprog installed files to USER.
--s         $stripprog installed files.
--t DIRECTORY  install into DIRECTORY.
--T         report an error if DSTFILE is a directory.
---help     display this help and exit.
---version  display version info and exit.
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
 
 Environment variables override the default commands:
-  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
 "
 
 while test $# -ne 0; do
   case $1 in
-    -c) shift
-        continue;;
+    -c) ;;
+
+    -C) copy_on_change=true;;
 
-    -d) dir_arg=true
-        shift
-        continue;;
+    -d) dir_arg=true;;
 
     -g) chgrpcmd="$chgrpprog $2"
-        shift
-        shift
-        continue;;
+       shift;;
 
     --help) echo "$usage"; exit $?;;
 
     -m) mode=$2
-        shift
-        shift
        case $mode in
          *' '* | *'    '* | *'
 '*       | *'*'* | *'?'* | *'['*)
            echo "$0: invalid mode: $mode" >&2
            exit 1;;
        esac
-        continue;;
+       shift;;
 
     -o) chowncmd="$chownprog $2"
-        shift
-        shift
-        continue;;
+       shift;;
 
-    -s) stripcmd=$stripprog
-        shift
-        continue;;
+    -s) stripcmd=$stripprog;;
 
-    -t) dstarg=$2
-       shift
-       shift
-       continue;;
+    -t) dst_arg=$2
+       shift;;
 
-    -T) no_target_directory=true
-       shift
-       continue;;
+    -T) no_target_directory=true;;
 
     --version) echo "$0 $scriptversion"; exit $?;;
 
@@ -165,21 +170,22 @@ while test $# -ne 0; do
 
     *)  break;;
   esac
+  shift
 done
 
-if test $# -ne 0 && test -z "$dir_arg$dstarg"; then
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
   # When -d is used, all remaining arguments are directories to create.
   # When -t is used, the destination is already specified.
   # Otherwise, the last argument is the destination.  Remove it from $@.
   for arg
   do
-    if test -n "$dstarg"; then
+    if test -n "$dst_arg"; then
       # $@ is not empty: it contains at least $arg.
-      set fnord "$@" "$dstarg"
+      set fnord "$@" "$dst_arg"
       shift # fnord
     fi
     shift # arg
-    dstarg=$arg
+    dst_arg=$arg
   done
 fi
 
@@ -224,7 +230,7 @@ for src
 do
   # Protect names starting with `-'.
   case $src in
-    -*) src=./$src ;;
+    -*) src=./$src;;
   esac
 
   if test -n "$dir_arg"; then
@@ -242,22 +248,22 @@ do
       exit 1
     fi
 
-    if test -z "$dstarg"; then
+    if test -z "$dst_arg"; then
       echo "$0: no destination specified." >&2
       exit 1
     fi
 
-    dst=$dstarg
+    dst=$dst_arg
     # Protect names starting with `-'.
     case $dst in
-      -*) dst=./$dst ;;
+      -*) dst=./$dst;;
     esac
 
     # If destination is a directory, append the input filename; won't work
     # if double slashes aren't ignored.
     if test -d "$dst"; then
       if test -n "$no_target_directory"; then
-       echo "$0: $dstarg: Is a directory" >&2
+       echo "$0: $dst_arg: Is a directory" >&2
        exit 1
       fi
       dstdir=$dst
@@ -378,26 +384,19 @@ do
       # directory the slow way, step by step, checking for races as we go.
 
       case $dstdir in
-       /*) prefix=;;
-       -*) prefix=./ ;;
-       *)  prefix= ;;
+       /*) prefix='/';;
+       -*) prefix='./';;
+       *)  prefix='';;
       esac
 
-      case $posix_glob in
-        '')
-         if (set -f) 2>/dev/null; then
-           posix_glob=true
-         else
-           posix_glob=false
-         fi ;;
-      esac
+      eval "$initialize_posix_glob"
 
       oIFS=$IFS
       IFS=/
-      $posix_glob && set -f
+      $posix_glob set -f
       set fnord $dstdir
       shift
-      $posix_glob && set +f
+      $posix_glob set +f
       IFS=$oIFS
 
       prefixes=
@@ -459,41 +458,54 @@ do
     # ignore errors from any of these, just make sure not to ignore
     # errors from the above "$doit $cpprog $src $dsttmp" command.
     #
-    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
-      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
-      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
-      && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
-
-    # Now rename the file to the real destination.
-    { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \
-      || {
-          # The rename failed, perhaps because mv can't rename something else
-          # to itself, or perhaps because mv is so ancient that it does not
-          # support -f.
-
-          # Now remove or move aside any old file at destination location.
-          # We try this two ways since rm can't unlink itself on some
-          # systems and the destination file might be busy for other
-          # reasons.  In this case, the final cleanup might fail but the new
-          # file should still install successfully.
-          {
-            if test -f "$dst"; then
-              $doit $rmcmd -f "$dst" 2>/dev/null \
-              || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \
-                    && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\
-              || {
-                echo "$0: cannot unlink or rename $dst" >&2
-                (exit 1); exit 1
-              }
-            else
-              :
-            fi
-          } &&
-
-          # Now rename the file to the real destination.
-          $doit $mvcmd "$dsttmp" "$dst"
-        }
-    } || exit 1
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"    2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` &&
+
+       eval "$initialize_posix_glob" &&
+       $posix_glob set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       $posix_glob set +f &&
+
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+       # Now remove or move aside any old file at destination location.
+       # We try this two ways since rm can't unlink itself on some
+       # systems and the destination file might be busy for other
+       # reasons.  In this case, the final cleanup might fail but the new
+       # file should still install successfully.
+       {
+         test ! -f "$dst" ||
+         $doit $rmcmd -f "$dst" 2>/dev/null ||
+         { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+           { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+         } ||
+         { echo "$0: cannot unlink or rename $dst" >&2
+           (exit 1); exit 1
+         }
+       } &&
+
+       # Now rename the file to the real destination.
+       $doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
 
     trap '' 0
   fi
@@ -503,5 +515,6 @@ done
 # 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:
similarity index 67%
rename from ltmain.sh
rename to build-aux/ltmain.sh
index ce149f1..859599a 100644 (file)
--- a/ltmain.sh
@@ -1,9 +1,9 @@
-# Generated from ltmain.m4sh.
 
-# ltmain.sh (GNU libtool) 2.2.6b
+# libtool (GNU libtool) 2.4.2
 # Written by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
 
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006, 2007 2008 Free Software Foundation, Inc.
+# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, 2006,
+# 2007, 2008, 2009, 2010, 2011 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.
 
 #
 # Provide generalized library-building support services.
 #
-#     --config             show all configuration variables
-#     --debug              enable verbose shell tracing
-# -n, --dry-run            display commands without modifying any files
-#     --features           display basic configuration information and exit
-#     --mode=MODE          use operation mode MODE
-#     --preserve-dup-deps  don't remove duplicate dependency libraries
-#     --quiet, --silent    don't print informational messages
-#     --tag=TAG            use configuration variables from tag TAG
-# -v, --verbose            print informational messages (default)
-#     --version            print version information
-# -h, --help               print short or long help message
+#       --config             show all configuration variables
+#       --debug              enable verbose shell tracing
+#   -n, --dry-run            display commands without modifying any files
+#       --features           display basic configuration information and exit
+#       --mode=MODE          use operation mode MODE
+#       --preserve-dup-deps  don't remove duplicate dependency libraries
+#       --quiet, --silent    don't print informational messages
+#       --no-quiet, --no-silent
+#                            print informational messages (default)
+#       --no-warn            don't display warning messages
+#       --tag=TAG            use configuration variables from tag TAG
+#   -v, --verbose            print more informational messages than default
+#       --no-verbose         don't print the extra informational messages
+#       --version            print version information
+#   -h, --help, --help-all   print short, long, or detailed help message
 #
 # MODE must be one of the following:
 #
-#       clean              remove files from the build directory
-#       compile            compile a source file into a libtool object
-#       execute            automatically set library path, then run a program
-#       finish             complete the installation of libtool libraries
-#       install            install libraries or executables
-#       link               create a library or an executable
-#       uninstall          remove libraries from an installed directory
+#         clean              remove files from the build directory
+#         compile            compile a source file into a libtool object
+#         execute            automatically set library path, then run a program
+#         finish             complete the installation of libtool libraries
+#         install            install libraries or executables
+#         link               create a library or an executable
+#         uninstall          remove libraries from an installed directory
 #
-# MODE-ARGS vary depending on the MODE.
+# MODE-ARGS vary depending on the MODE.  When passed as first option,
+# `--mode=MODE' may be abbreviated as `MODE' or a unique abbreviation of that.
 # Try `$progname --help --mode=MODE' for a more detailed description of MODE.
 #
 # When reporting a bug, please describe a test case to reproduce it and
 # include the following information:
 #
-#       host-triplet:  $host
-#       shell:         $SHELL
-#       compiler:              $LTCC
-#       compiler flags:                $LTCFLAGS
-#       linker:                $LD (gnu? $with_gnu_ld)
-#       $progname:             (GNU libtool) 2.2.6b Debian-2.2.6b-2
-#       automake:              $automake_version
-#       autoconf:              $autoconf_version
+#         host-triplet:        $host
+#         shell:               $SHELL
+#         compiler:            $LTCC
+#         compiler flags:              $LTCFLAGS
+#         linker:              $LD (gnu? $with_gnu_ld)
+#         $progname:   (GNU libtool) 2.4.2 Debian-2.4.2-1
+#         automake:    $automake_version
+#         autoconf:    $autoconf_version
 #
 # Report bugs to <bug-libtool@gnu.org>.
+# GNU libtool home page: <http://www.gnu.org/software/libtool/>.
+# General help using GNU software: <http://www.gnu.org/gethelp/>.
 
-PROGRAM=ltmain.sh
+PROGRAM=libtool
 PACKAGE=libtool
-VERSION="2.2.6b Debian-2.2.6b-2"
+VERSION="2.4.2 Debian-2.4.2-1"
 TIMESTAMP=""
-package_revision=1.3017
+package_revision=1.3337
 
 # Be Bourne compatible
 if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
@@ -91,10 +98,15 @@ fi
 BIN_SH=xpg4; export BIN_SH # for Tru64
 DUALCASE=1; export DUALCASE # for MKS sh
 
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+}
+
 # NLS nuisances: We save the old values to restore during execute mode.
-# Only set LANG and LC_ALL to C if already set.
-# These must not be set unconditionally because not all systems understand
-# e.g. LANG=C (notably SCO).
 lt_user_locale=
 lt_safe_locale=
 for lt_var in LANG LANGUAGE LC_ALL LC_CTYPE LC_COLLATE LC_MESSAGES
@@ -107,24 +119,28 @@ do
          lt_safe_locale=\"$lt_var=C; \$lt_safe_locale\"
        fi"
 done
+LC_ALL=C
+LANGUAGE=C
+export LANGUAGE LC_ALL
 
 $lt_unset CDPATH
 
 
+# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
+# is ksh but when the shell is invoked as "sh" and the current value of
+# the _XPG environment variable is not equal to 1 (one), the special
+# positional parameter $0, within a function call, is the name of the
+# function.
+progpath="$0"
 
 
 
 : ${CP="cp -f"}
-: ${ECHO="echo"}
-: ${EGREP="/bin/grep -E"}
-: ${FGREP="/bin/grep -F"}
-: ${GREP="/bin/grep"}
-: ${LN_S="ln -s"}
+test "${ECHO+set}" = set || ECHO=${as_echo-'printf %s\n'}
 : ${MAKE="make"}
 : ${MKDIR="mkdir"}
 : ${MV="mv -f"}
 : ${RM="rm -f"}
-: ${SED="/bin/sed"}
 : ${SHELL="${CONFIG_SHELL-/bin/sh}"}
 : ${Xsed="$SED -e 1s/^X//"}
 
@@ -144,6 +160,27 @@ IFS="      $lt_nl"
 dirname="s,/[^/]*$,,"
 basename="s,^.*/,,"
 
+# func_dirname file append nondir_replacement
+# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
+# otherwise set result to NONDIR_REPLACEMENT.
+func_dirname ()
+{
+    func_dirname_result=`$ECHO "${1}" | $SED "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+} # func_dirname may be replaced by extended shell implementation
+
+
+# func_basename file
+func_basename ()
+{
+    func_basename_result=`$ECHO "${1}" | $SED "$basename"`
+} # func_basename may be replaced by extended shell implementation
+
+
 # func_dirname_and_basename file append nondir_replacement
 # perform func_basename and func_dirname in a single function
 # call:
@@ -158,33 +195,183 @@ basename="s,^.*/,,"
 # those functions but instead duplicate the functionality here.
 func_dirname_and_basename ()
 {
-  # Extract subdirectory from the argument.
-  func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
-  if test "X$func_dirname_result" = "X${1}"; then
-    func_dirname_result="${3}"
-  else
-    func_dirname_result="$func_dirname_result${2}"
-  fi
-  func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
+    # Extract subdirectory from the argument.
+    func_dirname_result=`$ECHO "${1}" | $SED -e "$dirname"`
+    if test "X$func_dirname_result" = "X${1}"; then
+      func_dirname_result="${3}"
+    else
+      func_dirname_result="$func_dirname_result${2}"
+    fi
+    func_basename_result=`$ECHO "${1}" | $SED -e "$basename"`
+} # func_dirname_and_basename may be replaced by extended shell implementation
+
+
+# func_stripname prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+# func_strip_suffix prefix name
+func_stripname ()
+{
+    case ${2} in
+      .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+      *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+    esac
+} # func_stripname may be replaced by extended shell implementation
+
+
+# These SED scripts presuppose an absolute path with a trailing slash.
+pathcar='s,^/\([^/]*\).*$,\1,'
+pathcdr='s,^/[^/]*,,'
+removedotparts=':dotsl
+               s@/\./@/@g
+               t dotsl
+               s,/\.$,/,'
+collapseslashes='s@/\{1,\}@/@g'
+finalslash='s,/*$,/,'
+
+# func_normal_abspath PATH
+# Remove doubled-up and trailing slashes, "." path components,
+# and cancel out any ".." path components in PATH after making
+# it an absolute path.
+#             value returned in "$func_normal_abspath_result"
+func_normal_abspath ()
+{
+  # Start from root dir and reassemble the path.
+  func_normal_abspath_result=
+  func_normal_abspath_tpath=$1
+  func_normal_abspath_altnamespace=
+  case $func_normal_abspath_tpath in
+    "")
+      # Empty path, that just means $cwd.
+      func_stripname '' '/' "`pwd`"
+      func_normal_abspath_result=$func_stripname_result
+      return
+    ;;
+    # The next three entries are used to spot a run of precisely
+    # two leading slashes without using negated character classes;
+    # we take advantage of case's first-match behaviour.
+    ///*)
+      # Unusual form of absolute path, do nothing.
+    ;;
+    //*)
+      # Not necessarily an ordinary path; POSIX reserves leading '//'
+      # and for example Cygwin uses it to access remote file shares
+      # over CIFS/SMB, so we conserve a leading double slash if found.
+      func_normal_abspath_altnamespace=/
+    ;;
+    /*)
+      # Absolute path, do nothing.
+    ;;
+    *)
+      # Relative path, prepend $cwd.
+      func_normal_abspath_tpath=`pwd`/$func_normal_abspath_tpath
+    ;;
+  esac
+  # Cancel out all the simple stuff to save iterations.  We also want
+  # the path to end with a slash for ease of parsing, so make sure
+  # there is one (and only one) here.
+  func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$removedotparts" -e "$collapseslashes" -e "$finalslash"`
+  while :; do
+    # Processed it all yet?
+    if test "$func_normal_abspath_tpath" = / ; then
+      # If we ascended to the root using ".." the result may be empty now.
+      if test -z "$func_normal_abspath_result" ; then
+        func_normal_abspath_result=/
+      fi
+      break
+    fi
+    func_normal_abspath_tcomponent=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcar"`
+    func_normal_abspath_tpath=`$ECHO "$func_normal_abspath_tpath" | $SED \
+        -e "$pathcdr"`
+    # Figure out what to do with it
+    case $func_normal_abspath_tcomponent in
+      "")
+        # Trailing empty path component, ignore it.
+      ;;
+      ..)
+        # Parent dir; strip last assembled component from result.
+        func_dirname "$func_normal_abspath_result"
+        func_normal_abspath_result=$func_dirname_result
+      ;;
+      *)
+        # Actual path component, append it.
+        func_normal_abspath_result=$func_normal_abspath_result/$func_normal_abspath_tcomponent
+      ;;
+    esac
+  done
+  # Restore leading double-slash if one was found on entry.
+  func_normal_abspath_result=$func_normal_abspath_altnamespace$func_normal_abspath_result
 }
 
-# Generated shell functions inserted here.
+# func_relative_path SRCDIR DSTDIR
+# generates a relative path from SRCDIR to DSTDIR, with a trailing
+# slash if non-empty, suitable for immediately appending a filename
+# without needing to append a separator.
+#             value returned in "$func_relative_path_result"
+func_relative_path ()
+{
+  func_relative_path_result=
+  func_normal_abspath "$1"
+  func_relative_path_tlibdir=$func_normal_abspath_result
+  func_normal_abspath "$2"
+  func_relative_path_tbindir=$func_normal_abspath_result
+
+  # Ascend the tree starting from libdir
+  while :; do
+    # check if we have found a prefix of bindir
+    case $func_relative_path_tbindir in
+      $func_relative_path_tlibdir)
+        # found an exact match
+        func_relative_path_tcancelled=
+        break
+        ;;
+      $func_relative_path_tlibdir*)
+        # found a matching prefix
+        func_stripname "$func_relative_path_tlibdir" '' "$func_relative_path_tbindir"
+        func_relative_path_tcancelled=$func_stripname_result
+        if test -z "$func_relative_path_result"; then
+          func_relative_path_result=.
+        fi
+        break
+        ;;
+      *)
+        func_dirname $func_relative_path_tlibdir
+        func_relative_path_tlibdir=${func_dirname_result}
+        if test "x$func_relative_path_tlibdir" = x ; then
+          # Have to descend all the way to the root!
+          func_relative_path_result=../$func_relative_path_result
+          func_relative_path_tcancelled=$func_relative_path_tbindir
+          break
+        fi
+        func_relative_path_result=../$func_relative_path_result
+        ;;
+    esac
+  done
 
-# Work around backward compatibility issue on IRIX 6.5. On IRIX 6.4+, sh
-# is ksh but when the shell is invoked as "sh" and the current value of
-# the _XPG environment variable is not equal to 1 (one), the special
-# positional parameter $0, within a function call, is the name of the
-# function.
-progpath="$0"
+  # Now calculate path; take care to avoid doubling-up slashes.
+  func_stripname '' '/' "$func_relative_path_result"
+  func_relative_path_result=$func_stripname_result
+  func_stripname '/' '/' "$func_relative_path_tcancelled"
+  if test "x$func_stripname_result" != x ; then
+    func_relative_path_result=${func_relative_path_result}/${func_stripname_result}
+  fi
+
+  # Normalisation. If bindir is libdir, return empty string,
+  # else relative path ending with a slash; either way, target
+  # file name can be directly appended.
+  if test ! -z "$func_relative_path_result"; then
+    func_stripname './' '' "$func_relative_path_result/"
+    func_relative_path_result=$func_stripname_result
+  fi
+}
 
 # The name of this program:
-# In the unlikely event $progname began with a '-', it would play havoc with
-# func_echo (imagine progname=-n), so we prepend ./ in that case:
 func_dirname_and_basename "$progpath"
 progname=$func_basename_result
-case $progname in
-  -*) progname=./$progname ;;
-esac
 
 # Make sure we have an absolute path for reexecution:
 case $progpath in
@@ -196,7 +383,7 @@ case $progpath in
      ;;
   *)
      save_IFS="$IFS"
-     IFS=:
+     IFS=${PATH_SEPARATOR-:}
      for progdir in $PATH; do
        IFS="$save_IFS"
        test -x "$progdir/$progname" && break
@@ -215,6 +402,19 @@ sed_quote_subst='s/\([`"$\\]\)/\\\1/g'
 # Same as above, but do not quote variable references.
 double_quote_subst='s/\(["`\\]\)/\\\1/g'
 
+# Sed substitution that turns a string into a regex matching for the
+# string literally.
+sed_make_literal_regex='s,[].[^$\\*\/],\\&,g'
+
+# Sed substitution that converts a w32 file name or path
+# which contains forward slashes, into one that contains
+# (escaped) backslashes.  A very naive implementation.
+lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
+
+# Sed substitution to remove simple comments and empty
+# lines from a Windows .def file.
+sed_uncomment_deffile='/^;/d; /^[ ]*$/d'
+
 # Re-`\' parameter expansions in output of double_quote_subst that were
 # `\'-ed in input to the same.  If an odd number of `\' preceded a '$'
 # in input to double_quote_subst, that '$' was protected from expansion.
@@ -243,7 +443,7 @@ opt_warning=:
 # name if it has been set yet.
 func_echo ()
 {
-    $ECHO "$progname${mode+: }$mode: $*"
+    $ECHO "$progname: ${opt_mode+$opt_mode: }$*"
 }
 
 # func_verbose arg...
@@ -258,18 +458,25 @@ func_verbose ()
     :
 }
 
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*"
+}
+
 # func_error arg...
 # Echo program name prefixed message to standard error.
 func_error ()
 {
-    $ECHO "$progname${mode+: }$mode: "${1+"$@"} 1>&2
+    $ECHO "$progname: ${opt_mode+$opt_mode: }"${1+"$@"} 1>&2
 }
 
 # func_warning arg...
 # Echo program name prefixed warning message to standard error.
 func_warning ()
 {
-    $opt_warning && $ECHO "$progname${mode+: }$mode: warning: "${1+"$@"} 1>&2
+    $opt_warning && $ECHO "$progname: ${opt_mode+$opt_mode: }warning: "${1+"$@"} 1>&2
 
     # bash bug again:
     :
@@ -326,9 +533,9 @@ func_mkdir_p ()
         case $my_directory_path in */*) ;; *) break ;; esac
 
         # ...otherwise throw away the child directory and loop
-        my_directory_path=`$ECHO "X$my_directory_path" | $Xsed -e "$dirname"`
+        my_directory_path=`$ECHO "$my_directory_path" | $SED -e "$dirname"`
       done
-      my_dir_list=`$ECHO "X$my_dir_list" | $Xsed -e 's,:*$,,'`
+      my_dir_list=`$ECHO "$my_dir_list" | $SED 's,:*$,,'`
 
       save_mkdir_p_IFS="$IFS"; IFS=':'
       for my_dir in $my_dir_list; do
@@ -378,7 +585,7 @@ func_mktempdir ()
         func_fatal_error "cannot create temporary directory \`$my_tmpdir'"
     fi
 
-    $ECHO "X$my_tmpdir" | $Xsed
+    $ECHO "$my_tmpdir"
 }
 
 
@@ -392,7 +599,7 @@ func_quote_for_eval ()
 {
     case $1 in
       *[\\\`\"\$]*)
-       func_quote_for_eval_unquoted_result=`$ECHO "X$1" | $Xsed -e "$sed_quote_subst"` ;;
+       func_quote_for_eval_unquoted_result=`$ECHO "$1" | $SED "$sed_quote_subst"` ;;
       *)
         func_quote_for_eval_unquoted_result="$1" ;;
     esac
@@ -419,7 +626,7 @@ func_quote_for_expand ()
 {
     case $1 in
       *[\\\`\"]*)
-       my_arg=`$ECHO "X$1" | $Xsed \
+       my_arg=`$ECHO "$1" | $SED \
            -e "$double_quote_subst" -e "$sed_double_backslash"` ;;
       *)
         my_arg="$1" ;;
@@ -488,15 +695,39 @@ func_show_eval_locale ()
     fi
 }
 
-
-
+# func_tr_sh
+# Turn $1 into a string suitable for a shell variable name.
+# Result is stored in $func_tr_sh_result.  All characters
+# not in the set a-zA-Z0-9_ are replaced with '_'. Further,
+# if $1 begins with a digit, a '_' is prepended as well.
+func_tr_sh ()
+{
+  case $1 in
+  [0-9]* | *[!a-zA-Z0-9_]*)
+    func_tr_sh_result=`$ECHO "$1" | $SED 's/^\([0-9]\)/_\1/; s/[^a-zA-Z0-9_]/_/g'`
+    ;;
+  * )
+    func_tr_sh_result=$1
+    ;;
+  esac
+}
 
 
 # func_version
 # Echo version message to standard output and exit.
 func_version ()
 {
-    $SED -n '/^# '$PROGRAM' (GNU /,/# warranty; / {
+    $opt_debug
+
+    $SED -n '/(C)/!b go
+       :more
+       /\./!{
+         N
+         s/\n# / /
+         b more
+       }
+       :go
+       /^# '$PROGRAM' (GNU /,/# warranty; / {
         s/^# //
        s/^# *$//
         s/\((C)\)[ 0-9,-]*\( [1-9][0-9]*\)/\1\2/
@@ -509,22 +740,28 @@ func_version ()
 # Echo short help message to standard output and exit.
 func_usage ()
 {
-    $SED -n '/^# Usage:/,/# -h/ {
+    $opt_debug
+
+    $SED -n '/^# Usage:/,/^#  *.*--help/ {
         s/^# //
        s/^# *$//
        s/\$progname/'$progname'/
        p
     }' < "$progpath"
-    $ECHO
+    echo
     $ECHO "run \`$progname --help | more' for full usage"
     exit $?
 }
 
-# func_help
-# Echo long help message to standard output and exit.
+# func_help [NOEXIT]
+# Echo long help message to standard output and exit,
+# unless 'noexit' is passed as argument.
 func_help ()
 {
+    $opt_debug
+
     $SED -n '/^# Usage:/,/# Report bugs to/ {
+       :print
         s/^# //
        s/^# *$//
        s*\$progname*'$progname'*
@@ -534,11 +771,18 @@ func_help ()
        s*\$LTCFLAGS*'"$LTCFLAGS"'*
        s*\$LD*'"$LD"'*
        s/\$with_gnu_ld/'"$with_gnu_ld"'/
-       s/\$automake_version/'"`(automake --version) 2>/dev/null |$SED 1q`"'/
-       s/\$autoconf_version/'"`(autoconf --version) 2>/dev/null |$SED 1q`"'/
+       s/\$automake_version/'"`(${AUTOMAKE-automake} --version) 2>/dev/null |$SED 1q`"'/
+       s/\$autoconf_version/'"`(${AUTOCONF-autoconf} --version) 2>/dev/null |$SED 1q`"'/
        p
-     }' < "$progpath"
-    exit $?
+       d
+     }
+     /^# .* home page:/b print
+     /^# General help using/b print
+     ' < "$progpath"
+    ret=$?
+    if test -z "$1"; then
+      exit $ret
+    fi
 }
 
 # func_missing_arg argname
@@ -546,63 +790,106 @@ func_help ()
 # exit_cmd.
 func_missing_arg ()
 {
-    func_error "missing argument for $1"
+    $opt_debug
+
+    func_error "missing argument for $1."
     exit_cmd=exit
 }
 
-exit_cmd=:
 
+# func_split_short_opt shortopt
+# Set func_split_short_opt_name and func_split_short_opt_arg shell
+# variables after splitting SHORTOPT after the 2nd character.
+func_split_short_opt ()
+{
+    my_sed_short_opt='1s/^\(..\).*$/\1/;q'
+    my_sed_short_rest='1s/^..\(.*\)$/\1/;q'
 
+    func_split_short_opt_name=`$ECHO "$1" | $SED "$my_sed_short_opt"`
+    func_split_short_opt_arg=`$ECHO "$1" | $SED "$my_sed_short_rest"`
+} # func_split_short_opt may be replaced by extended shell implementation
+
+
+# func_split_long_opt longopt
+# Set func_split_long_opt_name and func_split_long_opt_arg shell
+# variables after splitting LONGOPT at the `=' sign.
+func_split_long_opt ()
+{
+    my_sed_long_opt='1s/^\(--[^=]*\)=.*/\1/;q'
+    my_sed_long_arg='1s/^--[^=]*=//'
+
+    func_split_long_opt_name=`$ECHO "$1" | $SED "$my_sed_long_opt"`
+    func_split_long_opt_arg=`$ECHO "$1" | $SED "$my_sed_long_arg"`
+} # func_split_long_opt may be replaced by extended shell implementation
+
+exit_cmd=:
 
 
 
-# Check that we have a working $ECHO.
-if test "X$1" = X--no-reexec; then
-  # Discard the --no-reexec flag, and continue.
-  shift
-elif test "X$1" = X--fallback-echo; then
-  # Avoid inline document here, it may be left over
-  :
-elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t'; then
-  # Yippee, $ECHO works!
-  :
-else
-  # Restart under the correct shell, and then maybe $ECHO will work.
-  exec $SHELL "$progpath" --no-reexec ${1+"$@"}
-fi
 
-if test "X$1" = X--fallback-echo; then
-  # used as fallback echo
-  shift
-  cat <<EOF
-$*
-EOF
-  exit $EXIT_SUCCESS
-fi
 
 magic="%%%MAGIC variable%%%"
 magic_exe="%%%MAGIC EXE variable%%%"
 
 # Global variables.
-# $mode is unset
 nonopt=
-execute_dlfiles=
 preserve_args=
 lo2o="s/\\.lo\$/.${objext}/"
 o2lo="s/\\.${objext}\$/.lo/"
 extracted_archives=
 extracted_serial=0
 
-opt_dry_run=false
-opt_duplicate_deps=false
-opt_silent=false
-opt_debug=:
-
 # If this variable is set in any of the actions, the command in it
 # will be execed at the end.  This prevents here-documents from being
 # left over by shells.
 exec_cmd=
 
+# func_append var value
+# Append VALUE to the end of shell variable VAR.
+func_append ()
+{
+    eval "${1}=\$${1}\${2}"
+} # func_append may be replaced by extended shell implementation
+
+# func_append_quoted var value
+# Quote VALUE and append to the end of shell variable VAR, separated
+# by a space.
+func_append_quoted ()
+{
+    func_quote_for_eval "${2}"
+    eval "${1}=\$${1}\\ \$func_quote_for_eval_result"
+} # func_append_quoted may be replaced by extended shell implementation
+
+
+# func_arith arithmetic-term...
+func_arith ()
+{
+    func_arith_result=`expr "${@}"`
+} # func_arith may be replaced by extended shell implementation
+
+
+# func_len string
+# STRING may not start with a hyphen.
+func_len ()
+{
+    func_len_result=`expr "${1}" : ".*" 2>/dev/null || echo $max_cmd_len`
+} # func_len may be replaced by extended shell implementation
+
+
+# func_lo2o object
+func_lo2o ()
+{
+    func_lo2o_result=`$ECHO "${1}" | $SED "$lo2o"`
+} # func_lo2o may be replaced by extended shell implementation
+
+
+# func_xform libobj-or-source
+func_xform ()
+{
+    func_xform_result=`$ECHO "${1}" | $SED 's/\.[^.]*$/.lo/'`
+} # func_xform may be replaced by extended shell implementation
+
+
 # func_fatal_configuration arg...
 # Echo program name prefixed message to standard error, followed by
 # a configuration failure hint, and exit.
@@ -636,16 +923,16 @@ func_config ()
 # Display the features supported by this script.
 func_features ()
 {
-    $ECHO "host: $host"
+    echo "host: $host"
     if test "$build_libtool_libs" = yes; then
-      $ECHO "enable shared libraries"
+      echo "enable shared libraries"
     else
-      $ECHO "disable shared libraries"
+      echo "disable shared libraries"
     fi
     if test "$build_old_libs" = yes; then
-      $ECHO "enable static libraries"
+      echo "enable static libraries"
     else
-      $ECHO "disable static libraries"
+      echo "disable static libraries"
     fi
 
     exit $?
@@ -692,117 +979,209 @@ func_enable_tag ()
   esac
 }
 
-# Parse options once, thoroughly.  This comes as soon as possible in
-# the script to make things like `libtool --version' happen quickly.
+# func_check_version_match
+# Ensure that we are using m4 macros, and libtool script from the same
+# release of libtool.
+func_check_version_match ()
 {
+  if test "$package_revision" != "$macro_revision"; then
+    if test "$VERSION" != "$macro_version"; then
+      if test -z "$macro_version"; then
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from an older release.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      else
+        cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
+$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
+$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
+$progname: and run autoconf again.
+_LT_EOF
+      fi
+    else
+      cat >&2 <<_LT_EOF
+$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
+$progname: but the definition of this LT_INIT comes from revision $macro_revision.
+$progname: You should recreate aclocal.m4 with macros from revision $package_revision
+$progname: of $PACKAGE $VERSION and run autoconf again.
+_LT_EOF
+    fi
+
+    exit $EXIT_MISMATCH
+  fi
+}
+
+
+# Shorthand for --mode=foo, only valid as the first argument
+case $1 in
+clean|clea|cle|cl)
+  shift; set dummy --mode clean ${1+"$@"}; shift
+  ;;
+compile|compil|compi|comp|com|co|c)
+  shift; set dummy --mode compile ${1+"$@"}; shift
+  ;;
+execute|execut|execu|exec|exe|ex|e)
+  shift; set dummy --mode execute ${1+"$@"}; shift
+  ;;
+finish|finis|fini|fin|fi|f)
+  shift; set dummy --mode finish ${1+"$@"}; shift
+  ;;
+install|instal|insta|inst|ins|in|i)
+  shift; set dummy --mode install ${1+"$@"}; shift
+  ;;
+link|lin|li|l)
+  shift; set dummy --mode link ${1+"$@"}; shift
+  ;;
+uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
+  shift; set dummy --mode uninstall ${1+"$@"}; shift
+  ;;
+esac
+
+
+
+# Option defaults:
+opt_debug=:
+opt_dry_run=false
+opt_config=false
+opt_preserve_dup_deps=false
+opt_features=false
+opt_finish=false
+opt_help=false
+opt_help_all=false
+opt_silent=:
+opt_warning=:
+opt_verbose=:
+opt_silent=false
+opt_verbose=false
 
-  # Shorthand for --mode=foo, only valid as the first argument
-  case $1 in
-  clean|clea|cle|cl)
-    shift; set dummy --mode clean ${1+"$@"}; shift
-    ;;
-  compile|compil|compi|comp|com|co|c)
-    shift; set dummy --mode compile ${1+"$@"}; shift
-    ;;
-  execute|execut|execu|exec|exe|ex|e)
-    shift; set dummy --mode execute ${1+"$@"}; shift
-    ;;
-  finish|finis|fini|fin|fi|f)
-    shift; set dummy --mode finish ${1+"$@"}; shift
-    ;;
-  install|instal|insta|inst|ins|in|i)
-    shift; set dummy --mode install ${1+"$@"}; shift
-    ;;
-  link|lin|li|l)
-    shift; set dummy --mode link ${1+"$@"}; shift
-    ;;
-  uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u)
-    shift; set dummy --mode uninstall ${1+"$@"}; shift
-    ;;
-  esac
 
-  # Parse non-mode specific arguments:
-  while test "$#" -gt 0; do
+# Parse options once, thoroughly.  This comes as soon as possible in the
+# script to make things like `--version' happen as quickly as we can.
+{
+  # this just eases exit handling
+  while test $# -gt 0; do
     opt="$1"
     shift
-
     case $opt in
-      --config)                func_config                                     ;;
-
-      --debug)         preserve_args="$preserve_args $opt"
+      --debug|-x)      opt_debug='set -x'
                        func_echo "enabling shell trace mode"
-                       opt_debug='set -x'
                        $opt_debug
                        ;;
-
-      -dlopen)         test "$#" -eq 0 && func_missing_arg "$opt" && break
-                       execute_dlfiles="$execute_dlfiles $1"
-                       shift
+      --dry-run|--dryrun|-n)
+                       opt_dry_run=:
                        ;;
-
-      --dry-run | -n)  opt_dry_run=:                                   ;;
-      --features)       func_features                                  ;;
-      --finish)                mode="finish"                                   ;;
-
-      --mode)          test "$#" -eq 0 && func_missing_arg "$opt" && break
-                       case $1 in
-                         # Valid mode arguments:
-                         clean)        ;;
-                         compile)      ;;
-                         execute)      ;;
-                         finish)       ;;
-                         install)      ;;
-                         link)         ;;
-                         relink)       ;;
-                         uninstall)    ;;
-
-                         # Catch anything else as an error
-                         *) func_error "invalid argument for $opt"
-                            exit_cmd=exit
-                            break
-                            ;;
-                       esac
-
-                       mode="$1"
+      --config)
+                       opt_config=:
+func_config
+                       ;;
+      --dlopen|-dlopen)
+                       optarg="$1"
+                       opt_dlopen="${opt_dlopen+$opt_dlopen
+}$optarg"
                        shift
                        ;;
-
       --preserve-dup-deps)
-                       opt_duplicate_deps=:                            ;;
-
-      --quiet|--silent)        preserve_args="$preserve_args $opt"
-                       opt_silent=:
+                       opt_preserve_dup_deps=:
                        ;;
-
-      --verbose| -v)   preserve_args="$preserve_args $opt"
+      --features)
+                       opt_features=:
+func_features
+                       ;;
+      --finish)
+                       opt_finish=:
+set dummy --mode finish ${1+"$@"}; shift
+                       ;;
+      --help)
+                       opt_help=:
+                       ;;
+      --help-all)
+                       opt_help_all=:
+opt_help=': help-all'
+                       ;;
+      --mode)
+                       test $# = 0 && func_missing_arg $opt && break
+                       optarg="$1"
+                       opt_mode="$optarg"
+case $optarg in
+  # Valid mode arguments:
+  clean|compile|execute|finish|install|link|relink|uninstall) ;;
+
+  # Catch anything else as an error
+  *) func_error "invalid argument for $opt"
+     exit_cmd=exit
+     break
+     ;;
+esac
+                       shift
+                       ;;
+      --no-silent|--no-quiet)
                        opt_silent=false
+func_append preserve_args " $opt"
                        ;;
-
-      --tag)           test "$#" -eq 0 && func_missing_arg "$opt" && break
-                       preserve_args="$preserve_args $opt $1"
-                       func_enable_tag "$1"    # tagname is set here
+      --no-warning|--no-warn)
+                       opt_warning=false
+func_append preserve_args " $opt"
+                       ;;
+      --no-verbose)
+                       opt_verbose=false
+func_append preserve_args " $opt"
+                       ;;
+      --silent|--quiet)
+                       opt_silent=:
+func_append preserve_args " $opt"
+        opt_verbose=false
+                       ;;
+      --verbose|-v)
+                       opt_verbose=:
+func_append preserve_args " $opt"
+opt_silent=false
+                       ;;
+      --tag)
+                       test $# = 0 && func_missing_arg $opt && break
+                       optarg="$1"
+                       opt_tag="$optarg"
+func_append preserve_args " $opt $optarg"
+func_enable_tag "$optarg"
                        shift
                        ;;
 
+      -\?|-h)          func_usage                              ;;
+      --help)          func_help                               ;;
+      --version)       func_version                            ;;
+
       # Separate optargs to long options:
-      -dlopen=*|--mode=*|--tag=*)
-                       func_opt_split "$opt"
-                       set dummy "$func_opt_split_opt" "$func_opt_split_arg" ${1+"$@"}
+      --*=*)
+                       func_split_long_opt "$opt"
+                       set dummy "$func_split_long_opt_name" "$func_split_long_opt_arg" ${1+"$@"}
                        shift
                        ;;
 
-      -\?|-h)          func_usage                                      ;;
-      --help)          opt_help=:                                      ;;
-      --version)       func_version                                    ;;
-
-      -*)              func_fatal_help "unrecognized option \`$opt'"   ;;
-
-      *)               nonopt="$opt"
-                       break
+      # Separate non-argument short options:
+      -\?*|-h*|-n*|-v*)
+                       func_split_short_opt "$opt"
+                       set dummy "$func_split_short_opt_name" "-$func_split_short_opt_arg" ${1+"$@"}
+                       shift
                        ;;
+
+      --)              break                                   ;;
+      -*)              func_fatal_help "unrecognized option \`$opt'" ;;
+      *)               set dummy "$opt" ${1+"$@"};     shift; break  ;;
     esac
   done
 
+  # Validate options:
+
+  # save first non-option argument
+  if test "$#" -gt 0; then
+    nonopt="$opt"
+    shift
+  fi
+
+  # preserve --debug
+  test "$opt_debug" = : || func_append preserve_args " --debug"
 
   case $host in
     *cygwin* | *mingw* | *pw32* | *cegcc*)
@@ -810,82 +1189,44 @@ func_enable_tag ()
       opt_duplicate_compiler_generated_deps=:
       ;;
     *)
-      opt_duplicate_compiler_generated_deps=$opt_duplicate_deps
+      opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps
       ;;
   esac
 
-  # Having warned about all mis-specified options, bail out if
-  # anything was wrong.
-  $exit_cmd $EXIT_FAILURE
-}
+  $opt_help || {
+    # Sanity checks first:
+    func_check_version_match
 
-# func_check_version_match
-# Ensure that we are using m4 macros, and libtool script from the same
-# release of libtool.
-func_check_version_match ()
-{
-  if test "$package_revision" != "$macro_revision"; then
-    if test "$VERSION" != "$macro_version"; then
-      if test -z "$macro_version"; then
-        cat >&2 <<_LT_EOF
-$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
-$progname: definition of this LT_INIT comes from an older release.
-$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
-$progname: and run autoconf again.
-_LT_EOF
-      else
-        cat >&2 <<_LT_EOF
-$progname: Version mismatch error.  This is $PACKAGE $VERSION, but the
-$progname: definition of this LT_INIT comes from $PACKAGE $macro_version.
-$progname: You should recreate aclocal.m4 with macros from $PACKAGE $VERSION
-$progname: and run autoconf again.
-_LT_EOF
-      fi
-    else
-      cat >&2 <<_LT_EOF
-$progname: Version mismatch error.  This is $PACKAGE $VERSION, revision $package_revision,
-$progname: but the definition of this LT_INIT comes from revision $macro_revision.
-$progname: You should recreate aclocal.m4 with macros from revision $package_revision
-$progname: of $PACKAGE $VERSION and run autoconf again.
-_LT_EOF
+    if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+      func_fatal_configuration "not configured to build any kind of library"
     fi
 
-    exit $EXIT_MISMATCH
-  fi
-}
+    # Darwin sucks
+    eval std_shrext=\"$shrext_cmds\"
 
+    # Only execute mode is allowed to have -dlopen flags.
+    if test -n "$opt_dlopen" && test "$opt_mode" != execute; then
+      func_error "unrecognized option \`-dlopen'"
+      $ECHO "$help" 1>&2
+      exit $EXIT_FAILURE
+    fi
 
-## ----------- ##
-##    Main.    ##
-## ----------- ##
-
-$opt_help || {
-  # Sanity checks first:
-  func_check_version_match
-
-  if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
-    func_fatal_configuration "not configured to build any kind of library"
-  fi
-
-  test -z "$mode" && func_fatal_error "error: you must specify a MODE."
+    # Change the help message to a mode-specific one.
+    generic_help="$help"
+    help="Try \`$progname --help --mode=$opt_mode' for more information."
+  }
 
 
-  # Darwin sucks
-  eval std_shrext=\"$shrext_cmds\"
+  # Bail if the options were screwed
+  $exit_cmd $EXIT_FAILURE
+}
 
 
-  # Only execute mode is allowed to have -dlopen flags.
-  if test -n "$execute_dlfiles" && test "$mode" != execute; then
-    func_error "unrecognized option \`-dlopen'"
-    $ECHO "$help" 1>&2
-    exit $EXIT_FAILURE
-  fi
 
-  # Change the help message to a mode-specific one.
-  generic_help="$help"
-  help="Try \`$progname --help --mode=$mode' for more information."
-}
 
+## ----------- ##
+##    Main.    ##
+## ----------- ##
 
 # func_lalib_p file
 # True iff FILE is a libtool `.la' library or `.lo' object file.
@@ -950,12 +1291,9 @@ func_ltwrapper_executable_p ()
 # temporary ltwrapper_script.
 func_ltwrapper_scriptname ()
 {
-    func_ltwrapper_scriptname_result=""
-    if func_ltwrapper_executable_p "$1"; then
-       func_dirname_and_basename "$1" "" "."
-       func_stripname '' '.exe' "$func_basename_result"
-       func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
-    fi
+    func_dirname_and_basename "$1" "" "."
+    func_stripname '' '.exe' "$func_basename_result"
+    func_ltwrapper_scriptname_result="$func_dirname_result/$objdir/${func_stripname_result}_ltshwrapper"
 }
 
 # func_ltwrapper_p file
@@ -1001,6 +1339,37 @@ func_source ()
 }
 
 
+# func_resolve_sysroot PATH
+# Replace a leading = in PATH with a sysroot.  Store the result into
+# func_resolve_sysroot_result
+func_resolve_sysroot ()
+{
+  func_resolve_sysroot_result=$1
+  case $func_resolve_sysroot_result in
+  =*)
+    func_stripname '=' '' "$func_resolve_sysroot_result"
+    func_resolve_sysroot_result=$lt_sysroot$func_stripname_result
+    ;;
+  esac
+}
+
+# func_replace_sysroot PATH
+# If PATH begins with the sysroot, replace it with = and
+# store the result into func_replace_sysroot_result.
+func_replace_sysroot ()
+{
+  case "$lt_sysroot:$1" in
+  ?*:"$lt_sysroot"*)
+    func_stripname "$lt_sysroot" '' "$1"
+    func_replace_sysroot_result="=$func_stripname_result"
+    ;;
+  *)
+    # Including no sysroot.
+    func_replace_sysroot_result=$1
+    ;;
+  esac
+}
+
 # func_infer_tag arg
 # Infer tagged configuration to use if any are available and
 # if one wasn't chosen via the "--tag" command line option.
@@ -1013,13 +1382,15 @@ func_infer_tag ()
     if test -n "$available_tags" && test -z "$tagname"; then
       CC_quoted=
       for arg in $CC; do
-        func_quote_for_eval "$arg"
-       CC_quoted="$CC_quoted $func_quote_for_eval_result"
+       func_append_quoted CC_quoted "$arg"
       done
+      CC_expanded=`func_echo_all $CC`
+      CC_quoted_expanded=`func_echo_all $CC_quoted`
       case $@ in
       # Blanks in the command may have been stripped by the calling shell,
       # but not from the CC environment variable when configure was run.
-      " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*) ;;
+      " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+      " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*) ;;
       # Blanks at the start of $base_compile will cause this to fail
       # if we don't check for them as well.
       *)
@@ -1030,11 +1401,13 @@ func_infer_tag ()
            CC_quoted=
            for arg in $CC; do
              # Double-quote args containing other shell metacharacters.
-             func_quote_for_eval "$arg"
-             CC_quoted="$CC_quoted $func_quote_for_eval_result"
+             func_append_quoted CC_quoted "$arg"
            done
+           CC_expanded=`func_echo_all $CC`
+           CC_quoted_expanded=`func_echo_all $CC_quoted`
            case "$@ " in
-             " $CC "* | "$CC "* | " `$ECHO $CC` "* | "`$ECHO $CC` "* | " $CC_quoted"* | "$CC_quoted "* | " `$ECHO $CC_quoted` "* | "`$ECHO $CC_quoted` "*)
+           " $CC "* | "$CC "* | " $CC_expanded "* | "$CC_expanded "* | \
+           " $CC_quoted"* | "$CC_quoted "* | " $CC_quoted_expanded "* | "$CC_quoted_expanded "*)
              # The compiler in the base compile command matches
              # the one in the tagged configuration.
              # Assume this is the tagged configuration we want.
@@ -1097,6 +1470,486 @@ EOF
     }
 }
 
+
+##################################################
+# FILE NAME AND PATH CONVERSION HELPER FUNCTIONS #
+##################################################
+
+# func_convert_core_file_wine_to_w32 ARG
+# Helper function used by file name conversion functions when $build is *nix,
+# and $host is mingw, cygwin, or some other w32 environment. Relies on a
+# correctly configured wine environment available, with the winepath program
+# in $build's $PATH.
+#
+# ARG is the $build file name to be converted to w32 format.
+# Result is available in $func_convert_core_file_wine_to_w32_result, and will
+# be empty on error (or when ARG is empty)
+func_convert_core_file_wine_to_w32 ()
+{
+  $opt_debug
+  func_convert_core_file_wine_to_w32_result="$1"
+  if test -n "$1"; then
+    # Unfortunately, winepath does not exit with a non-zero error code, so we
+    # are forced to check the contents of stdout. On the other hand, if the
+    # command is not found, the shell will set an exit code of 127 and print
+    # *an error message* to stdout. So we must check for both error code of
+    # zero AND non-empty stdout, which explains the odd construction:
+    func_convert_core_file_wine_to_w32_tmp=`winepath -w "$1" 2>/dev/null`
+    if test "$?" -eq 0 && test -n "${func_convert_core_file_wine_to_w32_tmp}"; then
+      func_convert_core_file_wine_to_w32_result=`$ECHO "$func_convert_core_file_wine_to_w32_tmp" |
+        $SED -e "$lt_sed_naive_backslashify"`
+    else
+      func_convert_core_file_wine_to_w32_result=
+    fi
+  fi
+}
+# end: func_convert_core_file_wine_to_w32
+
+
+# func_convert_core_path_wine_to_w32 ARG
+# Helper function used by path conversion functions when $build is *nix, and
+# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly
+# configured wine environment available, with the winepath program in $build's
+# $PATH. Assumes ARG has no leading or trailing path separator characters.
+#
+# ARG is path to be converted from $build format to win32.
+# Result is available in $func_convert_core_path_wine_to_w32_result.
+# Unconvertible file (directory) names in ARG are skipped; if no directory names
+# are convertible, then the result may be empty.
+func_convert_core_path_wine_to_w32 ()
+{
+  $opt_debug
+  # unfortunately, winepath doesn't convert paths, only file names
+  func_convert_core_path_wine_to_w32_result=""
+  if test -n "$1"; then
+    oldIFS=$IFS
+    IFS=:
+    for func_convert_core_path_wine_to_w32_f in $1; do
+      IFS=$oldIFS
+      func_convert_core_file_wine_to_w32 "$func_convert_core_path_wine_to_w32_f"
+      if test -n "$func_convert_core_file_wine_to_w32_result" ; then
+        if test -z "$func_convert_core_path_wine_to_w32_result"; then
+          func_convert_core_path_wine_to_w32_result="$func_convert_core_file_wine_to_w32_result"
+        else
+          func_append func_convert_core_path_wine_to_w32_result ";$func_convert_core_file_wine_to_w32_result"
+        fi
+      fi
+    done
+    IFS=$oldIFS
+  fi
+}
+# end: func_convert_core_path_wine_to_w32
+
+
+# func_cygpath ARGS...
+# Wrapper around calling the cygpath program via LT_CYGPATH. This is used when
+# when (1) $build is *nix and Cygwin is hosted via a wine environment; or (2)
+# $build is MSYS and $host is Cygwin, or (3) $build is Cygwin. In case (1) or
+# (2), returns the Cygwin file name or path in func_cygpath_result (input
+# file name or path is assumed to be in w32 format, as previously converted
+# from $build's *nix or MSYS format). In case (3), returns the w32 file name
+# or path in func_cygpath_result (input file name or path is assumed to be in
+# Cygwin format). Returns an empty string on error.
+#
+# ARGS are passed to cygpath, with the last one being the file name or path to
+# be converted.
+#
+# Specify the absolute *nix (or w32) name to cygpath in the LT_CYGPATH
+# environment variable; do not put it in $PATH.
+func_cygpath ()
+{
+  $opt_debug
+  if test -n "$LT_CYGPATH" && test -f "$LT_CYGPATH"; then
+    func_cygpath_result=`$LT_CYGPATH "$@" 2>/dev/null`
+    if test "$?" -ne 0; then
+      # on failure, ensure result is empty
+      func_cygpath_result=
+    fi
+  else
+    func_cygpath_result=
+    func_error "LT_CYGPATH is empty or specifies non-existent file: \`$LT_CYGPATH'"
+  fi
+}
+#end: func_cygpath
+
+
+# func_convert_core_msys_to_w32 ARG
+# Convert file name or path ARG from MSYS format to w32 format.  Return
+# result in func_convert_core_msys_to_w32_result.
+func_convert_core_msys_to_w32 ()
+{
+  $opt_debug
+  # awkward: cmd appends spaces to result
+  func_convert_core_msys_to_w32_result=`( cmd //c echo "$1" ) 2>/dev/null |
+    $SED -e 's/[ ]*$//' -e "$lt_sed_naive_backslashify"`
+}
+#end: func_convert_core_msys_to_w32
+
+
+# func_convert_file_check ARG1 ARG2
+# Verify that ARG1 (a file name in $build format) was converted to $host
+# format in ARG2. Otherwise, emit an error message, but continue (resetting
+# func_to_host_file_result to ARG1).
+func_convert_file_check ()
+{
+  $opt_debug
+  if test -z "$2" && test -n "$1" ; then
+    func_error "Could not determine host file name corresponding to"
+    func_error "  \`$1'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback:
+    func_to_host_file_result="$1"
+  fi
+}
+# end func_convert_file_check
+
+
+# func_convert_path_check FROM_PATHSEP TO_PATHSEP FROM_PATH TO_PATH
+# Verify that FROM_PATH (a path in $build format) was converted to $host
+# format in TO_PATH. Otherwise, emit an error message, but continue, resetting
+# func_to_host_file_result to a simplistic fallback value (see below).
+func_convert_path_check ()
+{
+  $opt_debug
+  if test -z "$4" && test -n "$3"; then
+    func_error "Could not determine the host path corresponding to"
+    func_error "  \`$3'"
+    func_error "Continuing, but uninstalled executables may not work."
+    # Fallback.  This is a deliberately simplistic "conversion" and
+    # should not be "improved".  See libtool.info.
+    if test "x$1" != "x$2"; then
+      lt_replace_pathsep_chars="s|$1|$2|g"
+      func_to_host_path_result=`echo "$3" |
+        $SED -e "$lt_replace_pathsep_chars"`
+    else
+      func_to_host_path_result="$3"
+    fi
+  fi
+}
+# end func_convert_path_check
+
+
+# func_convert_path_front_back_pathsep FRONTPAT BACKPAT REPL ORIG
+# Modifies func_to_host_path_result by prepending REPL if ORIG matches FRONTPAT
+# and appending REPL if ORIG matches BACKPAT.
+func_convert_path_front_back_pathsep ()
+{
+  $opt_debug
+  case $4 in
+  $1 ) func_to_host_path_result="$3$func_to_host_path_result"
+    ;;
+  esac
+  case $4 in
+  $2 ) func_append func_to_host_path_result "$3"
+    ;;
+  esac
+}
+# end func_convert_path_front_back_pathsep
+
+
+##################################################
+# $build to $host FILE NAME CONVERSION FUNCTIONS #
+##################################################
+# invoked via `$to_host_file_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# Result will be available in $func_to_host_file_result.
+
+
+# func_to_host_file ARG
+# Converts the file name ARG from $build format to $host format. Return result
+# in func_to_host_file_result.
+func_to_host_file ()
+{
+  $opt_debug
+  $to_host_file_cmd "$1"
+}
+# end func_to_host_file
+
+
+# func_to_tool_file ARG LAZY
+# converts the file name ARG from $build format to toolchain format. Return
+# result in func_to_tool_file_result.  If the conversion in use is listed
+# in (the comma separated) LAZY, no conversion takes place.
+func_to_tool_file ()
+{
+  $opt_debug
+  case ,$2, in
+    *,"$to_tool_file_cmd",*)
+      func_to_tool_file_result=$1
+      ;;
+    *)
+      $to_tool_file_cmd "$1"
+      func_to_tool_file_result=$func_to_host_file_result
+      ;;
+  esac
+}
+# end func_to_tool_file
+
+
+# func_convert_file_noop ARG
+# Copy ARG to func_to_host_file_result.
+func_convert_file_noop ()
+{
+  func_to_host_file_result="$1"
+}
+# end func_convert_file_noop
+
+
+# func_convert_file_msys_to_w32 ARG
+# Convert file name ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_file_result.
+func_convert_file_msys_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_to_host_file_result="$func_convert_core_msys_to_w32_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_w32
+
+
+# func_convert_file_cygwin_to_w32 ARG
+# Convert file name ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_file_cygwin_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    # because $build is cygwin, we call "the" cygpath in $PATH; no need to use
+    # LT_CYGPATH in this case.
+    func_to_host_file_result=`cygpath -m "$1"`
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_cygwin_to_w32
+
+
+# func_convert_file_nix_to_w32 ARG
+# Convert file name ARG from *nix to w32 format.  Requires a wine environment
+# and a working winepath. Returns result in func_to_host_file_result.
+func_convert_file_nix_to_w32 ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_file_wine_to_w32 "$1"
+    func_to_host_file_result="$func_convert_core_file_wine_to_w32_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_w32
+
+
+# func_convert_file_msys_to_cygwin ARG
+# Convert file name ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_file_msys_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    func_convert_core_msys_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_msys_to_w32_result"
+    func_to_host_file_result="$func_cygpath_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_msys_to_cygwin
+
+
+# func_convert_file_nix_to_cygwin ARG
+# Convert file name ARG from *nix to Cygwin format.  Requires Cygwin installed
+# in a wine environment, working winepath, and LT_CYGPATH set.  Returns result
+# in func_to_host_file_result.
+func_convert_file_nix_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_file_result="$1"
+  if test -n "$1"; then
+    # convert from *nix to w32, then use cygpath to convert from w32 to cygwin.
+    func_convert_core_file_wine_to_w32 "$1"
+    func_cygpath -u "$func_convert_core_file_wine_to_w32_result"
+    func_to_host_file_result="$func_cygpath_result"
+  fi
+  func_convert_file_check "$1" "$func_to_host_file_result"
+}
+# end func_convert_file_nix_to_cygwin
+
+
+#############################################
+# $build to $host PATH CONVERSION FUNCTIONS #
+#############################################
+# invoked via `$to_host_path_cmd ARG'
+#
+# In each case, ARG is the path to be converted from $build to $host format.
+# The result will be available in $func_to_host_path_result.
+#
+# Path separators are also converted from $build format to $host format.  If
+# ARG begins or ends with a path separator character, it is preserved (but
+# converted to $host format) on output.
+#
+# All path conversion functions are named using the following convention:
+#   file name conversion function    : func_convert_file_X_to_Y ()
+#   path conversion function         : func_convert_path_X_to_Y ()
+# where, for any given $build/$host combination the 'X_to_Y' value is the
+# same.  If conversion functions are added for new $build/$host combinations,
+# the two new functions must follow this pattern, or func_init_to_host_path_cmd
+# will break.
+
+
+# func_init_to_host_path_cmd
+# Ensures that function "pointer" variable $to_host_path_cmd is set to the
+# appropriate value, based on the value of $to_host_file_cmd.
+to_host_path_cmd=
+func_init_to_host_path_cmd ()
+{
+  $opt_debug
+  if test -z "$to_host_path_cmd"; then
+    func_stripname 'func_convert_file_' '' "$to_host_file_cmd"
+    to_host_path_cmd="func_convert_path_${func_stripname_result}"
+  fi
+}
+
+
+# func_to_host_path ARG
+# Converts the path ARG from $build format to $host format. Return result
+# in func_to_host_path_result.
+func_to_host_path ()
+{
+  $opt_debug
+  func_init_to_host_path_cmd
+  $to_host_path_cmd "$1"
+}
+# end func_to_host_path
+
+
+# func_convert_path_noop ARG
+# Copy ARG to func_to_host_path_result.
+func_convert_path_noop ()
+{
+  func_to_host_path_result="$1"
+}
+# end func_convert_path_noop
+
+
+# func_convert_path_msys_to_w32 ARG
+# Convert path ARG from (mingw) MSYS to (mingw) w32 format; automatic
+# conversion to w32 is not available inside the cwrapper.  Returns result in
+# func_to_host_path_result.
+func_convert_path_msys_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from ARG.  MSYS
+    # behavior is inconsistent here; cygpath turns them into '.;' and ';.';
+    # and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result="$func_convert_core_msys_to_w32_result"
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_msys_to_w32
+
+
+# func_convert_path_cygwin_to_w32 ARG
+# Convert path ARG from Cygwin to w32 format.  Returns result in
+# func_to_host_file_result.
+func_convert_path_cygwin_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_to_host_path_result=`cygpath -m -p "$func_to_host_path_tmp1"`
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_cygwin_to_w32
+
+
+# func_convert_path_nix_to_w32 ARG
+# Convert path ARG from *nix to w32 format.  Requires a wine environment and
+# a working winepath.  Returns result in func_to_host_file_result.
+func_convert_path_nix_to_w32 ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_to_host_path_result="$func_convert_core_path_wine_to_w32_result"
+    func_convert_path_check : ";" \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" ";" "$1"
+  fi
+}
+# end func_convert_path_nix_to_w32
+
+
+# func_convert_path_msys_to_cygwin ARG
+# Convert path ARG from MSYS to Cygwin format.  Requires LT_CYGPATH set.
+# Returns result in func_to_host_file_result.
+func_convert_path_msys_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # See func_convert_path_msys_to_w32:
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_msys_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_msys_to_w32_result"
+    func_to_host_path_result="$func_cygpath_result"
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_msys_to_cygwin
+
+
+# func_convert_path_nix_to_cygwin ARG
+# Convert path ARG from *nix to Cygwin format.  Requires Cygwin installed in a
+# a wine environment, working winepath, and LT_CYGPATH set.  Returns result in
+# func_to_host_file_result.
+func_convert_path_nix_to_cygwin ()
+{
+  $opt_debug
+  func_to_host_path_result="$1"
+  if test -n "$1"; then
+    # Remove leading and trailing path separator characters from
+    # ARG. msys behavior is inconsistent here, cygpath turns them
+    # into '.;' and ';.', and winepath ignores them completely.
+    func_stripname : : "$1"
+    func_to_host_path_tmp1=$func_stripname_result
+    func_convert_core_path_wine_to_w32 "$func_to_host_path_tmp1"
+    func_cygpath -u -p "$func_convert_core_path_wine_to_w32_result"
+    func_to_host_path_result="$func_cygpath_result"
+    func_convert_path_check : : \
+      "$func_to_host_path_tmp1" "$func_to_host_path_result"
+    func_convert_path_front_back_pathsep ":*" "*:" : "$1"
+  fi
+}
+# end func_convert_path_nix_to_cygwin
+
+
 # func_mode_compile arg...
 func_mode_compile ()
 {
@@ -1137,12 +1990,12 @@ func_mode_compile ()
          ;;
 
        -pie | -fpie | -fPIE)
-          pie_flag="$pie_flag $arg"
+          func_append pie_flag " $arg"
          continue
          ;;
 
        -shared | -static | -prefer-pic | -prefer-non-pic)
-         later="$later $arg"
+         func_append later " $arg"
          continue
          ;;
 
@@ -1163,15 +2016,14 @@ func_mode_compile ()
          save_ifs="$IFS"; IFS=','
          for arg in $args; do
            IFS="$save_ifs"
-           func_quote_for_eval "$arg"
-           lastarg="$lastarg $func_quote_for_eval_result"
+           func_append_quoted lastarg "$arg"
          done
          IFS="$save_ifs"
          func_stripname ' ' '' "$lastarg"
          lastarg=$func_stripname_result
 
          # Add the arguments to base_compile.
-         base_compile="$base_compile $lastarg"
+         func_append base_compile " $lastarg"
          continue
          ;;
 
@@ -1187,8 +2039,7 @@ func_mode_compile ()
       esac    #  case $arg_mode
 
       # Aesthetically quote the previous argument.
-      func_quote_for_eval "$lastarg"
-      base_compile="$base_compile $func_quote_for_eval_result"
+      func_append_quoted base_compile "$lastarg"
     done # for arg
 
     case $arg_mode in
@@ -1213,7 +2064,7 @@ func_mode_compile ()
     *.[cCFSifmso] | \
     *.ada | *.adb | *.ads | *.asm | \
     *.c++ | *.cc | *.ii | *.class | *.cpp | *.cxx | \
-    *.[fF][09]? | *.for | *.java | *.obj | *.sx)
+    *.[fF][09]? | *.for | *.java | *.go | *.obj | *.sx | *.cu | *.cup)
       func_xform "$libobj"
       libobj=$func_xform_result
       ;;
@@ -1288,7 +2139,7 @@ func_mode_compile ()
     # Calculate the filename of the output object if compiler does
     # not support -o with -c
     if test "$compiler_c_o" = no; then
-      output_obj=`$ECHO "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext}
+      output_obj=`$ECHO "$srcfile" | $SED 's%^.*/%%; s%\.[^.]*$%%'`.${objext}
       lockfile="$output_obj.lock"
     else
       output_obj=
@@ -1319,17 +2170,16 @@ compiler."
        $opt_dry_run || $RM $removelist
        exit $EXIT_FAILURE
       fi
-      removelist="$removelist $output_obj"
+      func_append removelist " $output_obj"
       $ECHO "$srcfile" > "$lockfile"
     fi
 
     $opt_dry_run || $RM $removelist
-    removelist="$removelist $lockfile"
+    func_append removelist " $lockfile"
     trap '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE' 1 2 15
 
-    if test -n "$fix_srcfile_path"; then
-      eval srcfile=\"$fix_srcfile_path\"
-    fi
+    func_to_tool_file "$srcfile" func_convert_file_msys_to_w32
+    srcfile=$func_to_tool_file_result
     func_quote_for_eval "$srcfile"
     qsrcfile=$func_quote_for_eval_result
 
@@ -1349,7 +2199,7 @@ compiler."
 
       if test -z "$output_obj"; then
        # Place PIC objects in $objdir
-       command="$command -o $lobj"
+       func_append command " -o $lobj"
       fi
 
       func_show_eval_locale "$command" \
@@ -1396,11 +2246,11 @@ compiler."
        command="$base_compile $qsrcfile $pic_flag"
       fi
       if test "$compiler_c_o" = yes; then
-       command="$command -o $obj"
+       func_append command " -o $obj"
       fi
 
       # Suppress compiler output if we already did a PIC compilation.
-      command="$command$suppress_output"
+      func_append command "$suppress_output"
       func_show_eval_locale "$command" \
         '$opt_dry_run || $RM $removelist; exit $EXIT_FAILURE'
 
@@ -1445,13 +2295,13 @@ compiler."
 }
 
 $opt_help || {
-test "$mode" = compile && func_mode_compile ${1+"$@"}
+  test "$opt_mode" = compile && func_mode_compile ${1+"$@"}
 }
 
 func_mode_help ()
 {
     # We need to display help for each of the modes.
-    case $mode in
+    case $opt_mode in
       "")
         # Generic help is extracted from the usage comments
         # at the start of this file.
@@ -1482,10 +2332,11 @@ This mode accepts the following additional options:
 
   -o OUTPUT-FILE    set the output file name to OUTPUT-FILE
   -no-suppress      do not suppress compiler output for multiple passes
-  -prefer-pic       try to building PIC objects only
-  -prefer-non-pic   try to building non-PIC objects only
+  -prefer-pic       try to build PIC objects only
+  -prefer-non-pic   try to build non-PIC objects only
   -shared           do not build a \`.o' file suitable for static linking
   -static           only build a \`.o' file suitable for static linking
+  -Wc,FLAG          pass FLAG directly to the compiler
 
 COMPILE-COMMAND is a command to be used in creating a \`standard' object file
 from the given SOURCEFILE.
@@ -1538,7 +2389,7 @@ either the \`install' or \`cp' program.
 
 The following components of INSTALL-COMMAND are treated specially:
 
-  -inst-prefix PREFIX-DIR  Use PREFIX-DIR as a staging area for installation
+  -inst-prefix-dir PREFIX-DIR  Use PREFIX-DIR as a staging area for installation
 
 The rest of the components are interpreted as arguments to that command (only
 BSD-compatible install options are recognized)."
@@ -1558,6 +2409,8 @@ The following components of LINK-COMMAND are treated specially:
 
   -all-static       do not do any dynamic linking at all
   -avoid-version    do not add a version suffix if possible
+  -bindir BINDIR    specify path to binaries directory (for systems where
+                    libraries must be found in the PATH setting at runtime)
   -dlopen FILE      \`-dlpreopen' FILE if it cannot be dlopened at runtime
   -dlpreopen FILE   link in FILE and add its symbols to lt_preloaded_symbols
   -export-dynamic   allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
@@ -1586,6 +2439,11 @@ The following components of LINK-COMMAND are treated specially:
   -version-info CURRENT[:REVISION[:AGE]]
                     specify library version info [each variable defaults to 0]
   -weak LIBNAME     declare that the target provides the LIBNAME interface
+  -Wc,FLAG
+  -Xcompiler FLAG   pass linker-specific FLAG directly to the compiler
+  -Wl,FLAG
+  -Xlinker FLAG     pass linker-specific FLAG directly to the linker
+  -XCClinker FLAG   pass link-specific FLAG to the compiler driver (CC)
 
 All other options (arguments beginning with \`-') are ignored.
 
@@ -1619,18 +2477,44 @@ Otherwise, only FILE itself is deleted using RM."
         ;;
 
       *)
-        func_fatal_help "invalid operation mode \`$mode'"
+        func_fatal_help "invalid operation mode \`$opt_mode'"
         ;;
     esac
 
-    $ECHO
+    echo
     $ECHO "Try \`$progname --help' for more information about other modes."
-
-    exit $?
 }
 
-  # Now that we've collected a possible --mode arg, show help if necessary
-  $opt_help && func_mode_help
+# Now that we've collected a possible --mode arg, show help if necessary
+if $opt_help; then
+  if test "$opt_help" = :; then
+    func_mode_help
+  else
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+       func_mode_help
+      done
+    } | sed -n '1p; 2,$s/^Usage:/  or: /p'
+    {
+      func_help noexit
+      for opt_mode in compile link execute install finish uninstall clean; do
+       echo
+       func_mode_help
+      done
+    } |
+    sed '1d
+      /^When reporting/,/^Report/{
+       H
+       d
+      }
+      $x
+      /information about other modes/d
+      /more detailed .*MODE/d
+      s/^Usage:.*--mode=\([^ ]*\) .*/Description of \1 mode:/'
+  fi
+  exit $?
+fi
 
 
 # func_mode_execute arg...
@@ -1643,13 +2527,16 @@ func_mode_execute ()
       func_fatal_help "you must specify a COMMAND"
 
     # Handle -dlopen flags immediately.
-    for file in $execute_dlfiles; do
+    for file in $opt_dlopen; do
       test -f "$file" \
        || func_fatal_help "\`$file' is not a file"
 
       dir=
       case $file in
       *.la)
+       func_resolve_sysroot "$file"
+       file=$func_resolve_sysroot_result
+
        # Check to see that this really is a libtool archive.
        func_lalib_unsafe_p "$file" \
          || func_fatal_help "\`$lib' is not a valid libtool archive"
@@ -1671,7 +2558,7 @@ func_mode_execute ()
        dir="$func_dirname_result"
 
        if test -f "$dir/$objdir/$dlname"; then
-         dir="$dir/$objdir"
+         func_append dir "/$objdir"
        else
          if test ! -f "$dir/$dlname"; then
            func_fatal_error "cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'"
@@ -1712,7 +2599,7 @@ func_mode_execute ()
     for file
     do
       case $file in
-      -*) ;;
+      -* | *.la | *.lo ) ;;
       *)
        # Do a test to see if this is really a libtool program.
        if func_ltwrapper_script_p "$file"; then
@@ -1728,8 +2615,7 @@ func_mode_execute ()
        ;;
       esac
       # Quote arguments (to preserve shell metacharacters).
-      func_quote_for_eval "$file"
-      args="$args $func_quote_for_eval_result"
+      func_append_quoted args "$file"
     done
 
     if test "X$opt_dry_run" = Xfalse; then
@@ -1754,29 +2640,66 @@ func_mode_execute ()
       # Display what would be done.
       if test -n "$shlibpath_var"; then
        eval "\$ECHO \"\$shlibpath_var=\$$shlibpath_var\""
-       $ECHO "export $shlibpath_var"
+       echo "export $shlibpath_var"
       fi
       $ECHO "$cmd$args"
       exit $EXIT_SUCCESS
     fi
 }
 
-test "$mode" = execute && func_mode_execute ${1+"$@"}
+test "$opt_mode" = execute && func_mode_execute ${1+"$@"}
 
 
 # func_mode_finish arg...
 func_mode_finish ()
 {
     $opt_debug
-    libdirs="$nonopt"
+    libs=
+    libdirs=
     admincmds=
 
-    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
-      for dir
-      do
-       libdirs="$libdirs $dir"
-      done
+    for opt in "$nonopt" ${1+"$@"}
+    do
+      if test -d "$opt"; then
+       func_append libdirs " $opt"
+
+      elif test -f "$opt"; then
+       if func_lalib_unsafe_p "$opt"; then
+         func_append libs " $opt"
+       else
+         func_warning "\`$opt' is not a valid libtool archive"
+       fi
+
+      else
+       func_fatal_error "invalid argument \`$opt'"
+      fi
+    done
+
+    if test -n "$libs"; then
+      if test -n "$lt_sysroot"; then
+        sysroot_regex=`$ECHO "$lt_sysroot" | $SED "$sed_make_literal_regex"`
+        sysroot_cmd="s/\([ ']\)$sysroot_regex/\1/g;"
+      else
+        sysroot_cmd=
+      fi
+
+      # Remove sysroot references
+      if $opt_dry_run; then
+        for lib in $libs; do
+          echo "removing references to $lt_sysroot and \`=' prefixes from $lib"
+        done
+      else
+        tmpdir=`func_mktempdir`
+        for lib in $libs; do
+         sed -e "${sysroot_cmd} s/\([ ']-[LR]\)=/\1/g; s/\([ ']\)=/\1/g" $lib \
+           > $tmpdir/tmp-la
+         mv -f $tmpdir/tmp-la $lib
+       done
+        ${RM}r "$tmpdir"
+      fi
+    fi
 
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
       for libdir in $libdirs; do
        if test -n "$finish_cmds"; then
          # Do each command in the finish commands.
@@ -1786,7 +2709,7 @@ func_mode_finish ()
        if test -n "$finish_eval"; then
          # Do the single finish_eval.
          eval cmds=\"$finish_eval\"
-         $opt_dry_run || eval "$cmds" || admincmds="$admincmds
+         $opt_dry_run || eval "$cmds" || func_append admincmds "
        $cmds"
        fi
       done
@@ -1795,53 +2718,55 @@ func_mode_finish ()
     # Exit here if they wanted silent mode.
     $opt_silent && exit $EXIT_SUCCESS
 
-    $ECHO "X----------------------------------------------------------------------" | $Xsed
-    $ECHO "Libraries have been installed in:"
-    for libdir in $libdirs; do
-      $ECHO "   $libdir"
-    done
-    $ECHO
-    $ECHO "If you ever happen to want to link against installed libraries"
-    $ECHO "in a given directory, LIBDIR, you must either use libtool, and"
-    $ECHO "specify the full pathname of the library, or use the \`-LLIBDIR'"
-    $ECHO "flag during linking and do at least one of the following:"
-    if test -n "$shlibpath_var"; then
-      $ECHO "   - add LIBDIR to the \`$shlibpath_var' environment variable"
-      $ECHO "     during execution"
-    fi
-    if test -n "$runpath_var"; then
-      $ECHO "   - add LIBDIR to the \`$runpath_var' environment variable"
-      $ECHO "     during linking"
-    fi
-    if test -n "$hardcode_libdir_flag_spec"; then
-      libdir=LIBDIR
-      eval flag=\"$hardcode_libdir_flag_spec\"
+    if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+      echo "----------------------------------------------------------------------"
+      echo "Libraries have been installed in:"
+      for libdir in $libdirs; do
+       $ECHO "   $libdir"
+      done
+      echo
+      echo "If you ever happen to want to link against installed libraries"
+      echo "in a given directory, LIBDIR, you must either use libtool, and"
+      echo "specify the full pathname of the library, or use the \`-LLIBDIR'"
+      echo "flag during linking and do at least one of the following:"
+      if test -n "$shlibpath_var"; then
+       echo "   - add LIBDIR to the \`$shlibpath_var' environment variable"
+       echo "     during execution"
+      fi
+      if test -n "$runpath_var"; then
+       echo "   - add LIBDIR to the \`$runpath_var' environment variable"
+       echo "     during linking"
+      fi
+      if test -n "$hardcode_libdir_flag_spec"; then
+       libdir=LIBDIR
+       eval flag=\"$hardcode_libdir_flag_spec\"
 
-      $ECHO "   - use the \`$flag' linker flag"
-    fi
-    if test -n "$admincmds"; then
-      $ECHO "   - have your system administrator run these commands:$admincmds"
-    fi
-    if test -f /etc/ld.so.conf; then
-      $ECHO "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
-    fi
-    $ECHO
+       $ECHO "   - use the \`$flag' linker flag"
+      fi
+      if test -n "$admincmds"; then
+       $ECHO "   - have your system administrator run these commands:$admincmds"
+      fi
+      if test -f /etc/ld.so.conf; then
+       echo "   - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+      fi
+      echo
 
-    $ECHO "See any operating system documentation about shared libraries for"
-    case $host in
-      solaris2.[6789]|solaris2.1[0-9])
-        $ECHO "more information, such as the ld(1), crle(1) and ld.so(8) manual"
-       $ECHO "pages."
-       ;;
-      *)
-        $ECHO "more information, such as the ld(1) and ld.so(8) manual pages."
-        ;;
-    esac
-    $ECHO "X----------------------------------------------------------------------" | $Xsed
+      echo "See any operating system documentation about shared libraries for"
+      case $host in
+       solaris2.[6789]|solaris2.1[0-9])
+         echo "more information, such as the ld(1), crle(1) and ld.so(8) manual"
+         echo "pages."
+         ;;
+       *)
+         echo "more information, such as the ld(1) and ld.so(8) manual pages."
+         ;;
+      esac
+      echo "----------------------------------------------------------------------"
+    fi
     exit $EXIT_SUCCESS
 }
 
-test "$mode" = finish && func_mode_finish ${1+"$@"}
+test "$opt_mode" = finish && func_mode_finish ${1+"$@"}
 
 
 # func_mode_install arg...
@@ -1852,7 +2777,7 @@ func_mode_install ()
     # install_prog (especially on Windows NT).
     if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh ||
        # Allow the use of GNU shtool's install command.
-       $ECHO "X$nonopt" | $GREP shtool >/dev/null; then
+       case $nonopt in *shtool*) :;; *) false;; esac; then
       # Aesthetically quote it.
       func_quote_for_eval "$nonopt"
       install_prog="$func_quote_for_eval_result "
@@ -1866,7 +2791,12 @@ func_mode_install ()
     # The real first argument should be the name of the installation program.
     # Aesthetically quote it.
     func_quote_for_eval "$arg"
-    install_prog="$install_prog$func_quote_for_eval_result"
+    func_append install_prog "$func_quote_for_eval_result"
+    install_shared_prog=$install_prog
+    case " $install_prog " in
+      *[\\\ /]cp\ *) install_cp=: ;;
+      *) install_cp=false ;;
+    esac
 
     # We need to accept at least all the BSD install flags.
     dest=
@@ -1876,10 +2806,12 @@ func_mode_install ()
     install_type=
     isdir=no
     stripme=
+    no_mode=:
     for arg
     do
+      arg2=
       if test -n "$dest"; then
-       files="$files $dest"
+       func_append files " $dest"
        dest=$arg
        continue
       fi
@@ -1887,10 +2819,9 @@ func_mode_install ()
       case $arg in
       -d) isdir=yes ;;
       -f)
-       case " $install_prog " in
-       *[\\\ /]cp\ *) ;;
-       *) prev=$arg ;;
-       esac
+       if $install_cp; then :; else
+         prev=$arg
+       fi
        ;;
       -g | -m | -o)
        prev=$arg
@@ -1904,6 +2835,10 @@ func_mode_install ()
       *)
        # If the previous option needed an argument, then skip it.
        if test -n "$prev"; then
+         if test "x$prev" = x-m && test -n "$install_override_mode"; then
+           arg2=$install_override_mode
+           no_mode=false
+         fi
          prev=
        else
          dest=$arg
@@ -1914,7 +2849,11 @@ func_mode_install ()
 
       # Aesthetically quote the argument.
       func_quote_for_eval "$arg"
-      install_prog="$install_prog $func_quote_for_eval_result"
+      func_append install_prog " $func_quote_for_eval_result"
+      if test -n "$arg2"; then
+       func_quote_for_eval "$arg2"
+      fi
+      func_append install_shared_prog " $func_quote_for_eval_result"
     done
 
     test -z "$install_prog" && \
@@ -1923,6 +2862,13 @@ func_mode_install ()
     test -n "$prev" && \
       func_fatal_help "the \`$prev' option requires an argument"
 
+    if test -n "$install_override_mode" && $no_mode; then
+      if $install_cp; then :; else
+       func_quote_for_eval "$install_override_mode"
+       func_append install_shared_prog " -m $func_quote_for_eval_result"
+      fi
+    fi
+
     if test -z "$files"; then
       if test -z "$dest"; then
        func_fatal_help "no file or destination specified"
@@ -1977,10 +2923,13 @@ func_mode_install ()
       case $file in
       *.$libext)
        # Do the static libraries later.
-       staticlibs="$staticlibs $file"
+       func_append staticlibs " $file"
        ;;
 
       *.la)
+       func_resolve_sysroot "$file"
+       file=$func_resolve_sysroot_result
+
        # Check to see that this really is a libtool archive.
        func_lalib_unsafe_p "$file" \
          || func_fatal_help "\`$file' is not a valid libtool archive"
@@ -1994,23 +2943,23 @@ func_mode_install ()
        if test "X$destdir" = "X$libdir"; then
          case "$current_libdirs " in
          *" $libdir "*) ;;
-         *) current_libdirs="$current_libdirs $libdir" ;;
+         *) func_append current_libdirs " $libdir" ;;
          esac
        else
          # Note the libdir as a future libdir.
          case "$future_libdirs " in
          *" $libdir "*) ;;
-         *) future_libdirs="$future_libdirs $libdir" ;;
+         *) func_append future_libdirs " $libdir" ;;
          esac
        fi
 
        func_dirname "$file" "/" ""
        dir="$func_dirname_result"
-       dir="$dir$objdir"
+       func_append dir "$objdir"
 
        if test -n "$relink_command"; then
          # Determine the prefix the user has applied to our future dir.
-         inst_prefix_dir=`$ECHO "X$destdir" | $Xsed -e "s%$libdir\$%%"`
+         inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"`
 
          # Don't allow the user to place us outside of our expected
          # location b/c this prevents finding dependent libraries that
@@ -2023,9 +2972,9 @@ func_mode_install ()
 
          if test -n "$inst_prefix_dir"; then
            # Stick the inst_prefix_dir data into the link command.
-           relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
+           relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%-inst-prefix-dir $inst_prefix_dir%"`
          else
-           relink_command=`$ECHO "X$relink_command" | $Xsed -e "s%@inst_prefix_dir@%%"`
+           relink_command=`$ECHO "$relink_command" | $SED "s%@inst_prefix_dir@%%"`
          fi
 
          func_warning "relinking \`$file'"
@@ -2043,7 +2992,7 @@ func_mode_install ()
          test -n "$relink_command" && srcname="$realname"T
 
          # Install the shared library and build the symlinks.
-         func_show_eval "$install_prog $dir/$srcname $destdir/$realname" \
+         func_show_eval "$install_shared_prog $dir/$srcname $destdir/$realname" \
              'exit $?'
          tstripme="$stripme"
          case $host_os in
@@ -2083,7 +3032,7 @@ func_mode_install ()
        func_show_eval "$install_prog $instname $destdir/$name" 'exit $?'
 
        # Maybe install the static library, too.
-       test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+       test -n "$old_library" && func_append staticlibs " $dir/$old_library"
        ;;
 
       *.lo)
@@ -2183,7 +3132,7 @@ func_mode_install ()
            if test -f "$lib"; then
              func_source "$lib"
            fi
-           libfile="$libdir/"`$ECHO "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test
+           libfile="$libdir/"`$ECHO "$lib" | $SED 's%^.*/%%g'` ### testsuite: skip nested quoting test
            if test -n "$libdir" && test ! -f "$libfile"; then
              func_warning "\`$lib' has not been installed in \`$libdir'"
              finalize=no
@@ -2202,7 +3151,7 @@ func_mode_install ()
                file="$func_basename_result"
                outputname="$tmpdir/$file"
                # Replace the output file specification.
-               relink_command=`$ECHO "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+               relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'`
 
                $opt_silent || {
                  func_quote_for_expand "$relink_command"
@@ -2221,7 +3170,7 @@ func_mode_install ()
            }
          else
            # Install the binary that we compiled earlier.
-           file=`$ECHO "X$file$stripped_ext" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+           file=`$ECHO "$file$stripped_ext" | $SED "s%\([^/]*\)$%$objdir/\1%"`
          fi
        fi
 
@@ -2257,11 +3206,13 @@ func_mode_install ()
 
       # Set up the ranlib parameters.
       oldlib="$destdir/$name"
+      func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+      tool_oldlib=$func_to_tool_file_result
 
       func_show_eval "$install_prog \$file \$oldlib" 'exit $?'
 
       if test -n "$stripme" && test -n "$old_striplib"; then
-       func_show_eval "$old_striplib $oldlib" 'exit $?'
+       func_show_eval "$old_striplib $tool_oldlib" 'exit $?'
       fi
 
       # Do each command in the postinstall commands.
@@ -2280,7 +3231,7 @@ func_mode_install ()
     fi
 }
 
-test "$mode" = install && func_mode_install ${1+"$@"}
+test "$opt_mode" = install && func_mode_install ${1+"$@"}
 
 
 # func_generate_dlsyms outputname originator pic_p
@@ -2323,6 +3274,22 @@ func_generate_dlsyms ()
 extern \"C\" {
 #endif
 
+#if defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4)) || (__GNUC__ > 4))
+#pragma GCC diagnostic ignored \"-Wstrict-prototypes\"
+#endif
+
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
 /* External symbol declarations for the compiler. */\
 "
 
@@ -2332,10 +3299,11 @@ extern \"C\" {
          $opt_dry_run || echo ': @PROGRAM@ ' > "$nlist"
 
          # Add our own program objects to the symbol list.
-         progfiles=`$ECHO "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+         progfiles=`$ECHO "$objs$old_deplibs" | $SP2NL | $SED "$lo2o" | $NL2SP`
          for progfile in $progfiles; do
-           func_verbose "extracting global C symbols from \`$progfile'"
-           $opt_dry_run || eval "$NM $progfile | $global_symbol_pipe >> '$nlist'"
+           func_to_tool_file "$progfile" func_convert_file_msys_to_w32
+           func_verbose "extracting global C symbols from \`$func_to_tool_file_result'"
+           $opt_dry_run || eval "$NM $func_to_tool_file_result | $global_symbol_pipe >> '$nlist'"
          done
 
          if test -n "$exclude_expsyms"; then
@@ -2371,7 +3339,7 @@ extern \"C\" {
              eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T'
              eval '$MV "$nlist"T "$nlist"'
              case $host in
-               *cygwin | *mingw* | *cegcc* )
+               *cygwin* | *mingw* | *cegcc* )
                  eval "echo EXPORTS "'> "$output_objdir/$outputname.def"'
                  eval 'cat "$nlist" >> "$output_objdir/$outputname.def"'
                  ;;
@@ -2384,10 +3352,52 @@ extern \"C\" {
          func_verbose "extracting global C symbols from \`$dlprefile'"
          func_basename "$dlprefile"
          name="$func_basename_result"
-         $opt_dry_run || {
-           eval '$ECHO ": $name " >> "$nlist"'
-           eval "$NM $dlprefile 2>/dev/null | $global_symbol_pipe >> '$nlist'"
-         }
+          case $host in
+           *cygwin* | *mingw* | *cegcc* )
+             # if an import library, we need to obtain dlname
+             if func_win32_import_lib_p "$dlprefile"; then
+               func_tr_sh "$dlprefile"
+               eval "curr_lafile=\$libfile_$func_tr_sh_result"
+               dlprefile_dlbasename=""
+               if test -n "$curr_lafile" && func_lalib_p "$curr_lafile"; then
+                 # Use subshell, to avoid clobbering current variable values
+                 dlprefile_dlname=`source "$curr_lafile" && echo "$dlname"`
+                 if test -n "$dlprefile_dlname" ; then
+                   func_basename "$dlprefile_dlname"
+                   dlprefile_dlbasename="$func_basename_result"
+                 else
+                   # no lafile. user explicitly requested -dlpreopen <import library>.
+                   $sharedlib_from_linklib_cmd "$dlprefile"
+                   dlprefile_dlbasename=$sharedlib_from_linklib_result
+                 fi
+               fi
+               $opt_dry_run || {
+                 if test -n "$dlprefile_dlbasename" ; then
+                   eval '$ECHO ": $dlprefile_dlbasename" >> "$nlist"'
+                 else
+                   func_warning "Could not compute DLL name from $name"
+                   eval '$ECHO ": $name " >> "$nlist"'
+                 fi
+                 func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+                 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe |
+                   $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'"
+               }
+             else # not an import lib
+               $opt_dry_run || {
+                 eval '$ECHO ": $name " >> "$nlist"'
+                 func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+                 eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+               }
+             fi
+           ;;
+           *)
+             $opt_dry_run || {
+               eval '$ECHO ": $name " >> "$nlist"'
+               func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32
+               eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe >> '$nlist'"
+             }
+           ;;
+          esac
        done
 
        $opt_dry_run || {
@@ -2415,36 +3425,19 @@ extern \"C\" {
          if test -f "$nlist"S; then
            eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$my_dlsyms"'
          else
-           $ECHO '/* NONE */' >> "$output_objdir/$my_dlsyms"
+           echo '/* NONE */' >> "$output_objdir/$my_dlsyms"
          fi
 
-         $ECHO >> "$output_objdir/$my_dlsyms" "\
+         echo >> "$output_objdir/$my_dlsyms" "\
 
 /* The mapping between symbol names and symbols.  */
 typedef struct {
   const char *name;
   void *address;
 } lt_dlsymlist;
-"
-         case $host in
-         *cygwin* | *mingw* | *cegcc* )
-           $ECHO >> "$output_objdir/$my_dlsyms" "\
-/* DATA imports from DLLs on WIN32 con't be const, because
-   runtime relocations are performed -- see ld's documentation
-   on pseudo-relocs.  */"
-           lt_dlsym_const= ;;
-         *osf5*)
-           echo >> "$output_objdir/$my_dlsyms" "\
-/* This system does not cope well with relocations in const data */"
-           lt_dlsym_const= ;;
-         *)
-           lt_dlsym_const=const ;;
-         esac
-
-         $ECHO >> "$output_objdir/$my_dlsyms" "\
-extern $lt_dlsym_const lt_dlsymlist
+extern LT_DLSYM_CONST lt_dlsymlist
 lt_${my_prefix}_LTX_preloaded_symbols[];
-$lt_dlsym_const lt_dlsymlist
+LT_DLSYM_CONST lt_dlsymlist
 lt_${my_prefix}_LTX_preloaded_symbols[] =
 {\
   { \"$my_originator\", (void *) 0 },"
@@ -2457,7 +3450,7 @@ lt_${my_prefix}_LTX_preloaded_symbols[] =
            eval "$global_symbol_to_c_name_address_lib_prefix" < "$nlist" >> "$output_objdir/$my_dlsyms"
            ;;
          esac
-         $ECHO >> "$output_objdir/$my_dlsyms" "\
+         echo >> "$output_objdir/$my_dlsyms" "\
   {0, (void *) 0}
 };
 
@@ -2484,7 +3477,7 @@ static const void *lt_preloaded_setup() {
          # linked before any other PIC object.  But we must not use
          # pic_flag when linking with -static.  The problem exists in
          # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
-         *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+         *-*-freebsd2.*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
            pic_flag_for_symtable=" $pic_flag -DFREEBSD_WORKAROUND" ;;
          *-*-hpux*)
            pic_flag_for_symtable=" $pic_flag"  ;;
@@ -2500,7 +3493,7 @@ static const void *lt_preloaded_setup() {
        for arg in $LTCFLAGS; do
          case $arg in
          -pie | -fpie | -fPIE) ;;
-         *) symtab_cflags="$symtab_cflags $arg" ;;
+         *) func_append symtab_cflags " $arg" ;;
          esac
        done
 
@@ -2515,16 +3508,16 @@ static const void *lt_preloaded_setup() {
        case $host in
        *cygwin* | *mingw* | *cegcc* )
          if test -f "$output_objdir/$my_outputname.def"; then
-           compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
-           finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+           compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
+           finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"`
          else
-           compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
-           finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+           compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+           finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
          fi
          ;;
        *)
-         compile_command=`$ECHO "X$compile_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
-         finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$symfileobj%"`
+         compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$symfileobj%"`
+         finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$symfileobj%"`
          ;;
        esac
        ;;
@@ -2538,8 +3531,8 @@ static const void *lt_preloaded_setup() {
       # really was required.
 
       # Nullify the symbol file.
-      compile_command=`$ECHO "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
-      finalize_command=`$ECHO "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+      compile_command=`$ECHO "$compile_command" | $SED "s% @SYMFILE@%%"`
+      finalize_command=`$ECHO "$finalize_command" | $SED "s% @SYMFILE@%%"`
     fi
 }
 
@@ -2549,6 +3542,7 @@ static const void *lt_preloaded_setup() {
 # Need a lot of goo to handle *both* DLLs and import libs
 # Has to be a shell function in order to 'eat' the argument
 # that is supplied when $file_magic_command is called.
+# Despite the name, also deal with 64 bit binaries.
 func_win32_libid ()
 {
   $opt_debug
@@ -2559,9 +3553,11 @@ func_win32_libid ()
     win32_libid_type="x86 archive import"
     ;;
   *ar\ archive*) # could be an import, or static
+    # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD.
     if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null |
-       $EGREP 'file format pe-i386(.*architecture: i386)?' >/dev/null ; then
-      win32_nmres=`eval $NM -f posix -A $1 |
+       $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then
+      func_to_tool_file "$1" func_convert_file_msys_to_w32
+      win32_nmres=`eval $NM -f posix -A \"$func_to_tool_file_result\" |
        $SED -n -e '
            1,100{
                / I /{
@@ -2590,6 +3586,131 @@ func_win32_libid ()
   $ECHO "$win32_libid_type"
 }
 
+# func_cygming_dll_for_implib ARG
+#
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib ()
+{
+  $opt_debug
+  sharedlib_from_linklib_result=`$DLLTOOL --identify-strict --identify "$1"`
+}
+
+# func_cygming_dll_for_implib_fallback_core SECTION_NAME LIBNAMEs
+#
+# The is the core of a fallback implementation of a
+# platform-specific function to extract the name of the
+# DLL associated with the specified import library LIBNAME.
+#
+# SECTION_NAME is either .idata$6 or .idata$7, depending
+# on the platform and compiler that created the implib.
+#
+# Echos the name of the DLL associated with the
+# specified import library.
+func_cygming_dll_for_implib_fallback_core ()
+{
+  $opt_debug
+  match_literal=`$ECHO "$1" | $SED "$sed_make_literal_regex"`
+  $OBJDUMP -s --section "$1" "$2" 2>/dev/null |
+    $SED '/^Contents of section '"$match_literal"':/{
+      # Place marker at beginning of archive member dllname section
+      s/.*/====MARK====/
+      p
+      d
+    }
+    # These lines can sometimes be longer than 43 characters, but
+    # are always uninteresting
+    /:[         ]*file format pe[i]\{,1\}-/d
+    /^In archive [^:]*:/d
+    # Ensure marker is printed
+    /^====MARK====/p
+    # Remove all lines with less than 43 characters
+    /^.\{43\}/!d
+    # From remaining lines, remove first 43 characters
+    s/^.\{43\}//' |
+    $SED -n '
+      # Join marker and all lines until next marker into a single line
+      /^====MARK====/ b para
+      H
+      $ b para
+      b
+      :para
+      x
+      s/\n//g
+      # Remove the marker
+      s/^====MARK====//
+      # Remove trailing dots and whitespace
+      s/[\. \t]*$//
+      # Print
+      /./p' |
+    # we now have a list, one entry per line, of the stringified
+    # contents of the appropriate section of all members of the
+    # archive which possess that section. Heuristic: eliminate
+    # all those which have a first or second character that is
+    # a '.' (that is, objdump's representation of an unprintable
+    # character.) This should work for all archives with less than
+    # 0x302f exports -- but will fail for DLLs whose name actually
+    # begins with a literal '.' or a single character followed by
+    # a '.'.
+    #
+    # Of those that remain, print the first one.
+    $SED -e '/^\./d;/^.\./d;q'
+}
+
+# func_cygming_gnu_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is a GNU/binutils-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_gnu_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_gnu_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $EGREP ' (_head_[A-Za-z0-9_]+_[ad]l*|[A-Za-z0-9_]+_[ad]l*_iname)$'`
+  test -n "$func_cygming_gnu_implib_tmp"
+}
+
+# func_cygming_ms_implib_p ARG
+# This predicate returns with zero status (TRUE) if
+# ARG is an MS-style import library. Returns
+# with nonzero status (FALSE) otherwise.
+func_cygming_ms_implib_p ()
+{
+  $opt_debug
+  func_to_tool_file "$1" func_convert_file_msys_to_w32
+  func_cygming_ms_implib_tmp=`$NM "$func_to_tool_file_result" | eval "$global_symbol_pipe" | $GREP '_NULL_IMPORT_DESCRIPTOR'`
+  test -n "$func_cygming_ms_implib_tmp"
+}
+
+# func_cygming_dll_for_implib_fallback ARG
+# Platform-specific function to extract the
+# name of the DLL associated with the specified
+# import library ARG.
+#
+# This fallback implementation is for use when $DLLTOOL
+# does not support the --identify-strict option.
+# Invoked by eval'ing the libtool variable
+#    $sharedlib_from_linklib_cmd
+# Result is available in the variable
+#    $sharedlib_from_linklib_result
+func_cygming_dll_for_implib_fallback ()
+{
+  $opt_debug
+  if func_cygming_gnu_implib_p "$1" ; then
+    # binutils import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$7' "$1"`
+  elif func_cygming_ms_implib_p "$1" ; then
+    # ms-generated import library
+    sharedlib_from_linklib_result=`func_cygming_dll_for_implib_fallback_core '.idata$6' "$1"`
+  else
+    # unknown
+    sharedlib_from_linklib_result=""
+  fi
+}
 
 
 # func_extract_an_archive dir oldlib
@@ -2598,7 +3719,18 @@ func_extract_an_archive ()
     $opt_debug
     f_ex_an_ar_dir="$1"; shift
     f_ex_an_ar_oldlib="$1"
-    func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" 'exit $?'
+    if test "$lock_old_archive_extraction" = yes; then
+      lockfile=$f_ex_an_ar_oldlib.lock
+      until $opt_dry_run || ln "$progpath" "$lockfile" 2>/dev/null; do
+       func_echo "Waiting for $lockfile to be removed"
+       sleep 2
+      done
+    fi
+    func_show_eval "(cd \$f_ex_an_ar_dir && $AR x \"\$f_ex_an_ar_oldlib\")" \
+                  'stat=$?; rm -f "$lockfile"; exit $stat'
+    if test "$lock_old_archive_extraction" = yes; then
+      $opt_dry_run || rm -f "$lockfile"
+    fi
     if ($AR t "$f_ex_an_ar_oldlib" | sort | sort -uc >/dev/null 2>&1); then
      :
     else
@@ -2669,7 +3801,7 @@ func_extract_archives ()
            darwin_file=
            darwin_files=
            for darwin_file in $darwin_filelist; do
-             darwin_files=`find unfat-$$ -name $darwin_file -print | $NL2SP`
+             darwin_files=`find unfat-$$ -name $darwin_file -print | sort | $NL2SP`
              $LIPO -create -output "$darwin_file" $darwin_files
            done # $darwin_filelist
            $RM -rf unfat-$$
@@ -2684,25 +3816,30 @@ func_extract_archives ()
         func_extract_an_archive "$my_xdir" "$my_xabs"
        ;;
       esac
-      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | $NL2SP`
+      my_oldobjs="$my_oldobjs "`find $my_xdir -name \*.$objext -print -o -name \*.lo -print | sort | $NL2SP`
     done
 
     func_extract_archives_result="$my_oldobjs"
 }
 
 
-
-# func_emit_wrapper_part1 [arg=no]
+# func_emit_wrapper [arg=no]
 #
-# Emit the first part of a libtool wrapper script on stdout.
-# For more information, see the description associated with
-# func_emit_wrapper(), below.
-func_emit_wrapper_part1 ()
+# Emit a libtool wrapper script on stdout.
+# Don't directly open a file because we may want to
+# incorporate the script contents within a cygwin/mingw
+# wrapper executable.  Must ONLY be called from within
+# func_mode_link because it depends on a number of variables
+# set therein.
+#
+# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
+# variable will take.  If 'yes', then the emitted script
+# will assume that the directory in which it is stored is
+# the $objdir directory.  This is a cygwin/mingw-specific
+# behavior.
+func_emit_wrapper ()
 {
-       func_emit_wrapper_part1_arg1=no
-       if test -n "$1" ; then
-         func_emit_wrapper_part1_arg1=$1
-       fi
+       func_emit_wrapper_arg1=${1-no}
 
        $ECHO "\
 #! $SHELL
@@ -2718,7 +3855,6 @@ func_emit_wrapper_part1 ()
 
 # Sed substitution that helps us do robust quoting.  It backslashifies
 # metacharacters that are still active within double-quoted strings.
-Xsed='${SED} -e 1s/^X//'
 sed_quote_subst='$sed_quote_subst'
 
 # Be Bourne compatible
@@ -2749,31 +3885,135 @@ if test \"\$libtool_install_magic\" = \"$magic\"; then
 else
   # When we are sourced in execute mode, \$file and \$ECHO are already set.
   if test \"\$libtool_execute_magic\" != \"$magic\"; then
-    ECHO=\"$qecho\"
-    file=\"\$0\"
-    # Make sure echo works.
-    if test \"X\$1\" = X--no-reexec; then
-      # Discard the --no-reexec flag, and continue.
-      shift
-    elif test \"X\`{ \$ECHO '\t'; } 2>/dev/null\`\" = 'X\t'; then
-      # Yippee, \$ECHO works!
-      :
-    else
-      # Restart under the correct shell, and then maybe \$ECHO will work.
-      exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
-    fi
-  fi\
+    file=\"\$0\""
+
+    qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"`
+    $ECHO "\
+
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+    ECHO=\"$qECHO\"
+  fi
+
+# Very basic option parsing. These options are (a) specific to
+# the libtool wrapper, (b) are identical between the wrapper
+# /script/ and the wrapper /executable/ which is used only on
+# windows platforms, and (c) all begin with the string "--lt-"
+# (application programs are unlikely to have options which match
+# this pattern).
+#
+# There are only two supported options: --lt-debug and
+# --lt-dump-script. There is, deliberately, no --lt-help.
+#
+# The first argument to this parsing function should be the
+# script's $0 value, followed by "$@".
+lt_option_debug=
+func_parse_lt_options ()
+{
+  lt_script_arg0=\$0
+  shift
+  for lt_opt
+  do
+    case \"\$lt_opt\" in
+    --lt-debug) lt_option_debug=1 ;;
+    --lt-dump-script)
+        lt_dump_D=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%/[^/]*$%%'\`
+        test \"X\$lt_dump_D\" = \"X\$lt_script_arg0\" && lt_dump_D=.
+        lt_dump_F=\`\$ECHO \"X\$lt_script_arg0\" | $SED -e 's/^X//' -e 's%^.*/%%'\`
+        cat \"\$lt_dump_D/\$lt_dump_F\"
+        exit 0
+      ;;
+    --lt-*)
+        \$ECHO \"Unrecognized --lt- option: '\$lt_opt'\" 1>&2
+        exit 1
+      ;;
+    esac
+  done
+
+  # Print the debug banner immediately:
+  if test -n \"\$lt_option_debug\"; then
+    echo \"${outputname}:${output}:\${LINENO}: libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\" 1>&2
+  fi
+}
+
+# Used when --lt-debug. Prints its arguments to stdout
+# (redirection is the responsibility of the caller)
+func_lt_dump_args ()
+{
+  lt_dump_args_N=1;
+  for lt_arg
+  do
+    \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[\$lt_dump_args_N]: \$lt_arg\"
+    lt_dump_args_N=\`expr \$lt_dump_args_N + 1\`
+  done
+}
+
+# Core function for launching the target application
+func_exec_program_core ()
+{
 "
-       $ECHO "\
+  case $host in
+  # Backslashes separate directories on plain windows
+  *-*-mingw | *-*-os2* | *-cegcc*)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir\\\\\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
+"
+    ;;
+
+  *)
+    $ECHO "\
+      if test -n \"\$lt_option_debug\"; then
+        \$ECHO \"${outputname}:${output}:\${LINENO}: newargv[0]: \$progdir/\$program\" 1>&2
+        func_lt_dump_args \${1+\"\$@\"} 1>&2
+      fi
+      exec \"\$progdir/\$program\" \${1+\"\$@\"}
+"
+    ;;
+  esac
+  $ECHO "\
+      \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
+      exit 1
+}
+
+# A function to encapsulate launching the target application
+# Strips options in the --lt-* namespace from \$@ and
+# launches target application with the remaining arguments.
+func_exec_program ()
+{
+  case \" \$* \" in
+  *\\ --lt-*)
+    for lt_wr_arg
+    do
+      case \$lt_wr_arg in
+      --lt-*) ;;
+      *) set x \"\$@\" \"\$lt_wr_arg\"; shift;;
+      esac
+      shift
+    done ;;
+  esac
+  func_exec_program_core \${1+\"\$@\"}
+}
+
+  # Parse options
+  func_parse_lt_options \"\$0\" \${1+\"\$@\"}
 
   # Find the directory that this script lives in.
-  thisdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+  thisdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*$%%'\`
   test \"x\$thisdir\" = \"x\$file\" && thisdir=.
 
   # Follow symbolic links until we get to the real thisdir.
-  file=\`ls -ld \"\$file\" | ${SED} -n 's/.*-> //p'\`
+  file=\`ls -ld \"\$file\" | $SED -n 's/.*-> //p'\`
   while test -n \"\$file\"; do
-    destdir=\`\$ECHO \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+    destdir=\`\$ECHO \"\$file\" | $SED 's%/[^/]*\$%%'\`
 
     # If there was a directory component, then change thisdir.
     if test \"x\$destdir\" != \"x\$file\"; then
@@ -2783,30 +4023,13 @@ else
       esac
     fi
 
-    file=\`\$ECHO \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
-    file=\`ls -ld \"\$thisdir/\$file\" | ${SED} -n 's/.*-> //p'\`
+    file=\`\$ECHO \"\$file\" | $SED 's%^.*/%%'\`
+    file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\`
   done
-"
-}
-# end: func_emit_wrapper_part1
-
-# func_emit_wrapper_part2 [arg=no]
-#
-# Emit the second part of a libtool wrapper script on stdout.
-# For more information, see the description associated with
-# func_emit_wrapper(), below.
-func_emit_wrapper_part2 ()
-{
-       func_emit_wrapper_part2_arg1=no
-       if test -n "$1" ; then
-         func_emit_wrapper_part2_arg1=$1
-       fi
-
-       $ECHO "\
 
   # Usually 'no', except on cygwin/mingw when embedded into
   # the cwrapper.
-  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_part2_arg1
+  WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1
   if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then
     # special case for '.'
     if test \"\$thisdir\" = \".\"; then
@@ -2814,7 +4037,7 @@ func_emit_wrapper_part2 ()
     fi
     # remove .libs from thisdir
     case \"\$thisdir\" in
-    *[\\\\/]$objdir ) thisdir=\`\$ECHO \"X\$thisdir\" | \$Xsed -e 's%[\\\\/][^\\\\/]*$%%'\` ;;
+    *[\\\\/]$objdir ) thisdir=\`\$ECHO \"\$thisdir\" | $SED 's%[\\\\/][^\\\\/]*$%%'\` ;;
     $objdir )   thisdir=. ;;
     esac
   fi
@@ -2869,6 +4092,18 @@ func_emit_wrapper_part2 ()
 
   if test -f \"\$progdir/\$program\"; then"
 
+       # fixup the dll searchpath if we need to.
+       #
+       # Fix the DLL searchpath if we need to.  Do this before prepending
+       # to shlibpath, because on Windows, both are PATH and uninstalled
+       # libraries must come first.
+       if test -n "$dllsearchpath"; then
+         $ECHO "\
+    # Add the dll search path components to the executable PATH
+    PATH=$dllsearchpath:\$PATH
+"
+       fi
+
        # Export our shlibpath_var if we have one.
        if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
          $ECHO "\
@@ -2877,253 +4112,28 @@ func_emit_wrapper_part2 ()
 
     # Some systems cannot cope with colon-terminated $shlibpath_var
     # The second colon is a workaround for a bug in BeOS R4 sed
-    $shlibpath_var=\`\$ECHO \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+    $shlibpath_var=\`\$ECHO \"\$$shlibpath_var\" | $SED 's/::*\$//'\`
 
     export $shlibpath_var
 "
        fi
 
-       # fixup the dll searchpath if we need to.
-       if test -n "$dllsearchpath"; then
-         $ECHO "\
-    # Add the dll search path components to the executable PATH
-    PATH=$dllsearchpath:\$PATH
-"
-       fi
-
        $ECHO "\
     if test \"\$libtool_execute_magic\" != \"$magic\"; then
       # Run the actual program with our arguments.
-"
-       case $host in
-       # Backslashes separate directories on plain windows
-       *-*-mingw | *-*-os2* | *-cegcc*)
-         $ECHO "\
-      exec \"\$progdir\\\\\$program\" \${1+\"\$@\"}
-"
-         ;;
-
-       *)
-         $ECHO "\
-      exec \"\$progdir/\$program\" \${1+\"\$@\"}
-"
-         ;;
-       esac
-       $ECHO "\
-      \$ECHO \"\$0: cannot exec \$program \$*\" 1>&2
-      exit 1
+      func_exec_program \${1+\"\$@\"}
     fi
   else
     # The program doesn't exist.
     \$ECHO \"\$0: error: \\\`\$progdir/\$program' does not exist\" 1>&2
     \$ECHO \"This script is just a wrapper for \$program.\" 1>&2
-    $ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
+    \$ECHO \"See the $PACKAGE documentation for more information.\" 1>&2
     exit 1
   fi
 fi\
 "
 }
-# end: func_emit_wrapper_part2
-
-
-# func_emit_wrapper [arg=no]
-#
-# Emit a libtool wrapper script on stdout.
-# Don't directly open a file because we may want to
-# incorporate the script contents within a cygwin/mingw
-# wrapper executable.  Must ONLY be called from within
-# func_mode_link because it depends on a number of variables
-# set therein.
-#
-# ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR
-# variable will take.  If 'yes', then the emitted script
-# will assume that the directory in which it is stored is
-# the $objdir directory.  This is a cygwin/mingw-specific
-# behavior.
-func_emit_wrapper ()
-{
-       func_emit_wrapper_arg1=no
-       if test -n "$1" ; then
-         func_emit_wrapper_arg1=$1
-       fi
-
-       # split this up so that func_emit_cwrapperexe_src
-       # can call each part independently.
-       func_emit_wrapper_part1 "${func_emit_wrapper_arg1}"
-       func_emit_wrapper_part2 "${func_emit_wrapper_arg1}"
-}
-
-
-# func_to_host_path arg
-#
-# Convert paths to host format when used with build tools.
-# Intended for use with "native" mingw (where libtool itself
-# is running under the msys shell), or in the following cross-
-# build environments:
-#    $build          $host
-#    mingw (msys)    mingw  [e.g. native]
-#    cygwin          mingw
-#    *nix + wine     mingw
-# where wine is equipped with the `winepath' executable.
-# In the native mingw case, the (msys) shell automatically
-# converts paths for any non-msys applications it launches,
-# but that facility isn't available from inside the cwrapper.
-# Similar accommodations are necessary for $host mingw and
-# $build cygwin.  Calling this function does no harm for other
-# $host/$build combinations not listed above.
-#
-# ARG is the path (on $build) that should be converted to
-# the proper representation for $host. The result is stored
-# in $func_to_host_path_result.
-func_to_host_path ()
-{
-  func_to_host_path_result="$1"
-  if test -n "$1" ; then
-    case $host in
-      *mingw* )
-        lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
-        case $build in
-          *mingw* ) # actually, msys
-            # awkward: cmd appends spaces to result
-            lt_sed_strip_trailing_spaces="s/[ ]*\$//"
-            func_to_host_path_tmp1=`( cmd //c echo "$1" |\
-              $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
-            func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
-              $SED -e "$lt_sed_naive_backslashify"`
-            ;;
-          *cygwin* )
-            func_to_host_path_tmp1=`cygpath -w "$1"`
-            func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
-              $SED -e "$lt_sed_naive_backslashify"`
-            ;;
-          * )
-            # Unfortunately, winepath does not exit with a non-zero
-            # error code, so we are forced to check the contents of
-            # stdout. On the other hand, if the command is not
-            # found, the shell will set an exit code of 127 and print
-            # *an error message* to stdout. So we must check for both
-            # error code of zero AND non-empty stdout, which explains
-            # the odd construction:
-            func_to_host_path_tmp1=`winepath -w "$1" 2>/dev/null`
-            if test "$?" -eq 0 && test -n "${func_to_host_path_tmp1}"; then
-              func_to_host_path_result=`echo "$func_to_host_path_tmp1" |\
-                $SED -e "$lt_sed_naive_backslashify"`
-            else
-              # Allow warning below.
-              func_to_host_path_result=""
-            fi
-            ;;
-        esac
-        if test -z "$func_to_host_path_result" ; then
-          func_error "Could not determine host path corresponding to"
-          func_error "  '$1'"
-          func_error "Continuing, but uninstalled executables may not work."
-          # Fallback:
-          func_to_host_path_result="$1"
-        fi
-        ;;
-    esac
-  fi
-}
-# end: func_to_host_path
 
-# func_to_host_pathlist arg
-#
-# Convert pathlists to host format when used with build tools.
-# See func_to_host_path(), above. This function supports the
-# following $build/$host combinations (but does no harm for
-# combinations not listed here):
-#    $build          $host
-#    mingw (msys)    mingw  [e.g. native]
-#    cygwin          mingw
-#    *nix + wine     mingw
-#
-# Path separators are also converted from $build format to
-# $host format. If ARG begins or ends with a path separator
-# character, it is preserved (but converted to $host format)
-# on output.
-#
-# ARG is a pathlist (on $build) that should be converted to
-# the proper representation on $host. The result is stored
-# in $func_to_host_pathlist_result.
-func_to_host_pathlist ()
-{
-  func_to_host_pathlist_result="$1"
-  if test -n "$1" ; then
-    case $host in
-      *mingw* )
-        lt_sed_naive_backslashify='s|\\\\*|\\|g;s|/|\\|g;s|\\|\\\\|g'
-        # Remove leading and trailing path separator characters from
-        # ARG. msys behavior is inconsistent here, cygpath turns them
-        # into '.;' and ';.', and winepath ignores them completely.
-        func_to_host_pathlist_tmp2="$1"
-        # Once set for this call, this variable should not be
-        # reassigned. It is used in tha fallback case.
-        func_to_host_pathlist_tmp1=`echo "$func_to_host_pathlist_tmp2" |\
-          $SED -e 's|^:*||' -e 's|:*$||'`
-        case $build in
-          *mingw* ) # Actually, msys.
-            # Awkward: cmd appends spaces to result.
-            lt_sed_strip_trailing_spaces="s/[ ]*\$//"
-            func_to_host_pathlist_tmp2=`( cmd //c echo "$func_to_host_pathlist_tmp1" |\
-              $SED -e "$lt_sed_strip_trailing_spaces" ) 2>/dev/null || echo ""`
-            func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
-              $SED -e "$lt_sed_naive_backslashify"`
-            ;;
-          *cygwin* )
-            func_to_host_pathlist_tmp2=`cygpath -w -p "$func_to_host_pathlist_tmp1"`
-            func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp2" |\
-              $SED -e "$lt_sed_naive_backslashify"`
-            ;;
-          * )
-            # unfortunately, winepath doesn't convert pathlists
-            func_to_host_pathlist_result=""
-            func_to_host_pathlist_oldIFS=$IFS
-            IFS=:
-            for func_to_host_pathlist_f in $func_to_host_pathlist_tmp1 ; do
-              IFS=$func_to_host_pathlist_oldIFS
-              if test -n "$func_to_host_pathlist_f" ; then
-                func_to_host_path "$func_to_host_pathlist_f"
-                if test -n "$func_to_host_path_result" ; then
-                  if test -z "$func_to_host_pathlist_result" ; then
-                    func_to_host_pathlist_result="$func_to_host_path_result"
-                  else
-                    func_to_host_pathlist_result="$func_to_host_pathlist_result;$func_to_host_path_result"
-                  fi
-                fi
-              fi
-              IFS=:
-            done
-            IFS=$func_to_host_pathlist_oldIFS
-            ;;
-        esac
-        if test -z "$func_to_host_pathlist_result" ; then
-          func_error "Could not determine the host path(s) corresponding to"
-          func_error "  '$1'"
-          func_error "Continuing, but uninstalled executables may not work."
-          # Fallback. This may break if $1 contains DOS-style drive
-          # specifications. The fix is not to complicate the expression
-          # below, but for the user to provide a working wine installation
-          # with winepath so that path translation in the cross-to-mingw
-          # case works properly.
-          lt_replace_pathsep_nix_to_dos="s|:|;|g"
-          func_to_host_pathlist_result=`echo "$func_to_host_pathlist_tmp1" |\
-            $SED -e "$lt_replace_pathsep_nix_to_dos"`
-        fi
-        # Now, add the leading and trailing path separators back
-        case "$1" in
-          :* ) func_to_host_pathlist_result=";$func_to_host_pathlist_result"
-            ;;
-        esac
-        case "$1" in
-          *: ) func_to_host_pathlist_result="$func_to_host_pathlist_result;"
-            ;;
-        esac
-        ;;
-    esac
-  fi
-}
-# end: func_to_host_pathlist
 
 # func_emit_cwrapperexe_src
 # emit the source code for a wrapper executable on stdout
@@ -3141,31 +4151,23 @@ func_emit_cwrapperexe_src ()
 
    This wrapper executable should never be moved out of the build directory.
    If it is, it will not operate correctly.
-
-   Currently, it simply execs the wrapper *script* "$SHELL $output",
-   but could eventually absorb all of the scripts functionality and
-   exec $objdir/$outputname directly.
 */
 EOF
            cat <<"EOF"
+#ifdef _MSC_VER
+# define _CRT_SECURE_NO_DEPRECATE 1
+#endif
 #include <stdio.h>
 #include <stdlib.h>
 #ifdef _MSC_VER
 # include <direct.h>
 # include <process.h>
 # include <io.h>
-# define setmode _setmode
 #else
 # include <unistd.h>
 # include <stdint.h>
 # ifdef __CYGWIN__
 #  include <io.h>
-#  define HAVE_SETENV
-#  ifdef __STRICT_ANSI__
-char *realpath (const char *, char *);
-int putenv (char *);
-int setenv (const char *, const char *, int);
-#  endif
 # endif
 #endif
 #include <malloc.h>
@@ -3177,6 +4179,44 @@ int setenv (const char *, const char *, int);
 #include <fcntl.h>
 #include <sys/stat.h>
 
+/* declarations of non-ANSI functions */
+#if defined(__MINGW32__)
+# ifdef __STRICT_ANSI__
+int _putenv (const char *);
+# endif
+#elif defined(__CYGWIN__)
+# ifdef __STRICT_ANSI__
+char *realpath (const char *, char *);
+int putenv (char *);
+int setenv (const char *, const char *, int);
+# endif
+/* #elif defined (other platforms) ... */
+#endif
+
+/* portability defines, excluding path handling macros */
+#if defined(_MSC_VER)
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+# define S_IXUSR _S_IEXEC
+# ifndef _INTPTR_T_DEFINED
+#  define _INTPTR_T_DEFINED
+#  define intptr_t int
+# endif
+#elif defined(__MINGW32__)
+# define setmode _setmode
+# define stat    _stat
+# define chmod   _chmod
+# define getcwd  _getcwd
+# define putenv  _putenv
+#elif defined(__CYGWIN__)
+# define HAVE_SETENV
+# define FOPEN_WB "wb"
+/* #elif defined (other platforms) ... */
+#endif
+
 #if defined(PATH_MAX)
 # define LT_PATHMAX PATH_MAX
 #elif defined(MAXPATHLEN)
@@ -3192,14 +4232,7 @@ int setenv (const char *, const char *, int);
 # define S_IXGRP 0
 #endif
 
-#ifdef _MSC_VER
-# define S_IXUSR _S_IEXEC
-# define stat _stat
-# ifndef _INTPTR_T_DEFINED
-#  define intptr_t int
-# endif
-#endif
-
+/* path handling portability macros */
 #ifndef DIR_SEPARATOR
 # define DIR_SEPARATOR '/'
 # define PATH_SEPARATOR ':'
@@ -3230,10 +4263,6 @@ int setenv (const char *, const char *, int);
 # define IS_PATH_SEPARATOR(ch) ((ch) == PATH_SEPARATOR_2)
 #endif /* PATH_SEPARATOR_2 */
 
-#ifdef __CYGWIN__
-# define FOPEN_WB "wb"
-#endif
-
 #ifndef FOPEN_WB
 # define FOPEN_WB "w"
 #endif
@@ -3246,22 +4275,13 @@ int setenv (const char *, const char *, int);
   if (stale) { free ((void *) stale); stale = 0; } \
 } while (0)
 
-#undef LTWRAPPER_DEBUGPRINTF
-#if defined DEBUGWRAPPER
-# define LTWRAPPER_DEBUGPRINTF(args) ltwrapper_debugprintf args
-static void
-ltwrapper_debugprintf (const char *fmt, ...)
-{
-    va_list args;
-    va_start (args, fmt);
-    (void) vfprintf (stderr, fmt, args);
-    va_end (args);
-}
+#if defined(LT_DEBUGWRAPPER)
+static int lt_debug = 1;
 #else
-# define LTWRAPPER_DEBUGPRINTF(args)
+static int lt_debug = 0;
 #endif
 
-const char *program_name = NULL;
+const char *program_name = "libtool-wrapper"; /* in case xstrdup fails */
 
 void *xmalloc (size_t num);
 char *xstrdup (const char *string);
@@ -3271,41 +4291,27 @@ char *chase_symlinks (const char *pathspec);
 int make_executable (const char *path);
 int check_executable (const char *path);
 char *strendzap (char *str, const char *pat);
-void lt_fatal (const char *message, ...);
+void lt_debugprintf (const char *file, int line, const char *fmt, ...);
+void lt_fatal (const char *file, int line, const char *message, ...);
+static const char *nonnull (const char *s);
+static const char *nonempty (const char *s);
 void lt_setenv (const char *name, const char *value);
 char *lt_extend_str (const char *orig_value, const char *add, int to_end);
-void lt_opt_process_env_set (const char *arg);
-void lt_opt_process_env_prepend (const char *arg);
-void lt_opt_process_env_append (const char *arg);
-int lt_split_name_value (const char *arg, char** name, char** value);
 void lt_update_exe_path (const char *name, const char *value);
 void lt_update_lib_path (const char *name, const char *value);
-
-static const char *script_text_part1 =
-EOF
-
-           func_emit_wrapper_part1 yes |
-               $SED -e 's/\([\\"]\)/\\\1/g' \
-                    -e 's/^/  "/' -e 's/$/\\n"/'
-           echo ";"
-           cat <<EOF
-
-static const char *script_text_part2 =
+char **prepare_spawn (char **argv);
+void lt_dump_script (FILE *f);
 EOF
-           func_emit_wrapper_part2 yes |
-               $SED -e 's/\([\\"]\)/\\\1/g' \
-                    -e 's/^/  "/' -e 's/$/\\n"/'
-           echo ";"
 
            cat <<EOF
-const char * MAGIC_EXE = "$magic_exe";
+volatile const char * MAGIC_EXE = "$magic_exe";
 const char * LIB_PATH_VARNAME = "$shlibpath_var";
 EOF
 
            if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
-              func_to_host_pathlist "$temp_rpath"
+              func_to_host_path "$temp_rpath"
              cat <<EOF
-const char * LIB_PATH_VALUE   = "$func_to_host_pathlist_result";
+const char * LIB_PATH_VALUE   = "$func_to_host_path_result";
 EOF
            else
              cat <<"EOF"
@@ -3314,10 +4320,10 @@ EOF
            fi
 
            if test -n "$dllsearchpath"; then
-              func_to_host_pathlist "$dllsearchpath:"
+              func_to_host_path "$dllsearchpath:"
              cat <<EOF
 const char * EXE_PATH_VARNAME = "PATH";
-const char * EXE_PATH_VALUE   = "$func_to_host_pathlist_result";
+const char * EXE_PATH_VALUE   = "$func_to_host_path_result";
 EOF
            else
              cat <<"EOF"
@@ -3340,24 +4346,10 @@ EOF
            cat <<"EOF"
 
 #define LTWRAPPER_OPTION_PREFIX         "--lt-"
-#define LTWRAPPER_OPTION_PREFIX_LENGTH  5
 
-static const size_t opt_prefix_len         = LTWRAPPER_OPTION_PREFIX_LENGTH;
 static const char *ltwrapper_option_prefix = LTWRAPPER_OPTION_PREFIX;
-
 static const char *dumpscript_opt       = LTWRAPPER_OPTION_PREFIX "dump-script";
-
-static const size_t env_set_opt_len     = LTWRAPPER_OPTION_PREFIX_LENGTH + 7;
-static const char *env_set_opt          = LTWRAPPER_OPTION_PREFIX "env-set";
-  /* argument is putenv-style "foo=bar", value of foo is set to bar */
-
-static const size_t env_prepend_opt_len = LTWRAPPER_OPTION_PREFIX_LENGTH + 11;
-static const char *env_prepend_opt      = LTWRAPPER_OPTION_PREFIX "env-prepend";
-  /* argument is putenv-style "foo=bar", new value of foo is bar${foo} */
-
-static const size_t env_append_opt_len  = LTWRAPPER_OPTION_PREFIX_LENGTH + 10;
-static const char *env_append_opt       = LTWRAPPER_OPTION_PREFIX "env-append";
-  /* argument is putenv-style "foo=bar", new value of foo is ${foo}bar */
+static const char *debug_opt            = LTWRAPPER_OPTION_PREFIX "debug";
 
 int
 main (int argc, char *argv[])
@@ -3374,10 +4366,13 @@ main (int argc, char *argv[])
   int i;
 
   program_name = (char *) xstrdup (base_name (argv[0]));
-  LTWRAPPER_DEBUGPRINTF (("(main) argv[0]      : %s\n", argv[0]));
-  LTWRAPPER_DEBUGPRINTF (("(main) program_name : %s\n", program_name));
+  newargz = XMALLOC (char *, argc + 1);
 
-  /* very simple arg parsing; don't want to rely on getopt */
+  /* very simple arg parsing; don't want to rely on getopt
+   * also, copy all non cwrapper options to newargz, except
+   * argz[0], which is handled differently
+   */
+  newargc=0;
   for (i = 1; i < argc; i++)
     {
       if (strcmp (argv[i], dumpscript_opt) == 0)
@@ -3391,25 +4386,57 @@ EOF
              esac
 
            cat <<"EOF"
-         printf ("%s", script_text_part1);
-         printf ("%s", script_text_part2);
+         lt_dump_script (stdout);
          return 0;
        }
+      if (strcmp (argv[i], debug_opt) == 0)
+       {
+          lt_debug = 1;
+          continue;
+       }
+      if (strcmp (argv[i], ltwrapper_option_prefix) == 0)
+        {
+          /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
+             namespace, but it is not one of the ones we know about and
+             have already dealt with, above (inluding dump-script), then
+             report an error. Otherwise, targets might begin to believe
+             they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
+             namespace. The first time any user complains about this, we'll
+             need to make LTWRAPPER_OPTION_PREFIX a configure-time option
+             or a configure.ac-settable value.
+           */
+          lt_fatal (__FILE__, __LINE__,
+                   "unrecognized %s option: '%s'",
+                    ltwrapper_option_prefix, argv[i]);
+        }
+      /* otherwise ... */
+      newargz[++newargc] = xstrdup (argv[i]);
     }
+  newargz[++newargc] = NULL;
+
+EOF
+           cat <<EOF
+  /* The GNU banner must be the first non-error debug message */
+  lt_debugprintf (__FILE__, __LINE__, "libtool wrapper (GNU $PACKAGE$TIMESTAMP) $VERSION\n");
+EOF
+           cat <<"EOF"
+  lt_debugprintf (__FILE__, __LINE__, "(main) argv[0]: %s\n", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__, "(main) program_name: %s\n", program_name);
 
-  newargz = XMALLOC (char *, argc + 1);
   tmp_pathspec = find_executable (argv[0]);
   if (tmp_pathspec == NULL)
-    lt_fatal ("Couldn't find %s", argv[0]);
-  LTWRAPPER_DEBUGPRINTF (("(main) found exe (before symlink chase) at : %s\n",
-                         tmp_pathspec));
+    lt_fatal (__FILE__, __LINE__, "couldn't find %s", argv[0]);
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (before symlink chase) at: %s\n",
+                 tmp_pathspec);
 
   actual_cwrapper_path = chase_symlinks (tmp_pathspec);
-  LTWRAPPER_DEBUGPRINTF (("(main) found exe (after symlink chase) at : %s\n",
-                         actual_cwrapper_path));
+  lt_debugprintf (__FILE__, __LINE__,
+                  "(main) found exe (after symlink chase) at: %s\n",
+                 actual_cwrapper_path);
   XFREE (tmp_pathspec);
 
-  actual_cwrapper_name = xstrdupbase_name (actual_cwrapper_path));
+  actual_cwrapper_name = xstrdup (base_name (actual_cwrapper_path));
   strendzap (actual_cwrapper_path, actual_cwrapper_name);
 
   /* wrapper name transforms */
@@ -3427,8 +4454,9 @@ EOF
   target_name = tmp_pathspec;
   tmp_pathspec = 0;
 
-  LTWRAPPER_DEBUGPRINTF (("(main) libtool target name: %s\n",
-                         target_name));
+  lt_debugprintf (__FILE__, __LINE__,
+                 "(main) libtool target name: %s\n",
+                 target_name);
 EOF
 
            cat <<EOF
@@ -3478,80 +4506,19 @@ EOF
 
   lt_setenv ("BIN_SH", "xpg4"); /* for Tru64 */
   lt_setenv ("DUALCASE", "1");  /* for MSK sh */
-  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
+  /* Update the DLL searchpath.  EXE_PATH_VALUE ($dllsearchpath) must
+     be prepended before (that is, appear after) LIB_PATH_VALUE ($temp_rpath)
+     because on Windows, both *_VARNAMEs are PATH but uninstalled
+     libraries must come first. */
   lt_update_exe_path (EXE_PATH_VARNAME, EXE_PATH_VALUE);
+  lt_update_lib_path (LIB_PATH_VARNAME, LIB_PATH_VALUE);
 
-  newargc=0;
-  for (i = 1; i < argc; i++)
-    {
-      if (strncmp (argv[i], env_set_opt, env_set_opt_len) == 0)
-        {
-          if (argv[i][env_set_opt_len] == '=')
-            {
-              const char *p = argv[i] + env_set_opt_len + 1;
-              lt_opt_process_env_set (p);
-            }
-          else if (argv[i][env_set_opt_len] == '\0' && i + 1 < argc)
-            {
-              lt_opt_process_env_set (argv[++i]); /* don't copy */
-            }
-          else
-            lt_fatal ("%s missing required argument", env_set_opt);
-          continue;
-        }
-      if (strncmp (argv[i], env_prepend_opt, env_prepend_opt_len) == 0)
-        {
-          if (argv[i][env_prepend_opt_len] == '=')
-            {
-              const char *p = argv[i] + env_prepend_opt_len + 1;
-              lt_opt_process_env_prepend (p);
-            }
-          else if (argv[i][env_prepend_opt_len] == '\0' && i + 1 < argc)
-            {
-              lt_opt_process_env_prepend (argv[++i]); /* don't copy */
-            }
-          else
-            lt_fatal ("%s missing required argument", env_prepend_opt);
-          continue;
-        }
-      if (strncmp (argv[i], env_append_opt, env_append_opt_len) == 0)
-        {
-          if (argv[i][env_append_opt_len] == '=')
-            {
-              const char *p = argv[i] + env_append_opt_len + 1;
-              lt_opt_process_env_append (p);
-            }
-          else if (argv[i][env_append_opt_len] == '\0' && i + 1 < argc)
-            {
-              lt_opt_process_env_append (argv[++i]); /* don't copy */
-            }
-          else
-            lt_fatal ("%s missing required argument", env_append_opt);
-          continue;
-        }
-      if (strncmp (argv[i], ltwrapper_option_prefix, opt_prefix_len) == 0)
-        {
-          /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX
-             namespace, but it is not one of the ones we know about and
-             have already dealt with, above (inluding dump-script), then
-             report an error. Otherwise, targets might begin to believe
-             they are allowed to use options in the LTWRAPPER_OPTION_PREFIX
-             namespace. The first time any user complains about this, we'll
-             need to make LTWRAPPER_OPTION_PREFIX a configure-time option
-             or a configure.ac-settable value.
-           */
-          lt_fatal ("Unrecognized option in %s namespace: '%s'",
-                    ltwrapper_option_prefix, argv[i]);
-        }
-      /* otherwise ... */
-      newargz[++newargc] = xstrdup (argv[i]);
-    }
-  newargz[++newargc] = NULL;
-
-  LTWRAPPER_DEBUGPRINTF     (("(main) lt_argv_zero : %s\n", (lt_argv_zero ? lt_argv_zero : "<NULL>")));
+  lt_debugprintf (__FILE__, __LINE__, "(main) lt_argv_zero: %s\n",
+                 nonnull (lt_argv_zero));
   for (i = 0; i < newargc; i++)
     {
-      LTWRAPPER_DEBUGPRINTF (("(main) newargz[%d]   : %s\n", i, (newargz[i] ? newargz[i] : "<NULL>")));
+      lt_debugprintf (__FILE__, __LINE__, "(main) newargz[%d]: %s\n",
+                     i, nonnull (newargz[i]));
     }
 
 EOF
@@ -3560,11 +4527,14 @@ EOF
              mingw*)
                cat <<"EOF"
   /* execv doesn't actually work on mingw as expected on unix */
+  newargz = prepare_spawn (newargz);
   rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);
   if (rval == -1)
     {
       /* failed to start process */
-      LTWRAPPER_DEBUGPRINTF (("(main) failed to launch target \"%s\": errno = %d\n", lt_argv_zero, errno));
+      lt_debugprintf (__FILE__, __LINE__,
+                     "(main) failed to launch target \"%s\": %s\n",
+                     lt_argv_zero, nonnull (strerror (errno)));
       return 127;
     }
   return rval;
@@ -3586,7 +4556,7 @@ xmalloc (size_t num)
 {
   void *p = (void *) malloc (num);
   if (!p)
-    lt_fatal ("Memory exhausted");
+    lt_fatal (__FILE__, __LINE__, "memory exhausted");
 
   return p;
 }
@@ -3620,8 +4590,8 @@ check_executable (const char *path)
 {
   struct stat st;
 
-  LTWRAPPER_DEBUGPRINTF (("(check_executable)  : %s\n",
-                         path ? (*path ? path : "EMPTY!") : "NULL!"));
+  lt_debugprintf (__FILE__, __LINE__, "(check_executable): %s\n",
+                  nonempty (path));
   if ((!path) || (!*path))
     return 0;
 
@@ -3638,8 +4608,8 @@ make_executable (const char *path)
   int rval = 0;
   struct stat st;
 
-  LTWRAPPER_DEBUGPRINTF (("(make_executable)   : %s\n",
-                         path ? (*path ? path : "EMPTY!") : "NULL!"));
+  lt_debugprintf (__FILE__, __LINE__, "(make_executable): %s\n",
+                  nonempty (path));
   if ((!path) || (!*path))
     return 0;
 
@@ -3665,8 +4635,8 @@ find_executable (const char *wrapper)
   int tmp_len;
   char *concat_name;
 
-  LTWRAPPER_DEBUGPRINTF (("(find_executable)   : %s\n",
-                         wrapper ? (*wrapper ? wrapper : "EMPTY!") : "NULL!"));
+  lt_debugprintf (__FILE__, __LINE__, "(find_executable): %s\n",
+                  nonempty (wrapper));
 
   if ((wrapper == NULL) || (*wrapper == '\0'))
     return NULL;
@@ -3719,7 +4689,8 @@ find_executable (const char *wrapper)
                {
                  /* empty path: current directory */
                  if (getcwd (tmp, LT_PATHMAX) == NULL)
-                   lt_fatal ("getcwd failed");
+                   lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+                              nonnull (strerror (errno)));
                  tmp_len = strlen (tmp);
                  concat_name =
                    XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
@@ -3744,7 +4715,8 @@ find_executable (const char *wrapper)
     }
   /* Relative path | not found in path: prepend cwd */
   if (getcwd (tmp, LT_PATHMAX) == NULL)
-    lt_fatal ("getcwd failed");
+    lt_fatal (__FILE__, __LINE__, "getcwd failed: %s",
+              nonnull (strerror (errno)));
   tmp_len = strlen (tmp);
   concat_name = XMALLOC (char, tmp_len + 1 + strlen (wrapper) + 1);
   memcpy (concat_name, tmp, tmp_len);
@@ -3770,8 +4742,9 @@ chase_symlinks (const char *pathspec)
   int has_symlinks = 0;
   while (strlen (tmp_pathspec) && !has_symlinks)
     {
-      LTWRAPPER_DEBUGPRINTF (("checking path component for symlinks: %s\n",
-                             tmp_pathspec));
+      lt_debugprintf (__FILE__, __LINE__,
+                     "checking path component for symlinks: %s\n",
+                     tmp_pathspec);
       if (lstat (tmp_pathspec, &s) == 0)
        {
          if (S_ISLNK (s.st_mode) != 0)
@@ -3793,8 +4766,9 @@ chase_symlinks (const char *pathspec)
        }
       else
        {
-         char *errstr = strerror (errno);
-         lt_fatal ("Error accessing file %s (%s)", tmp_pathspec, errstr);
+         lt_fatal (__FILE__, __LINE__,
+                   "error accessing file \"%s\": %s",
+                   tmp_pathspec, nonnull (strerror (errno)));
        }
     }
   XFREE (tmp_pathspec);
@@ -3807,7 +4781,8 @@ chase_symlinks (const char *pathspec)
   tmp_pathspec = realpath (pathspec, buf);
   if (tmp_pathspec == 0)
     {
-      lt_fatal ("Could not follow symlinks for %s", pathspec);
+      lt_fatal (__FILE__, __LINE__,
+               "could not follow symlinks for %s", pathspec);
     }
   return xstrdup (tmp_pathspec);
 #endif
@@ -3833,11 +4808,25 @@ strendzap (char *str, const char *pat)
   return str;
 }
 
+void
+lt_debugprintf (const char *file, int line, const char *fmt, ...)
+{
+  va_list args;
+  if (lt_debug)
+    {
+      (void) fprintf (stderr, "%s:%s:%d: ", program_name, file, line);
+      va_start (args, fmt);
+      (void) vfprintf (stderr, fmt, args);
+      va_end (args);
+    }
+}
+
 static void
-lt_error_core (int exit_status, const char *mode,
+lt_error_core (int exit_status, const char *file,
+              int line, const char *mode,
               const char *message, va_list ap)
 {
-  fprintf (stderr, "%s: %s: ", program_name, mode);
+  fprintf (stderr, "%s:%s:%d: %s: ", program_name, file, line, mode);
   vfprintf (stderr, message, ap);
   fprintf (stderr, ".\n");
 
@@ -3846,20 +4835,32 @@ lt_error_core (int exit_status, const char *mode,
 }
 
 void
-lt_fatal (const char *message, ...)
+lt_fatal (const char *file, int line, const char *message, ...)
 {
   va_list ap;
   va_start (ap, message);
-  lt_error_core (EXIT_FAILURE, "FATAL", message, ap);
+  lt_error_core (EXIT_FAILURE, file, line, "FATAL", message, ap);
   va_end (ap);
 }
 
+static const char *
+nonnull (const char *s)
+{
+  return s ? s : "(null)";
+}
+
+static const char *
+nonempty (const char *s)
+{
+  return (s && !*s) ? "(empty)" : nonnull (s);
+}
+
 void
 lt_setenv (const char *name, const char *value)
 {
-  LTWRAPPER_DEBUGPRINTF (("(lt_setenv) setting '%s' to '%s'\n",
-                          (name ? name : "<NULL>"),
-                          (value ? value : "<NULL>")));
+  lt_debugprintf (__FILE__, __LINE__,
+                 "(lt_setenv) setting '%s' to '%s'\n",
+                  nonnull (name), nonnull (value));
   {
 #ifdef HAVE_SETENV
     /* always make a copy, for consistency with !HAVE_SETENV */
@@ -3904,95 +4905,12 @@ lt_extend_str (const char *orig_value, const char *add, int to_end)
   return new_value;
 }
 
-int
-lt_split_name_value (const char *arg, char** name, char** value)
-{
-  const char *p;
-  int len;
-  if (!arg || !*arg)
-    return 1;
-
-  p = strchr (arg, (int)'=');
-
-  if (!p)
-    return 1;
-
-  *value = xstrdup (++p);
-
-  len = strlen (arg) - strlen (*value);
-  *name = XMALLOC (char, len);
-  strncpy (*name, arg, len-1);
-  (*name)[len - 1] = '\0';
-
-  return 0;
-}
-
-void
-lt_opt_process_env_set (const char *arg)
-{
-  char *name = NULL;
-  char *value = NULL;
-
-  if (lt_split_name_value (arg, &name, &value) != 0)
-    {
-      XFREE (name);
-      XFREE (value);
-      lt_fatal ("bad argument for %s: '%s'", env_set_opt, arg);
-    }
-
-  lt_setenv (name, value);
-  XFREE (name);
-  XFREE (value);
-}
-
-void
-lt_opt_process_env_prepend (const char *arg)
-{
-  char *name = NULL;
-  char *value = NULL;
-  char *new_value = NULL;
-
-  if (lt_split_name_value (arg, &name, &value) != 0)
-    {
-      XFREE (name);
-      XFREE (value);
-      lt_fatal ("bad argument for %s: '%s'", env_prepend_opt, arg);
-    }
-
-  new_value = lt_extend_str (getenv (name), value, 0);
-  lt_setenv (name, new_value);
-  XFREE (new_value);
-  XFREE (name);
-  XFREE (value);
-}
-
-void
-lt_opt_process_env_append (const char *arg)
-{
-  char *name = NULL;
-  char *value = NULL;
-  char *new_value = NULL;
-
-  if (lt_split_name_value (arg, &name, &value) != 0)
-    {
-      XFREE (name);
-      XFREE (value);
-      lt_fatal ("bad argument for %s: '%s'", env_append_opt, arg);
-    }
-
-  new_value = lt_extend_str (getenv (name), value, 1);
-  lt_setenv (name, new_value);
-  XFREE (new_value);
-  XFREE (name);
-  XFREE (value);
-}
-
 void
 lt_update_exe_path (const char *name, const char *value)
 {
-  LTWRAPPER_DEBUGPRINTF (("(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
-                          (name ? name : "<NULL>"),
-                          (value ? value : "<NULL>")));
+  lt_debugprintf (__FILE__, __LINE__,
+                 "(lt_update_exe_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
 
   if (name && *name && value && *value)
     {
@@ -4011,9 +4929,9 @@ lt_update_exe_path (const char *name, const char *value)
 void
 lt_update_lib_path (const char *name, const char *value)
 {
-  LTWRAPPER_DEBUGPRINTF (("(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
-                          (name ? name : "<NULL>"),
-                          (value ? value : "<NULL>")));
+  lt_debugprintf (__FILE__, __LINE__,
+                 "(lt_update_lib_path) modifying '%s' by prepending '%s'\n",
+                  nonnull (name), nonnull (value));
 
   if (name && *name && value && *value)
     {
@@ -4023,11 +4941,158 @@ lt_update_lib_path (const char *name, const char *value)
     }
 }
 
+EOF
+           case $host_os in
+             mingw*)
+               cat <<"EOF"
+
+/* Prepares an argument vector before calling spawn().
+   Note that spawn() does not by itself call the command interpreter
+     (getenv ("COMSPEC") != NULL ? getenv ("COMSPEC") :
+      ({ OSVERSIONINFO v; v.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+         GetVersionEx(&v);
+         v.dwPlatformId == VER_PLATFORM_WIN32_NT;
+      }) ? "cmd.exe" : "command.com").
+   Instead it simply concatenates the arguments, separated by ' ', and calls
+   CreateProcess().  We must quote the arguments since Win32 CreateProcess()
+   interprets characters like ' ', '\t', '\\', '"' (but not '<' and '>') in a
+   special way:
+   - Space and tab are interpreted as delimiters. They are not treated as
+     delimiters if they are surrounded by double quotes: "...".
+   - Unescaped double quotes are removed from the input. Their only effect is
+     that within double quotes, space and tab are treated like normal
+     characters.
+   - Backslashes not followed by double quotes are not special.
+   - But 2*n+1 backslashes followed by a double quote become
+     n backslashes followed by a double quote (n >= 0):
+       \" -> "
+       \\\" -> \"
+       \\\\\" -> \\"
+ */
+#define SHELL_SPECIAL_CHARS "\"\\ \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+#define SHELL_SPACE_CHARS " \001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037"
+char **
+prepare_spawn (char **argv)
+{
+  size_t argc;
+  char **new_argv;
+  size_t i;
+
+  /* Count number of arguments.  */
+  for (argc = 0; argv[argc] != NULL; argc++)
+    ;
+
+  /* Allocate new argument vector.  */
+  new_argv = XMALLOC (char *, argc + 1);
+
+  /* Put quoted arguments into the new argument vector.  */
+  for (i = 0; i < argc; i++)
+    {
+      const char *string = argv[i];
+
+      if (string[0] == '\0')
+       new_argv[i] = xstrdup ("\"\"");
+      else if (strpbrk (string, SHELL_SPECIAL_CHARS) != NULL)
+       {
+         int quote_around = (strpbrk (string, SHELL_SPACE_CHARS) != NULL);
+         size_t length;
+         unsigned int backslashes;
+         const char *s;
+         char *quoted_string;
+         char *p;
+
+         length = 0;
+         backslashes = 0;
+         if (quote_around)
+           length++;
+         for (s = string; *s != '\0'; s++)
+           {
+             char c = *s;
+             if (c == '"')
+               length += backslashes + 1;
+             length++;
+             if (c == '\\')
+               backslashes++;
+             else
+               backslashes = 0;
+           }
+         if (quote_around)
+           length += backslashes + 1;
+
+         quoted_string = XMALLOC (char, length + 1);
+
+         p = quoted_string;
+         backslashes = 0;
+         if (quote_around)
+           *p++ = '"';
+         for (s = string; *s != '\0'; s++)
+           {
+             char c = *s;
+             if (c == '"')
+               {
+                 unsigned int j;
+                 for (j = backslashes + 1; j > 0; j--)
+                   *p++ = '\\';
+               }
+             *p++ = c;
+             if (c == '\\')
+               backslashes++;
+             else
+               backslashes = 0;
+           }
+         if (quote_around)
+           {
+             unsigned int j;
+             for (j = backslashes; j > 0; j--)
+               *p++ = '\\';
+             *p++ = '"';
+           }
+         *p = '\0';
 
+         new_argv[i] = quoted_string;
+       }
+      else
+       new_argv[i] = (char *) string;
+    }
+  new_argv[argc] = NULL;
+
+  return new_argv;
+}
+EOF
+               ;;
+           esac
+
+            cat <<"EOF"
+void lt_dump_script (FILE* f)
+{
+EOF
+           func_emit_wrapper yes |
+             $SED -n -e '
+s/^\(.\{79\}\)\(..*\)/\1\
+\2/
+h
+s/\([\\"]\)/\\\1/g
+s/$/\\n/
+s/\([^\n]*\).*/  fputs ("\1", f);/p
+g
+D'
+            cat <<"EOF"
+}
 EOF
 }
 # end: func_emit_cwrapperexe_src
 
+# func_win32_import_lib_p ARG
+# True if ARG is an import lib, as indicated by $file_magic_cmd
+func_win32_import_lib_p ()
+{
+    $opt_debug
+    case `eval $file_magic_cmd \"\$1\" 2>/dev/null | $SED -e 10q` in
+    *import*) : ;;
+    *) false ;;
+    esac
+}
+
 # func_mode_link arg...
 func_mode_link ()
 {
@@ -4072,6 +5137,7 @@ func_mode_link ()
     new_inherited_linker_flags=
 
     avoid_version=no
+    bindir=
     dlfiles=
     dlprefiles=
     dlself=no
@@ -4164,6 +5230,11 @@ func_mode_link ()
        esac
 
        case $prev in
+       bindir)
+         bindir="$arg"
+         prev=
+         continue
+         ;;
        dlfiles|dlprefiles)
          if test "$preload" = no; then
            # Add the symbol object into the linking commands.
@@ -4195,9 +5266,9 @@ func_mode_link ()
            ;;
          *)
            if test "$prev" = dlfiles; then
-             dlfiles="$dlfiles $arg"
+             func_append dlfiles " $arg"
            else
-             dlprefiles="$dlprefiles $arg"
+             func_append dlprefiles " $arg"
            fi
            prev=
            continue
@@ -4221,7 +5292,7 @@ func_mode_link ()
            *-*-darwin*)
              case "$deplibs " in
                *" $qarg.ltframework "*) ;;
-               *) deplibs="$deplibs $qarg.ltframework" # this is fixed later
+               *) func_append deplibs " $qarg.ltframework" # this is fixed later
                   ;;
              esac
              ;;
@@ -4240,7 +5311,7 @@ func_mode_link ()
            moreargs=
            for fil in `cat "$save_arg"`
            do
-#            moreargs="$moreargs $fil"
+#            func_append moreargs " $fil"
              arg=$fil
              # A libtool-controlled object.
 
@@ -4269,7 +5340,7 @@ func_mode_link ()
 
                  if test "$prev" = dlfiles; then
                    if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
-                     dlfiles="$dlfiles $pic_object"
+                     func_append dlfiles " $pic_object"
                      prev=
                      continue
                    else
@@ -4281,7 +5352,7 @@ func_mode_link ()
                  # CHECK ME:  I think I busted this.  -Ossama
                  if test "$prev" = dlprefiles; then
                    # Preload the old-style object.
-                   dlprefiles="$dlprefiles $pic_object"
+                   func_append dlprefiles " $pic_object"
                    prev=
                  fi
 
@@ -4351,12 +5422,12 @@ func_mode_link ()
          if test "$prev" = rpath; then
            case "$rpath " in
            *" $arg "*) ;;
-           *) rpath="$rpath $arg" ;;
+           *) func_append rpath " $arg" ;;
            esac
          else
            case "$xrpath " in
            *" $arg "*) ;;
-           *) xrpath="$xrpath $arg" ;;
+           *) func_append xrpath " $arg" ;;
            esac
          fi
          prev=
@@ -4368,28 +5439,28 @@ func_mode_link ()
          continue
          ;;
        weak)
-         weak_libs="$weak_libs $arg"
+         func_append weak_libs " $arg"
          prev=
          continue
          ;;
        xcclinker)
-         linker_flags="$linker_flags $qarg"
-         compiler_flags="$compiler_flags $qarg"
+         func_append linker_flags " $qarg"
+         func_append compiler_flags " $qarg"
          prev=
          func_append compile_command " $qarg"
          func_append finalize_command " $qarg"
          continue
          ;;
        xcompiler)
-         compiler_flags="$compiler_flags $qarg"
+         func_append compiler_flags " $qarg"
          prev=
          func_append compile_command " $qarg"
          func_append finalize_command " $qarg"
          continue
          ;;
        xlinker)
-         linker_flags="$linker_flags $qarg"
-         compiler_flags="$compiler_flags $wl$qarg"
+         func_append linker_flags " $qarg"
+         func_append compiler_flags " $wl$qarg"
          prev=
          func_append compile_command " $wl$qarg"
          func_append finalize_command " $wl$qarg"
@@ -4425,6 +5496,11 @@ func_mode_link ()
        continue
        ;;
 
+      -bindir)
+       prev=bindir
+       continue
+       ;;
+
       -dlopen)
        prev=dlfiles
        continue
@@ -4475,15 +5551,16 @@ func_mode_link ()
        ;;
 
       -L*)
-       func_stripname '-L' '' "$arg"
-       dir=$func_stripname_result
-       if test -z "$dir"; then
+       func_stripname "-L" '' "$arg"
+       if test -z "$func_stripname_result"; then
          if test "$#" -gt 0; then
            func_fatal_error "require no space between \`-L' and \`$1'"
          else
            func_fatal_error "need path for \`-L' option"
          fi
        fi
+       func_resolve_sysroot "$func_stripname_result"
+       dir=$func_resolve_sysroot_result
        # We need an absolute path.
        case $dir in
        [\\/]* | [A-Za-z]:[\\/]*) ;;
@@ -4495,24 +5572,30 @@ func_mode_link ()
          ;;
        esac
        case "$deplibs " in
-       *" -L$dir "*) ;;
+       *" -L$dir "* | *" $arg "*)
+         # Will only happen for absolute or sysroot arguments
+         ;;
        *)
-         deplibs="$deplibs -L$dir"
-         lib_search_path="$lib_search_path $dir"
+         # Preserve sysroot, but never include relative directories
+         case $dir in
+           [\\/]* | [A-Za-z]:[\\/]* | =*) func_append deplibs " $arg" ;;
+           *) func_append deplibs " -L$dir" ;;
+         esac
+         func_append lib_search_path " $dir"
          ;;
        esac
        case $host in
        *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*)
-         testbindir=`$ECHO "X$dir" | $Xsed -e 's*/lib$*/bin*'`
+         testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'`
          case :$dllsearchpath: in
          *":$dir:"*) ;;
          ::) dllsearchpath=$dir;;
-         *) dllsearchpath="$dllsearchpath:$dir";;
+         *) func_append dllsearchpath ":$dir";;
          esac
          case :$dllsearchpath: in
          *":$testbindir:"*) ;;
          ::) dllsearchpath=$testbindir;;
-         *) dllsearchpath="$dllsearchpath:$testbindir";;
+         *) func_append dllsearchpath ":$testbindir";;
          esac
          ;;
        esac
@@ -4522,7 +5605,7 @@ func_mode_link ()
       -l*)
        if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then
          case $host in
-         *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc*)
+         *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*)
            # These systems don't actually have a C or math library (as such)
            continue
            ;;
@@ -4536,7 +5619,7 @@ func_mode_link ()
            ;;
          *-*-rhapsody* | *-*-darwin1.[012])
            # Rhapsody C and math libraries are in the System framework
-           deplibs="$deplibs System.ltframework"
+           func_append deplibs " System.ltframework"
            continue
            ;;
          *-*-sco3.2v5* | *-*-sco5v6*)
@@ -4556,7 +5639,7 @@ func_mode_link ()
           ;;
         esac
        fi
-       deplibs="$deplibs $arg"
+       func_append deplibs " $arg"
        continue
        ;;
 
@@ -4568,21 +5651,22 @@ func_mode_link ()
       # Tru64 UNIX uses -model [arg] to determine the layout of C++
       # classes, name mangling, and exception handling.
       # Darwin uses the -arch flag to determine output architecture.
-      -model|-arch|-isysroot)
-       compiler_flags="$compiler_flags $arg"
+      -model|-arch|-isysroot|--sysroot)
+       func_append compiler_flags " $arg"
        func_append compile_command " $arg"
        func_append finalize_command " $arg"
        prev=xcompiler
        continue
        ;;
 
-      -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
-       compiler_flags="$compiler_flags $arg"
+      -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+      |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
+       func_append compiler_flags " $arg"
        func_append compile_command " $arg"
        func_append finalize_command " $arg"
        case "$new_inherited_linker_flags " in
            *" $arg "*) ;;
-           * ) new_inherited_linker_flags="$new_inherited_linker_flags $arg" ;;
+           * ) func_append new_inherited_linker_flags " $arg" ;;
        esac
        continue
        ;;
@@ -4649,13 +5733,17 @@ func_mode_link ()
        # We need an absolute path.
        case $dir in
        [\\/]* | [A-Za-z]:[\\/]*) ;;
+       =*)
+         func_stripname '=' '' "$dir"
+         dir=$lt_sysroot$func_stripname_result
+         ;;
        *)
          func_fatal_error "only absolute run-paths are allowed"
          ;;
        esac
        case "$xrpath " in
        *" $dir "*) ;;
-       *) xrpath="$xrpath $dir" ;;
+       *) func_append xrpath " $dir" ;;
        esac
        continue
        ;;
@@ -4708,8 +5796,8 @@ func_mode_link ()
        for flag in $args; do
          IFS="$save_ifs"
           func_quote_for_eval "$flag"
-         arg="$arg $wl$func_quote_for_eval_result"
-         compiler_flags="$compiler_flags $func_quote_for_eval_result"
+         func_append arg " $func_quote_for_eval_result"
+         func_append compiler_flags " $func_quote_for_eval_result"
        done
        IFS="$save_ifs"
        func_stripname ' ' '' "$arg"
@@ -4724,9 +5812,9 @@ func_mode_link ()
        for flag in $args; do
          IFS="$save_ifs"
           func_quote_for_eval "$flag"
-         arg="$arg $wl$func_quote_for_eval_result"
-         compiler_flags="$compiler_flags $wl$func_quote_for_eval_result"
-         linker_flags="$linker_flags $func_quote_for_eval_result"
+         func_append arg " $wl$func_quote_for_eval_result"
+         func_append compiler_flags " $wl$func_quote_for_eval_result"
+         func_append linker_flags " $func_quote_for_eval_result"
        done
        IFS="$save_ifs"
        func_stripname ' ' '' "$arg"
@@ -4754,23 +5842,27 @@ func_mode_link ()
        arg="$func_quote_for_eval_result"
        ;;
 
-      # -64, -mips[0-9] enable 64-bit mode on the SGI compiler
-      # -r[0-9][0-9]* specifies the processor on the SGI compiler
-      # -xarch=*, -xtarget=* enable 64-bit mode on the Sun compiler
-      # +DA*, +DD* enable 64-bit mode on the HP compiler
-      # -q* pass through compiler args for the IBM compiler
-      # -m*, -t[45]*, -txscale* pass through architecture-specific
-      # compiler args for GCC
-      # -F/path gives path to uninstalled frameworks, gcc on darwin
-      # -p, -pg, --coverage, -fprofile-* pass through profiling flag for GCC
-      # @file GCC response files
+      # Flags to be passed through unchanged, with rationale:
+      # -64, -mips[0-9]      enable 64-bit mode for the SGI compiler
+      # -r[0-9][0-9]*        specify processor for the SGI compiler
+      # -xarch=*, -xtarget=* enable 64-bit mode for the Sun compiler
+      # +DA*, +DD*           enable 64-bit mode for the HP compiler
+      # -q*                  compiler args for the IBM compiler
+      # -m*, -t[45]*, -txscale* architecture-specific flags for GCC
+      # -F/path              path to uninstalled frameworks, gcc on darwin
+      # -p, -pg, --coverage, -fprofile-*  profiling flags for GCC
+      # @file                GCC response files
+      # -tp=*                Portland pgcc target processor selection
+      # --sysroot=*          for sysroot support
+      # -O*, -flto*, -fwhopr*, -fuse-linker-plugin GCC link-time optimization
       -64|-mips[0-9]|-r[0-9][0-9]*|-xarch=*|-xtarget=*|+DA*|+DD*|-q*|-m*| \
-      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*)
+      -t[45]*|-txscale*|-p|-pg|--coverage|-fprofile-*|-F*|@*|-tp=*|--sysroot=*| \
+      -O*|-flto*|-fwhopr*|-fuse-linker-plugin)
         func_quote_for_eval "$arg"
        arg="$func_quote_for_eval_result"
         func_append compile_command " $arg"
         func_append finalize_command " $arg"
-        compiler_flags="$compiler_flags $arg"
+        func_append compiler_flags " $arg"
         continue
         ;;
 
@@ -4782,7 +5874,7 @@ func_mode_link ()
 
       *.$objext)
        # A standard object.
-       objs="$objs $arg"
+       func_append objs " $arg"
        ;;
 
       *.lo)
@@ -4813,7 +5905,7 @@ func_mode_link ()
 
            if test "$prev" = dlfiles; then
              if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then
-               dlfiles="$dlfiles $pic_object"
+               func_append dlfiles " $pic_object"
                prev=
                continue
              else
@@ -4825,7 +5917,7 @@ func_mode_link ()
            # CHECK ME:  I think I busted this.  -Ossama
            if test "$prev" = dlprefiles; then
              # Preload the old-style object.
-             dlprefiles="$dlprefiles $pic_object"
+             func_append dlprefiles " $pic_object"
              prev=
            fi
 
@@ -4870,24 +5962,25 @@ func_mode_link ()
 
       *.$libext)
        # An archive.
-       deplibs="$deplibs $arg"
-       old_deplibs="$old_deplibs $arg"
+       func_append deplibs " $arg"
+       func_append old_deplibs " $arg"
        continue
        ;;
 
       *.la)
        # A libtool-controlled library.
 
+       func_resolve_sysroot "$arg"
        if test "$prev" = dlfiles; then
          # This library was specified with -dlopen.
-         dlfiles="$dlfiles $arg"
+         func_append dlfiles " $func_resolve_sysroot_result"
          prev=
        elif test "$prev" = dlprefiles; then
          # The library was specified with -dlpreopen.
-         dlprefiles="$dlprefiles $arg"
+         func_append dlprefiles " $func_resolve_sysroot_result"
          prev=
        else
-         deplibs="$deplibs $arg"
+         func_append deplibs " $func_resolve_sysroot_result"
        fi
        continue
        ;;
@@ -4925,7 +6018,7 @@ func_mode_link ()
 
     if test -n "$shlibpath_var"; then
       # get the directories listed in $shlibpath_var
-      eval shlib_search_path=\`\$ECHO \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+      eval shlib_search_path=\`\$ECHO \"\${$shlibpath_var}\" \| \$SED \'s/:/ /g\'\`
     else
       shlib_search_path=
     fi
@@ -4934,6 +6027,8 @@ func_mode_link ()
 
     func_dirname "$output" "/" ""
     output_objdir="$func_dirname_result$objdir"
+    func_to_tool_file "$output_objdir/"
+    tool_output_objdir=$func_to_tool_file_result
     # Create the object directory.
     func_mkdir_p "$output_objdir"
 
@@ -4954,12 +6049,12 @@ func_mode_link ()
     # Find all interdependent deplibs by searching for libraries
     # that are linked more than once (e.g. -la -lb -la)
     for deplib in $deplibs; do
-      if $opt_duplicate_deps ; then
+      if $opt_preserve_dup_deps ; then
        case "$libs " in
-       *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+       *" $deplib "*) func_append specialdeplibs " $deplib" ;;
        esac
       fi
-      libs="$libs $deplib"
+      func_append libs " $deplib"
     done
 
     if test "$linkmode" = lib; then
@@ -4972,9 +6067,9 @@ func_mode_link ()
       if $opt_duplicate_compiler_generated_deps; then
        for pre_post_dep in $predeps $postdeps; do
          case "$pre_post_deps " in
-         *" $pre_post_dep "*) specialdeplibs="$specialdeplibs $pre_post_deps" ;;
+         *" $pre_post_dep "*) func_append specialdeplibs " $pre_post_deps" ;;
          esac
-         pre_post_deps="$pre_post_deps $pre_post_dep"
+         func_append pre_post_deps " $pre_post_dep"
        done
       fi
       pre_post_deps=
@@ -5044,17 +6139,19 @@ func_mode_link ()
        for lib in $dlprefiles; do
          # Ignore non-libtool-libs
          dependency_libs=
+         func_resolve_sysroot "$lib"
          case $lib in
-         *.la) func_source "$lib" ;;
+         *.la) func_source "$func_resolve_sysroot_result" ;;
          esac
 
          # Collect preopened libtool deplibs, except any this library
          # has declared as weak libs
          for deplib in $dependency_libs; do
-            deplib_base=`$ECHO "X$deplib" | $Xsed -e "$basename"`
+           func_basename "$deplib"
+            deplib_base=$func_basename_result
            case " $weak_libs " in
            *" $deplib_base "*) ;;
-           *) deplibs="$deplibs $deplib" ;;
+           *) func_append deplibs " $deplib" ;;
            esac
          done
        done
@@ -5070,16 +6167,17 @@ func_mode_link ()
        lib=
        found=no
        case $deplib in
-       -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe|-threads)
+       -mt|-mthreads|-kthread|-Kthread|-pthread|-pthreads|--thread-safe \
+        |-threads|-fopenmp|-openmp|-mp|-xopenmp|-omp|-qsmp=*)
          if test "$linkmode,$pass" = "prog,link"; then
            compile_deplibs="$deplib $compile_deplibs"
            finalize_deplibs="$deplib $finalize_deplibs"
          else
-           compiler_flags="$compiler_flags $deplib"
+           func_append compiler_flags " $deplib"
            if test "$linkmode" = lib ; then
                case "$new_inherited_linker_flags " in
                    *" $deplib "*) ;;
-                   * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
+                   * ) func_append new_inherited_linker_flags " $deplib" ;;
                esac
            fi
          fi
@@ -5164,7 +6262,7 @@ func_mode_link ()
            if test "$linkmode" = lib ; then
                case "$new_inherited_linker_flags " in
                    *" $deplib "*) ;;
-                   * ) new_inherited_linker_flags="$new_inherited_linker_flags $deplib" ;;
+                   * ) func_append new_inherited_linker_flags " $deplib" ;;
                esac
            fi
          fi
@@ -5177,7 +6275,8 @@ func_mode_link ()
            test "$pass" = conv && continue
            newdependency_libs="$deplib $newdependency_libs"
            func_stripname '-L' '' "$deplib"
-           newlib_search_path="$newlib_search_path $func_stripname_result"
+           func_resolve_sysroot "$func_stripname_result"
+           func_append newlib_search_path " $func_resolve_sysroot_result"
            ;;
          prog)
            if test "$pass" = conv; then
@@ -5191,7 +6290,8 @@ func_mode_link ()
              finalize_deplibs="$deplib $finalize_deplibs"
            fi
            func_stripname '-L' '' "$deplib"
-           newlib_search_path="$newlib_search_path $func_stripname_result"
+           func_resolve_sysroot "$func_stripname_result"
+           func_append newlib_search_path " $func_resolve_sysroot_result"
            ;;
          *)
            func_warning "\`-L' is ignored for archives/objects"
@@ -5202,17 +6302,21 @@ func_mode_link ()
        -R*)
          if test "$pass" = link; then
            func_stripname '-R' '' "$deplib"
-           dir=$func_stripname_result
+           func_resolve_sysroot "$func_stripname_result"
+           dir=$func_resolve_sysroot_result
            # Make sure the xrpath contains only unique directories.
            case "$xrpath " in
            *" $dir "*) ;;
-           *) xrpath="$xrpath $dir" ;;
+           *) func_append xrpath " $dir" ;;
            esac
          fi
          deplibs="$deplib $deplibs"
          continue
          ;;
-       *.la) lib="$deplib" ;;
+       *.la)
+         func_resolve_sysroot "$deplib"
+         lib=$func_resolve_sysroot_result
+         ;;
        *.$libext)
          if test "$pass" = conv; then
            deplibs="$deplib $deplibs"
@@ -5230,7 +6334,7 @@ func_mode_link ()
                match_pattern*)
                  set dummy $deplibs_check_method; shift
                  match_pattern_regex=`expr "$deplibs_check_method" : "$1 \(.*\)"`
-                 if eval "\$ECHO \"X$deplib\"" 2>/dev/null | $Xsed -e 10q \
+                 if eval "\$ECHO \"$deplib\"" 2>/dev/null | $SED 10q \
                    | $EGREP "$match_pattern_regex" > /dev/null; then
                    valid_a_lib=yes
                  fi
@@ -5240,15 +6344,15 @@ func_mode_link ()
                ;;
              esac
              if test "$valid_a_lib" != yes; then
-               $ECHO
+               echo
                $ECHO "*** Warning: Trying to link with static lib archive $deplib."
-               $ECHO "*** I have the capability to make that library automatically link in when"
-               $ECHO "*** you link to this library.  But I can only do this if you have a"
-               $ECHO "*** shared version of the library, which you do not appear to have"
-               $ECHO "*** because the file extensions .$libext of this argument makes me believe"
-               $ECHO "*** that it is just a static archive that I should not use here."
+               echo "*** I have the capability to make that library automatically link in when"
+               echo "*** you link to this library.  But I can only do this if you have a"
+               echo "*** shared version of the library, which you do not appear to have"
+               echo "*** because the file extensions .$libext of this argument makes me believe"
+               echo "*** that it is just a static archive that I should not use here."
              else
-               $ECHO
+               echo
                $ECHO "*** Warning: Linking the shared library $output against the"
                $ECHO "*** static library $deplib is not portable!"
                deplibs="$deplib $deplibs"
@@ -5275,11 +6379,11 @@ func_mode_link ()
            if test "$pass" = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then
              # If there is no dlopen support or we're linking statically,
              # we need to preload.
-             newdlprefiles="$newdlprefiles $deplib"
+             func_append newdlprefiles " $deplib"
              compile_deplibs="$deplib $compile_deplibs"
              finalize_deplibs="$deplib $finalize_deplibs"
            else
-             newdlfiles="$newdlfiles $deplib"
+             func_append newdlfiles " $deplib"
            fi
          fi
          continue
@@ -5321,20 +6425,20 @@ func_mode_link ()
 
        # Convert "-framework foo" to "foo.ltframework"
        if test -n "$inherited_linker_flags"; then
-         tmp_inherited_linker_flags=`$ECHO "X$inherited_linker_flags" | $Xsed -e 's/-framework \([^ $]*\)/\1.ltframework/g'`
+         tmp_inherited_linker_flags=`$ECHO "$inherited_linker_flags" | $SED 's/-framework \([^ $]*\)/\1.ltframework/g'`
          for tmp_inherited_linker_flag in $tmp_inherited_linker_flags; do
            case " $new_inherited_linker_flags " in
              *" $tmp_inherited_linker_flag "*) ;;
-             *) new_inherited_linker_flags="$new_inherited_linker_flags $tmp_inherited_linker_flag";;
+             *) func_append new_inherited_linker_flags " $tmp_inherited_linker_flag";;
            esac
          done
        fi
-       dependency_libs=`$ECHO "X $dependency_libs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+       dependency_libs=`$ECHO " $dependency_libs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
        if test "$linkmode,$pass" = "lib,link" ||
           test "$linkmode,$pass" = "prog,scan" ||
           { test "$linkmode" != prog && test "$linkmode" != lib; }; then
-         test -n "$dlopen" && dlfiles="$dlfiles $dlopen"
-         test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen"
+         test -n "$dlopen" && func_append dlfiles " $dlopen"
+         test -n "$dlpreopen" && func_append dlprefiles " $dlpreopen"
        fi
 
        if test "$pass" = conv; then
@@ -5345,17 +6449,17 @@ func_mode_link ()
              func_fatal_error "cannot find name of link library for \`$lib'"
            fi
            # It is a libtool convenience library, so add in its objects.
-           convenience="$convenience $ladir/$objdir/$old_library"
-           old_convenience="$old_convenience $ladir/$objdir/$old_library"
+           func_append convenience " $ladir/$objdir/$old_library"
+           func_append old_convenience " $ladir/$objdir/$old_library"
            tmp_libs=
            for deplib in $dependency_libs; do
              deplibs="$deplib $deplibs"
-             if $opt_duplicate_deps ; then
+             if $opt_preserve_dup_deps ; then
                case "$tmp_libs " in
-               *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+               *" $deplib "*) func_append specialdeplibs " $deplib" ;;
                esac
              fi
-             tmp_libs="$tmp_libs $deplib"
+             func_append tmp_libs " $deplib"
            done
          elif test "$linkmode" != prog && test "$linkmode" != lib; then
            func_fatal_error "\`$lib' is not a convenience library"
@@ -5366,9 +6470,15 @@ func_mode_link ()
 
        # Get the name of the library we link against.
        linklib=
-       for l in $old_library $library_names; do
-         linklib="$l"
-       done
+       if test -n "$old_library" &&
+          { test "$prefer_static_libs" = yes ||
+            test "$prefer_static_libs,$installed" = "built,no"; }; then
+         linklib=$old_library
+       else
+         for l in $old_library $library_names; do
+           linklib="$l"
+         done
+       fi
        if test -z "$linklib"; then
          func_fatal_error "cannot find name of link library for \`$lib'"
        fi
@@ -5385,9 +6495,9 @@ func_mode_link ()
            # statically, we need to preload.  We also need to preload any
            # dependent libraries so libltdl's deplib preloader doesn't
            # bomb out in the load deplibs phase.
-           dlprefiles="$dlprefiles $lib $dependency_libs"
+           func_append dlprefiles " $lib $dependency_libs"
          else
-           newdlfiles="$newdlfiles $lib"
+           func_append newdlfiles " $lib"
          fi
          continue
        fi # $pass = dlopen
@@ -5409,14 +6519,14 @@ func_mode_link ()
 
        # Find the relevant object directory and library name.
        if test "X$installed" = Xyes; then
-         if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
+         if test ! -f "$lt_sysroot$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then
            func_warning "library \`$lib' was moved."
            dir="$ladir"
            absdir="$abs_ladir"
            libdir="$abs_ladir"
          else
-           dir="$libdir"
-           absdir="$libdir"
+           dir="$lt_sysroot$libdir"
+           absdir="$lt_sysroot$libdir"
          fi
          test "X$hardcode_automatic" = Xyes && avoidtemprpath=yes
        else
@@ -5424,12 +6534,12 @@ func_mode_link ()
            dir="$ladir"
            absdir="$abs_ladir"
            # Remove this search path later
-           notinst_path="$notinst_path $abs_ladir"
+           func_append notinst_path " $abs_ladir"
          else
            dir="$ladir/$objdir"
            absdir="$abs_ladir/$objdir"
            # Remove this search path later
-           notinst_path="$notinst_path $abs_ladir"
+           func_append notinst_path " $abs_ladir"
          fi
        fi # $installed = yes
        func_stripname 'lib' '.la' "$laname"
@@ -5440,20 +6550,46 @@ func_mode_link ()
          if test -z "$libdir" && test "$linkmode" = prog; then
            func_fatal_error "only libraries may -dlpreopen a convenience library: \`$lib'"
          fi
-         # Prefer using a static library (so that no silly _DYNAMIC symbols
-         # are required to link).
-         if test -n "$old_library"; then
-           newdlprefiles="$newdlprefiles $dir/$old_library"
-           # Keep a list of preopened convenience libraries to check
-           # that they are being used correctly in the link pass.
-           test -z "$libdir" && \
-               dlpreconveniencelibs="$dlpreconveniencelibs $dir/$old_library"
-         # Otherwise, use the dlname, so that lt_dlopen finds it.
-         elif test -n "$dlname"; then
-           newdlprefiles="$newdlprefiles $dir/$dlname"
-         else
-           newdlprefiles="$newdlprefiles $dir/$linklib"
-         fi
+         case "$host" in
+           # special handling for platforms with PE-DLLs.
+           *cygwin* | *mingw* | *cegcc* )
+             # Linker will automatically link against shared library if both
+             # static and shared are present.  Therefore, ensure we extract
+             # symbols from the import library if a shared library is present
+             # (otherwise, the dlopen module name will be incorrect).  We do
+             # this by putting the import library name into $newdlprefiles.
+             # We recover the dlopen module name by 'saving' the la file
+             # name in a special purpose variable, and (later) extracting the
+             # dlname from the la file.
+             if test -n "$dlname"; then
+               func_tr_sh "$dir/$linklib"
+               eval "libfile_$func_tr_sh_result=\$abs_ladir/\$laname"
+               func_append newdlprefiles " $dir/$linklib"
+             else
+               func_append newdlprefiles " $dir/$old_library"
+               # Keep a list of preopened convenience libraries to check
+               # that they are being used correctly in the link pass.
+               test -z "$libdir" && \
+                 func_append dlpreconveniencelibs " $dir/$old_library"
+             fi
+           ;;
+           * )
+             # Prefer using a static library (so that no silly _DYNAMIC symbols
+             # are required to link).
+             if test -n "$old_library"; then
+               func_append newdlprefiles " $dir/$old_library"
+               # Keep a list of preopened convenience libraries to check
+               # that they are being used correctly in the link pass.
+               test -z "$libdir" && \
+                 func_append dlpreconveniencelibs " $dir/$old_library"
+             # Otherwise, use the dlname, so that lt_dlopen finds it.
+             elif test -n "$dlname"; then
+               func_append newdlprefiles " $dir/$dlname"
+             else
+               func_append newdlprefiles " $dir/$linklib"
+             fi
+           ;;
+         esac
        fi # $pass = dlpreopen
 
        if test -z "$libdir"; then
@@ -5471,7 +6607,7 @@ func_mode_link ()
 
 
        if test "$linkmode" = prog && test "$pass" != link; then
-         newlib_search_path="$newlib_search_path $ladir"
+         func_append newlib_search_path " $ladir"
          deplibs="$lib $deplibs"
 
          linkalldeplibs=no
@@ -5484,7 +6620,8 @@ func_mode_link ()
          for deplib in $dependency_libs; do
            case $deplib in
            -L*) func_stripname '-L' '' "$deplib"
-                newlib_search_path="$newlib_search_path $func_stripname_result"
+                func_resolve_sysroot "$func_stripname_result"
+                func_append newlib_search_path " $func_resolve_sysroot_result"
                 ;;
            esac
            # Need to link against all dependency_libs?
@@ -5495,12 +6632,12 @@ func_mode_link ()
              # or/and link against static libraries
              newdependency_libs="$deplib $newdependency_libs"
            fi
-           if $opt_duplicate_deps ; then
+           if $opt_preserve_dup_deps ; then
              case "$tmp_libs " in
-             *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+             *" $deplib "*) func_append specialdeplibs " $deplib" ;;
              esac
            fi
-           tmp_libs="$tmp_libs $deplib"
+           func_append tmp_libs " $deplib"
          done # for deplib
          continue
        fi # $linkmode = prog...
@@ -5515,7 +6652,7 @@ func_mode_link ()
              # Make sure the rpath contains only unique directories.
              case "$temp_rpath:" in
              *"$absdir:"*) ;;
-             *) temp_rpath="$temp_rpath$absdir:" ;;
+             *) func_append temp_rpath "$absdir:" ;;
              esac
            fi
 
@@ -5527,7 +6664,7 @@ func_mode_link ()
            *)
              case "$compile_rpath " in
              *" $absdir "*) ;;
-             *) compile_rpath="$compile_rpath $absdir"
+             *) func_append compile_rpath " $absdir" ;;
              esac
              ;;
            esac
@@ -5536,7 +6673,7 @@ func_mode_link ()
            *)
              case "$finalize_rpath " in
              *" $libdir "*) ;;
-             *) finalize_rpath="$finalize_rpath $libdir"
+             *) func_append finalize_rpath " $libdir" ;;
              esac
              ;;
            esac
@@ -5561,12 +6698,12 @@ func_mode_link ()
          case $host in
          *cygwin* | *mingw* | *cegcc*)
              # No point in relinking DLLs because paths are not encoded
-             notinst_deplibs="$notinst_deplibs $lib"
+             func_append notinst_deplibs " $lib"
              need_relink=no
            ;;
          *)
            if test "$installed" = no; then
-             notinst_deplibs="$notinst_deplibs $lib"
+             func_append notinst_deplibs " $lib"
              need_relink=yes
            fi
            ;;
@@ -5583,7 +6720,7 @@ func_mode_link ()
            fi
          done
          if test -z "$dlopenmodule" && test "$shouldnotlink" = yes && test "$pass" = link; then
-           $ECHO
+           echo
            if test "$linkmode" = prog; then
              $ECHO "*** Warning: Linking the executable $output against the loadable module"
            else
@@ -5601,7 +6738,7 @@ func_mode_link ()
            *)
              case "$compile_rpath " in
              *" $absdir "*) ;;
-             *) compile_rpath="$compile_rpath $absdir"
+             *) func_append compile_rpath " $absdir" ;;
              esac
              ;;
            esac
@@ -5610,7 +6747,7 @@ func_mode_link ()
            *)
              case "$finalize_rpath " in
              *" $libdir "*) ;;
-             *) finalize_rpath="$finalize_rpath $libdir"
+             *) func_append finalize_rpath " $libdir" ;;
              esac
              ;;
            esac
@@ -5664,7 +6801,7 @@ func_mode_link ()
            linklib=$newlib
          fi # test -n "$old_archive_from_expsyms_cmds"
 
-         if test "$linkmode" = prog || test "$mode" != relink; then
+         if test "$linkmode" = prog || test "$opt_mode" != relink; then
            add_shlibpath=
            add_dir=
            add=
@@ -5686,9 +6823,9 @@ func_mode_link ()
                      if test "X$dlopenmodule" != "X$lib"; then
                        $ECHO "*** Warning: lib $linklib is a module, not a shared library"
                        if test -z "$old_library" ; then
-                         $ECHO
-                         $ECHO "*** And there doesn't seem to be a static archive available"
-                         $ECHO "*** The link will probably fail, sorry"
+                         echo
+                         echo "*** And there doesn't seem to be a static archive available"
+                         echo "*** The link will probably fail, sorry"
                        else
                          add="$dir/$old_library"
                        fi
@@ -5715,12 +6852,12 @@ func_mode_link ()
                 test "$hardcode_direct_absolute" = no; then
                add="$dir/$linklib"
              elif test "$hardcode_minus_L" = yes; then
-               add_dir="-L$dir"
+               add_dir="-L$absdir"
                # Try looking first in the location we're being installed to.
                if test -n "$inst_prefix_dir"; then
                  case $libdir in
                    [\\/]*)
-                     add_dir="$add_dir -L$inst_prefix_dir$libdir"
+                     func_append add_dir " -L$inst_prefix_dir$libdir"
                      ;;
                  esac
                fi
@@ -5742,7 +6879,7 @@ func_mode_link ()
            if test -n "$add_shlibpath"; then
              case :$compile_shlibpath: in
              *":$add_shlibpath:"*) ;;
-             *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;;
+             *) func_append compile_shlibpath "$add_shlibpath:" ;;
              esac
            fi
            if test "$linkmode" = prog; then
@@ -5756,13 +6893,13 @@ func_mode_link ()
                 test "$hardcode_shlibpath_var" = yes; then
                case :$finalize_shlibpath: in
                *":$libdir:"*) ;;
-               *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+               *) func_append finalize_shlibpath "$libdir:" ;;
                esac
              fi
            fi
          fi
 
-         if test "$linkmode" = prog || test "$mode" = relink; then
+         if test "$linkmode" = prog || test "$opt_mode" = relink; then
            add_shlibpath=
            add_dir=
            add=
@@ -5776,7 +6913,7 @@ func_mode_link ()
            elif test "$hardcode_shlibpath_var" = yes; then
              case :$finalize_shlibpath: in
              *":$libdir:"*) ;;
-             *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;;
+             *) func_append finalize_shlibpath "$libdir:" ;;
              esac
              add="-l$name"
            elif test "$hardcode_automatic" = yes; then
@@ -5793,7 +6930,7 @@ func_mode_link ()
              if test -n "$inst_prefix_dir"; then
                case $libdir in
                  [\\/]*)
-                   add_dir="$add_dir -L$inst_prefix_dir$libdir"
+                   func_append add_dir " -L$inst_prefix_dir$libdir"
                    ;;
                esac
              fi
@@ -5828,21 +6965,21 @@ func_mode_link ()
 
            # Just print a warning and add the library to dependency_libs so
            # that the program can be linked against the static library.
-           $ECHO
+           echo
            $ECHO "*** Warning: This system can not link to static lib archive $lib."
-           $ECHO "*** I have the capability to make that library automatically link in when"
-           $ECHO "*** you link to this library.  But I can only do this if you have a"
-           $ECHO "*** shared version of the library, which you do not appear to have."
+           echo "*** I have the capability to make that library automatically link in when"
+           echo "*** you link to this library.  But I can only do this if you have a"
+           echo "*** shared version of the library, which you do not appear to have."
            if test "$module" = yes; then
-             $ECHO "*** But as you try to build a module library, libtool will still create "
-             $ECHO "*** a static module, that should work as long as the dlopening application"
-             $ECHO "*** is linked with the -dlopen flag to resolve symbols at runtime."
+             echo "*** But as you try to build a module library, libtool will still create "
+             echo "*** a static module, that should work as long as the dlopening application"
+             echo "*** is linked with the -dlopen flag to resolve symbols at runtime."
              if test -z "$global_symbol_pipe"; then
-               $ECHO
-               $ECHO "*** However, this would only work if libtool was able to extract symbol"
-               $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
-               $ECHO "*** not find such a program.  So, this module is probably useless."
-               $ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
+               echo
+               echo "*** However, this would only work if libtool was able to extract symbol"
+               echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+               echo "*** not find such a program.  So, this module is probably useless."
+               echo "*** \`nm' from GNU binutils and a full rebuild may help."
              fi
              if test "$build_old_libs" = no; then
                build_libtool_libs=module
@@ -5870,27 +7007,33 @@ func_mode_link ()
                   temp_xrpath=$func_stripname_result
                   case " $xrpath " in
                   *" $temp_xrpath "*) ;;
-                  *) xrpath="$xrpath $temp_xrpath";;
+                  *) func_append xrpath " $temp_xrpath";;
                   esac;;
-             *) temp_deplibs="$temp_deplibs $libdir";;
+             *) func_append temp_deplibs " $libdir";;
              esac
            done
            dependency_libs="$temp_deplibs"
          fi
 
-         newlib_search_path="$newlib_search_path $absdir"
+         func_append newlib_search_path " $absdir"
          # Link against this library
          test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs"
          # ... and its dependency_libs
          tmp_libs=
          for deplib in $dependency_libs; do
            newdependency_libs="$deplib $newdependency_libs"
-           if $opt_duplicate_deps ; then
+           case $deplib in
+              -L*) func_stripname '-L' '' "$deplib"
+                   func_resolve_sysroot "$func_stripname_result";;
+              *) func_resolve_sysroot "$deplib" ;;
+            esac
+           if $opt_preserve_dup_deps ; then
              case "$tmp_libs " in
-             *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;;
+             *" $func_resolve_sysroot_result "*)
+                func_append specialdeplibs " $func_resolve_sysroot_result" ;;
              esac
            fi
-           tmp_libs="$tmp_libs $deplib"
+           func_append tmp_libs " $func_resolve_sysroot_result"
          done
 
          if test "$link_all_deplibs" != no; then
@@ -5900,8 +7043,10 @@ func_mode_link ()
              case $deplib in
              -L*) path="$deplib" ;;
              *.la)
+               func_resolve_sysroot "$deplib"
+               deplib=$func_resolve_sysroot_result
                func_dirname "$deplib" "" "."
-               dir="$func_dirname_result"
+               dir=$func_dirname_result
                # We need an absolute path.
                case $dir in
                [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;;
@@ -5928,8 +7073,8 @@ func_mode_link ()
                       if test -z "$darwin_install_name"; then
                           darwin_install_name=`${OTOOL64} -L $depdepl  | awk '{if (NR == 2) {print $1;exit}}'`
                       fi
-                     compiler_flags="$compiler_flags ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
-                     linker_flags="$linker_flags -dylib_file ${darwin_install_name}:${depdepl}"
+                     func_append compiler_flags " ${wl}-dylib_file ${wl}${darwin_install_name}:${depdepl}"
+                     func_append linker_flags " -dylib_file ${darwin_install_name}:${depdepl}"
                      path=
                    fi
                  fi
@@ -5962,7 +7107,7 @@ func_mode_link ()
          compile_deplibs="$new_inherited_linker_flags $compile_deplibs"
          finalize_deplibs="$new_inherited_linker_flags $finalize_deplibs"
        else
-         compiler_flags="$compiler_flags "`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+         compiler_flags="$compiler_flags "`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
        fi
       fi
       dependency_libs="$newdependency_libs"
@@ -5979,7 +7124,7 @@ func_mode_link ()
          for dir in $newlib_search_path; do
            case "$lib_search_path " in
            *" $dir "*) ;;
-           *) lib_search_path="$lib_search_path $dir" ;;
+           *) func_append lib_search_path " $dir" ;;
            esac
          done
          newlib_search_path=
@@ -6037,10 +7182,10 @@ func_mode_link ()
            -L*)
              case " $tmp_libs " in
              *" $deplib "*) ;;
-             *) tmp_libs="$tmp_libs $deplib" ;;
+             *) func_append tmp_libs " $deplib" ;;
              esac
              ;;
-           *) tmp_libs="$tmp_libs $deplib" ;;
+           *) func_append tmp_libs " $deplib" ;;
            esac
          done
          eval $var=\"$tmp_libs\"
@@ -6056,7 +7201,7 @@ func_mode_link ()
          ;;
        esac
        if test -n "$i" ; then
-         tmp_libs="$tmp_libs $i"
+         func_append tmp_libs " $i"
        fi
       done
       dependency_libs=$tmp_libs
@@ -6097,7 +7242,7 @@ func_mode_link ()
       # Now set the variables for building old libraries.
       build_libtool_libs=no
       oldlibs="$output"
-      objs="$objs$old_deplibs"
+      func_append objs "$old_deplibs"
       ;;
 
     lib)
@@ -6130,10 +7275,10 @@ func_mode_link ()
        if test "$deplibs_check_method" != pass_all; then
          func_fatal_error "cannot build libtool library \`$output' from non-libtool objects on this host:$objs"
        else
-         $ECHO
+         echo
          $ECHO "*** Warning: Linking the shared library $output against the non-libtool"
          $ECHO "*** objects $objs is not portable!"
-         libobjs="$libobjs $objs"
+         func_append libobjs " $objs"
        fi
       fi
 
@@ -6192,13 +7337,14 @@ func_mode_link ()
          # which has an extra 1 added just for fun
          #
          case $version_type in
+         # correct linux to gnu/linux during the next big refactor
          darwin|linux|osf|windows|none)
            func_arith $number_major + $number_minor
            current=$func_arith_result
            age="$number_minor"
            revision="$number_revision"
            ;;
-         freebsd-aout|freebsd-elf|sunos)
+         freebsd-aout|freebsd-elf|qnx|sunos)
            current="$number_major"
            revision="$number_minor"
            age="0"
@@ -6311,7 +7457,7 @@ func_mode_link ()
          versuffix="$major.$revision"
          ;;
 
-       linux)
+       linux) # correct to gnu/linux during the next big refactor
          func_arith $current - $age
          major=.$func_arith_result
          versuffix="$major.$age.$revision"
@@ -6334,7 +7480,7 @@ func_mode_link ()
          done
 
          # Make executables depend on our current version.
-         verstring="$verstring:${current}.0"
+         func_append verstring ":${current}.0"
          ;;
 
        qnx)
@@ -6402,10 +7548,10 @@ func_mode_link ()
       fi
 
       func_generate_dlsyms "$libname" "$libname" "yes"
-      libobjs="$libobjs $symfileobj"
+      func_append libobjs " $symfileobj"
       test "X$libobjs" = "X " && libobjs=
 
-      if test "$mode" != relink; then
+      if test "$opt_mode" != relink; then
        # Remove our outputs, but don't remove object files since they
        # may have been created when compiling PIC objects.
        removelist=
@@ -6421,7 +7567,7 @@ func_mode_link ()
                   continue
                 fi
               fi
-              removelist="$removelist $p"
+              func_append removelist " $p"
               ;;
            *) ;;
          esac
@@ -6432,27 +7578,28 @@ func_mode_link ()
 
       # Now set the variables for building old libraries.
       if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
-       oldlibs="$oldlibs $output_objdir/$libname.$libext"
+       func_append oldlibs " $output_objdir/$libname.$libext"
 
        # Transform .lo files to .o files.
-       oldobjs="$objs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+       oldobjs="$objs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; $lo2o" | $NL2SP`
       fi
 
       # Eliminate all temporary directories.
       #for path in $notinst_path; do
-      #        lib_search_path=`$ECHO "X$lib_search_path " | $Xsed -e "s% $path % %g"`
-      #        deplibs=`$ECHO "X$deplibs " | $Xsed -e "s% -L$path % %g"`
-      #        dependency_libs=`$ECHO "X$dependency_libs " | $Xsed -e "s% -L$path % %g"`
+      #        lib_search_path=`$ECHO "$lib_search_path " | $SED "s% $path % %g"`
+      #        deplibs=`$ECHO "$deplibs " | $SED "s% -L$path % %g"`
+      #        dependency_libs=`$ECHO "$dependency_libs " | $SED "s% -L$path % %g"`
       #done
 
       if test -n "$xrpath"; then
        # If the user specified any rpath flags, then add them.
        temp_xrpath=
        for libdir in $xrpath; do
-         temp_xrpath="$temp_xrpath -R$libdir"
+         func_replace_sysroot "$libdir"
+         func_append temp_xrpath " -R$func_replace_sysroot_result"
          case "$finalize_rpath " in
          *" $libdir "*) ;;
-         *) finalize_rpath="$finalize_rpath $libdir" ;;
+         *) func_append finalize_rpath " $libdir" ;;
          esac
        done
        if test "$hardcode_into_libs" != yes || test "$build_old_libs" = yes; then
@@ -6466,7 +7613,7 @@ func_mode_link ()
       for lib in $old_dlfiles; do
        case " $dlprefiles $dlfiles " in
        *" $lib "*) ;;
-       *) dlfiles="$dlfiles $lib" ;;
+       *) func_append dlfiles " $lib" ;;
        esac
       done
 
@@ -6476,19 +7623,19 @@ func_mode_link ()
       for lib in $old_dlprefiles; do
        case "$dlprefiles " in
        *" $lib "*) ;;
-       *) dlprefiles="$dlprefiles $lib" ;;
+       *) func_append dlprefiles " $lib" ;;
        esac
       done
 
       if test "$build_libtool_libs" = yes; then
        if test -n "$rpath"; then
          case $host in
-         *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc*)
+         *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos* | *-cegcc* | *-*-haiku*)
            # these systems don't actually have a c library (as such)!
            ;;
          *-*-rhapsody* | *-*-darwin1.[012])
            # Rhapsody C library is in the System framework
-           deplibs="$deplibs System.ltframework"
+           func_append deplibs " System.ltframework"
            ;;
          *-*-netbsd*)
            # Don't link with libc until the a.out ld.so is fixed.
@@ -6505,7 +7652,7 @@ func_mode_link ()
          *)
            # Add libc to deplibs on all other systems if necessary.
            if test "$build_libtool_need_lc" = "yes"; then
-             deplibs="$deplibs -lc"
+             func_append deplibs " -lc"
            fi
            ;;
          esac
@@ -6554,7 +7701,7 @@ EOF
                if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
                  case " $predeps $postdeps " in
                  *" $i "*)
-                   newdeplibs="$newdeplibs $i"
+                   func_append newdeplibs " $i"
                    i=""
                    ;;
                  esac
@@ -6565,21 +7712,21 @@ EOF
                  set dummy $deplib_matches; shift
                  deplib_match=$1
                  if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
-                   newdeplibs="$newdeplibs $i"
+                   func_append newdeplibs " $i"
                  else
                    droppeddeps=yes
-                   $ECHO
+                   echo
                    $ECHO "*** Warning: dynamic linker does not accept needed library $i."
-                   $ECHO "*** I have the capability to make that library automatically link in when"
-                   $ECHO "*** you link to this library.  But I can only do this if you have a"
-                   $ECHO "*** shared version of the library, which I believe you do not have"
-                   $ECHO "*** because a test_compile did reveal that the linker did not use it for"
-                   $ECHO "*** its dynamic dependency list that programs get resolved with at runtime."
+                   echo "*** I have the capability to make that library automatically link in when"
+                   echo "*** you link to this library.  But I can only do this if you have a"
+                   echo "*** shared version of the library, which I believe you do not have"
+                   echo "*** because a test_compile did reveal that the linker did not use it for"
+                   echo "*** its dynamic dependency list that programs get resolved with at runtime."
                  fi
                fi
                ;;
              *)
-               newdeplibs="$newdeplibs $i"
+               func_append newdeplibs " $i"
                ;;
              esac
            done
@@ -6597,7 +7744,7 @@ EOF
                  if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
                    case " $predeps $postdeps " in
                    *" $i "*)
-                     newdeplibs="$newdeplibs $i"
+                     func_append newdeplibs " $i"
                      i=""
                      ;;
                    esac
@@ -6608,29 +7755,29 @@ EOF
                    set dummy $deplib_matches; shift
                    deplib_match=$1
                    if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
-                     newdeplibs="$newdeplibs $i"
+                     func_append newdeplibs " $i"
                    else
                      droppeddeps=yes
-                     $ECHO
+                     echo
                      $ECHO "*** Warning: dynamic linker does not accept needed library $i."
-                     $ECHO "*** I have the capability to make that library automatically link in when"
-                     $ECHO "*** you link to this library.  But I can only do this if you have a"
-                     $ECHO "*** shared version of the library, which you do not appear to have"
-                     $ECHO "*** because a test_compile did reveal that the linker did not use this one"
-                     $ECHO "*** as a dynamic dependency that programs can get resolved with at runtime."
+                     echo "*** I have the capability to make that library automatically link in when"
+                     echo "*** you link to this library.  But I can only do this if you have a"
+                     echo "*** shared version of the library, which you do not appear to have"
+                     echo "*** because a test_compile did reveal that the linker did not use this one"
+                     echo "*** as a dynamic dependency that programs can get resolved with at runtime."
                    fi
                  fi
                else
                  droppeddeps=yes
-                 $ECHO
+                 echo
                  $ECHO "*** Warning!  Library $i is needed by this library but I was not able to"
-                 $ECHO "*** make it link in!  You will probably need to install it or some"
-                 $ECHO "*** library that it depends on before this library will be fully"
-                 $ECHO "*** functional.  Installing it before continuing would be even better."
+                 echo "*** make it link in!  You will probably need to install it or some"
+                 echo "*** library that it depends on before this library will be fully"
+                 echo "*** functional.  Installing it before continuing would be even better."
                fi
                ;;
              *)
-               newdeplibs="$newdeplibs $i"
+               func_append newdeplibs " $i"
                ;;
              esac
            done
@@ -6647,15 +7794,27 @@ EOF
              if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
                case " $predeps $postdeps " in
                *" $a_deplib "*)
-                 newdeplibs="$newdeplibs $a_deplib"
+                 func_append newdeplibs " $a_deplib"
                  a_deplib=""
                  ;;
                esac
              fi
              if test -n "$a_deplib" ; then
                libname=`eval "\\$ECHO \"$libname_spec\""`
+               if test -n "$file_magic_glob"; then
+                 libnameglob=`func_echo_all "$libname" | $SED -e $file_magic_glob`
+               else
+                 libnameglob=$libname
+               fi
+               test "$want_nocaseglob" = yes && nocaseglob=`shopt -p nocaseglob`
                for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do
-                 potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+                 if test "$want_nocaseglob" = yes; then
+                   shopt -s nocaseglob
+                   potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+                   $nocaseglob
+                 else
+                   potential_libs=`ls $i/$libnameglob[.-]* 2>/dev/null`
+                 fi
                  for potent_lib in $potential_libs; do
                      # Follow soft links.
                      if ls -lLd "$potent_lib" 2>/dev/null |
@@ -6672,13 +7831,13 @@ EOF
                        potliblink=`ls -ld $potlib | ${SED} 's/.* -> //'`
                        case $potliblink in
                        [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
-                       *) potlib=`$ECHO "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+                       *) potlib=`$ECHO "$potlib" | $SED 's,[^/]*$,,'`"$potliblink";;
                        esac
                      done
                      if eval $file_magic_cmd \"\$potlib\" 2>/dev/null |
                         $SED -e 10q |
                         $EGREP "$file_magic_regex" > /dev/null; then
-                       newdeplibs="$newdeplibs $a_deplib"
+                       func_append newdeplibs " $a_deplib"
                        a_deplib=""
                        break 2
                      fi
@@ -6687,12 +7846,12 @@ EOF
              fi
              if test -n "$a_deplib" ; then
                droppeddeps=yes
-               $ECHO
+               echo
                $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
-               $ECHO "*** I have the capability to make that library automatically link in when"
-               $ECHO "*** you link to this library.  But I can only do this if you have a"
-               $ECHO "*** shared version of the library, which you do not appear to have"
-               $ECHO "*** because I did check the linker path looking for a file starting"
+               echo "*** I have the capability to make that library automatically link in when"
+               echo "*** you link to this library.  But I can only do this if you have a"
+               echo "*** shared version of the library, which you do not appear to have"
+               echo "*** because I did check the linker path looking for a file starting"
                if test -z "$potlib" ; then
                  $ECHO "*** with $libname but no candidates were found. (...for file magic test)"
                else
@@ -6703,7 +7862,7 @@ EOF
              ;;
            *)
              # Add a -L argument.
-             newdeplibs="$newdeplibs $a_deplib"
+             func_append newdeplibs " $a_deplib"
              ;;
            esac
          done # Gone through all deplibs.
@@ -6719,7 +7878,7 @@ EOF
              if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
                case " $predeps $postdeps " in
                *" $a_deplib "*)
-                 newdeplibs="$newdeplibs $a_deplib"
+                 func_append newdeplibs " $a_deplib"
                  a_deplib=""
                  ;;
                esac
@@ -6730,9 +7889,9 @@ EOF
                  potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
                  for potent_lib in $potential_libs; do
                    potlib="$potent_lib" # see symlink-check above in file_magic test
-                   if eval "\$ECHO \"X$potent_lib\"" 2>/dev/null | $Xsed -e 10q | \
+                   if eval "\$ECHO \"$potent_lib\"" 2>/dev/null | $SED 10q | \
                       $EGREP "$match_pattern_regex" > /dev/null; then
-                     newdeplibs="$newdeplibs $a_deplib"
+                     func_append newdeplibs " $a_deplib"
                      a_deplib=""
                      break 2
                    fi
@@ -6741,12 +7900,12 @@ EOF
              fi
              if test -n "$a_deplib" ; then
                droppeddeps=yes
-               $ECHO
+               echo
                $ECHO "*** Warning: linker path does not have real file for library $a_deplib."
-               $ECHO "*** I have the capability to make that library automatically link in when"
-               $ECHO "*** you link to this library.  But I can only do this if you have a"
-               $ECHO "*** shared version of the library, which you do not appear to have"
-               $ECHO "*** because I did check the linker path looking for a file starting"
+               echo "*** I have the capability to make that library automatically link in when"
+               echo "*** you link to this library.  But I can only do this if you have a"
+               echo "*** shared version of the library, which you do not appear to have"
+               echo "*** because I did check the linker path looking for a file starting"
                if test -z "$potlib" ; then
                  $ECHO "*** with $libname but no candidates were found. (...for regex pattern test)"
                else
@@ -6757,32 +7916,32 @@ EOF
              ;;
            *)
              # Add a -L argument.
-             newdeplibs="$newdeplibs $a_deplib"
+             func_append newdeplibs " $a_deplib"
              ;;
            esac
          done # Gone through all deplibs.
          ;;
        none | unknown | *)
          newdeplibs=""
-         tmp_deplibs=`$ECHO "X $deplibs" | $Xsed \
-             -e 's/ -lc$//' -e 's/ -[LR][^ ]*//g'`
+         tmp_deplibs=`$ECHO " $deplibs" | $SED 's/ -lc$//; s/ -[LR][^ ]*//g'`
          if test "X$allow_libtool_libs_with_static_runtimes" = "Xyes" ; then
            for i in $predeps $postdeps ; do
              # can't use Xsed below, because $i might contain '/'
-             tmp_deplibs=`$ECHO "X $tmp_deplibs" | $Xsed -e "s,$i,,"`
+             tmp_deplibs=`$ECHO " $tmp_deplibs" | $SED "s,$i,,"`
            done
          fi
-         if $ECHO "X $tmp_deplibs" | $Xsed -e 's/[      ]//g' |
-            $GREP . >/dev/null; then
-           $ECHO
+         case $tmp_deplibs in
+         *[!\  \ ]*)
+           echo
            if test "X$deplibs_check_method" = "Xnone"; then
-             $ECHO "*** Warning: inter-library dependencies are not supported in this platform."
+             echo "*** Warning: inter-library dependencies are not supported in this platform."
            else
-             $ECHO "*** Warning: inter-library dependencies are not known to be supported."
+             echo "*** Warning: inter-library dependencies are not known to be supported."
            fi
-           $ECHO "*** All declared inter-library dependencies are being dropped."
+           echo "*** All declared inter-library dependencies are being dropped."
            droppeddeps=yes
-         fi
+           ;;
+         esac
          ;;
        esac
        versuffix=$versuffix_save
@@ -6794,23 +7953,23 @@ EOF
        case $host in
        *-*-rhapsody* | *-*-darwin1.[012])
          # On Rhapsody replace the C library with the System framework
-         newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+         newdeplibs=`$ECHO " $newdeplibs" | $SED 's/ -lc / System.ltframework /'`
          ;;
        esac
 
        if test "$droppeddeps" = yes; then
          if test "$module" = yes; then
-           $ECHO
-           $ECHO "*** Warning: libtool could not satisfy all declared inter-library"
+           echo
+           echo "*** Warning: libtool could not satisfy all declared inter-library"
            $ECHO "*** dependencies of module $libname.  Therefore, libtool will create"
-           $ECHO "*** a static module, that should work as long as the dlopening"
-           $ECHO "*** application is linked with the -dlopen flag."
+           echo "*** a static module, that should work as long as the dlopening"
+           echo "*** application is linked with the -dlopen flag."
            if test -z "$global_symbol_pipe"; then
-             $ECHO
-             $ECHO "*** However, this would only work if libtool was able to extract symbol"
-             $ECHO "*** lists from a program, using \`nm' or equivalent, but libtool could"
-             $ECHO "*** not find such a program.  So, this module is probably useless."
-             $ECHO "*** \`nm' from GNU binutils and a full rebuild may help."
+             echo
+             echo "*** However, this would only work if libtool was able to extract symbol"
+             echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+             echo "*** not find such a program.  So, this module is probably useless."
+             echo "*** \`nm' from GNU binutils and a full rebuild may help."
            fi
            if test "$build_old_libs" = no; then
              oldlibs="$output_objdir/$libname.$libext"
@@ -6820,16 +7979,16 @@ EOF
              build_libtool_libs=no
            fi
          else
-           $ECHO "*** The inter-library dependencies that have been dropped here will be"
-           $ECHO "*** automatically added whenever a program is linked with this library"
-           $ECHO "*** or is declared to -dlopen it."
+           echo "*** The inter-library dependencies that have been dropped here will be"
+           echo "*** automatically added whenever a program is linked with this library"
+           echo "*** or is declared to -dlopen it."
 
            if test "$allow_undefined" = no; then
-             $ECHO
-             $ECHO "*** Since this library must not contain undefined symbols,"
-             $ECHO "*** because either the platform does not support them or"
-             $ECHO "*** it was explicitly requested with -no-undefined,"
-             $ECHO "*** libtool will only create a static version of it."
+             echo
+             echo "*** Since this library must not contain undefined symbols,"
+             echo "*** because either the platform does not support them or"
+             echo "*** it was explicitly requested with -no-undefined,"
+             echo "*** libtool will only create a static version of it."
              if test "$build_old_libs" = no; then
                oldlibs="$output_objdir/$libname.$libext"
                build_libtool_libs=module
@@ -6846,9 +8005,9 @@ EOF
       # Time to change all our "foo.ltframework" stuff back to "-framework foo"
       case $host in
        *-*-darwin*)
-         newdeplibs=`$ECHO "X $newdeplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
-         new_inherited_linker_flags=`$ECHO "X $new_inherited_linker_flags" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
-         deplibs=`$ECHO "X $deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+         newdeplibs=`$ECHO " $newdeplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+         new_inherited_linker_flags=`$ECHO " $new_inherited_linker_flags" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+         deplibs=`$ECHO " $deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
          ;;
       esac
 
@@ -6861,7 +8020,7 @@ EOF
        *)
          case " $deplibs " in
          *" -L$path/$objdir "*)
-           new_libs="$new_libs -L$path/$objdir" ;;
+           func_append new_libs " -L$path/$objdir" ;;
          esac
          ;;
        esac
@@ -6871,10 +8030,10 @@ EOF
        -L*)
          case " $new_libs " in
          *" $deplib "*) ;;
-         *) new_libs="$new_libs $deplib" ;;
+         *) func_append new_libs " $deplib" ;;
          esac
          ;;
-       *) new_libs="$new_libs $deplib" ;;
+       *) func_append new_libs " $deplib" ;;
        esac
       done
       deplibs="$new_libs"
@@ -6886,15 +8045,22 @@ EOF
 
       # Test again, we may have decided not to build it any more
       if test "$build_libtool_libs" = yes; then
+       # Remove ${wl} instances when linking with ld.
+       # FIXME: should test the right _cmds variable.
+       case $archive_cmds in
+         *\$LD\ *) wl= ;;
+        esac
        if test "$hardcode_into_libs" = yes; then
          # Hardcode the library paths
          hardcode_libdirs=
          dep_rpath=
          rpath="$finalize_rpath"
-         test "$mode" != relink && rpath="$compile_rpath$rpath"
+         test "$opt_mode" != relink && rpath="$compile_rpath$rpath"
          for libdir in $rpath; do
            if test -n "$hardcode_libdir_flag_spec"; then
              if test -n "$hardcode_libdir_separator"; then
+               func_replace_sysroot "$libdir"
+               libdir=$func_replace_sysroot_result
                if test -z "$hardcode_libdirs"; then
                  hardcode_libdirs="$libdir"
                else
@@ -6903,18 +8069,18 @@ EOF
                  *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
                    ;;
                  *)
-                   hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+                   func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
                    ;;
                  esac
                fi
              else
                eval flag=\"$hardcode_libdir_flag_spec\"
-               dep_rpath="$dep_rpath $flag"
+               func_append dep_rpath " $flag"
              fi
            elif test -n "$runpath_var"; then
              case "$perm_rpath " in
              *" $libdir "*) ;;
-             *) perm_rpath="$perm_rpath $libdir" ;;
+             *) func_append perm_rpath " $libdir" ;;
              esac
            fi
          done
@@ -6922,17 +8088,13 @@ EOF
          if test -n "$hardcode_libdir_separator" &&
             test -n "$hardcode_libdirs"; then
            libdir="$hardcode_libdirs"
-           if test -n "$hardcode_libdir_flag_spec_ld"; then
-             eval dep_rpath=\"$hardcode_libdir_flag_spec_ld\"
-           else
-             eval dep_rpath=\"$hardcode_libdir_flag_spec\"
-           fi
+           eval "dep_rpath=\"$hardcode_libdir_flag_spec\""
          fi
          if test -n "$runpath_var" && test -n "$perm_rpath"; then
            # We should set the runpath_var.
            rpath=
            for dir in $perm_rpath; do
-             rpath="$rpath$dir:"
+             func_append rpath "$dir:"
            done
            eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var"
          fi
@@ -6940,7 +8102,7 @@ EOF
        fi
 
        shlibpath="$finalize_shlibpath"
-       test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
+       test "$opt_mode" != relink && shlibpath="$compile_shlibpath$shlibpath"
        if test -n "$shlibpath"; then
          eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var"
        fi
@@ -6966,18 +8128,18 @@ EOF
        linknames=
        for link
        do
-         linknames="$linknames $link"
+         func_append linknames " $link"
        done
 
        # Use standard objects if they are pic
-       test -z "$pic_flag" && libobjs=`$ECHO "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+       test -z "$pic_flag" && libobjs=`$ECHO "$libobjs" | $SP2NL | $SED "$lo2o" | $NL2SP`
        test "X$libobjs" = "X " && libobjs=
 
        delfiles=
        if test -n "$export_symbols" && test -n "$include_expsyms"; then
          $opt_dry_run || cp "$export_symbols" "$output_objdir/$libname.uexp"
          export_symbols="$output_objdir/$libname.uexp"
-         delfiles="$delfiles $export_symbols"
+         func_append delfiles " $export_symbols"
        fi
 
        orig_export_symbols=
@@ -6985,7 +8147,7 @@ EOF
        cygwin* | mingw* | cegcc*)
          if test -n "$export_symbols" && test -z "$export_symbols_regex"; then
            # exporting using user supplied symfile
-           if test "x`$SED 1q $export_symbols`" != xEXPORTS; then
+           if test "x`$SED "$sed_uncomment_deffile" $export_symbols | $SED 1q`" != xEXPORTS; then
              # and it's NOT already a .def file. Must figure out
              # which of the given symbols are data symbols and tag
              # them as such. So, trigger use of export_symbols_cmds.
@@ -7008,13 +8170,45 @@ EOF
            $opt_dry_run || $RM $export_symbols
            cmds=$export_symbols_cmds
            save_ifs="$IFS"; IFS='~'
-           for cmd in $cmds; do
+           for cmd1 in $cmds; do
              IFS="$save_ifs"
-             eval cmd=\"$cmd\"
-             func_len " $cmd"
-             len=$func_len_result
-             if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
+             # Take the normal branch if the nm_file_list_spec branch
+             # doesn't work or if tool conversion is not needed.
+             case $nm_file_list_spec~$to_tool_file_cmd in
+               *~func_convert_file_noop | *~func_convert_file_msys_to_w32 | ~*)
+                 try_normal_branch=yes
+                 eval cmd=\"$cmd1\"
+                 func_len " $cmd"
+                 len=$func_len_result
+                 ;;
+               *)
+                 try_normal_branch=no
+                 ;;
+             esac
+             if test "$try_normal_branch" = yes \
+                && { test "$len" -lt "$max_cmd_len" \
+                     || test "$max_cmd_len" -le -1; }
+             then
+               func_show_eval "$cmd" 'exit $?'
+               skipped_export=false
+             elif test -n "$nm_file_list_spec"; then
+               func_basename "$output"
+               output_la=$func_basename_result
+               save_libobjs=$libobjs
+               save_output=$output
+               output=${output_objdir}/${output_la}.nm
+               func_to_tool_file "$output"
+               libobjs=$nm_file_list_spec$func_to_tool_file_result
+               func_append delfiles " $output"
+               func_verbose "creating $NM input file list: $output"
+               for obj in $save_libobjs; do
+                 func_to_tool_file "$obj"
+                 $ECHO "$func_to_tool_file_result"
+               done > "$output"
+               eval cmd=\"$cmd1\"
                func_show_eval "$cmd" 'exit $?'
+               output=$save_output
+               libobjs=$save_libobjs
                skipped_export=false
              else
                # The command line is too long to execute in one step.
@@ -7036,7 +8230,7 @@ EOF
        if test -n "$export_symbols" && test -n "$include_expsyms"; then
          tmp_export_symbols="$export_symbols"
          test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
-         $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
+         $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
        fi
 
        if test "X$skipped_export" != "X:" && test -n "$orig_export_symbols"; then
@@ -7048,7 +8242,7 @@ EOF
          # global variables. join(1) would be nice here, but unfortunately
          # isn't a blessed tool.
          $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
-         delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
+         func_append delfiles " $export_symbols $output_objdir/$libname.filter"
          export_symbols=$output_objdir/$libname.def
          $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
        fi
@@ -7058,7 +8252,7 @@ EOF
          case " $convenience " in
          *" $test_deplib "*) ;;
          *)
-           tmp_deplibs="$tmp_deplibs $test_deplib"
+           func_append tmp_deplibs " $test_deplib"
            ;;
          esac
        done
@@ -7078,21 +8272,21 @@ EOF
            test "X$libobjs" = "X " && libobjs=
          else
            gentop="$output_objdir/${outputname}x"
-           generated="$generated $gentop"
+           func_append generated " $gentop"
 
            func_extract_archives $gentop $convenience
-           libobjs="$libobjs $func_extract_archives_result"
+           func_append libobjs " $func_extract_archives_result"
            test "X$libobjs" = "X " && libobjs=
          fi
        fi
 
        if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
          eval flag=\"$thread_safe_flag_spec\"
-         linker_flags="$linker_flags $flag"
+         func_append linker_flags " $flag"
        fi
 
        # Make a backup of the uninstalled library when relinking
-       if test "$mode" = relink; then
+       if test "$opt_mode" = relink; then
          $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}U && $MV $realname ${realname}U)' || exit $?
        fi
 
@@ -7137,7 +8331,8 @@ EOF
            save_libobjs=$libobjs
          fi
          save_output=$output
-         output_la=`$ECHO "X$output" | $Xsed -e "$basename"`
+         func_basename "$output"
+         output_la=$func_basename_result
 
          # Clear the reloadable object creation command queue and
          # initialize k to one.
@@ -7150,13 +8345,16 @@ EOF
          if test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "$with_gnu_ld" = yes; then
            output=${output_objdir}/${output_la}.lnkscript
            func_verbose "creating GNU ld script: $output"
-           $ECHO 'INPUT (' > $output
+           echo 'INPUT (' > $output
            for obj in $save_libobjs
            do
-             $ECHO "$obj" >> $output
+             func_to_tool_file "$obj"
+             $ECHO "$func_to_tool_file_result" >> $output
            done
-           $ECHO ')' >> $output
-           delfiles="$delfiles $output"
+           echo ')' >> $output
+           func_append delfiles " $output"
+           func_to_tool_file "$output"
+           output=$func_to_tool_file_result
          elif test -n "$save_libobjs" && test "X$skipped_export" != "X:" && test "X$file_list_spec" != X; then
            output=${output_objdir}/${output_la}.lnk
            func_verbose "creating linker input file list: $output"
@@ -7170,10 +8368,12 @@ EOF
            fi
            for obj
            do
-             $ECHO "$obj" >> $output
+             func_to_tool_file "$obj"
+             $ECHO "$func_to_tool_file_result" >> $output
            done
-           delfiles="$delfiles $output"
-           output=$firstobj\"$file_list_spec$output\"
+           func_append delfiles " $output"
+           func_to_tool_file "$output"
+           output=$firstobj\"$file_list_spec$func_to_tool_file_result\"
          else
            if test -n "$save_libobjs"; then
              func_verbose "creating reloadable object files..."
@@ -7197,17 +8397,19 @@ EOF
                  # command to the queue.
                  if test "$k" -eq 1 ; then
                    # The first file doesn't have a previous command to add.
-                   eval concat_cmds=\"$reload_cmds $objlist $last_robj\"
+                   reload_objs=$objlist
+                   eval concat_cmds=\"$reload_cmds\"
                  else
                    # All subsequent reloadable object files will link in
                    # the last one created.
-                   eval concat_cmds=\"\$concat_cmds~$reload_cmds $objlist $last_robj~\$RM $last_robj\"
+                   reload_objs="$objlist $last_robj"
+                   eval concat_cmds=\"\$concat_cmds~$reload_cmds~\$RM $last_robj\"
                  fi
                  last_robj=$output_objdir/$output_la-${k}.$objext
                  func_arith $k + 1
                  k=$func_arith_result
                  output=$output_objdir/$output_la-${k}.$objext
-                 objlist=$obj
+                 objlist=" $obj"
                  func_len " $last_robj"
                  func_arith $len0 + $func_len_result
                  len=$func_arith_result
@@ -7217,11 +8419,12 @@ EOF
              # reloadable object file.  All subsequent reloadable object
              # files will link in the last one created.
              test -z "$concat_cmds" || concat_cmds=$concat_cmds~
-             eval concat_cmds=\"\${concat_cmds}$reload_cmds $objlist $last_robj\"
+             reload_objs="$objlist $last_robj"
+             eval concat_cmds=\"\${concat_cmds}$reload_cmds\"
              if test -n "$last_robj"; then
                eval concat_cmds=\"\${concat_cmds}~\$RM $last_robj\"
              fi
-             delfiles="$delfiles $output"
+             func_append delfiles " $output"
 
            else
              output=
@@ -7255,7 +8458,7 @@ EOF
                lt_exit=$?
 
                # Restore the uninstalled library and exit
-               if test "$mode" = relink; then
+               if test "$opt_mode" = relink; then
                  ( cd "$output_objdir" && \
                    $RM "${realname}T" && \
                    $MV "${realname}U" "$realname" )
@@ -7276,7 +8479,7 @@ EOF
            if test -n "$export_symbols" && test -n "$include_expsyms"; then
              tmp_export_symbols="$export_symbols"
              test -n "$orig_export_symbols" && tmp_export_symbols="$orig_export_symbols"
-             $opt_dry_run || eval '$ECHO "X$include_expsyms" | $Xsed | $SP2NL >> "$tmp_export_symbols"'
+             $opt_dry_run || eval '$ECHO "$include_expsyms" | $SP2NL >> "$tmp_export_symbols"'
            fi
 
            if test -n "$orig_export_symbols"; then
@@ -7288,7 +8491,7 @@ EOF
              # global variables. join(1) would be nice here, but unfortunately
              # isn't a blessed tool.
              $opt_dry_run || $SED -e '/[ ,]DATA/!d;s,\(.*\)\([ \,].*\),s|^\1$|\1\2|,' < $export_symbols > $output_objdir/$libname.filter
-             delfiles="$delfiles $export_symbols $output_objdir/$libname.filter"
+             func_append delfiles " $export_symbols $output_objdir/$libname.filter"
              export_symbols=$output_objdir/$libname.def
              $opt_dry_run || $SED -f $output_objdir/$libname.filter < $orig_export_symbols > $export_symbols
            fi
@@ -7329,10 +8532,10 @@ EOF
        # Add any objects from preloaded convenience libraries
        if test -n "$dlprefiles"; then
          gentop="$output_objdir/${outputname}x"
-         generated="$generated $gentop"
+         func_append generated " $gentop"
 
          func_extract_archives $gentop $dlprefiles
-         libobjs="$libobjs $func_extract_archives_result"
+         func_append libobjs " $func_extract_archives_result"
          test "X$libobjs" = "X " && libobjs=
        fi
 
@@ -7348,7 +8551,7 @@ EOF
            lt_exit=$?
 
            # Restore the uninstalled library and exit
-           if test "$mode" = relink; then
+           if test "$opt_mode" = relink; then
              ( cd "$output_objdir" && \
                $RM "${realname}T" && \
                $MV "${realname}U" "$realname" )
@@ -7360,7 +8563,7 @@ EOF
        IFS="$save_ifs"
 
        # Restore the uninstalled library and exit
-       if test "$mode" = relink; then
+       if test "$opt_mode" = relink; then
          $opt_dry_run || eval '(cd $output_objdir && $RM ${realname}T && $MV $realname ${realname}T && $MV ${realname}U $realname)' || exit $?
 
          if test -n "$convenience"; then
@@ -7441,18 +8644,21 @@ EOF
       if test -n "$convenience"; then
        if test -n "$whole_archive_flag_spec"; then
          eval tmp_whole_archive_flags=\"$whole_archive_flag_spec\"
-         reload_conv_objs=$reload_objs\ `$ECHO "X$tmp_whole_archive_flags" | $Xsed -e 's|,| |g'`
+         reload_conv_objs=$reload_objs\ `$ECHO "$tmp_whole_archive_flags" | $SED 's|,| |g'`
        else
          gentop="$output_objdir/${obj}x"
-         generated="$generated $gentop"
+         func_append generated " $gentop"
 
          func_extract_archives $gentop $convenience
          reload_conv_objs="$reload_objs $func_extract_archives_result"
        fi
       fi
 
+      # If we're not building shared, we need to use non_pic_objs
+      test "$build_libtool_libs" != yes && libobjs="$non_pic_objects"
+
       # Create the old-style object.
-      reload_objs="$objs$old_deplibs "`$ECHO "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
+      reload_objs="$objs$old_deplibs "`$ECHO "$libobjs" | $SP2NL | $SED "/\.${libext}$/d; /\.lib$/d; $lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test
 
       output="$obj"
       func_execute_cmds "$reload_cmds" 'exit $?'
@@ -7512,8 +8718,8 @@ EOF
       case $host in
       *-*-rhapsody* | *-*-darwin1.[012])
        # On Rhapsody replace the C library is the System framework
-       compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
-       finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's/ -lc / System.ltframework /'`
+       compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's/ -lc / System.ltframework /'`
+       finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's/ -lc / System.ltframework /'`
        ;;
       esac
 
@@ -7524,14 +8730,14 @@ EOF
        if test "$tagname" = CXX ; then
          case ${MACOSX_DEPLOYMENT_TARGET-10.0} in
            10.[0123])
-             compile_command="$compile_command ${wl}-bind_at_load"
-             finalize_command="$finalize_command ${wl}-bind_at_load"
+             func_append compile_command " ${wl}-bind_at_load"
+             func_append finalize_command " ${wl}-bind_at_load"
            ;;
          esac
        fi
        # Time to change all our "foo.ltframework" stuff back to "-framework foo"
-       compile_deplibs=`$ECHO "X $compile_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
-       finalize_deplibs=`$ECHO "X $finalize_deplibs" | $Xsed -e 's% \([^ $]*\).ltframework% -framework \1%g'`
+       compile_deplibs=`$ECHO " $compile_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
+       finalize_deplibs=`$ECHO " $finalize_deplibs" | $SED 's% \([^ $]*\).ltframework% -framework \1%g'`
        ;;
       esac
 
@@ -7545,7 +8751,7 @@ EOF
        *)
          case " $compile_deplibs " in
          *" -L$path/$objdir "*)
-           new_libs="$new_libs -L$path/$objdir" ;;
+           func_append new_libs " -L$path/$objdir" ;;
          esac
          ;;
        esac
@@ -7555,17 +8761,17 @@ EOF
        -L*)
          case " $new_libs " in
          *" $deplib "*) ;;
-         *) new_libs="$new_libs $deplib" ;;
+         *) func_append new_libs " $deplib" ;;
          esac
          ;;
-       *) new_libs="$new_libs $deplib" ;;
+       *) func_append new_libs " $deplib" ;;
        esac
       done
       compile_deplibs="$new_libs"
 
 
-      compile_command="$compile_command $compile_deplibs"
-      finalize_command="$finalize_command $finalize_deplibs"
+      func_append compile_command " $compile_deplibs"
+      func_append finalize_command " $finalize_deplibs"
 
       if test -n "$rpath$xrpath"; then
        # If the user specified any rpath flags, then add them.
@@ -7573,7 +8779,7 @@ EOF
          # This is the magic to use -rpath.
          case "$finalize_rpath " in
          *" $libdir "*) ;;
-         *) finalize_rpath="$finalize_rpath $libdir" ;;
+         *) func_append finalize_rpath " $libdir" ;;
          esac
        done
       fi
@@ -7592,18 +8798,18 @@ EOF
              *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
                ;;
              *)
-               hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+               func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
                ;;
              esac
            fi
          else
            eval flag=\"$hardcode_libdir_flag_spec\"
-           rpath="$rpath $flag"
+           func_append rpath " $flag"
          fi
        elif test -n "$runpath_var"; then
          case "$perm_rpath " in
          *" $libdir "*) ;;
-         *) perm_rpath="$perm_rpath $libdir" ;;
+         *) func_append perm_rpath " $libdir" ;;
          esac
        fi
        case $host in
@@ -7612,12 +8818,12 @@ EOF
          case :$dllsearchpath: in
          *":$libdir:"*) ;;
          ::) dllsearchpath=$libdir;;
-         *) dllsearchpath="$dllsearchpath:$libdir";;
+         *) func_append dllsearchpath ":$libdir";;
          esac
          case :$dllsearchpath: in
          *":$testbindir:"*) ;;
          ::) dllsearchpath=$testbindir;;
-         *) dllsearchpath="$dllsearchpath:$testbindir";;
+         *) func_append dllsearchpath ":$testbindir";;
          esac
          ;;
        esac
@@ -7643,18 +8849,18 @@ EOF
              *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
                ;;
              *)
-               hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+               func_append hardcode_libdirs "$hardcode_libdir_separator$libdir"
                ;;
              esac
            fi
          else
            eval flag=\"$hardcode_libdir_flag_spec\"
-           rpath="$rpath $flag"
+           func_append rpath " $flag"
          fi
        elif test -n "$runpath_var"; then
          case "$finalize_perm_rpath " in
          *" $libdir "*) ;;
-         *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+         *) func_append finalize_perm_rpath " $libdir" ;;
          esac
        fi
       done
@@ -7668,8 +8874,8 @@ EOF
 
       if test -n "$libobjs" && test "$build_old_libs" = yes; then
        # Transform all the library objects into standard objects.
-       compile_command=`$ECHO "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
-       finalize_command=`$ECHO "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+       compile_command=`$ECHO "$compile_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
+       finalize_command=`$ECHO "$finalize_command" | $SP2NL | $SED "$lo2o" | $NL2SP`
       fi
 
       func_generate_dlsyms "$outputname" "@PROGRAM@" "no"
@@ -7681,8 +8887,8 @@ EOF
 
       wrappers_required=yes
       case $host in
-      *cegcc | *mingw32ce* )
-        # Disable wrappers for cegcc, we are cross compiling anyway.
+      *cegcc* | *mingw32ce*)
+        # Disable wrappers for cegcc and mingw32ce hosts, we are cross compiling anyway.
         wrappers_required=no
         ;;
       *cygwin* | *mingw* )
@@ -7698,13 +8904,19 @@ EOF
       esac
       if test "$wrappers_required" = no; then
        # Replace the output file specification.
-       compile_command=`$ECHO "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+       compile_command=`$ECHO "$compile_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
        link_command="$compile_command$compile_rpath"
 
        # We have no uninstalled library dependencies, so finalize right now.
        exit_status=0
        func_show_eval "$link_command" 'exit_status=$?'
 
+       if test -n "$postlink_cmds"; then
+         func_to_tool_file "$output"
+         postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+         func_execute_cmds "$postlink_cmds" 'exit $?'
+       fi
+
        # Delete the generated files.
        if test -f "$output_objdir/${outputname}S.${objext}"; then
          func_show_eval '$RM "$output_objdir/${outputname}S.${objext}"'
@@ -7727,7 +8939,7 @@ EOF
          # We should set the runpath_var.
          rpath=
          for dir in $perm_rpath; do
-           rpath="$rpath$dir:"
+           func_append rpath "$dir:"
          done
          compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
        fi
@@ -7735,7 +8947,7 @@ EOF
          # We should set the runpath_var.
          rpath=
          for dir in $finalize_perm_rpath; do
-           rpath="$rpath$dir:"
+           func_append rpath "$dir:"
          done
          finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
        fi
@@ -7745,11 +8957,18 @@ EOF
        # We don't need to create a wrapper script.
        link_command="$compile_var$compile_command$compile_rpath"
        # Replace the output file specification.
-       link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+       link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output"'%g'`
        # Delete the old output file.
        $opt_dry_run || $RM $output
        # Link the executable and exit
        func_show_eval "$link_command" 'exit $?'
+
+       if test -n "$postlink_cmds"; then
+         func_to_tool_file "$output"
+         postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+         func_execute_cmds "$postlink_cmds" 'exit $?'
+       fi
+
        exit $EXIT_SUCCESS
       fi
 
@@ -7764,7 +8983,7 @@ EOF
        if test "$fast_install" != no; then
          link_command="$finalize_var$compile_command$finalize_rpath"
          if test "$fast_install" = yes; then
-           relink_command=`$ECHO "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+           relink_command=`$ECHO "$compile_var$compile_command$compile_rpath" | $SED 's%@OUTPUT@%\$progdir/\$file%g'`
          else
            # fast_install is set to needless
            relink_command=
@@ -7776,13 +8995,19 @@ EOF
       fi
 
       # Replace the output file specification.
-      link_command=`$ECHO "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+      link_command=`$ECHO "$link_command" | $SED 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
 
       # Delete the old output files.
       $opt_dry_run || $RM $output $output_objdir/$outputname $output_objdir/lt-$outputname
 
       func_show_eval "$link_command" 'exit $?'
 
+      if test -n "$postlink_cmds"; then
+       func_to_tool_file "$output_objdir/$outputname"
+       postlink_cmds=`func_echo_all "$postlink_cmds" | $SED -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g' -e 's%@TOOL_OUTPUT@%'"$func_to_tool_file_result"'%g'`
+       func_execute_cmds "$postlink_cmds" 'exit $?'
+      fi
+
       # Now create the wrapper script.
       func_verbose "creating $output"
 
@@ -7800,18 +9025,7 @@ EOF
          fi
        done
        relink_command="(cd `pwd`; $relink_command)"
-       relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
-      fi
-
-      # Quote $ECHO for shipping.
-      if test "X$ECHO" = "X$SHELL $progpath --fallback-echo"; then
-       case $progpath in
-       [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $progpath --fallback-echo";;
-       *) qecho="$SHELL `pwd`/$progpath --fallback-echo";;
-       esac
-       qecho=`$ECHO "X$qecho" | $Xsed -e "$sed_quote_subst"`
-      else
-       qecho=`$ECHO "X$ECHO" | $Xsed -e "$sed_quote_subst"`
+       relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
       fi
 
       # Only actually do things if not in dry run mode.
@@ -7891,7 +9105,7 @@ EOF
        else
          oldobjs="$old_deplibs $non_pic_objects"
          if test "$preload" = yes && test -f "$symfileobj"; then
-           oldobjs="$oldobjs $symfileobj"
+           func_append oldobjs " $symfileobj"
          fi
        fi
        addlibs="$old_convenience"
@@ -7899,10 +9113,10 @@ EOF
 
       if test -n "$addlibs"; then
        gentop="$output_objdir/${outputname}x"
-       generated="$generated $gentop"
+       func_append generated " $gentop"
 
        func_extract_archives $gentop $addlibs
-       oldobjs="$oldobjs $func_extract_archives_result"
+       func_append oldobjs " $func_extract_archives_result"
       fi
 
       # Do each command in the archive commands.
@@ -7913,10 +9127,10 @@ EOF
        # Add any objects from preloaded convenience libraries
        if test -n "$dlprefiles"; then
          gentop="$output_objdir/${outputname}x"
-         generated="$generated $gentop"
+         func_append generated " $gentop"
 
          func_extract_archives $gentop $dlprefiles
-         oldobjs="$oldobjs $func_extract_archives_result"
+         func_append oldobjs " $func_extract_archives_result"
        fi
 
        # POSIX demands no paths to be encoded in archives.  We have
@@ -7932,9 +9146,9 @@ EOF
            done | sort | sort -uc >/dev/null 2>&1); then
          :
        else
-         $ECHO "copying selected object files to avoid basename conflicts..."
+         echo "copying selected object files to avoid basename conflicts..."
          gentop="$output_objdir/${outputname}x"
-         generated="$generated $gentop"
+         func_append generated " $gentop"
          func_mkdir_p "$gentop"
          save_oldobjs=$oldobjs
          oldobjs=
@@ -7958,18 +9172,30 @@ EOF
                esac
              done
              func_show_eval "ln $obj $gentop/$newobj || cp $obj $gentop/$newobj"
-             oldobjs="$oldobjs $gentop/$newobj"
+             func_append oldobjs " $gentop/$newobj"
              ;;
-           *) oldobjs="$oldobjs $obj" ;;
+           *) func_append oldobjs " $obj" ;;
            esac
          done
        fi
+       func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
+       tool_oldlib=$func_to_tool_file_result
        eval cmds=\"$old_archive_cmds\"
 
        func_len " $cmds"
        len=$func_len_result
        if test "$len" -lt "$max_cmd_len" || test "$max_cmd_len" -le -1; then
          cmds=$old_archive_cmds
+       elif test -n "$archiver_list_spec"; then
+         func_verbose "using command file archive linking..."
+         for obj in $oldobjs
+         do
+           func_to_tool_file "$obj"
+           $ECHO "$func_to_tool_file_result"
+         done > $output_objdir/$libname.libcmd
+         func_to_tool_file "$output_objdir/$libname.libcmd"
+         oldobjs=" $archiver_list_spec$func_to_tool_file_result"
+         cmds=$old_archive_cmds
        else
          # the command line is too long to link in one step, link in parts
          func_verbose "using piecewise archive linking..."
@@ -8043,7 +9269,7 @@ EOF
       done
       # Quote the link command for shipping.
       relink_command="(cd `pwd`; $SHELL $progpath $preserve_args --mode=relink $libtool_args @inst_prefix_dir@)"
-      relink_command=`$ECHO "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+      relink_command=`$ECHO "$relink_command" | $SED "$sed_quote_subst"`
       if test "$hardcode_automatic" = yes ; then
        relink_command=
       fi
@@ -8063,12 +9289,23 @@ EOF
              *.la)
                func_basename "$deplib"
                name="$func_basename_result"
-               eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $deplib`
+               func_resolve_sysroot "$deplib"
+               eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $func_resolve_sysroot_result`
                test -z "$libdir" && \
                  func_fatal_error "\`$deplib' is not a valid libtool archive"
-               newdependency_libs="$newdependency_libs $libdir/$name"
+               func_append newdependency_libs " ${lt_sysroot:+=}$libdir/$name"
+               ;;
+             -L*)
+               func_stripname -L '' "$deplib"
+               func_replace_sysroot "$func_stripname_result"
+               func_append newdependency_libs " -L$func_replace_sysroot_result"
+               ;;
+             -R*)
+               func_stripname -R '' "$deplib"
+               func_replace_sysroot "$func_stripname_result"
+               func_append newdependency_libs " -R$func_replace_sysroot_result"
                ;;
-             *) newdependency_libs="$newdependency_libs $deplib" ;;
+             *) func_append newdependency_libs " $deplib" ;;
              esac
            done
            dependency_libs="$newdependency_libs"
@@ -8082,9 +9319,9 @@ EOF
                eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
                test -z "$libdir" && \
                  func_fatal_error "\`$lib' is not a valid libtool archive"
-               newdlfiles="$newdlfiles $libdir/$name"
+               func_append newdlfiles " ${lt_sysroot:+=}$libdir/$name"
                ;;
-             *) newdlfiles="$newdlfiles $lib" ;;
+             *) func_append newdlfiles " $lib" ;;
              esac
            done
            dlfiles="$newdlfiles"
@@ -8101,7 +9338,7 @@ EOF
                eval libdir=`${SED} -n -e 's/^libdir=\(.*\)$/\1/p' $lib`
                test -z "$libdir" && \
                  func_fatal_error "\`$lib' is not a valid libtool archive"
-               newdlprefiles="$newdlprefiles $libdir/$name"
+               func_append newdlprefiles " ${lt_sysroot:+=}$libdir/$name"
                ;;
              esac
            done
@@ -8113,7 +9350,7 @@ EOF
                [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
                *) abs=`pwd`"/$lib" ;;
              esac
-             newdlfiles="$newdlfiles $abs"
+             func_append newdlfiles " $abs"
            done
            dlfiles="$newdlfiles"
            newdlprefiles=
@@ -8122,15 +9359,33 @@ EOF
                [\\/]* | [A-Za-z]:[\\/]*) abs="$lib" ;;
                *) abs=`pwd`"/$lib" ;;
              esac
-             newdlprefiles="$newdlprefiles $abs"
+             func_append newdlprefiles " $abs"
            done
            dlprefiles="$newdlprefiles"
          fi
          $RM $output
          # place dlname in correct position for cygwin
+         # In fact, it would be nice if we could use this code for all target
+         # systems that can't hard-code library paths into their executables
+         # and that have no shared library path variable independent of PATH,
+         # but it turns out we can't easily determine that from inspecting
+         # libtool variables, so we have to hard-code the OSs to which it
+         # applies here; at the moment, that means platforms that use the PE
+         # object format with DLL files.  See the long comment at the top of
+         # tests/bindir.at for full details.
          tdlname=$dlname
          case $host,$output,$installed,$module,$dlname in
-           *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;;
+           *cygwin*,*lai,yes,no,*.dll | *mingw*,*lai,yes,no,*.dll | *cegcc*,*lai,yes,no,*.dll)
+             # If a -bindir argument was supplied, place the dll there.
+             if test "x$bindir" != x ;
+             then
+               func_relative_path "$install_libdir" "$bindir"
+               tdlname=$func_relative_path_result$dlname
+             else
+               # Otherwise fall back on heuristic.
+               tdlname=../bin/$dlname
+             fi
+             ;;
          esac
          $ECHO > $output "\
 # $outputname - a libtool library file
@@ -8189,7 +9444,7 @@ relink_command=\"$relink_command\""
     exit $EXIT_SUCCESS
 }
 
-{ test "$mode" = link || test "$mode" = relink; } &&
+{ test "$opt_mode" = link || test "$opt_mode" = relink; } &&
     func_mode_link ${1+"$@"}
 
 
@@ -8209,9 +9464,9 @@ func_mode_uninstall ()
     for arg
     do
       case $arg in
-      -f) RM="$RM $arg"; rmforce=yes ;;
-      -*) RM="$RM $arg" ;;
-      *) files="$files $arg" ;;
+      -f) func_append RM " $arg"; rmforce=yes ;;
+      -*) func_append RM " $arg" ;;
+      *) func_append files " $arg" ;;
       esac
     done
 
@@ -8220,24 +9475,23 @@ func_mode_uninstall ()
 
     rmdirs=
 
-    origobjdir="$objdir"
     for file in $files; do
       func_dirname "$file" "" "."
       dir="$func_dirname_result"
       if test "X$dir" = X.; then
-       objdir="$origobjdir"
+       odir="$objdir"
       else
-       objdir="$dir/$origobjdir"
+       odir="$dir/$objdir"
       fi
       func_basename "$file"
       name="$func_basename_result"
-      test "$mode" = uninstall && objdir="$dir"
+      test "$opt_mode" = uninstall && odir="$dir"
 
-      # Remember objdir for removal later, being careful to avoid duplicates
-      if test "$mode" = clean; then
+      # Remember odir for removal later, being careful to avoid duplicates
+      if test "$opt_mode" = clean; then
        case " $rmdirs " in
-         *" $objdir "*) ;;
-         *) rmdirs="$rmdirs $objdir" ;;
+         *" $odir "*) ;;
+         *) func_append rmdirs " $odir" ;;
        esac
       fi
 
@@ -8263,18 +9517,17 @@ func_mode_uninstall ()
 
          # Delete the libtool libraries and symlinks.
          for n in $library_names; do
-           rmfiles="$rmfiles $objdir/$n"
+           func_append rmfiles " $odir/$n"
          done
-         test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library"
+         test -n "$old_library" && func_append rmfiles " $odir/$old_library"
 
-         case "$mode" in
+         case "$opt_mode" in
          clean)
-           case "  $library_names " in
-           # "  " in the beginning catches empty $dlname
+           case " $library_names " in
            *" $dlname "*) ;;
-           *) rmfiles="$rmfiles $objdir/$dlname" ;;
+           *) test -n "$dlname" && func_append rmfiles " $odir/$dlname" ;;
            esac
-           test -n "$libdir" && rmfiles="$rmfiles $objdir/$name $objdir/${name}i"
+           test -n "$libdir" && func_append rmfiles " $odir/$name $odir/${name}i"
            ;;
          uninstall)
            if test -n "$library_names"; then
@@ -8302,19 +9555,19 @@ func_mode_uninstall ()
          # Add PIC object to the list of files to remove.
          if test -n "$pic_object" &&
             test "$pic_object" != none; then
-           rmfiles="$rmfiles $dir/$pic_object"
+           func_append rmfiles " $dir/$pic_object"
          fi
 
          # Add non-PIC object to the list of files to remove.
          if test -n "$non_pic_object" &&
             test "$non_pic_object" != none; then
-           rmfiles="$rmfiles $dir/$non_pic_object"
+           func_append rmfiles " $dir/$non_pic_object"
          fi
        fi
        ;;
 
       *)
-       if test "$mode" = clean ; then
+       if test "$opt_mode" = clean ; then
          noexename=$name
          case $file in
          *.exe)
@@ -8324,7 +9577,7 @@ func_mode_uninstall ()
            noexename=$func_stripname_result
            # $file with .exe has already been added to rmfiles,
            # add $file without .exe
-           rmfiles="$rmfiles $file"
+           func_append rmfiles " $file"
            ;;
          esac
          # Do a test to see if this is a libtool program.
@@ -8333,7 +9586,7 @@ func_mode_uninstall ()
              func_ltwrapper_scriptname "$file"
              relink_command=
              func_source $func_ltwrapper_scriptname_result
-             rmfiles="$rmfiles $func_ltwrapper_scriptname_result"
+             func_append rmfiles " $func_ltwrapper_scriptname_result"
            else
              relink_command=
              func_source $dir/$noexename
@@ -8341,12 +9594,12 @@ func_mode_uninstall ()
 
            # note $name still contains .exe if it was in $file originally
            # as does the version of $file that was added into $rmfiles
-           rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}"
+           func_append rmfiles " $odir/$name $odir/${name}S.${objext}"
            if test "$fast_install" = yes && test -n "$relink_command"; then
-             rmfiles="$rmfiles $objdir/lt-$name"
+             func_append rmfiles " $odir/lt-$name"
            fi
            if test "X$noexename" != "X$name" ; then
-             rmfiles="$rmfiles $objdir/lt-${noexename}.c"
+             func_append rmfiles " $odir/lt-${noexename}.c"
            fi
          fi
        fi
@@ -8354,7 +9607,6 @@ func_mode_uninstall ()
       esac
       func_show_eval "$RM $rmfiles" 'exit_status=1'
     done
-    objdir="$origobjdir"
 
     # Try to remove the ${objdir}s in the directories where we deleted files
     for dir in $rmdirs; do
@@ -8366,16 +9618,16 @@ func_mode_uninstall ()
     exit $exit_status
 }
 
-{ test "$mode" = uninstall || test "$mode" = clean; } &&
+{ test "$opt_mode" = uninstall || test "$opt_mode" = clean; } &&
     func_mode_uninstall ${1+"$@"}
 
-test -z "$mode" && {
+test -z "$opt_mode" && {
   help="$generic_help"
   func_fatal_help "you must specify a MODE"
 }
 
 test -z "$exec_cmd" && \
-  func_fatal_help "invalid operation mode \`$mode'"
+  func_fatal_help "invalid operation mode \`$opt_mode'"
 
 if test -n "$exec_cmd"; then
   eval exec "$exec_cmd"
@@ -8410,4 +9662,3 @@ build_old_libs=`case $build_libtool_libs in yes) echo no;; *) echo yes;; esac`
 # sh-indentation:2
 # End:
 # vi:sw=2
-
similarity index 100%
rename from doc/mdate-sh
rename to build-aux/mdate-sh
similarity index 100%
rename from missing
rename to build-aux/missing
similarity index 99%
rename from doc/texinfo.tex
rename to build-aux/texinfo.tex
index 8083622..8f99418 100644 (file)
                % We don't want .vr (or whatever) entries like this:
                % \entry{{\tt \indexbackslash }acronym}{32}{\code {\acronym}}
                % "\acronym" won't work when it's read back in;
-               % it needs to be 
+               % it needs to be
                % {\code {{\tt \backslashcurfont }acronym}
     \shipout\vbox{%
       % Do this early so pdf references go to the beginning of the page.
 \def\?{?\spacefactor=\endofsentencespacefactor\space}
 
 % @frenchspacing on|off  says whether to put extra space after punctuation.
-% 
+%
 \def\onword{on}
 \def\offword{off}
 %
@@ -1216,7 +1216,7 @@ where each line of input produces a line of output.}
 % that's what we do).
 
 % double active backslashes.
-% 
+%
 {\catcode`\@=0 \catcode`\\=\active
  @gdef@activebackslashdouble{%
    @catcode`@\=@active
@@ -1227,11 +1227,11 @@ where each line of input produces a line of output.}
 % 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.
-% 
+%
 % #1 is the tokens to replace.
 % #2 is the replacement.
 % #3 is the control sequence with the string.
-% 
+%
 \def\HyPsdSubst#1#2#3{%
   \def\HyPsdReplace##1#1##2\END{%
     ##1%
@@ -1420,7 +1420,7 @@ where each line of input produces a line of output.}
       % tried to figure out what each command should do in the context
       % of @url.  for now, just make @/ a no-op, that's the only one
       % people have actually reported a problem with.
-      % 
+      %
       \normalturnoffactive
       \def\@{@}%
       \let\/=\empty
@@ -1547,7 +1547,7 @@ 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{
 % Text fonts (11.2pt, magstep1).
 \def\textnominalsize{11pt}
@@ -1672,7 +1672,7 @@ where each line of input produces a line of output.}
 % section, chapter, etc., sizes following suit.  This is for the GNU
 % Press printing of the Emacs 22 manual.  Maybe other manuals in the
 % future.  Used with @smallbook, which sets the leading to 12pt.
-% 
+%
 \def\definetextfontsizex{%
 % Text fonts (10pt).
 \def\textnominalsize{10pt}
@@ -1758,7 +1758,7 @@ where each line of input produces a line of output.}
 \setfont\secsf\sfbshape{12}{1000}
 \let\secbf\secrm
 \setfont\secsc\scbshape{10}{\magstep1}
-\font\seci=cmmi12 
+\font\seci=cmmi12
 \font\secsy=cmsy10 scaled \magstep1
 
 % Subsection fonts (10pt).
@@ -1799,7 +1799,7 @@ where each line of input produces a line of output.}
 % We provide the user-level command
 %   @fonttextsize 10
 % (or 11) to redefine the text font size.  pt is assumed.
-% 
+%
 \def\xword{10}
 \def\xiword{11}
 %
@@ -1809,7 +1809,7 @@ where each line of input produces a line of output.}
   %
   % Set \globaldefs so that documents can use this inside @tex, since
   % makeinfo 4.8 does not support it, but we need it nonetheless.
-  % 
+  %
  \begingroup \globaldefs=1
   \ifx\textsizearg\xword \definetextfontsizex
   \else \ifx\textsizearg\xiword \definetextfontsizexi
@@ -2094,7 +2094,7 @@ where each line of input produces a line of output.}
 % each of the four underscores in __typeof__.  This is undesirable in
 % some manuals, especially if they don't have long identifiers in
 % general.  @allowcodebreaks provides a way to control this.
-% 
+%
 \newif\ifallowcodebreaks  \allowcodebreakstrue
 
 \def\keywordtrue{true}
@@ -2225,7 +2225,7 @@ where each line of input produces a line of output.}
 % @acronym for "FBI", "NATO", and the like.
 % We print this one point size smaller, since it's intended for
 % all-uppercase.
-% 
+%
 \def\acronym#1{\doacronym #1,,\finish}
 \def\doacronym#1,#2,#3\finish{%
   {\selectfonts\lsize #1}%
@@ -2237,7 +2237,7 @@ where each line of input produces a line of output.}
 
 % @abbr for "Comput. J." and the like.
 % No font change, but don't do end-of-sentence spacing.
-% 
+%
 \def\abbr#1{\doabbr #1,,\finish}
 \def\doabbr#1,#2,#3\finish{%
   {\plainfrenchspacing #1}%
@@ -2256,43 +2256,43 @@ where each line of input produces a line of output.}
 % Theiling, which support regular, slanted, bold and bold slanted (and
 % "outlined" (blackboard board, sort of) versions, which we don't need).
 % It is available from http://www.ctan.org/tex-archive/fonts/eurosym.
-% 
+%
 % Although only regular is the truly official Euro symbol, we ignore
 % that.  The Euro is designed to be slightly taller than the regular
 % font height.
-% 
+%
 % feymr - regular
 % feymo - slanted
 % feybr - bold
 % feybo - bold slanted
-% 
+%
 % There is no good (free) typewriter version, to my knowledge.
 % A feymr10 euro is ~7.3pt wide, while a normal cmtt10 char is ~5.25pt wide.
 % Hmm.
-% 
+%
 % Also doesn't work in math.  Do we need to do math with euro symbols?
 % Hope not.
-% 
-% 
+%
+%
 \def\euro{{\eurofont e}}
 \def\eurofont{%
   % We set the font at each command, rather than predefining it in
   % \textfonts and the other font-switching commands, so that
   % installations which never need the symbol don't have to have the
   % font installed.
-  % 
+  %
   % There is only one designed size (nominal 10pt), so we always scale
   % that to the current nominal size.
-  % 
+  %
   % By the way, simply using "at 1em" works for cmr10 and the like, but
   % does not work for cmbx10 and other extended/shrunken fonts.
-  % 
+  %
   \def\eurosize{\csname\curfontsize nominalsize\endcsname}%
   %
-  \ifx\curfontstyle\bfstylename 
+  \ifx\curfontstyle\bfstylename
     % bold:
     \font\thiseurofont = \ifusingit{feybo10}{feybr10} at \eurosize
-  \else 
+  \else
     % regular:
     \font\thiseurofont = \ifusingit{feymo10}{feymr10} at \eurosize
   \fi
@@ -2316,7 +2316,7 @@ where each line of input produces a line of output.}
 % Laurent Siebenmann reports \Orb undefined with:
 %  Textures 1.7.7 (preloaded format=plain 93.10.14)  (68K)  16 APR 2004 02:38
 % so we'll define it if necessary.
-% 
+%
 \ifx\Orb\undefined
 \def\Orb{\mathhexbox20D}
 \fi
@@ -2632,7 +2632,7 @@ where each line of input produces a line of output.}
     % cause the example and the item to crash together.  So we use this
     % bizarre value of 10001 as a signal to \aboveenvbreak to insert
     % \parskip glue after all.  Section titles are handled this way also.
-    % 
+    %
     \penalty 10001
     \endgroup
     \itemxneedsnegativevskipfalse
@@ -3428,7 +3428,7 @@ where each line of input produces a line of output.}
   % processing continues to some further point.  On the other hand, it
   % seems \endinput does not hurt in the printed index arg, since that
   % is still getting written without apparent harm.
-  % 
+  %
   % Sample source (mac-idx3.tex, reported by Graham Percival to
   % help-texinfo, 22may06):
   % @macro funindex {WORD}
@@ -3436,12 +3436,12 @@ where each line of input produces a line of output.}
   % @end macro
   % ...
   % @funindex commtest
-  % 
+  %
   % The above is not enough to reproduce the bug, but it gives the flavor.
-  % 
+  %
   % Sample whatsit resulting:
   % .@write3{\entry{xyz}{@folio }{@code {xyz@endinput }}}
-  % 
+  %
   % So:
   \let\endinput = \empty
   %
@@ -3677,11 +3677,11 @@ where each line of input produces a line of output.}
   % makeinfo does not expand macros in the argument to @deffn, which ends up
   % writing an index entry, and texindex isn't prepared for an index sort entry
   % that starts with \.
-  % 
+  %
   % Since macro invocations are followed by braces, we can just redefine them
   % to take a single TeX argument.  The case of a macro invocation that
   % goes to end-of-line is not handled.
-  % 
+  %
   \macrolist
 }
 
@@ -3807,7 +3807,7 @@ where each line of input produces a line of output.}
     % to re-insert the same penalty (values >10000 are used for various
     % signals); since we just inserted a non-discardable item, any
     % following glue (such as a \parskip) would be a breakpoint.  For example:
-    % 
+    %
     %   @deffn deffn-whatever
     %   @vindex index-whatever
     %   Description.
@@ -4759,11 +4759,11 @@ where each line of input produces a line of output.}
   % glue accumulate.  (Not a breakpoint because it's preceded by a
   % discardable item.)
   \vskip-\parskip
-  % 
+  %
   % This is purely so the last item on the list is a known \penalty >
   % 10000.  This is so \startdefun can avoid allowing breakpoints after
   % section headings.  Otherwise, it would insert a valid breakpoint between:
-  % 
+  %
   %   @section sec-whatever
   %   @deffn def-whatever
   \penalty 10001
@@ -4821,7 +4821,7 @@ where each line of input produces a line of output.}
 % These characters do not print properly in the Computer Modern roman
 % fonts, so we must take special care.  This is more or less redundant
 % with the Texinfo input format setup at the end of this file.
-% 
+%
 \def\activecatcodes{%
   \catcode`\"=\active
   \catcode`\$=\active
@@ -5416,8 +5416,8 @@ where each line of input produces a line of output.}
 % from cmtt (char 0x0d).  The undirected quote is ugly, so don't make it
 % the default, but it works for pasting with more pdf viewers (at least
 % evince), the lilypond developers report.  xpdf does work with the
-% regular 0x27.  
-% 
+% regular 0x27.
+%
 \def\codequoteright{%
   \expandafter\ifx\csname SETcodequoteundirected\endcsname\relax
     '%
@@ -5429,7 +5429,7 @@ where each line of input produces a line of output.}
 % and a similar option for the left quote char vs. a grave accent.
 % Modern fonts display ASCII 0x60 as a grave accent, so some people like
 % the code environments to do likewise.
-% 
+%
 \def\codequoteleft{%
   \expandafter\ifx\csname SETcodequotebacktick\endcsname\relax
     `%
@@ -5572,7 +5572,7 @@ where each line of input produces a line of output.}
     % by \defargscommonending, 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
     %
     % Similarly, after a section heading, do not allow a break.
@@ -5950,7 +5950,7 @@ where each line of input produces a line of output.}
 % This does \let #1 = #2, with \csnames; that is,
 %   \let \csname#1\endcsname = \csname#2\endcsname
 % (except of course we have to play expansion games).
-% 
+%
 \def\cslet#1#2{%
   \expandafter\let
   \csname#1\expandafter\endcsname
@@ -7420,7 +7420,7 @@ should work if nowhere else does.}
 
 % Same as @turnoffactive except outputs \ as {\tt\char`\\} instead of
 % the literal character `\'.
-% 
+%
 @def@normalturnoffactive{%
   @let\=@normalbackslash
   @let"=@normaldoublequote
similarity index 99%
rename from cipher/ChangeLog
rename to cipher/ChangeLog-2011
index 16632f0..1ce6bd1 100644 (file)
@@ -1,3 +1,43 @@
+2011-12-01  Werner Koch  <wk@g10code.com>
+
+       NB: ChangeLog files are no longer manually maintained.  Starting
+       on December 1st, 2011 we put change information only in the GIT
+       commit log, and generate a top-level ChangeLog file from logs at
+       "make dist".  See doc/HACKING for details.
+
+2011-09-16  Werner Koch  <wk@g10code.com>
+
+       * primegen.c (_gcry_primegen_init): New.
+
+2011-09-15  Werner Koch  <wk@g10code.com>
+
+       * cipher-cbc.c, cipher-cfb.c, cipher-ofb.c, cipher-ctr.c: New.
+       * cipher-aeswrap.c: New.
+       * cipher-internal.h: New.
+       * cipher.c (cipher_context_alignment_t, struct gcry_cipher_handle)
+       (CTX_MAGIC_NORMAL, CTX_MAGIC_SECURE, NEED_16BYTE_ALIGNED_CONTEXT)
+       (MAX_BLOCKSIZE): Move to cipher-internal.h.
+       (do_aeswrap_encrypt, do_aeswrap_encrypt)
+       (do_cbc_encrypt, do_cbc_decrypt, do_ctr_encrypt, do_ctr_decrypt)
+       (do_ofb_encrypt, do_ofb_decrypt, do_ctr_encrypt): Move to the
+       respective new cipher-foo.c files.
+       (do_ctr_decrypt): Remove.
+
+2011-09-15  Werner Koch  <wk@g10code.com>
+
+       * pubkey.c (gcry_pk_list): Remove.
+       (gcry_pk_unregister): Remove.
+       * md.c (gcry_md_list): Remove.
+       (gcry_md_unregister): Remove.
+       * cipher.c (gcry_cipher_list): Remove.
+       (gcry_cipher_unregister): Remove.
+       * ac.c: Remove.
+
+2011-06-29  Werner Koch  <wk@g10code.com>
+
+       * cipher.c (cipher_get_keylen): Return zero for an invalid algorithm.
+       (cipher_get_blocksize): Ditto.
+
 2011-06-13  Werner Koch  <wk@g10code.com>
 
        * dsa.c (selftest_sign_1024): Use the raw and not the pkcs1 flag.
 
 2000-12-19  Werner Koch  <wk@gnupg.org>
 
-       Major change:
+       Major change:
        Removed all GnuPG stuff and renamed this piece of software
        to gcrypt.
 
@@ -4233,3 +4273,7 @@ Mon Feb 16 10:08:47 1998  Werner Koch  (wk@isil.d.shuttle.de)
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
index cbeace8..0a62d3c 100644 (file)
@@ -26,49 +26,71 @@ EXTRA_DIST = Manifest
 AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
 AM_CFLAGS = $(GPG_ERROR_CFLAGS)
 
+AM_CCASFLAGS = $(NOEXECSTACK_FLAGS)
+
 
 noinst_LTLIBRARIES = libcipher.la
 
-GCRYPT_MODULES = @GCRYPT_CIPHERS@ @GCRYPT_PUBKEY_CIPHERS@ @GCRYPT_DIGESTS@
+GCRYPT_MODULES = @GCRYPT_CIPHERS@ @GCRYPT_PUBKEY_CIPHERS@ \
+                 @GCRYPT_DIGESTS@ @GCRYPT_KDFS@
 
 libcipher_la_DEPENDENCIES = $(GCRYPT_MODULES)
 libcipher_la_LIBADD = $(GCRYPT_MODULES)
 
 libcipher_la_SOURCES = \
-cipher.c pubkey.c ac.c md.c kdf.c \
+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-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 \
+kdf.c kdf-internal.h \
 hmac-tests.c \
 bithelp.h  \
+bufhelp.h  \
 primegen.c  \
 hash-common.c hash-common.h \
+dsa-common.c rsa-common.c \
 rmd.h
 
 EXTRA_libcipher_la_SOURCES = \
 arcfour.c \
-blowfish.c \
-cast5.c \
+blowfish.c blowfish-amd64.S blowfish-arm.S \
+cast5.c cast5-amd64.S cast5-arm.S \
 crc.c \
 des.c \
 dsa.c \
 elgamal.c \
-ecc.c \
+ecc.c ecc-curves.c ecc-misc.c ecc-common.h \
+ecc-ecdsa.c ecc-eddsa.c ecc-gost.c \
+idea.c \
+gost28147.c gost.h \
+gostr3411-94.c \
 md4.c \
 md5.c \
-rijndael.c rijndael-tables.h \
+rijndael.c rijndael-tables.h rijndael-amd64.S rijndael-arm.S \
 rmd160.c \
 rsa.c \
+salsa20.c salsa20-amd64.S salsa20-armv7-neon.S \
+scrypt.c \
 seed.c \
-serpent.c \
-sha1.c \
-sha256.c \
-sha512.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 \
+sha512.c sha512-ssse3-amd64.S sha512-avx-amd64.S sha512-avx2-bmi2-amd64.S \
+  sha512-armv7-neon.S \
+stribog.c \
 tiger.c \
 whirlpool.c \
-twofish.c \
+twofish.c twofish-amd64.S twofish-arm.S \
 rfc2268.c \
-camellia.c camellia.h camellia-glue.c
+camellia.c camellia.h camellia-glue.c camellia-aesni-avx-amd64.S \
+  camellia-aesni-avx2-amd64.S camellia-arm.S
 
 if ENABLE_O_FLAG_MUNGING
-o_flag_munging = sed -e 's/-O[2-9s]*/-O1/g'
+o_flag_munging = sed -e 's/-O\([2-9s][2-9s]*\)/-O1/' -e 's/-Ofast/-O1/g'
 else
 o_flag_munging = cat
 endif
index d935dbe..e9f20b0 100644 (file)
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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; \
+    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;; \
+    esac; \
+    test $$am__dry = yes; \
+  }
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -56,46 +73,82 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = cipher
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ChangeLog
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.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/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/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
        $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
-       $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+       $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/acinclude.m4 \
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 am__DEPENDENCIES_1 =
-am_libcipher_la_OBJECTS = cipher.lo pubkey.lo ac.lo md.lo kdf.lo \
-       hmac-tests.lo primegen.lo hash-common.lo
+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 \
+       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
 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
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
 am__depfiles_maybe = depfiles
 am__mv = mv -f
+CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)
+LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \
+       $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(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 = @
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
-       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+       $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(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    " $@;
 CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
-       $(LDFLAGS) -o $@
+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   " $@;
 SOURCES = $(libcipher_la_SOURCES) $(EXTRA_libcipher_la_SOURCES)
 DIST_SOURCES = $(libcipher_la_SOURCES) $(EXTRA_libcipher_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AR = @AR@
 AS = @AS@
 AUTOCONF = @AUTOCONF@
@@ -110,6 +163,7 @@ CCAS = @CCAS@
 CCASDEPMODE = @CCASDEPMODE@
 CCASFLAGS = @CCASFLAGS@
 CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
@@ -129,6 +183,8 @@ FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
 FGREP = @FGREP@
 GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
 GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_HWF_MODULES = @GCRYPT_HWF_MODULES@
+GCRYPT_KDFS = @GCRYPT_KDFS@
 GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
 GCRYPT_RANDOM = @GCRYPT_RANDOM@
 GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
@@ -154,14 +210,19 @@ 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@
 MKDIR_P = @MKDIR_P@
 MPI_SFLAGS = @MPI_SFLAGS@
 NM = @NM@
@@ -184,16 +245,19 @@ PTH_CONFIG = @PTH_CONFIG@
 PTH_LIBS = @PTH_LIBS@
 RANLIB = @RANLIB@
 RC = @RC@
+RUN_LARGE_DATA_TESTS = @RUN_LARGE_DATA_TESTS@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
 SYS_SOCKET_H = @SYS_SOCKET_H@
 VERSION = @VERSION@
+VERSION_NUMBER = @VERSION_NUMBER@
 abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
@@ -229,7 +293,6 @@ libdir = @libdir@
 libexecdir = @libexecdir@
 localedir = @localedir@
 localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 oldincludedir = @oldincludedir@
@@ -251,49 +314,71 @@ EXTRA_DIST = Manifest
 # a built header.
 AM_CPPFLAGS = -I../src -I$(top_srcdir)/src
 AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+AM_CCASFLAGS = $(NOEXECSTACK_FLAGS)
 noinst_LTLIBRARIES = libcipher.la
-GCRYPT_MODULES = @GCRYPT_CIPHERS@ @GCRYPT_PUBKEY_CIPHERS@ @GCRYPT_DIGESTS@
+GCRYPT_MODULES = @GCRYPT_CIPHERS@ @GCRYPT_PUBKEY_CIPHERS@ \
+                 @GCRYPT_DIGESTS@ @GCRYPT_KDFS@
+
 libcipher_la_DEPENDENCIES = $(GCRYPT_MODULES)
 libcipher_la_LIBADD = $(GCRYPT_MODULES)
 libcipher_la_SOURCES = \
-cipher.c pubkey.c ac.c md.c kdf.c \
+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-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 \
+kdf.c kdf-internal.h \
 hmac-tests.c \
 bithelp.h  \
+bufhelp.h  \
 primegen.c  \
 hash-common.c hash-common.h \
+dsa-common.c rsa-common.c \
 rmd.h
 
 EXTRA_libcipher_la_SOURCES = \
 arcfour.c \
-blowfish.c \
-cast5.c \
+blowfish.c blowfish-amd64.S blowfish-arm.S \
+cast5.c cast5-amd64.S cast5-arm.S \
 crc.c \
 des.c \
 dsa.c \
 elgamal.c \
-ecc.c \
+ecc.c ecc-curves.c ecc-misc.c ecc-common.h \
+ecc-ecdsa.c ecc-eddsa.c ecc-gost.c \
+idea.c \
+gost28147.c gost.h \
+gostr3411-94.c \
 md4.c \
 md5.c \
-rijndael.c rijndael-tables.h \
+rijndael.c rijndael-tables.h rijndael-amd64.S rijndael-arm.S \
 rmd160.c \
 rsa.c \
+salsa20.c salsa20-amd64.S salsa20-armv7-neon.S \
+scrypt.c \
 seed.c \
-serpent.c \
-sha1.c \
-sha256.c \
-sha512.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 \
+sha512.c sha512-ssse3-amd64.S sha512-avx-amd64.S sha512-avx2-bmi2-amd64.S \
+  sha512-armv7-neon.S \
+stribog.c \
 tiger.c \
 whirlpool.c \
-twofish.c \
+twofish.c twofish-amd64.S twofish-arm.S \
 rfc2268.c \
-camellia.c camellia.h camellia-glue.c
+camellia.c camellia.h camellia-glue.c camellia-aesni-avx-amd64.S \
+  camellia-aesni-avx2-amd64.S camellia-arm.S
 
 @ENABLE_O_FLAG_MUNGING_FALSE@o_flag_munging = cat
-@ENABLE_O_FLAG_MUNGING_TRUE@o_flag_munging = sed -e 's/-O[2-9s]*/-O1/g'
+@ENABLE_O_FLAG_MUNGING_TRUE@o_flag_munging = sed -e 's/-O\([2-9s][2-9s]*\)/-O1/' -e 's/-Ofast/-O1/g'
 all: all-am
 
 .SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
+.SUFFIXES: .S .c .lo .o .obj
 $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
        @for dep in $?; do \
          case '$(am__configure_deps)' in \
@@ -333,8 +418,8 @@ clean-noinstLTLIBRARIES:
          echo "rm -f \"$${dir}/so_locations\""; \
          rm -f "$${dir}/so_locations"; \
        done
-libcipher.la: $(libcipher_la_OBJECTS) $(libcipher_la_DEPENDENCIES) 
-       $(LINK)  $(libcipher_la_OBJECTS) $(libcipher_la_LIBADD) $(LIBS)
+libcipher.la: $(libcipher_la_OBJECTS) $(libcipher_la_DEPENDENCIES) $(EXTRA_libcipher_la_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK)  $(libcipher_la_OBJECTS) $(libcipher_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
        -rm -f *.$(OBJEXT)
@@ -342,59 +427,128 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ac.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@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/blowfish.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camellia-aesni-avx-amd64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camellia-aesni-avx2-amd64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camellia-arm.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camellia-glue.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/camellia.Plo@am__quote@
+@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)/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.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cipher-ofb.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.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@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecc-curves.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecc-ecdsa.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecc-eddsa.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecc-gost.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecc-misc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ecc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elgamal.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gost28147.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gostr3411-94.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash-common.Plo@am__quote@
 @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)/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.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)/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-amd64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rijndael-arm.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@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsa.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/salsa20-amd64.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/salsa20-armv7-neon.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/salsa20.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scrypt.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/seed.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/serpent-armv7-neon.Plo@am__quote@
+@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-ssse3-amd64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha1.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-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@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha512-ssse3-amd64.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sha512.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/stribog.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tiger.Plo@am__quote@
+@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.Plo@am__quote@
 
+.S.o:
+@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@    $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@    DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@        $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ $<
+
+.S.obj:
+@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@    $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@    DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@        $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+
+.S.lo:
+@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@    $(AM_V_CPPAS)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@    DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCCAS_FALSE@        $(AM_V_CPPAS@am__nodep@)$(LTCPPASCOMPILE) -c -o $@ $<
+
 .c.o:
-@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@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@  $(COMPILE) -c $<
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
 
 .c.obj:
-@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@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@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
 
 .c.lo:
-@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
 mostlyclean-libtool:
        -rm -f *.lo
@@ -498,10 +652,15 @@ install-am: all-am
 
 installcheck: installcheck-am
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-         `test -z '$(STRIP)' || \
-           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+       if test -z '$(STRIP)'; then \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+             install; \
+       else \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+           "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+       fi
 mostlyclean-generic:
 
 clean-generic:
diff --git a/cipher/ac.c b/cipher/ac.c
deleted file mode 100644 (file)
index f5e946a..0000000
+++ /dev/null
@@ -1,3301 +0,0 @@
-/* ac.c - Alternative interface for asymmetric cryptography.
-   Copyright (C) 2003, 2004, 2005, 2006
-                 2007, 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>
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <stddef.h>
-
-#include "g10lib.h"
-#include "cipher.h"
-#include "mpi.h"
-
-\f
-
-/* At the moment the ac interface is a wrapper around the pk
-   interface, but this might change somewhen in the future, depending
-   on how many people prefer the ac interface.  */
-
-/* Mapping of flag numbers to the according strings as it is expected
-   for S-expressions.  */
-static struct number_string
-{
-  int number;
-  const char *string;
-} ac_flags[] =
-  {
-    { GCRY_AC_FLAG_NO_BLINDING, "no-blinding" },
-  };
-
-/* The positions in this list correspond to the values contained in
-   the gcry_ac_key_type_t enumeration list.  */
-static const char *ac_key_identifiers[] =
-  {
-    "private-key",
-    "public-key"
-  };
-
-/* These specifications are needed for key-pair generation; the caller
-   is allowed to pass additional, algorithm-specific `specs' to
-   gcry_ac_key_pair_generate.  This list is used for decoding the
-   provided values according to the selected algorithm.  */
-struct gcry_ac_key_generate_spec
-{
-  int algorithm;               /* Algorithm for which this flag is
-                                  relevant.  */
-  const char *name;            /* Name of this flag.  */
-  size_t offset;               /* Offset in the cipher-specific spec
-                                  structure at which the MPI value
-                                  associated with this flag is to be
-                                  found.  */
-} ac_key_generate_specs[] =
-  {
-    { GCRY_AC_RSA, "rsa-use-e", offsetof (gcry_ac_key_spec_rsa_t, e) },
-    { 0 }
-  };
-
-/* Handle structure.  */
-struct gcry_ac_handle
-{
-  int algorithm;               /* Algorithm ID associated with this
-                                  handle.  */
-  const char *algorithm_name;  /* Name of the algorithm.  */
-  unsigned int flags;          /* Flags, not used yet.  */
-  gcry_module_t module;                /* Reference to the algorithm
-                                  module.  */
-};
-
-/* A named MPI value.  */
-typedef struct gcry_ac_mpi
-{
-  char *name;                  /* Self-maintained copy of name.  */
-  gcry_mpi_t mpi;              /* MPI value.         */
-  unsigned int flags;          /* Flags.             */
-} gcry_ac_mpi_t;
-
-/* A data set, that is simply a list of named MPI values.  */
-struct gcry_ac_data
-{
-  gcry_ac_mpi_t *data;         /* List of named values.      */
-  unsigned int data_n;         /* Number of values in DATA.  */
-};
-
-/* A single key.  */
-struct gcry_ac_key
-{
-  gcry_ac_data_t data;         /* Data in native ac structure.  */
-  gcry_ac_key_type_t type;     /* Type of the key.              */
-};
-
-/* A key pair.  */
-struct gcry_ac_key_pair
-{
-  gcry_ac_key_t public;
-  gcry_ac_key_t secret;
-};
-
-\f
-
-/*
- * Functions for working with data sets.
- */
-
-/* Creates a new, empty data set and store it in DATA.  */
-gcry_error_t
-_gcry_ac_data_new (gcry_ac_data_t *data)
-{
-  gcry_ac_data_t data_new;
-  gcry_error_t err;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  data_new = gcry_malloc (sizeof (*data_new));
-  if (! data_new)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  data_new->data = NULL;
-  data_new->data_n = 0;
-  *data = data_new;
-  err = 0;
-
- out:
-
-  return err;
-}
-
-/* Destroys all the entries in DATA, but not DATA itself.  */
-static void
-ac_data_values_destroy (gcry_ac_data_t data)
-{
-  unsigned int i;
-
-  for (i = 0; i < data->data_n; i++)
-    if (data->data[i].flags & GCRY_AC_FLAG_DEALLOC)
-      {
-       gcry_mpi_release (data->data[i].mpi);
-       gcry_free (data->data[i].name);
-      }
-}
-
-/* Destroys the data set DATA.  */
-void
-_gcry_ac_data_destroy (gcry_ac_data_t data)
-{
-  if (data)
-    {
-      ac_data_values_destroy (data);
-      gcry_free (data->data);
-      gcry_free (data);
-    }
-}
-
-/* This function creates a copy of the array of named MPIs DATA_MPIS,
-   which is of length DATA_MPIS_N; the copy is stored in
-   DATA_MPIS_CP.  */
-static gcry_error_t
-ac_data_mpi_copy (gcry_ac_mpi_t *data_mpis, unsigned int data_mpis_n,
-                 gcry_ac_mpi_t **data_mpis_cp)
-{
-  gcry_ac_mpi_t *data_mpis_new;
-  gcry_error_t err;
-  unsigned int i;
-  gcry_mpi_t mpi;
-  char *label;
-
-  data_mpis_new = gcry_malloc (sizeof (*data_mpis_new) * data_mpis_n);
-  if (! data_mpis_new)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-  memset (data_mpis_new, 0, sizeof (*data_mpis_new) * data_mpis_n);
-
-  err = 0;
-  for (i = 0; i < data_mpis_n; i++)
-    {
-      /* Copy values.  */
-
-      label = gcry_strdup (data_mpis[i].name);
-      mpi = gcry_mpi_copy (data_mpis[i].mpi);
-      if (! (label && mpi))
-       {
-         err = gcry_error_from_errno (errno);
-         gcry_mpi_release (mpi);
-         gcry_free (label);
-         break;
-       }
-
-      data_mpis_new[i].flags = GCRY_AC_FLAG_DEALLOC;
-      data_mpis_new[i].name = label;
-      data_mpis_new[i].mpi = mpi;
-    }
-  if (err)
-    goto out;
-
-  *data_mpis_cp = data_mpis_new;
-  err = 0;
-
- out:
-
-  if (err)
-    if (data_mpis_new)
-      {
-       for (i = 0; i < data_mpis_n; i++)
-         {
-           gcry_mpi_release (data_mpis_new[i].mpi);
-           gcry_free (data_mpis_new[i].name);
-         }
-       gcry_free (data_mpis_new);
-      }
-
-  return err;
-}
-
-/* Create a copy of the data set DATA and store it in DATA_CP.  */
-gcry_error_t
-_gcry_ac_data_copy (gcry_ac_data_t *data_cp, gcry_ac_data_t data)
-{
-  gcry_ac_mpi_t *data_mpis = NULL;
-  gcry_ac_data_t data_new;
-  gcry_error_t err;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  /* Allocate data set.  */
-  data_new = gcry_malloc (sizeof (*data_new));
-  if (! data_new)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  err = ac_data_mpi_copy (data->data, data->data_n, &data_mpis);
-  if (err)
-    goto out;
-
-  data_new->data_n = data->data_n;
-  data_new->data = data_mpis;
-  *data_cp = data_new;
-
- out:
-
-  if (err)
-    gcry_free (data_new);
-
-  return err;
-}
-
-/* Returns the number of named MPI values inside of the data set
-   DATA.  */
-unsigned int
-_gcry_ac_data_length (gcry_ac_data_t data)
-{
-  return data->data_n;
-}
-
-
-/* Add the value MPI to DATA with the label NAME.  If FLAGS contains
-   GCRY_AC_FLAG_COPY, the data set will contain copies of NAME
-   and MPI.  If FLAGS contains GCRY_AC_FLAG_DEALLOC or
-   GCRY_AC_FLAG_COPY, the values contained in the data set will
-   be deallocated when they are to be removed from the data set.  */
-gcry_error_t
-_gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
-                  const char *name, gcry_mpi_t mpi)
-{
-  gcry_error_t err;
-  gcry_mpi_t mpi_cp;
-  char *name_cp;
-  unsigned int i;
-
-  name_cp = NULL;
-  mpi_cp = NULL;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  if (flags & ~(GCRY_AC_FLAG_DEALLOC | GCRY_AC_FLAG_COPY))
-    {
-      err = gcry_error (GPG_ERR_INV_ARG);
-      goto out;
-    }
-
-  if (flags & GCRY_AC_FLAG_COPY)
-    {
-      /* Create copies.  */
-
-      flags |= GCRY_AC_FLAG_DEALLOC;
-      name_cp = gcry_strdup (name);
-      mpi_cp = gcry_mpi_copy (mpi);
-      if (! (name_cp && mpi_cp))
-       {
-         err = gcry_error_from_errno (errno);
-         goto out;
-       }
-    }
-
-  /* Search for existing entry.  */
-  for (i = 0; i < data->data_n; i++)
-    if (! strcmp (name, data->data[i].name))
-      break;
-  if (i < data->data_n)
-    {
-      /* An entry for NAME does already exist.  */
-      if (data->data[i].flags & GCRY_AC_FLAG_DEALLOC)
-       {
-         gcry_mpi_release (data->data[i].mpi);
-         gcry_free (data->data[i].name);
-       }
-    }
-  else
-    {
-      /* Create a new entry.  */
-
-      gcry_ac_mpi_t *ac_mpis;
-
-      ac_mpis = gcry_realloc (data->data,
-                             sizeof (*data->data) * (data->data_n + 1));
-      if (! ac_mpis)
-       {
-         err = gcry_error_from_errno (errno);
-         goto out;
-       }
-
-      if (data->data != ac_mpis)
-       data->data = ac_mpis;
-      data->data_n++;
-    }
-
-  data->data[i].name = name_cp ? name_cp : ((char *) name);
-  data->data[i].mpi = mpi_cp ? mpi_cp : mpi;
-  data->data[i].flags = flags;
-  err = 0;
-
- out:
-
-  if (err)
-    {
-      gcry_mpi_release (mpi_cp);
-      gcry_free (name_cp);
-    }
-
-  return err;
-}
-
-/* Stores the value labelled with NAME found in the data set DATA in
-   MPI.  The returned MPI value will be released in case
-   gcry_ac_data_set is used to associate the label NAME with a
-   different MPI value.  */
-gcry_error_t
-_gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
-                       const char *name, gcry_mpi_t *mpi)
-{
-  gcry_mpi_t mpi_return;
-  gcry_error_t err;
-  unsigned int i;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  if (flags & ~(GCRY_AC_FLAG_COPY))
-    {
-      err = gcry_error (GPG_ERR_INV_ARG);
-      goto out;
-    }
-
-  for (i = 0; i < data->data_n; i++)
-    if (! strcmp (name, data->data[i].name))
-      break;
-  if (i == data->data_n)
-    {
-      err = gcry_error (GPG_ERR_NOT_FOUND);
-      goto out;
-    }
-
-  if (flags & GCRY_AC_FLAG_COPY)
-    {
-      mpi_return = gcry_mpi_copy (data->data[i].mpi);
-      if (! mpi_return)
-       {
-         err = gcry_error_from_errno (errno); /* FIXME? */
-         goto out;
-       }
-    }
-  else
-    mpi_return = data->data[i].mpi;
-
-  *mpi = mpi_return;
-  err = 0;
-
- out:
-
-  return err;
-}
-
-/* Stores in NAME and MPI the named MPI value contained in the data
-   set DATA with the index IDX.  NAME or MPI may be NULL.  The
-   returned MPI value will be released in case gcry_ac_data_set is
-   used to associate the label NAME with a different MPI value.  */
-gcry_error_t
-_gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
-                        unsigned int idx,
-                        const char **name, gcry_mpi_t *mpi)
-{
-  gcry_error_t err;
-  gcry_mpi_t mpi_cp;
-  char *name_cp;
-
-  name_cp = NULL;
-  mpi_cp = NULL;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  if (flags & ~(GCRY_AC_FLAG_COPY))
-    {
-      err = gcry_error (GPG_ERR_INV_ARG);
-      goto out;
-    }
-
-  if (idx >= data->data_n)
-    {
-      err = gcry_error (GPG_ERR_INV_ARG);
-      goto out;
-    }
-
-  if (flags & GCRY_AC_FLAG_COPY)
-    {
-      /* Return copies to the user.  */
-      if (name)
-       {
-         name_cp = gcry_strdup (data->data[idx].name);
-         if (! name_cp)
-           {
-             err = gcry_error_from_errno (errno);
-             goto out;
-           }
-       }
-      if (mpi)
-       {
-         mpi_cp = gcry_mpi_copy (data->data[idx].mpi);
-         if (! mpi_cp)
-           {
-             err = gcry_error_from_errno (errno);
-             goto out;
-           }
-       }
-    }
-
-  if (name)
-    *name = name_cp ? name_cp : data->data[idx].name;
-  if (mpi)
-    *mpi = mpi_cp ? mpi_cp : data->data[idx].mpi;
-  err = 0;
-
- out:
-
-  if (err)
-    {
-      gcry_mpi_release (mpi_cp);
-      gcry_free (name_cp);
-    }
-
-  return err;
-}
-
-/* Convert the data set DATA into a new S-Expression, which is to be
-   stored in SEXP, according to the identifiers contained in
-   IDENTIFIERS.  */
-gcry_error_t
-_gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
-                      const char **identifiers)
-{
-  gcry_sexp_t sexp_new;
-  gcry_error_t err;
-  char *sexp_buffer;
-  size_t sexp_buffer_n;
-  size_t identifiers_n;
-  const char *label;
-  gcry_mpi_t mpi;
-  void **arg_list;
-  size_t data_n;
-  unsigned int i;
-
-  sexp_buffer_n = 1;
-  sexp_buffer = NULL;
-  arg_list = NULL;
-  err = 0;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  /* Calculate size of S-expression representation.  */
-
-  i = 0;
-  if (identifiers)
-    while (identifiers[i])
-      {
-       /* For each identifier, we add "(<IDENTIFIER>)".  */
-       sexp_buffer_n += 1 + strlen (identifiers[i]) + 1;
-       i++;
-      }
-  identifiers_n = i;
-
-  if (! identifiers_n)
-    /* If there are NO identifiers, we still add surrounding braces so
-       that we have a list of named MPI value lists.  Otherwise it
-       wouldn't be too much fun to process these lists.  */
-    sexp_buffer_n += 2;
-
-  data_n = _gcry_ac_data_length (data);
-  for (i = 0; i < data_n; i++)
-    {
-      err = gcry_ac_data_get_index (data, 0, i, &label, NULL);
-      if (err)
-       break;
-      /* For each MPI we add "(<LABEL> %m)".  */
-      sexp_buffer_n += 1 + strlen (label) + 4;
-    }
-  if (err)
-    goto out;
-
-  /* Allocate buffer.  */
-
-  sexp_buffer = gcry_malloc (sexp_buffer_n);
-  if (! sexp_buffer)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  /* Fill buffer.  */
-
-  *sexp_buffer = 0;
-  sexp_buffer_n = 0;
-
-  /* Add identifiers: (<IDENTIFIER0>(<IDENTIFIER1>...)).  */
-  if (identifiers_n)
-    {
-      /* Add nested identifier lists as usual.  */
-      for (i = 0; i < identifiers_n; i++)
-       sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, "(%s",
-                                 identifiers[i]);
-    }
-  else
-    {
-      /* Add special list.  */
-      sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, "(");
-    }
-
-  /* Add MPI list.  */
-  arg_list = gcry_malloc (sizeof (*arg_list) * (data_n + 1));
-  if (! arg_list)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-  for (i = 0; i < data_n; i++)
-    {
-      err = gcry_ac_data_get_index (data, 0, i, &label, &mpi);
-      if (err)
-       break;
-      sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n,
-                               "(%s %%m)", label);
-      arg_list[i] = &data->data[i].mpi;
-    }
-  if (err)
-    goto out;
-
-  if (identifiers_n)
-    {
-      /* Add closing braces for identifier lists as usual.  */
-      for (i = 0; i < identifiers_n; i++)
-       sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, ")");
-    }
-  else
-    {
-      /* Add closing braces for special list.  */
-      sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, ")");
-    }
-
-  /* Construct.  */
-  err = gcry_sexp_build_array (&sexp_new, NULL, sexp_buffer, arg_list);
-  if (err)
-    goto out;
-
-  *sexp = sexp_new;
-
- out:
-
-  gcry_free (sexp_buffer);
-  gcry_free (arg_list);
-
-  return err;
-}
-
-/* Create a new data set, which is to be stored in DATA_SET, from the
-   S-Expression SEXP, according to the identifiers contained in
-   IDENTIFIERS.  */
-gcry_error_t
-_gcry_ac_data_from_sexp (gcry_ac_data_t *data_set, gcry_sexp_t sexp,
-                        const char **identifiers)
-{
-  gcry_ac_data_t data_set_new;
-  gcry_error_t err;
-  gcry_sexp_t sexp_cur;
-  gcry_sexp_t sexp_tmp;
-  gcry_mpi_t mpi;
-  char *string;
-  const char *data;
-  size_t data_n;
-  size_t sexp_n;
-  unsigned int i;
-  int skip_name;
-
-  data_set_new = NULL;
-  sexp_cur = sexp;
-  sexp_tmp = NULL;
-  string = NULL;
-  mpi = NULL;
-  err = 0;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  /* Process S-expression/identifiers.  */
-
-  if (identifiers)
-    {
-      for (i = 0; identifiers[i]; i++)
-       {
-         /* Next identifier.  Extract first data item from
-            SEXP_CUR.  */
-         data = gcry_sexp_nth_data (sexp_cur, 0, &data_n);
-
-         if (! ((data_n == strlen (identifiers[i]))
-                && (! strncmp (data, identifiers[i], data_n))))
-           {
-             /* Identifier mismatch -> error.  */
-             err = gcry_error (GPG_ERR_INV_SEXP);
-             break;
-           }
-
-         /* Identifier matches.  Now we have to distinguish two
-            cases:
-
-            (i)  we are at the last identifier:
-            leave loop
-
-            (ii) we are not at the last identifier:
-            extract next element, which is supposed to be a
-            sublist.  */
-
-         if (! identifiers[i + 1])
-           /* Last identifier.  */
-           break;
-         else
-           {
-             /* Not the last identifier, extract next sublist.  */
-
-             sexp_tmp = gcry_sexp_nth (sexp_cur, 1);
-             if (! sexp_tmp)
-               {
-                 /* Missing sublist.  */
-                 err = gcry_error (GPG_ERR_INV_SEXP);
-                 break;
-               }
-
-             /* Release old SEXP_CUR, in case it is not equal to the
-                original SEXP.  */
-             if (sexp_cur != sexp)
-               gcry_sexp_release (sexp_cur);
-
-             /* Make SEXP_CUR point to the new current sublist.  */
-             sexp_cur = sexp_tmp;
-              sexp_tmp = NULL;
-           }
-       }
-      if (err)
-       goto out;
-
-      if (i)
-        {
-          /* We have at least one identifier in the list, this means
-             the the list of named MPI values is prefixed, this means
-             that we need to skip the first item (the list name), when
-             processing the MPI values.  */
-          skip_name = 1;
-        }
-      else
-        {
-          /* Since there is no identifiers list, the list of named MPI
-             values is not prefixed with a list name, therefore the
-             offset to use is zero.  */
-          skip_name = 0;
-        }
-    }
-  else
-    /* Since there is no identifiers list, the list of named MPI
-       values is not prefixed with a list name, therefore the offset
-       to use is zero.  */
-    skip_name = 0;
-
-  /* Create data set from S-expression data.  */
-
-  err = gcry_ac_data_new (&data_set_new);
-  if (err)
-    goto out;
-
-  /* Figure out amount of named MPIs in SEXP_CUR.  */
-  if (sexp_cur)
-    sexp_n = gcry_sexp_length (sexp_cur) - skip_name;
-  else
-    sexp_n = 0;
-
-  /* Extracte the named MPIs sequentially.  */
-  for (i = 0; i < sexp_n; i++)
-    {
-      /* Store next S-Expression pair, which is supposed to consist of
-        a name and an MPI value, in SEXP_TMP.  */
-
-      sexp_tmp = gcry_sexp_nth (sexp_cur, i + skip_name);
-      if (! sexp_tmp)
-       {
-         err = gcry_error (GPG_ERR_INV_SEXP);
-         break;
-       }
-
-      /* Extract name from current S-Expression pair.  */
-      data = gcry_sexp_nth_data (sexp_tmp, 0, &data_n);
-      string = gcry_malloc (data_n + 1);
-      if (! string)
-       {
-         err = gcry_error_from_errno (errno);
-         break;
-       }
-      memcpy (string, data, data_n);
-      string[data_n] = 0;
-
-      /* Extract MPI value.  */
-      mpi = gcry_sexp_nth_mpi (sexp_tmp, 1, 0);
-      if (! mpi)
-       {
-         err = gcry_error (GPG_ERR_INV_SEXP); /* FIXME? */
-         break;
-       }
-
-      /* Store named MPI in data_set_new.  */
-      err = gcry_ac_data_set (data_set_new, GCRY_AC_FLAG_DEALLOC, string, mpi);
-      if (err)
-       break;
-
-/*       gcry_free (string); */
-      string = NULL;
-/*       gcry_mpi_release (mpi); */
-      mpi = NULL;
-
-      gcry_sexp_release (sexp_tmp);
-      sexp_tmp = NULL;
-    }
-  if (err)
-    goto out;
-
-  *data_set = data_set_new;
-
- out:
-
-  if (sexp_cur != sexp)
-    gcry_sexp_release (sexp_cur);
-  gcry_sexp_release (sexp_tmp);
-  gcry_mpi_release (mpi);
-  gcry_free (string);
-
-  if (err)
-    gcry_ac_data_destroy (data_set_new);
-
-  return err;
-}
-
-
-static void
-_gcry_ac_data_dump (const char *prefix, gcry_ac_data_t data)
-{
-  unsigned char *mpi_buffer;
-  size_t mpi_buffer_n;
-  unsigned int data_n;
-  gcry_error_t err;
-  const char *name;
-  gcry_mpi_t mpi;
-  unsigned int i;
-
-  if (! data)
-    return;
-
-  if (fips_mode ())
-    return;
-
-  mpi_buffer = NULL;
-
-  data_n = _gcry_ac_data_length (data);
-  for (i = 0; i < data_n; i++)
-    {
-      err = gcry_ac_data_get_index (data, 0, i, &name, &mpi);
-      if (err)
-       {
-         log_error ("failed to dump data set");
-         break;
-       }
-
-      err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &mpi_buffer, &mpi_buffer_n, mpi);
-      if (err)
-       {
-         log_error ("failed to dump data set");
-         break;
-       }
-
-      log_printf ("%s%s%s: %s\n",
-                 prefix ? prefix : "",
-                 prefix ? ": " : ""
-                 , name, mpi_buffer);
-
-      gcry_free (mpi_buffer);
-      mpi_buffer = NULL;
-    }
-
-  gcry_free (mpi_buffer);
-}
-
-/* Dump the named MPI values contained in the data set DATA to
-   Libgcrypt's logging stream.  */
-void
-gcry_ac_data_dump (const char *prefix, gcry_ac_data_t data)
-{
-  _gcry_ac_data_dump (prefix, data);
-}
-
-/* Destroys any values contained in the data set DATA.  */
-void
-_gcry_ac_data_clear (gcry_ac_data_t data)
-{
-  ac_data_values_destroy (data);
-  gcry_free (data->data);
-  data->data = NULL;
-  data->data_n = 0;
-}
-
-\f
-
-/*
- * Implementation of `ac io' objects.
- */
-
-/* Initialize AC_IO according to MODE, TYPE and the variable list of
-   arguments AP.  The list of variable arguments to specify depends on
-   the given TYPE.  */
-void
-_gcry_ac_io_init_va (gcry_ac_io_t *ac_io,
-                    gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, va_list ap)
-{
-  memset (ac_io, 0, sizeof (*ac_io));
-
-  if (fips_mode ())
-    return;
-
-  gcry_assert ((mode == GCRY_AC_IO_READABLE) || (mode == GCRY_AC_IO_WRITABLE));
-  gcry_assert ((type == GCRY_AC_IO_STRING) || (type == GCRY_AC_IO_STRING));
-
-  ac_io->mode = mode;
-  ac_io->type = type;
-
-  switch (mode)
-    {
-    case GCRY_AC_IO_READABLE:
-      switch (type)
-       {
-       case GCRY_AC_IO_STRING:
-         ac_io->io.readable.string.data = va_arg (ap, unsigned char *);
-         ac_io->io.readable.string.data_n = va_arg (ap, size_t);
-         break;
-
-       case GCRY_AC_IO_CALLBACK:
-         ac_io->io.readable.callback.cb = va_arg (ap, gcry_ac_data_read_cb_t);
-         ac_io->io.readable.callback.opaque = va_arg (ap, void *);
-         break;
-       }
-      break;
-    case GCRY_AC_IO_WRITABLE:
-      switch (type)
-       {
-       case GCRY_AC_IO_STRING:
-         ac_io->io.writable.string.data = va_arg (ap, unsigned char **);
-         ac_io->io.writable.string.data_n = va_arg (ap, size_t *);
-         break;
-
-       case GCRY_AC_IO_CALLBACK:
-         ac_io->io.writable.callback.cb = va_arg (ap, gcry_ac_data_write_cb_t);
-         ac_io->io.writable.callback.opaque = va_arg (ap, void *);
-         break;
-       }
-      break;
-    }
-}
-
-/* Initialize AC_IO according to MODE, TYPE and the variable list of
-   arguments.  The list of variable arguments to specify depends on
-   the given TYPE. */
-void
-_gcry_ac_io_init (gcry_ac_io_t *ac_io,
-                 gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, ...)
-{
-  va_list ap;
-
-  va_start (ap, type);
-  _gcry_ac_io_init_va (ac_io, mode, type, ap);
-  va_end (ap);
-}
-
-
-/* Write to the IO object AC_IO BUFFER_N bytes from BUFFER.  Return
-   zero on success or error code.  */
-static gcry_error_t
-_gcry_ac_io_write (gcry_ac_io_t *ac_io, unsigned char *buffer, size_t buffer_n)
-{
-  gcry_error_t err;
-
-  gcry_assert (ac_io->mode == GCRY_AC_IO_WRITABLE);
-  err = 0;
-
-  switch (ac_io->type)
-    {
-    case GCRY_AC_IO_STRING:
-      {
-       unsigned char *p;
-
-       if (*ac_io->io.writable.string.data)
-         {
-           p = gcry_realloc (*ac_io->io.writable.string.data,
-                             *ac_io->io.writable.string.data_n + buffer_n);
-           if (! p)
-             err = gcry_error_from_errno (errno);
-           else
-             {
-               if (*ac_io->io.writable.string.data != p)
-                 *ac_io->io.writable.string.data = p;
-               memcpy (p + *ac_io->io.writable.string.data_n, buffer, buffer_n);
-               *ac_io->io.writable.string.data_n += buffer_n;
-             }
-         }
-       else
-         {
-           if (gcry_is_secure (buffer))
-             p = gcry_malloc_secure (buffer_n);
-           else
-             p = gcry_malloc (buffer_n);
-           if (! p)
-             err = gcry_error_from_errno (errno);
-           else
-             {
-               memcpy (p, buffer, buffer_n);
-               *ac_io->io.writable.string.data = p;
-               *ac_io->io.writable.string.data_n = buffer_n;
-             }
-         }
-      }
-      break;
-
-    case GCRY_AC_IO_CALLBACK:
-      err = (*ac_io->io.writable.callback.cb) (ac_io->io.writable.callback.opaque,
-                                              buffer, buffer_n);
-      break;
-    }
-
-  return err;
-}
-
-/* Read *BUFFER_N bytes from the IO object AC_IO into BUFFER; NREAD
-   bytes have already been read from the object; on success, store the
-   amount of bytes read in *BUFFER_N; zero bytes read means EOF.
-   Return zero on success or error code.  */
-static gcry_error_t
-_gcry_ac_io_read (gcry_ac_io_t *ac_io,
-                 unsigned int nread, unsigned char *buffer, size_t *buffer_n)
-{
-  gcry_error_t err;
-
-  gcry_assert (ac_io->mode == GCRY_AC_IO_READABLE);
-  err = 0;
-
-  switch (ac_io->type)
-    {
-    case GCRY_AC_IO_STRING:
-      {
-       size_t bytes_available;
-       size_t bytes_to_read;
-       size_t bytes_wanted;
-
-       bytes_available = ac_io->io.readable.string.data_n - nread;
-       bytes_wanted = *buffer_n;
-
-       if (bytes_wanted > bytes_available)
-         bytes_to_read = bytes_available;
-       else
-         bytes_to_read = bytes_wanted;
-
-       memcpy (buffer, ac_io->io.readable.string.data + nread, bytes_to_read);
-       *buffer_n = bytes_to_read;
-       err = 0;
-       break;
-      }
-
-    case GCRY_AC_IO_CALLBACK:
-      err = (*ac_io->io.readable.callback.cb)
-       (ac_io->io.readable.callback.opaque, buffer, buffer_n);
-      break;
-    }
-
-  return err;
-}
-
-/* Read all data available from the IO object AC_IO into newly
-   allocated memory, storing an appropriate pointer in *BUFFER and the
-   amount of bytes read in *BUFFER_N.  Return zero on success or error
-   code.  */
-static gcry_error_t
-_gcry_ac_io_read_all (gcry_ac_io_t *ac_io, unsigned char **buffer, size_t *buffer_n)
-{
-  unsigned char *buffer_new;
-  size_t buffer_new_n;
-  unsigned char buf[BUFSIZ];
-  size_t buf_n;
-  unsigned char *p;
-  gcry_error_t err;
-
-  buffer_new = NULL;
-  buffer_new_n = 0;
-
-  while (1)
-    {
-      buf_n = sizeof (buf);
-      err = _gcry_ac_io_read (ac_io, buffer_new_n, buf, &buf_n);
-      if (err)
-       break;
-
-      if (buf_n)
-       {
-         p = gcry_realloc (buffer_new, buffer_new_n + buf_n);
-         if (! p)
-           {
-             err = gcry_error_from_errno (errno);
-             break;
-           }
-
-         if (buffer_new != p)
-           buffer_new = p;
-
-         memcpy (buffer_new + buffer_new_n, buf, buf_n);
-         buffer_new_n += buf_n;
-       }
-      else
-       break;
-    }
-  if (err)
-    goto out;
-
-  *buffer_n = buffer_new_n;
-  *buffer = buffer_new;
-
- out:
-
-  if (err)
-    gcry_free (buffer_new);
-
-  return err;
-}
-
-/* Read data chunks from the IO object AC_IO until EOF, feeding them
-   to the callback function CB.  Return zero on success or error
-   code.  */
-static gcry_error_t
-_gcry_ac_io_process (gcry_ac_io_t *ac_io,
-                    gcry_ac_data_write_cb_t cb, void *opaque)
-{
-  unsigned char buffer[BUFSIZ];
-  unsigned int nread;
-  size_t buffer_n;
-  gcry_error_t err;
-
-  nread = 0;
-
-  while (1)
-    {
-      buffer_n = sizeof (buffer);
-      err = _gcry_ac_io_read (ac_io, nread, buffer, &buffer_n);
-      if (err)
-       break;
-      if (buffer_n)
-       {
-         err = (*cb) (opaque, buffer, buffer_n);
-         if (err)
-           break;
-         nread += buffer_n;
-       }
-      else
-       break;
-    }
-
-  return err;
-}
-
-\f
-
-/*
- * Functions for converting data between the native ac and the
- * S-expression structure used by the pk interface.
- */
-
-/* Extract the S-Expression DATA_SEXP into DATA under the control of
-   TYPE and NAME.  This function assumes that S-Expressions are of the
-   following structure:
-
-   (IDENTIFIER [...]
-   (ALGORITHM <list of named MPI values>)) */
-static gcry_error_t
-ac_data_extract (const char *identifier, const char *algorithm,
-                gcry_sexp_t sexp, gcry_ac_data_t *data)
-{
-  gcry_error_t err;
-  gcry_sexp_t value_sexp;
-  gcry_sexp_t data_sexp;
-  size_t data_sexp_n;
-  gcry_mpi_t value_mpi;
-  char *value_name;
-  const char *data_raw;
-  size_t data_raw_n;
-  gcry_ac_data_t data_new;
-  unsigned int i;
-
-  value_sexp = NULL;
-  data_sexp = NULL;
-  value_name = NULL;
-  value_mpi = NULL;
-  data_new = NULL;
-
-  /* Verify that the S-expression contains the correct identifier.  */
-  data_raw = gcry_sexp_nth_data (sexp, 0, &data_raw_n);
-  if ((! data_raw) || strncmp (identifier, data_raw, data_raw_n))
-    {
-      err = gcry_error (GPG_ERR_INV_SEXP);
-      goto out;
-    }
-
-  /* Extract inner S-expression.  */
-  data_sexp = gcry_sexp_find_token (sexp, algorithm, 0);
-  if (! data_sexp)
-    {
-      err = gcry_error (GPG_ERR_INV_SEXP);
-      goto out;
-    }
-
-  /* Count data elements.  */
-  data_sexp_n = gcry_sexp_length (data_sexp);
-  data_sexp_n--;
-
-  /* Allocate new data set.  */
-  err = _gcry_ac_data_new (&data_new);
-  if (err)
-    goto out;
-
-  /* Iterate through list of data elements and add them to the data
-     set.  */
-  for (i = 0; i < data_sexp_n; i++)
-    {
-      /* Get the S-expression of the named MPI, that contains the name
-        and the MPI value.  */
-      value_sexp = gcry_sexp_nth (data_sexp, i + 1);
-      if (! value_sexp)
-       {
-         err = gcry_error (GPG_ERR_INV_SEXP);
-         break;
-       }
-
-      /* Extract the name.  */
-      data_raw = gcry_sexp_nth_data (value_sexp, 0, &data_raw_n);
-      if (! data_raw)
-       {
-         err = gcry_error (GPG_ERR_INV_SEXP);
-         break;
-       }
-
-      /* Extract the MPI value.  */
-      value_mpi = gcry_sexp_nth_mpi (value_sexp, 1, GCRYMPI_FMT_USG);
-      if (! value_mpi)
-       {
-         err = gcry_error (GPG_ERR_INTERNAL); /* FIXME? */
-         break;
-       }
-
-      /* Duplicate the name.  */
-      value_name = gcry_malloc (data_raw_n + 1);
-      if (! value_name)
-       {
-         err = gcry_error_from_errno (errno);
-         break;
-       }
-      strncpy (value_name, data_raw, data_raw_n);
-      value_name[data_raw_n] = 0;
-
-      err = _gcry_ac_data_set (data_new, GCRY_AC_FLAG_DEALLOC, value_name, value_mpi);
-      if (err)
-       break;
-
-      gcry_sexp_release (value_sexp);
-      value_sexp = NULL;
-      value_name = NULL;
-      value_mpi = NULL;
-    }
-  if (err)
-    goto out;
-
-  /* Copy out.  */
-  *data = data_new;
-
- out:
-
-  /* Deallocate resources.  */
-  if (err)
-    {
-      _gcry_ac_data_destroy (data_new);
-      gcry_mpi_release (value_mpi);
-      gcry_free (value_name);
-      gcry_sexp_release (value_sexp);
-    }
-  gcry_sexp_release (data_sexp);
-
-  return err;
-}
-
-/* Construct an S-expression from the DATA and store it in
-   DATA_SEXP. The S-expression will be of the following structure:
-
-   (IDENTIFIER [(flags [...])]
-   (ALGORITHM <list of named MPI values>))  */
-static gcry_error_t
-ac_data_construct (const char *identifier, int include_flags,
-                  unsigned int flags, const char *algorithm,
-                  gcry_ac_data_t data, gcry_sexp_t *sexp)
-{
-  unsigned int data_length;
-  gcry_sexp_t sexp_new;
-  gcry_error_t err;
-  size_t sexp_format_n;
-  char *sexp_format;
-  void **arg_list;
-  unsigned int i;
-
-  arg_list = NULL;
-  sexp_new = NULL;
-  sexp_format = NULL;
-
-  /* We build a list of arguments to pass to
-     gcry_sexp_build_array().  */
-  data_length = _gcry_ac_data_length (data);
-  arg_list = gcry_malloc (sizeof (*arg_list) * (data_length * 2));
-  if (! arg_list)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  /* Fill list with MPIs.  */
-  for (i = 0; i < data_length; i++)
-    {
-      char **nameaddr  = &data->data[i].name;
-
-      arg_list[(i * 2) + 0] = nameaddr;
-      arg_list[(i * 2) + 1] = &data->data[i].mpi;
-    }
-
-  /* Calculate size of format string.  */
-  sexp_format_n = (3
-                  + (include_flags ? 7 : 0)
-                  + (algorithm ? (2 + strlen (algorithm)) : 0)
-                  + strlen (identifier));
-
-  for (i = 0; i < data_length; i++)
-    /* Per-element sizes.  */
-    sexp_format_n += 6;
-
-  if (include_flags)
-    /* Add flags.  */
-    for (i = 0; i < DIM (ac_flags); i++)
-      if (flags & ac_flags[i].number)
-       sexp_format_n += strlen (ac_flags[i].string) + 1;
-
-  /* Done.  */
-  sexp_format = gcry_malloc (sexp_format_n);
-  if (! sexp_format)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  /* Construct the format string.  */
-
-  *sexp_format = 0;
-  strcat (sexp_format, "(");
-  strcat (sexp_format, identifier);
-  if (include_flags)
-    {
-      strcat (sexp_format, "(flags");
-      for (i = 0; i < DIM (ac_flags); i++)
-       if (flags & ac_flags[i].number)
-         {
-           strcat (sexp_format, " ");
-           strcat (sexp_format, ac_flags[i].string);
-         }
-      strcat (sexp_format, ")");
-    }
-  if (algorithm)
-    {
-      strcat (sexp_format, "(");
-      strcat (sexp_format, algorithm);
-    }
-  for (i = 0; i < data_length; i++)
-    strcat (sexp_format, "(%s%m)");
-  if (algorithm)
-    strcat (sexp_format, ")");
-  strcat (sexp_format, ")");
-
-  /* Create final S-expression.  */
-  err = gcry_sexp_build_array (&sexp_new, NULL, sexp_format, arg_list);
-  if (err)
-    goto out;
-
-  *sexp = sexp_new;
-
- out:
-
-  /* Deallocate resources.  */
-  gcry_free (sexp_format);
-  gcry_free (arg_list);
-  if (err)
-    gcry_sexp_release (sexp_new);
-
-  return err;
-}
-
-\f
-
-/*
- * Handle management.
- */
-
-/* Creates a new handle for the algorithm ALGORITHM and stores it in
-   HANDLE.  FLAGS is not used yet.  */
-gcry_error_t
-_gcry_ac_open (gcry_ac_handle_t *handle,
-              gcry_ac_id_t algorithm, unsigned int flags)
-{
-  gcry_ac_handle_t handle_new;
-  const char *algorithm_name;
-  gcry_module_t module;
-  gcry_error_t err;
-
-  *handle = NULL;
-  module = NULL;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  /* Get name.  */
-  algorithm_name = _gcry_pk_aliased_algo_name (algorithm);
-  if (! algorithm_name)
-    {
-      err = gcry_error (GPG_ERR_PUBKEY_ALGO);
-      goto out;
-    }
-
-  /* Acquire reference to the pubkey module.  */
-  err = _gcry_pk_module_lookup (algorithm, &module);
-  if (err)
-    goto out;
-
-  /* Allocate.  */
-  handle_new = gcry_malloc (sizeof (*handle_new));
-  if (! handle_new)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  /* Done.  */
-  handle_new->algorithm = algorithm;
-  handle_new->algorithm_name = algorithm_name;
-  handle_new->flags = flags;
-  handle_new->module = module;
-  *handle = handle_new;
-
- out:
-
-  /* Deallocate resources.  */
-  if (err)
-    _gcry_pk_module_release (module);
-
-  return err;
-}
-
-
-/* Destroys the handle HANDLE.  */
-void
-_gcry_ac_close (gcry_ac_handle_t handle)
-{
-  /* Release reference to pubkey module.  */
-  if (handle)
-    {
-      _gcry_pk_module_release (handle->module);
-      gcry_free (handle);
-    }
-}
-
-
-\f
-/*
- * Key management.
- */
-
-/* Initialize a key from a given data set.  */
-/* FIXME/Damn: the argument HANDLE is not only unnecessary, it is
-   completely WRONG here.  */
-gcry_error_t
-_gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
-                  gcry_ac_key_type_t type, gcry_ac_data_t data)
-{
-  gcry_ac_data_t data_new;
-  gcry_ac_key_t key_new;
-  gcry_error_t err;
-
-  (void)handle;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  /* Allocate.  */
-  key_new = gcry_malloc (sizeof (*key_new));
-  if (! key_new)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  /* Copy data set.  */
-  err = _gcry_ac_data_copy (&data_new, data);
-  if (err)
-    goto out;
-
-  /* Done.  */
-  key_new->data = data_new;
-  key_new->type = type;
-  *key = key_new;
-
- out:
-
-  if (err)
-    /* Deallocate resources.  */
-    gcry_free (key_new);
-
-  return err;
-}
-
-
-/* Generates a new key pair via the handle HANDLE of NBITS bits and
-   stores it in KEY_PAIR.  In case non-standard settings are wanted, a
-   pointer to a structure of type gcry_ac_key_spec_<algorithm>_t,
-   matching the selected algorithm, can be given as KEY_SPEC.
-   MISC_DATA is not used yet.  */
-gcry_error_t
-_gcry_ac_key_pair_generate (gcry_ac_handle_t handle, unsigned int nbits,
-                           void *key_spec,
-                           gcry_ac_key_pair_t *key_pair,
-                           gcry_mpi_t **misc_data)
-{
-  gcry_sexp_t genkey_sexp_request;
-  gcry_sexp_t genkey_sexp_reply;
-  gcry_ac_data_t key_data_secret;
-  gcry_ac_data_t key_data_public;
-  gcry_ac_key_pair_t key_pair_new;
-  gcry_ac_key_t key_secret;
-  gcry_ac_key_t key_public;
-  gcry_sexp_t key_sexp;
-  gcry_error_t err;
-  char *genkey_format;
-  size_t genkey_format_n;
-  void **arg_list;
-  size_t arg_list_n;
-  unsigned int i;
-  unsigned int j;
-
-  (void)misc_data;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  key_data_secret = NULL;
-  key_data_public = NULL;
-  key_secret = NULL;
-  key_public = NULL;
-  genkey_format = NULL;
-  arg_list = NULL;
-  genkey_sexp_request = NULL;
-  genkey_sexp_reply = NULL;
-  key_sexp = NULL;
-
-  /* Allocate key pair.  */
-  key_pair_new = gcry_malloc (sizeof (struct gcry_ac_key_pair));
-  if (! key_pair_new)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  /* Allocate keys.  */
-  key_secret = gcry_malloc (sizeof (*key_secret));
-  if (! key_secret)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-  key_public = gcry_malloc (sizeof (*key_public));
-  if (! key_public)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  /* Calculate size of the format string, that is used for creating
-     the request S-expression.  */
-  genkey_format_n = 22;
-
-  /* Respect any relevant algorithm specific commands.  */
-  if (key_spec)
-    for (i = 0; i < DIM (ac_key_generate_specs); i++)
-      if (handle->algorithm == ac_key_generate_specs[i].algorithm)
-       genkey_format_n += 6;
-
-  /* Create format string.  */
-  genkey_format = gcry_malloc (genkey_format_n);
-  if (! genkey_format)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  /* Fill format string.  */
-  *genkey_format = 0;
-  strcat (genkey_format, "(genkey(%s(nbits%d)");
-  if (key_spec)
-    for (i = 0; i < DIM (ac_key_generate_specs); i++)
-      if (handle->algorithm == ac_key_generate_specs[i].algorithm)
-       strcat (genkey_format, "(%s%m)");
-  strcat (genkey_format, "))");
-
-  /* Build list of argument pointers, the algorithm name and the nbits
-     are always needed.  */
-  arg_list_n = 2;
-
-  /* Now the algorithm specific arguments.  */
-  if (key_spec)
-    for (i = 0; i < DIM (ac_key_generate_specs); i++)
-      if (handle->algorithm == ac_key_generate_specs[i].algorithm)
-       arg_list_n += 2;
-
-  /* Allocate list.  */
-  arg_list = gcry_malloc (sizeof (*arg_list) * arg_list_n);
-  if (! arg_list)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  arg_list[0] = (void *) &handle->algorithm_name;
-  arg_list[1] = (void *) &nbits;
-  if (key_spec)
-    for (j = 2, i = 0; i < DIM (ac_key_generate_specs); i++)
-      if (handle->algorithm == ac_key_generate_specs[i].algorithm)
-       {
-         /* Add name of this specification flag and the
-            according member of the spec strucuture.  */
-         arg_list[j++] = (void *)(&ac_key_generate_specs[i].name);
-         arg_list[j++] = (void *)
-           (((char *) key_spec)
-            + ac_key_generate_specs[i].offset);
-         /* FIXME: above seems to suck.  */
-       }
-
-  /* Construct final request S-expression.  */
-  err = gcry_sexp_build_array (&genkey_sexp_request,
-                              NULL, genkey_format, arg_list);
-  if (err)
-    goto out;
-
-  /* Perform genkey operation.  */
-  err = gcry_pk_genkey (&genkey_sexp_reply, genkey_sexp_request);
-  if (err)
-    goto out;
-
-  key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "private-key", 0);
-  if (! key_sexp)
-    {
-      err = gcry_error (GPG_ERR_INTERNAL);
-      goto out;
-    }
-  err = ac_data_extract ("private-key", handle->algorithm_name,
-                        key_sexp, &key_data_secret);
-  if (err)
-    goto out;
-
-  gcry_sexp_release (key_sexp);
-  key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "public-key", 0);
-  if (! key_sexp)
-    {
-      err = gcry_error (GPG_ERR_INTERNAL);
-      goto out;
-    }
-  err = ac_data_extract ("public-key", handle->algorithm_name,
-                        key_sexp, &key_data_public);
-  if (err)
-    goto out;
-
-  /* Done.  */
-
-  key_secret->type = GCRY_AC_KEY_SECRET;
-  key_secret->data = key_data_secret;
-  key_public->type = GCRY_AC_KEY_PUBLIC;
-  key_public->data = key_data_public;
-  key_pair_new->secret = key_secret;
-  key_pair_new->public = key_public;
-  *key_pair = key_pair_new;
-
- out:
-
-  /* Deallocate resources.  */
-
-  gcry_free (genkey_format);
-  gcry_free (arg_list);
-  gcry_sexp_release (genkey_sexp_request);
-  gcry_sexp_release (genkey_sexp_reply);
-  gcry_sexp_release (key_sexp);
-  if (err)
-    {
-      _gcry_ac_data_destroy (key_data_secret);
-      _gcry_ac_data_destroy (key_data_public);
-      gcry_free (key_secret);
-      gcry_free (key_public);
-      gcry_free (key_pair_new);
-    }
-
-  return err;
-}
-
-/* Returns the key of type WHICH out of the key pair KEY_PAIR.  */
-gcry_ac_key_t
-_gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair,
-                           gcry_ac_key_type_t which)
-{
-  gcry_ac_key_t key;
-
-  if (fips_mode ())
-    return NULL;
-
-  switch (which)
-    {
-    case GCRY_AC_KEY_SECRET:
-      key = key_pair->secret;
-      break;
-
-    case GCRY_AC_KEY_PUBLIC:
-      key = key_pair->public;
-      break;
-
-    default:
-      key = NULL;
-      break;
-    }
-
-  return key;
-}
-
-/* Destroys the key KEY.  */
-void
-_gcry_ac_key_destroy (gcry_ac_key_t key)
-{
-  unsigned int i;
-
-  if (key)
-    {
-      if (key->data)
-        {
-          for (i = 0; i < key->data->data_n; i++)
-            {
-              if (key->data->data[i].mpi)
-                gcry_mpi_release (key->data->data[i].mpi);
-              if (key->data->data[i].name)
-                gcry_free (key->data->data[i].name);
-            }
-          gcry_free (key->data->data);
-          gcry_free (key->data);
-        }
-      gcry_free (key);
-    }
-}
-
-/* Destroys the key pair KEY_PAIR.  */
-void
-_gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
-{
-  if (key_pair)
-    {
-      gcry_ac_key_destroy (key_pair->secret);
-      gcry_ac_key_destroy (key_pair->public);
-      gcry_free (key_pair);
-    }
-}
-
-/* Returns the data set contained in the key KEY.  */
-gcry_ac_data_t
-_gcry_ac_key_data_get (gcry_ac_key_t key)
-{
-  if (fips_mode ())
-    return NULL;
-  return key->data;
-}
-
-/* Verifies that the key KEY is sane via HANDLE.  */
-gcry_error_t
-_gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
-{
-  gcry_sexp_t key_sexp;
-  gcry_error_t err;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  key_sexp = NULL;
-  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
-                          handle->algorithm_name, key->data, &key_sexp);
-  if (err)
-    goto out;
-
-  err = gcry_pk_testkey (key_sexp);
-
- out:
-
-  gcry_sexp_release (key_sexp);
-
-  return gcry_error (err);
-}
-
-/* Stores the number of bits of the key KEY in NBITS via HANDLE.  */
-gcry_error_t
-_gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
-                       gcry_ac_key_t key, unsigned int *nbits)
-{
-  gcry_sexp_t key_sexp;
-  gcry_error_t err;
-  unsigned int n;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  key_sexp = NULL;
-
-  err = ac_data_construct (ac_key_identifiers[key->type],
-                          0, 0, handle->algorithm_name, key->data, &key_sexp);
-  if (err)
-    goto out;
-
-  n = gcry_pk_get_nbits (key_sexp);
-  if (! n)
-    {
-      err = gcry_error (GPG_ERR_PUBKEY_ALGO);
-      goto out;
-    }
-
-  *nbits = n;
-
- out:
-
-  gcry_sexp_release (key_sexp);
-
-  return err;
-}
-
-/* Writes the 20 byte long key grip of the key KEY to KEY_GRIP via
-   HANDLE.  */
-gcry_error_t
-_gcry_ac_key_get_grip (gcry_ac_handle_t handle,
-                      gcry_ac_key_t key, unsigned char *key_grip)
-{
-  gcry_sexp_t key_sexp;
-  gcry_error_t err;
-  unsigned char *ret;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  key_sexp = NULL;
-  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
-                          handle->algorithm_name, key->data, &key_sexp);
-  if (err)
-    goto out;
-
-  ret = gcry_pk_get_keygrip (key_sexp, key_grip);
-  if (! ret)
-    {
-      err = gcry_error (GPG_ERR_INV_OBJ);
-      goto out;
-    }
-
-  err = 0;
-
- out:
-
-  gcry_sexp_release (key_sexp);
-
-  return err;
-}
-
-
-\f
-
-/*
- * Functions performing cryptographic operations.
- */
-
-/* Encrypts the plain text MPI value DATA_PLAIN with the key public
-   KEY under the control of the flags FLAGS and stores the resulting
-   data set into DATA_ENCRYPTED.  */
-gcry_error_t
-_gcry_ac_data_encrypt (gcry_ac_handle_t handle,
-                      unsigned int flags,
-                      gcry_ac_key_t key,
-                      gcry_mpi_t data_plain,
-                      gcry_ac_data_t *data_encrypted)
-{
-  gcry_ac_data_t data_encrypted_new;
-  gcry_ac_data_t data_value;
-  gcry_sexp_t sexp_request;
-  gcry_sexp_t sexp_reply;
-  gcry_sexp_t sexp_key;
-  gcry_error_t err;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  data_encrypted_new = NULL;
-  sexp_request = NULL;
-  sexp_reply = NULL;
-  data_value = NULL;
-  sexp_key = NULL;
-
-  if (key->type != GCRY_AC_KEY_PUBLIC)
-    {
-      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
-      goto out;
-    }
-
-  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
-                          handle->algorithm_name, key->data, &sexp_key);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_data_new (&data_value);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_data_set (data_value, 0, "value", data_plain);
-  if (err)
-    goto out;
-
-  err = ac_data_construct ("data", 1, flags, handle->algorithm_name,
-                          data_value, &sexp_request);
-  if (err)
-    goto out;
-
-  /* FIXME: error vs. errcode? */
-
-  err = gcry_pk_encrypt (&sexp_reply, sexp_request, sexp_key);
-  if (err)
-    goto out;
-
-  /* Extract data.  */
-  err = ac_data_extract ("enc-val", handle->algorithm_name,
-                        sexp_reply, &data_encrypted_new);
-  if (err)
-    goto out;
-
-  *data_encrypted = data_encrypted_new;
-
- out:
-
-  /* Deallocate resources.  */
-
-  gcry_sexp_release (sexp_request);
-  gcry_sexp_release (sexp_reply);
-  gcry_sexp_release (sexp_key);
-  _gcry_ac_data_destroy (data_value);
-
-  return err;
-}
-
-/* Decrypts the encrypted data contained in the data set
-   DATA_ENCRYPTED with the secret key KEY under the control of the
-   flags FLAGS and stores the resulting plain text MPI value in
-   DATA_PLAIN.  */
-gcry_error_t
-_gcry_ac_data_decrypt (gcry_ac_handle_t handle,
-                      unsigned int flags,
-                      gcry_ac_key_t key,
-                      gcry_mpi_t *data_plain,
-                      gcry_ac_data_t data_encrypted)
-{
-  gcry_mpi_t data_decrypted;
-  gcry_sexp_t sexp_request;
-  gcry_sexp_t sexp_reply;
-  gcry_sexp_t sexp_value;
-  gcry_sexp_t sexp_key;
-  gcry_error_t err;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  sexp_request = NULL;
-  sexp_reply = NULL;
-  sexp_value = NULL;
-  sexp_key = NULL;
-
-  if (key->type != GCRY_AC_KEY_SECRET)
-    {
-      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
-      goto out;
-    }
-
-  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
-                          handle->algorithm_name, key->data, &sexp_key);
-  if (err)
-    goto out;
-
-  /* Create S-expression from data.  */
-  err = ac_data_construct ("enc-val", 1, flags, handle->algorithm_name,
-                          data_encrypted, &sexp_request);
-  if (err)
-    goto out;
-
-  /* Decrypt.  */
-  err = gcry_pk_decrypt (&sexp_reply, sexp_request, sexp_key);
-  if (err)
-    goto out;
-
-  /* Extract plain text. */
-  sexp_value = gcry_sexp_find_token (sexp_reply, "value", 0);
-  if (! sexp_value)
-    {
-      /* FIXME?  */
-      err = gcry_error (GPG_ERR_GENERAL);
-      goto out;
-    }
-
-  data_decrypted = gcry_sexp_nth_mpi (sexp_value, 1, GCRYMPI_FMT_USG);
-  if (! data_decrypted)
-    {
-      err = gcry_error (GPG_ERR_GENERAL);
-      goto out;
-    }
-
-  *data_plain = data_decrypted;
-
- out:
-
-  /* Deallocate resources.  */
-  gcry_sexp_release (sexp_request);
-  gcry_sexp_release (sexp_reply);
-  gcry_sexp_release (sexp_value);
-  gcry_sexp_release (sexp_key);
-
-  return gcry_error (err);
-
-}
-
-/* Signs the data contained in DATA with the secret key KEY and stores
-   the resulting signature data set in DATA_SIGNATURE.  */
-gcry_error_t
-_gcry_ac_data_sign (gcry_ac_handle_t handle,
-                   gcry_ac_key_t key,
-                   gcry_mpi_t data,
-                   gcry_ac_data_t *data_signature)
-{
-  gcry_ac_data_t data_signed;
-  gcry_ac_data_t data_value;
-  gcry_sexp_t sexp_request;
-  gcry_sexp_t sexp_reply;
-  gcry_sexp_t sexp_key;
-  gcry_error_t err;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  data_signed = NULL;
-  data_value = NULL;
-  sexp_request = NULL;
-  sexp_reply = NULL;
-  sexp_key = NULL;
-
-  if (key->type != GCRY_AC_KEY_SECRET)
-    {
-      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
-      goto out;
-    }
-
-  err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
-                          handle->algorithm_name, key->data, &sexp_key);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_data_new (&data_value);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_data_set (data_value, 0, "value", data);
-  if (err)
-    goto out;
-
-  /* Create S-expression holding the data.  */
-  err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_request);
-  if (err)
-    goto out;
-
-  /* Sign.  */
-  err = gcry_pk_sign (&sexp_reply, sexp_request, sexp_key);
-  if (err)
-    goto out;
-
-  /* Extract data.  */
-  err = ac_data_extract ("sig-val", handle->algorithm_name,
-                        sexp_reply, &data_signed);
-  if (err)
-    goto out;
-
-  /* Done.  */
-  *data_signature = data_signed;
-
- out:
-
-  gcry_sexp_release (sexp_request);
-  gcry_sexp_release (sexp_reply);
-  gcry_sexp_release (sexp_key);
-  _gcry_ac_data_destroy (data_value);
-
-  return gcry_error (err);
-}
-
-
-/* Verifies that the signature contained in the data set
-   DATA_SIGNATURE is indeed the result of signing the data contained
-   in DATA with the secret key belonging to the public key KEY.  */
-gcry_error_t
-_gcry_ac_data_verify (gcry_ac_handle_t handle,
-                     gcry_ac_key_t key,
-                     gcry_mpi_t data,
-                     gcry_ac_data_t data_signature)
-{
-  gcry_sexp_t sexp_signature;
-  gcry_ac_data_t data_value;
-  gcry_sexp_t sexp_data;
-  gcry_sexp_t sexp_key;
-  gcry_error_t err;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  sexp_signature = NULL;
-  data_value = NULL;
-  sexp_data = NULL;
-  sexp_key = NULL;
-
-  err = ac_data_construct ("public-key", 0, 0,
-                          handle->algorithm_name, key->data, &sexp_key);
-  if (err)
-    goto out;
-
-  if (key->type != GCRY_AC_KEY_PUBLIC)
-    {
-      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
-      goto out;
-    }
-
-  /* Construct S-expression holding the signature data.  */
-  err = ac_data_construct ("sig-val", 1, 0, handle->algorithm_name,
-                          data_signature, &sexp_signature);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_data_new (&data_value);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_data_set (data_value, 0, "value", data);
-  if (err)
-    goto out;
-
-  /* Construct S-expression holding the data.  */
-  err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_data);
-  if (err)
-    goto out;
-
-  /* Verify signature.  */
-  err = gcry_pk_verify (sexp_signature, sexp_data, sexp_key);
-
- out:
-
-  gcry_sexp_release (sexp_signature);
-  gcry_sexp_release (sexp_data);
-  gcry_sexp_release (sexp_key);
-  _gcry_ac_data_destroy (data_value);
-
-  return gcry_error (err);
-}
-
-
-
-\f
-/*
- * Implementation of encoding methods (em).
- */
-
-/* Type for functions that encode or decode (hence the name) a
-   message.  */
-typedef gcry_error_t (*gcry_ac_em_dencode_t) (unsigned int flags,
-                                                void *options,
-                                                gcry_ac_io_t *ac_io_read,
-                                                gcry_ac_io_t *ac_io_write);
-
-/* Fill the buffer BUFFER which is BUFFER_N bytes long with non-zero
-   random bytes of random level LEVEL.  */
-static void
-em_randomize_nonzero (unsigned char *buffer, size_t buffer_n,
-                     gcry_random_level_t level)
-{
-  unsigned char *buffer_rand;
-  unsigned int buffer_rand_n;
-  unsigned int zeros;
-  unsigned int i;
-  unsigned int j;
-
-  for (i = 0; i < buffer_n; i++)
-    buffer[i] = 0;
-
-  do
-    {
-      /* Count zeros.  */
-      for (i = zeros = 0; i < buffer_n; i++)
-       if (! buffer[i])
-         zeros++;
-
-      if (zeros)
-       {
-         /* Get random bytes.  */
-         buffer_rand_n = zeros + (zeros / 128);
-         buffer_rand = gcry_random_bytes_secure (buffer_rand_n, level);
-
-         /* Substitute zeros with non-zero random bytes.  */
-         for (i = j = 0; zeros && (i < buffer_n) && (j < buffer_rand_n); i++)
-           if (! buffer[i])
-             {
-               while ((j < buffer_rand_n) && (! buffer_rand[j]))
-                 j++;
-               if (j < buffer_rand_n)
-                 {
-                   buffer[i] = buffer_rand[j++];
-                   zeros--;
-                 }
-               else
-                 break;
-             }
-         gcry_free (buffer_rand);
-       }
-    }
-  while (zeros);
-}
-
-/* Encode a message according to the Encoding Method for Encryption
-   `PKCS-V1_5' (EME-PKCS-V1_5).  */
-static gcry_error_t
-eme_pkcs_v1_5_encode (unsigned int flags, void *opts,
-                     gcry_ac_io_t *ac_io_read,
-                     gcry_ac_io_t *ac_io_write)
-{
-  gcry_ac_eme_pkcs_v1_5_t *options;
-  gcry_error_t err;
-  unsigned char *buffer;
-  unsigned char *ps;
-  unsigned char *m;
-  size_t m_n;
-  unsigned int ps_n;
-  unsigned int k;
-
-  (void)flags;
-
-  options = opts;
-  buffer = NULL;
-  m = NULL;
-
-  err = _gcry_ac_io_read_all (ac_io_read, &m, &m_n);
-  if (err)
-    goto out;
-
-  /* Figure out key length in bytes.  */
-  k = options->key_size / 8;
-
-  if (m_n > k - 11)
-    {
-      /* Key is too short for message.  */
-      err = gcry_error (GPG_ERR_TOO_SHORT);
-      goto out;
-    }
-
-  /* According to this encoding method, the first byte of the encoded
-     message is zero.  This byte will be lost anyway, when the encoded
-     message is to be converted into an MPI, that's why we skip
-     it.  */
-
-  /* Allocate buffer.  */
-  buffer = gcry_malloc (k - 1);
-  if (! buffer)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  /* Generate an octet string PS of length k - mLen - 3 consisting
-     of pseudorandomly generated nonzero octets.  The length of PS
-     will be at least eight octets.  */
-  ps_n = k - m_n - 3;
-  ps = buffer + 1;
-  em_randomize_nonzero (ps, ps_n, GCRY_STRONG_RANDOM);
-
-  /* Concatenate PS, the message M, and other padding to form an
-     encoded message EM of length k octets as:
-
-     EM = 0x00 || 0x02 || PS || 0x00 || M.  */
-
-  buffer[0] = 0x02;
-  buffer[ps_n + 1] = 0x00;
-  memcpy (buffer + ps_n + 2, m, m_n);
-
-  err = _gcry_ac_io_write (ac_io_write, buffer, k - 1);
-
- out:
-
-  gcry_free (buffer);
-  gcry_free (m);
-
-  return err;
-}
-
-/* Decode a message according to the Encoding Method for Encryption
-   `PKCS-V1_5' (EME-PKCS-V1_5).  */
-static gcry_error_t
-eme_pkcs_v1_5_decode (unsigned int flags, void *opts,
-                     gcry_ac_io_t *ac_io_read,
-                     gcry_ac_io_t *ac_io_write)
-{
-  gcry_ac_eme_pkcs_v1_5_t *options;
-  unsigned char *buffer;
-  unsigned char *em;
-  size_t em_n;
-  gcry_error_t err;
-  unsigned int i;
-  unsigned int k;
-
-  (void)flags;
-
-  options = opts;
-  buffer = NULL;
-  em = NULL;
-
-  err = _gcry_ac_io_read_all (ac_io_read, &em, &em_n);
-  if (err)
-    goto out;
-
-  /* Figure out key size.  */
-  k = options->key_size / 8;
-
-  /* Search for zero byte.  */
-  for (i = 0; (i < em_n) && em[i]; i++);
-
-  /* According to this encoding method, the first byte of the encoded
-     message should be zero.  This byte is lost.  */
-
-  if (! ((em_n >= 10)
-        && (em_n == (k - 1))
-        && (em[0] == 0x02)
-        && (i < em_n)
-        && ((i - 1) >= 8)))
-    {
-      err = gcry_error (GPG_ERR_DECRYPT_FAILED);
-      goto out;
-    }
-
-  i++;
-  buffer = gcry_malloc (em_n - i);
-  if (! buffer)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  memcpy (buffer, em + i, em_n - i);
-  err = _gcry_ac_io_write (ac_io_write, buffer, em_n - i);
-
- out:
-
-  gcry_free (buffer);
-  gcry_free (em);
-
-  return err;
-}
-
-static gcry_error_t
-emsa_pkcs_v1_5_encode_data_cb (void *opaque,
-                              unsigned char *buffer, size_t buffer_n)
-{
-  gcry_md_hd_t md_handle;
-
-  md_handle = opaque;
-  gcry_md_write (md_handle, buffer, buffer_n);
-
-  return 0;
-}
-
-
-/* Encode a message according to the Encoding Method for Signatures
-   with Appendix `PKCS-V1_5' (EMSA-PKCS-V1_5).  */
-static gcry_error_t
-emsa_pkcs_v1_5_encode (unsigned int flags, void *opts,
-                      gcry_ac_io_t *ac_io_read,
-                      gcry_ac_io_t *ac_io_write)
-{
-  gcry_ac_emsa_pkcs_v1_5_t *options;
-  gcry_error_t err;
-  gcry_md_hd_t md;
-  unsigned char *t;
-  size_t t_n;
-  unsigned char *h;
-  size_t h_n;
-  unsigned char *ps;
-  size_t ps_n;
-  unsigned char *buffer;
-  size_t buffer_n;
-  unsigned char asn[100];      /* FIXME, always enough?  */
-  size_t asn_n;
-  unsigned int i;
-
-  (void)flags;
-
-  options = opts;
-  buffer = NULL;
-  md = NULL;
-  ps = NULL;
-  t = NULL;
-
-  /* Create hashing handle and get the necessary information.  */
-  err = gcry_md_open (&md, options->md, 0);
-  if (err)
-    goto out;
-
-  asn_n = DIM (asn);
-  err = gcry_md_algo_info (options->md, GCRYCTL_GET_ASNOID, asn, &asn_n);
-  if (err)
-    goto out;
-
-  h_n = gcry_md_get_algo_dlen (options->md);
-
-  err = _gcry_ac_io_process (ac_io_read, emsa_pkcs_v1_5_encode_data_cb, md);
-  if (err)
-    goto out;
-
-  h = gcry_md_read (md, 0);
-
-  /* Encode the algorithm ID for the hash function and the hash value
-     into an ASN.1 value of type DigestInfo with the Distinguished
-     Encoding Rules (DER), where the type DigestInfo has the syntax:
-
-     DigestInfo ::== SEQUENCE {
-     digestAlgorithm AlgorithmIdentifier,
-     digest OCTET STRING
-     }
-
-     The first field identifies the hash function and the second
-     contains the hash value.  Let T be the DER encoding of the
-     DigestInfo value and let tLen be the length in octets of T.  */
-
-  t_n = asn_n + h_n;
-  t = gcry_malloc (t_n);
-  if (! t)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  for (i = 0; i < asn_n; i++)
-    t[i] = asn[i];
-  for (i = 0; i < h_n; i++)
-    t[asn_n + i] = h[i];
-
-  /* If emLen < tLen + 11, output "intended encoded message length
-     too short" and stop.  */
-  if (options->em_n < t_n + 11)
-    {
-      err = gcry_error (GPG_ERR_TOO_SHORT);
-      goto out;
-    }
-
-  /* Generate an octet string PS consisting of emLen - tLen - 3 octets
-     with hexadecimal value 0xFF.  The length of PS will be at least 8
-     octets.  */
-  ps_n = options->em_n - t_n - 3;
-  ps = gcry_malloc (ps_n);
-  if (! ps)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-  for (i = 0; i < ps_n; i++)
-    ps[i] = 0xFF;
-
-  /* Concatenate PS, the DER encoding T, and other padding to form the
-     encoded message EM as:
-
-     EM = 0x00 || 0x01 || PS || 0x00 || T.  */
-
-  buffer_n = ps_n + t_n + 3;
-  buffer = gcry_malloc (buffer_n);
-  if (! buffer)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  buffer[0] = 0x00;
-  buffer[1] = 0x01;
-  for (i = 0; i < ps_n; i++)
-    buffer[2 + i] = ps[i];
-  buffer[2 + ps_n] = 0x00;
-  for (i = 0; i < t_n; i++)
-    buffer[3 + ps_n + i] = t[i];
-
-  err = _gcry_ac_io_write (ac_io_write, buffer, buffer_n);
-
- out:
-
-  gcry_md_close (md);
-
-  gcry_free (buffer);
-  gcry_free (ps);
-  gcry_free (t);
-
-  return err;
-}
-
-/* `Actions' for data_dencode().  */
-typedef enum dencode_action
-  {
-    DATA_ENCODE,
-    DATA_DECODE,
-  }
-dencode_action_t;
-
-/* Encode or decode a message according to the the encoding method
-   METHOD; ACTION specifies whether the message that is contained in
-   BUFFER_IN and of length BUFFER_IN_N should be encoded or decoded.
-   The resulting message will be stored in a newly allocated buffer in
-   BUFFER_OUT and BUFFER_OUT_N.  */
-static gcry_error_t
-ac_data_dencode (gcry_ac_em_t method, dencode_action_t action,
-                unsigned int flags, void *options,
-                gcry_ac_io_t *ac_io_read,
-                gcry_ac_io_t *ac_io_write)
-{
-  struct
-  {
-    gcry_ac_em_t method;
-    gcry_ac_em_dencode_t encode;
-    gcry_ac_em_dencode_t decode;
-  } methods[] =
-    {
-      { GCRY_AC_EME_PKCS_V1_5,
-       eme_pkcs_v1_5_encode, eme_pkcs_v1_5_decode },
-      { GCRY_AC_EMSA_PKCS_V1_5,
-       emsa_pkcs_v1_5_encode, NULL },
-    };
-  size_t methods_n;
-  gcry_error_t err;
-  unsigned int i;
-
-  methods_n = sizeof (methods) / sizeof (*methods);
-
-  for (i = 0; i < methods_n; i++)
-    if (methods[i].method == method)
-      break;
-  if (i == methods_n)
-    {
-      err = gcry_error (GPG_ERR_NOT_FOUND);    /* FIXME? */
-      goto out;
-    }
-
-  err = 0;
-  switch (action)
-    {
-    case DATA_ENCODE:
-      if (methods[i].encode)
-       /* FIXME? */
-       err = (*methods[i].encode) (flags, options, ac_io_read, ac_io_write);
-      break;
-
-    case DATA_DECODE:
-      if (methods[i].decode)
-       /* FIXME? */
-       err = (*methods[i].decode) (flags, options, ac_io_read, ac_io_write);
-      break;
-
-    default:
-      err = gcry_error (GPG_ERR_INV_ARG);
-      break;
-    }
-
- out:
-
-  return err;
-}
-
-/* Encode a message according to the encoding method METHOD.  OPTIONS
-   must be a pointer to a method-specific structure
-   (gcry_ac_em*_t).  */
-gcry_error_t
-_gcry_ac_data_encode (gcry_ac_em_t method,
-                     unsigned int flags, void *options,
-                     gcry_ac_io_t *ac_io_read,
-                     gcry_ac_io_t *ac_io_write)
-{
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  return ac_data_dencode (method, DATA_ENCODE, flags, options,
-                         ac_io_read, ac_io_write);
-}
-
-/* Dencode a message according to the encoding method METHOD.  OPTIONS
-   must be a pointer to a method-specific structure
-   (gcry_ac_em*_t).  */
-gcry_error_t
-_gcry_ac_data_decode (gcry_ac_em_t method,
-                     unsigned int flags, void *options,
-                     gcry_ac_io_t *ac_io_read,
-                     gcry_ac_io_t *ac_io_write)
-{
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  return ac_data_dencode (method, DATA_DECODE, flags, options,
-                         ac_io_read, ac_io_write);
-}
-
-/* Convert an MPI into an octet string.  */
-void
-_gcry_ac_mpi_to_os (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
-{
-  unsigned long digit;
-  gcry_mpi_t base;
-  unsigned int i;
-  unsigned int n;
-  gcry_mpi_t m;
-  gcry_mpi_t d;
-
-  if (fips_mode ())
-    return;
-
-  base = gcry_mpi_new (0);
-  gcry_mpi_set_ui (base, 256);
-
-  n = 0;
-  m = gcry_mpi_copy (mpi);
-  while (gcry_mpi_cmp_ui (m, 0))
-    {
-      n++;
-      gcry_mpi_div (m, NULL, m, base, 0);
-    }
-
-  gcry_mpi_set (m, mpi);
-  d = gcry_mpi_new (0);
-  for (i = 0; (i < n) && (i < os_n); i++)
-    {
-      gcry_mpi_mod (d, m, base);
-      _gcry_mpi_get_ui (d, &digit);
-      gcry_mpi_div (m, NULL, m, base, 0);
-      os[os_n - i - 1] = (digit & 0xFF);
-    }
-
-  for (; i < os_n; i++)
-    os[os_n - i - 1] = 0;
-
-  gcry_mpi_release (base);
-  gcry_mpi_release (d);
-  gcry_mpi_release (m);
-}
-
-/* Convert an MPI into an newly allocated octet string.  */
-gcry_error_t
-_gcry_ac_mpi_to_os_alloc (gcry_mpi_t mpi, unsigned char **os, size_t *os_n)
-{
-  unsigned char *buffer;
-  size_t buffer_n;
-  gcry_error_t err;
-  unsigned int nbits;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  nbits = gcry_mpi_get_nbits (mpi);
-  buffer_n = (nbits + 7) / 8;
-  buffer = gcry_malloc (buffer_n);
-  if (! buffer)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  _gcry_ac_mpi_to_os (mpi, buffer, buffer_n);
-  *os = buffer;
-  *os_n = buffer_n;
-  err = 0;
-
- out:
-
-  return err;
-}
-
-
-/* Convert an octet string into an MPI.  */
-void
-_gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
-{
-  unsigned int i;
-  gcry_mpi_t xi;
-  gcry_mpi_t x;
-  gcry_mpi_t a;
-
-  if (fips_mode ())
-    return;
-
-  a = gcry_mpi_new (0);
-  gcry_mpi_set_ui (a, 1);
-  x = gcry_mpi_new (0);
-  gcry_mpi_set_ui (x, 0);
-  xi = gcry_mpi_new (0);
-
-  for (i = 0; i < os_n; i++)
-    {
-      gcry_mpi_mul_ui (xi, a, os[os_n - i - 1]);
-      gcry_mpi_add (x, x, xi);
-      gcry_mpi_mul_ui (a, a, 256);
-    }
-
-  gcry_mpi_release (xi);
-  gcry_mpi_release (a);
-
-  gcry_mpi_set (mpi, x);
-  gcry_mpi_release (x);                /* FIXME: correct? */
-}
-
-
-\f
-/*
- * Implementation of Encryption Schemes (ES) and Signature Schemes
- * with Appendix (SSA).
- */
-
-/* Schemes consist of two things: encoding methods and cryptographic
-   primitives.
-
-   Since encoding methods are accessible through a common API with
-   method-specific options passed as an anonymous struct, schemes have
-   to provide functions that construct this method-specific structure;
-   this is what the functions of type `gcry_ac_dencode_prepare_t' are
-   there for.  */
-
-typedef gcry_error_t (*gcry_ac_dencode_prepare_t) (gcry_ac_handle_t handle,
-                                                  gcry_ac_key_t key,
-                                                  void *opts,
-                                                  void *opts_em);
-
-/* The `dencode_prepare' function for ES-PKCS-V1_5.  */
-static gcry_error_t
-ac_es_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key,
-                                void *opts, void *opts_em)
-{
-  gcry_ac_eme_pkcs_v1_5_t *options_em;
-  unsigned int nbits;
-  gcry_error_t err;
-
-  (void)opts;
-
-  err = _gcry_ac_key_get_nbits (handle, key, &nbits);
-  if (err)
-    goto out;
-
-  options_em = opts_em;
-  options_em->key_size = nbits;
-
- out:
-
-  return err;
-}
-
-/* The `dencode_prepare' function for SSA-PKCS-V1_5.  */
-static gcry_error_t
-ac_ssa_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key,
-                                 void *opts, void *opts_em)
-{
-  gcry_ac_emsa_pkcs_v1_5_t *options_em;
-  gcry_ac_ssa_pkcs_v1_5_t *options;
-  gcry_error_t err;
-  unsigned int k;
-
-  options_em = opts_em;
-  options = opts;
-
-  err = _gcry_ac_key_get_nbits (handle, key, &k);
-  if (err)
-    goto out;
-
-  k = (k + 7) / 8;
-  options_em->md = options->md;
-  options_em->em_n = k;
-
- out:
-
-  return err;
-}
-
-/* Type holding the information about each supported
-   Encryption/Signature Scheme.  */
-typedef struct ac_scheme
-{
-  gcry_ac_scheme_t scheme;
-  gcry_ac_em_t scheme_encoding;
-  gcry_ac_dencode_prepare_t dencode_prepare;
-  size_t options_em_n;
-} ac_scheme_t;
-
-/* List of supported Schemes.  */
-static ac_scheme_t ac_schemes[] =
-  {
-    { GCRY_AC_ES_PKCS_V1_5, GCRY_AC_EME_PKCS_V1_5,
-      ac_es_dencode_prepare_pkcs_v1_5,
-      sizeof (gcry_ac_eme_pkcs_v1_5_t) },
-    { GCRY_AC_SSA_PKCS_V1_5, GCRY_AC_EMSA_PKCS_V1_5,
-      ac_ssa_dencode_prepare_pkcs_v1_5,
-      sizeof (gcry_ac_emsa_pkcs_v1_5_t) }
-  };
-
-/* Lookup a scheme by it's ID.  */
-static ac_scheme_t *
-ac_scheme_get (gcry_ac_scheme_t scheme)
-{
-  ac_scheme_t *ac_scheme;
-  unsigned int i;
-
-  for (i = 0; i < DIM (ac_schemes); i++)
-    if (scheme == ac_schemes[i].scheme)
-      break;
-  if (i == DIM (ac_schemes))
-    ac_scheme = NULL;
-  else
-    ac_scheme = ac_schemes + i;
-
-  return ac_scheme;
-}
-
-/* Prepares the encoding/decoding by creating an according option
-   structure.  */
-static gcry_error_t
-ac_dencode_prepare (gcry_ac_handle_t handle, gcry_ac_key_t key, void *opts,
-                   ac_scheme_t scheme, void **opts_em)
-{
-  gcry_error_t err;
-  void *options_em;
-
-  options_em = gcry_malloc (scheme.options_em_n);
-  if (! options_em)
-    {
-      err = gcry_error_from_errno (errno);
-      goto out;
-    }
-
-  err = (*scheme.dencode_prepare) (handle, key, opts, options_em);
-  if (err)
-    goto out;
-
-  *opts_em = options_em;
-
- out:
-
-  if (err)
-    free (options_em);
-
-  return err;
-}
-
-/* Convert a data set into a single MPI; currently, this is only
-   supported for data sets containing a single MPI.  */
-static gcry_error_t
-ac_data_set_to_mpi (gcry_ac_data_t data, gcry_mpi_t *mpi)
-{
-  gcry_error_t err;
-  gcry_mpi_t mpi_new;
-  unsigned int elems;
-
-  elems = _gcry_ac_data_length (data);
-
-  if (elems != 1)
-    {
-      /* FIXME: I guess, we should be more flexible in this respect by
-        allowing the actual encryption/signature schemes to implement
-        this conversion mechanism.  */
-      err = gcry_error (GPG_ERR_CONFLICT);
-      goto out;
-    }
-
-  err = _gcry_ac_data_get_index (data, GCRY_AC_FLAG_COPY, 0, NULL, &mpi_new);
-  if (err)
-    goto out;
-
-  *mpi = mpi_new;
-
- out:
-
-  return err;
-}
-
-/* Encrypts the plain text message contained in M, which is of size
-   M_N, with the public key KEY_PUBLIC according to the Encryption
-   Scheme SCHEME_ID.  HANDLE is used for accessing the low-level
-   cryptographic primitives.  If OPTS is not NULL, it has to be an
-   anonymous structure specific to the chosen scheme (gcry_ac_es_*_t).
-   The encrypted message will be stored in C and C_N.  */
-gcry_error_t
-_gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
-                             gcry_ac_scheme_t scheme_id,
-                             unsigned int flags, void *opts,
-                             gcry_ac_key_t key,
-                             gcry_ac_io_t *io_message,
-                             gcry_ac_io_t *io_cipher)
-{
-  gcry_error_t err;
-  gcry_ac_io_t io_em;
-  unsigned char *em;
-  size_t em_n;
-  gcry_mpi_t mpi_plain;
-  gcry_ac_data_t data_encrypted;
-  gcry_mpi_t mpi_encrypted;
-  unsigned char *buffer;
-  size_t buffer_n;
-  void *opts_em;
-  ac_scheme_t *scheme;
-
-  (void)flags;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  data_encrypted = NULL;
-  mpi_encrypted = NULL;
-  mpi_plain = NULL;
-  opts_em = NULL;
-  buffer = NULL;
-  em = NULL;
-
-  scheme = ac_scheme_get (scheme_id);
-  if (! scheme)
-    {
-      err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME);
-      goto out;
-    }
-
-  if (key->type != GCRY_AC_KEY_PUBLIC)
-    {
-      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
-      goto out;
-    }
-
-  err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
-  if (err)
-    goto out;
-
-  _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
-                   GCRY_AC_IO_STRING, &em, &em_n);
-
-  err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
-                             io_message, &io_em);
-  if (err)
-    goto out;
-
-  mpi_plain = gcry_mpi_snew (0);
-  gcry_ac_os_to_mpi (mpi_plain, em, em_n);
-
-  err = _gcry_ac_data_encrypt (handle, 0, key, mpi_plain, &data_encrypted);
-  if (err)
-    goto out;
-
-  err = ac_data_set_to_mpi (data_encrypted, &mpi_encrypted);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_mpi_to_os_alloc (mpi_encrypted, &buffer, &buffer_n);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_io_write (io_cipher, buffer, buffer_n);
-
- out:
-
-  gcry_ac_data_destroy (data_encrypted);
-  gcry_mpi_release (mpi_encrypted);
-  gcry_mpi_release (mpi_plain);
-  gcry_free (opts_em);
-  gcry_free (buffer);
-  gcry_free (em);
-
-  return err;
-}
-
-/* Decryptes the cipher message contained in C, which is of size C_N,
-   with the secret key KEY_SECRET according to the Encryption Scheme
-   SCHEME_ID.  Handle is used for accessing the low-level
-   cryptographic primitives.  If OPTS is not NULL, it has to be an
-   anonymous structure specific to the chosen scheme (gcry_ac_es_*_t).
-   The decrypted message will be stored in M and M_N.  */
-gcry_error_t
-_gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
-                             gcry_ac_scheme_t scheme_id,
-                             unsigned int flags, void *opts,
-                             gcry_ac_key_t key,
-                             gcry_ac_io_t *io_cipher,
-                             gcry_ac_io_t *io_message)
-{
-  gcry_ac_io_t io_em;
-  gcry_error_t err;
-  gcry_ac_data_t data_encrypted;
-  unsigned char *em;
-  size_t em_n;
-  gcry_mpi_t mpi_encrypted;
-  gcry_mpi_t mpi_decrypted;
-  void *opts_em;
-  ac_scheme_t *scheme;
-  char *elements_enc;
-  size_t elements_enc_n;
-  unsigned char *c;
-  size_t c_n;
-
-  (void)flags;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  data_encrypted = NULL;
-  mpi_encrypted = NULL;
-  mpi_decrypted = NULL;
-  elements_enc = NULL;
-  opts_em = NULL;
-  em = NULL;
-  c = NULL;
-
-  scheme = ac_scheme_get (scheme_id);
-  if (! scheme)
-    {
-      err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME);
-      goto out;
-    }
-
-  if (key->type != GCRY_AC_KEY_SECRET)
-    {
-      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
-      goto out;
-    }
-
-  err = _gcry_ac_io_read_all (io_cipher, &c, &c_n);
-  if (err)
-    goto out;
-
-  mpi_encrypted = gcry_mpi_snew (0);
-  gcry_ac_os_to_mpi (mpi_encrypted, c, c_n);
-
-  err = _gcry_pk_get_elements (handle->algorithm, &elements_enc, NULL);
-  if (err)
-    goto out;
-
-  elements_enc_n = strlen (elements_enc);
-  if (elements_enc_n != 1)
-    {
-      /* FIXME? */
-      err = gcry_error (GPG_ERR_CONFLICT);
-      goto out;
-    }
-
-  err = _gcry_ac_data_new (&data_encrypted);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_data_set (data_encrypted, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
-                          elements_enc, mpi_encrypted);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_data_decrypt (handle, 0, key, &mpi_decrypted, data_encrypted);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_mpi_to_os_alloc (mpi_decrypted, &em, &em_n);
-  if (err)
-    goto out;
-
-  err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
-  if (err)
-    goto out;
-
-  _gcry_ac_io_init (&io_em, GCRY_AC_IO_READABLE,
-                   GCRY_AC_IO_STRING, em, em_n);
-
-  err = _gcry_ac_data_decode (scheme->scheme_encoding, 0, opts_em,
-                             &io_em, io_message);
-  if (err)
-    goto out;
-
- out:
-
-  _gcry_ac_data_destroy (data_encrypted);
-  gcry_mpi_release (mpi_encrypted);
-  gcry_mpi_release (mpi_decrypted);
-  free (elements_enc);
-  gcry_free (opts_em);
-  gcry_free (em);
-  gcry_free (c);
-
-  return err;
-}
-
-
-/* Signs the message contained in M, which is of size M_N, with the
-   secret key KEY according to the Signature Scheme SCHEME_ID.  Handle
-   is used for accessing the low-level cryptographic primitives.  If
-   OPTS is not NULL, it has to be an anonymous structure specific to
-   the chosen scheme (gcry_ac_ssa_*_t).  The signed message will be
-   stored in S and S_N.  */
-gcry_error_t
-_gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
-                          gcry_ac_scheme_t scheme_id,
-                          unsigned int flags, void *opts,
-                          gcry_ac_key_t key,
-                          gcry_ac_io_t *io_message,
-                          gcry_ac_io_t *io_signature)
-{
-  gcry_ac_io_t io_em;
-  gcry_error_t err;
-  gcry_ac_data_t data_signed;
-  unsigned char *em;
-  size_t em_n;
-  gcry_mpi_t mpi;
-  void *opts_em;
-  unsigned char *buffer;
-  size_t buffer_n;
-  gcry_mpi_t mpi_signed;
-  ac_scheme_t *scheme;
-
-  (void)flags;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  data_signed = NULL;
-  mpi_signed = NULL;
-  opts_em = NULL;
-  buffer = NULL;
-  mpi = NULL;
-  em = NULL;
-
-  if (key->type != GCRY_AC_KEY_SECRET)
-    {
-      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
-      goto out;
-    }
-
-  scheme = ac_scheme_get (scheme_id);
-  if (! scheme)
-    {
-      /* FIXME: adjust api of scheme_get in respect to err codes.  */
-      err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME);
-      goto out;
-    }
-
-  err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
-  if (err)
-    goto out;
-
-  _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
-                   GCRY_AC_IO_STRING, &em, &em_n);
-
-  err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
-                             io_message, &io_em);
-  if (err)
-    goto out;
-
-  mpi = gcry_mpi_new (0);
-  _gcry_ac_os_to_mpi (mpi, em, em_n);
-
-  err = _gcry_ac_data_sign (handle, key, mpi, &data_signed);
-  if (err)
-    goto out;
-
-  err = ac_data_set_to_mpi (data_signed, &mpi_signed);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_mpi_to_os_alloc (mpi_signed, &buffer, &buffer_n);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_io_write (io_signature, buffer, buffer_n);
-
- out:
-
-  _gcry_ac_data_destroy (data_signed);
-  gcry_mpi_release (mpi_signed);
-  gcry_mpi_release (mpi);
-  gcry_free (opts_em);
-  gcry_free (buffer);
-  gcry_free (em);
-
-  return err;
-}
-
-/* Verifies that the signature contained in S, which is of length S_N,
-   is indeed the result of signing the message contained in M, which
-   is of size M_N, with the secret key belonging to the public key
-   KEY_PUBLIC.  If OPTS is not NULL, it has to be an anonymous
-   structure (gcry_ac_ssa_*_t) specific to the Signature Scheme, whose
-   ID is contained in SCHEME_ID.  */
-gcry_error_t
-_gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
-                            gcry_ac_scheme_t scheme_id,
-                            unsigned int flags, void *opts,
-                            gcry_ac_key_t key,
-                            gcry_ac_io_t *io_message,
-                            gcry_ac_io_t *io_signature)
-{
-  gcry_ac_io_t io_em;
-  gcry_error_t err;
-  gcry_ac_data_t data_signed;
-  unsigned char *em;
-  size_t em_n;
-  void *opts_em;
-  gcry_mpi_t mpi_signature;
-  gcry_mpi_t mpi_data;
-  ac_scheme_t *scheme;
-  char *elements_sig;
-  size_t elements_sig_n;
-  unsigned char *s;
-  size_t s_n;
-
-  (void)flags;
-
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  mpi_signature = NULL;
-  elements_sig = NULL;
-  data_signed = NULL;
-  mpi_data = NULL;
-  opts_em = NULL;
-  em = NULL;
-  s = NULL;
-
-  if (key->type != GCRY_AC_KEY_PUBLIC)
-    {
-      err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
-      goto out;
-    }
-
-  scheme = ac_scheme_get (scheme_id);
-  if (! scheme)
-    {
-      err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME);
-      goto out;
-    }
-
-  err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
-  if (err)
-    goto out;
-
-  _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
-                   GCRY_AC_IO_STRING, &em, &em_n);
-
-  err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
-                             io_message, &io_em);
-  if (err)
-    goto out;
-
-  mpi_data = gcry_mpi_new (0);
-  _gcry_ac_os_to_mpi (mpi_data, em, em_n);
-
-  err = _gcry_ac_io_read_all (io_signature, &s, &s_n);
-  if (err)
-    goto out;
-
-  mpi_signature = gcry_mpi_new (0);
-  _gcry_ac_os_to_mpi (mpi_signature, s, s_n);
-
-  err = _gcry_pk_get_elements (handle->algorithm, NULL, &elements_sig);
-  if (err)
-    goto out;
-
-  elements_sig_n = strlen (elements_sig);
-  if (elements_sig_n != 1)
-    {
-      /* FIXME? */
-      err = gcry_error (GPG_ERR_CONFLICT);
-      goto out;
-    }
-
-  err = _gcry_ac_data_new (&data_signed);
-  if (err)
-    goto out;
-
-  err = _gcry_ac_data_set (data_signed, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
-                          elements_sig, mpi_signature);
-  if (err)
-    goto out;
-
-  gcry_mpi_release (mpi_signature);
-  mpi_signature = NULL;
-
-  err = _gcry_ac_data_verify (handle, key, mpi_data, data_signed);
-
- out:
-
-  _gcry_ac_data_destroy (data_signed);
-  gcry_mpi_release (mpi_signature);
-  gcry_mpi_release (mpi_data);
-  free (elements_sig);
-  gcry_free (opts_em);
-  gcry_free (em);
-  gcry_free (s);
-
-  return err;
-}
-
-
-/*
- * General functions.
- */
-
-gcry_err_code_t
-_gcry_ac_init (void)
-{
-  if (fips_mode ())
-    return GPG_ERR_NOT_SUPPORTED;
-
-  return 0;
-}
index 6ef07fb..d692c84 100644 (file)
 static const char *selftest(void);
 
 typedef struct {
-    int idx_i, idx_j;
     byte sbox[256];
+    int idx_i, idx_j;
 } ARCFOUR_context;
 
 static void
 do_encrypt_stream( ARCFOUR_context *ctx,
-                  byte *outbuf, const byte *inbuf, unsigned int length )
+                  byte *outbuf, const byte *inbuf, size_t length )
 {
+#ifndef __i386__
+  register unsigned int i = ctx->idx_i;
+  register byte j = ctx->idx_j;
+  register byte *sbox = ctx->sbox;
+  register byte t, u;
+
+  while ( length-- )
+    {
+      i++;
+      t = sbox[(byte)i];
+      j += t;
+      u = sbox[j];
+      sbox[(byte)i] = u;
+      u += t;
+      sbox[j] = t;
+      *outbuf++ = sbox[u] ^ *inbuf++;
+    }
+
+  ctx->idx_i = (byte)i;
+  ctx->idx_j = (byte)j;
+#else /*__i386__*/
+  /* Old implementation of arcfour is faster on i386 than the version above.
+   * This is because version above increases register pressure which on i386
+   * would push some of the variables to memory/stack.  Therefore keep this
+   * version for i386 to avoid regressing performance.  */
   register int i = ctx->idx_i;
   register int j = ctx->idx_j;
   register byte *sbox = ctx->sbox;
@@ -59,11 +84,12 @@ do_encrypt_stream( ARCFOUR_context *ctx,
 
   ctx->idx_i = i;
   ctx->idx_j = j;
+#endif
 }
 
 static void
 encrypt_stream (void *context,
-                byte *outbuf, const byte *inbuf, unsigned int length)
+                byte *outbuf, const byte *inbuf, size_t length)
 {
   ARCFOUR_context *ctx = (ARCFOUR_context *) context;
   do_encrypt_stream (ctx, outbuf, inbuf, length );
@@ -96,17 +122,21 @@ do_arcfour_setkey (void *context, const byte *key, unsigned int keylen)
   ctx->idx_i = ctx->idx_j = 0;
   for (i=0; i < 256; i++ )
     ctx->sbox[i] = i;
-  for (i=0; i < 256; i++ )
-    karr[i] = key[i%keylen];
+  for (i=j=0; i < 256; i++,j++ )
+    {
+      if (j >= keylen)
+        j = 0;
+      karr[i] = key[j];
+    }
   for (i=j=0; i < 256; i++ )
     {
       int t;
-      j = (j + ctx->sbox[i] + karr[i]) % 256;
+      j = (j + ctx->sbox[i] + karr[i]) & 255;
       t = ctx->sbox[i];
       ctx->sbox[i] = ctx->sbox[j];
       ctx->sbox[j] = t;
     }
-  memset( karr, 0, 256 );
+  wipememory( karr, sizeof(karr) );
 
   return GPG_ERR_NO_ERROR;
 }
@@ -116,7 +146,6 @@ arcfour_setkey ( void *context, const byte *key, unsigned int keylen )
 {
   ARCFOUR_context *ctx = (ARCFOUR_context *) context;
   gcry_err_code_t rc = do_arcfour_setkey (ctx, key, keylen );
-  _gcry_burn_stack (300);
   return rc;
 }
 
@@ -129,9 +158,9 @@ selftest(void)
 
   /* Test vector from Cryptlib labeled there: "from the
      State/Commerce Department". */
-  static byte key_1[] =
+  static const byte key_1[] =
     { 0x61, 0x8A, 0x63, 0xD2, 0xFB };
-  static byte plaintext_1[] =
+  static const byte plaintext_1[] =
     { 0xDC, 0xEE, 0x4C, 0xF9, 0x2C };
   static const byte ciphertext_1[] =
     { 0xF1, 0x38, 0x29, 0xC9, 0xDE };
@@ -150,6 +179,7 @@ selftest(void)
 
 gcry_cipher_spec_t _gcry_cipher_spec_arcfour =
   {
+    GCRY_CIPHER_ARCFOUR, {0, 0},
     "ARCFOUR", NULL, NULL, 1, 128, sizeof (ARCFOUR_context),
     arcfour_setkey, NULL, NULL, encrypt_stream, encrypt_stream,
   };
index 1505324..6e59c53 100644 (file)
 #ifndef G10_BITHELP_H
 #define G10_BITHELP_H
 
+#include "types.h"
+
 
 /****************
  * Rotate the 32 bit unsigned integer X by N bits left/right
  */
-#if defined(__GNUC__) && defined(__i386__)
-static inline u32
-rol( u32 x, int n)
+static inline u32 rol(u32 x, int n)
 {
-       __asm__("roll %%cl,%0"
-               :"=r" (x)
-               :"0" (x),"c" (n));
-       return x;
+       return ( (x << (n&(32-1))) | (x >> ((32-n)&(32-1))) );
 }
+
+static inline u32 ror(u32 x, int n)
+{
+       return ( (x >> (n&(32-1))) | (x << ((32-n)&(32-1))) );
+}
+
+/* Byte swap for 32-bit and 64-bit integers.  If available, use compiler
+   provided helpers.  */
+#ifdef HAVE_BUILTIN_BSWAP32
+# define _gcry_bswap32 __builtin_bswap32
 #else
-#define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
+static inline u32
+_gcry_bswap32(u32 x)
+{
+       return ((rol(x, 8) & 0x00ff00ffL) | (ror(x, 8) & 0xff00ff00L));
+}
 #endif
 
-#if defined(__GNUC__) && defined(__i386__)
-static inline u32
-ror(u32 x, int n)
+#ifdef HAVE_U64_TYPEDEF
+# ifdef HAVE_BUILTIN_BSWAP64
+#  define _gcry_bswap64 __builtin_bswap64
+# else
+static inline u64
+_gcry_bswap64(u64 x)
 {
-       __asm__("rorl %%cl,%0"
-               :"=r" (x)
-               :"0" (x),"c" (n));
-       return x;
+       return ((u64)_gcry_bswap32(x) << 32) | (_gcry_bswap32(x >> 32));
 }
-#else
-#define ror(x,n) ( ((x) >> (n)) | ((x) << (32-(n))) )
+# 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
+#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
+#endif
 
 #endif /*G10_BITHELP_H*/
diff --git a/cipher/blowfish-amd64.S b/cipher/blowfish-amd64.S
new file mode 100644 (file)
index 0000000..6975e55
--- /dev/null
@@ -0,0 +1,533 @@
+/* blowfish-amd64.S  -  AMD64 assembly implementation of Blowfish cipher
+ *
+ * Copyright © 2013 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_BLOWFISH) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS)
+
+.text
+
+/* structure of BLOWFISH_context: */
+#define s0     0
+#define s1     ((s0) + 256 * 4)
+#define s2     ((s1) + 256 * 4)
+#define s3     ((s2) + 256 * 4)
+#define p      ((s3) + 256 * 4)
+
+/* register macros */
+#define CTX %rdi
+#define RIO %rsi
+
+#define RX0 %rax
+#define RX1 %rbx
+#define RX2 %rcx
+#define RX3 %rdx
+
+#define RX0d %eax
+#define RX1d %ebx
+#define RX2d %ecx
+#define RX3d %edx
+
+#define RX0bl %al
+#define RX1bl %bl
+#define RX2bl %cl
+#define RX3bl %dl
+
+#define RX0bh %ah
+#define RX1bh %bh
+#define RX2bh %ch
+#define RX3bh %dh
+
+#define RT0 %rbp
+#define RT1 %rsi
+#define RT2 %r8
+#define RT3 %r9
+
+#define RT0d %ebp
+#define RT1d %esi
+#define RT2d %r8d
+#define RT3d %r9d
+
+#define RKEY %r10
+
+/***********************************************************************
+ * 1-way blowfish
+ ***********************************************************************/
+#define F() \
+       movzbl RX0bh,           RT1d; \
+       movzbl RX0bl,           RT3d; \
+       rorq $16,               RX0; \
+       movzbl RX0bh,           RT0d; \
+       movzbl RX0bl,           RT2d; \
+       rorq $16,               RX0; \
+       movl s0(CTX,RT0,4),     RT0d; \
+       addl s1(CTX,RT2,4),     RT0d; \
+       xorl s2(CTX,RT1,4),     RT0d; \
+       addl s3(CTX,RT3,4),     RT0d; \
+       xorq RT0,               RX0;
+
+#define load_roundkey_enc(n) \
+       movq p+4*(n)(CTX),      RX3;
+
+#define add_roundkey_enc() \
+       xorq RX3,               RX0;
+
+#define round_enc(n) \
+       add_roundkey_enc(); \
+       load_roundkey_enc(n); \
+       \
+       F(); \
+       F();
+
+#define load_roundkey_dec(n) \
+       movq p+4*(n-1)(CTX),    RX3; \
+       rorq $32,               RX3;
+
+#define add_roundkey_dec() \
+       xorq RX3,               RX0;
+
+#define round_dec(n) \
+       add_roundkey_dec(); \
+       load_roundkey_dec(n); \
+       \
+       F(); \
+       F();
+
+#define read_block() \
+       movq (RIO),             RX0; \
+       rorq $32,               RX0; \
+       bswapq                  RX0;
+
+#define write_block() \
+       bswapq                  RX0; \
+       movq RX0,               (RIO);
+
+.align 8
+.type   __blowfish_enc_blk1,@function;
+
+__blowfish_enc_blk1:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      RX0: input plaintext block
+        * output:
+        *      RX0: output plaintext block
+        */
+       movq %rbp, %r11;
+
+       load_roundkey_enc(0);
+       round_enc(2);
+       round_enc(4);
+       round_enc(6);
+       round_enc(8);
+       round_enc(10);
+       round_enc(12);
+       round_enc(14);
+       round_enc(16);
+       add_roundkey_enc();
+
+       movq %r11, %rbp;
+
+       ret;
+.size __blowfish_enc_blk1,.-__blowfish_enc_blk1;
+
+.align 8
+.globl  _gcry_blowfish_amd64_do_encrypt
+.type   _gcry_blowfish_amd64_do_encrypt,@function;
+
+_gcry_blowfish_amd64_do_encrypt:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: u32 *ret_xl
+        *      %rdx: u32 *ret_xr
+        */
+       movl (%rdx), RX0d;
+       shlq $32, RX0;
+       movl (%rsi), RT3d;
+       movq %rdx, %r10;
+       orq RT3, RX0;
+       movq %rsi, RX2;
+
+       call __blowfish_enc_blk1;
+
+       movl RX0d, (%r10);
+       shrq $32, RX0;
+       movl RX0d, (RX2);
+
+       ret;
+.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;
+
+_gcry_blowfish_amd64_encrypt_block:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst
+        *      %rdx: src
+        */
+
+       movq %rsi, %r10;
+
+       movq %rdx, RIO;
+       read_block();
+
+       call __blowfish_enc_blk1;
+
+       movq %r10, RIO;
+       write_block();
+
+       ret;
+.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;
+
+_gcry_blowfish_amd64_decrypt_block:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst
+        *      %rdx: src
+        */
+       movq %rbp, %r11;
+
+       movq %rsi, %r10;
+       movq %rdx, RIO;
+
+       read_block();
+
+       load_roundkey_dec(17);
+       round_dec(15);
+       round_dec(13);
+       round_dec(11);
+       round_dec(9);
+       round_dec(7);
+       round_dec(5);
+       round_dec(3);
+       round_dec(1);
+       add_roundkey_dec();
+
+       movq %r10, RIO;
+       write_block();
+
+       movq %r11, %rbp;
+
+       ret;
+.size _gcry_blowfish_amd64_decrypt_block,.-_gcry_blowfish_amd64_decrypt_block;
+
+/**********************************************************************
+  4-way blowfish, four blocks parallel
+ **********************************************************************/
+#define F4(x) \
+       movzbl x ## bh,         RT1d; \
+       movzbl x ## bl,         RT3d; \
+       rorq $16,               x; \
+       movzbl x ## bh,         RT0d; \
+       movzbl x ## bl,         RT2d; \
+       rorq $16,               x; \
+       movl s0(CTX,RT0,4),     RT0d; \
+       addl s1(CTX,RT2,4),     RT0d; \
+       xorl s2(CTX,RT1,4),     RT0d; \
+       addl s3(CTX,RT3,4),     RT0d; \
+       xorq RT0,               x;
+
+#define add_preloaded_roundkey4() \
+       xorq RKEY,              RX0; \
+       xorq RKEY,              RX1; \
+       xorq RKEY,              RX2; \
+       xorq RKEY,              RX3;
+
+#define preload_roundkey_enc(n) \
+       movq p+4*(n)(CTX),      RKEY;
+
+#define add_roundkey_enc4(n) \
+       add_preloaded_roundkey4(); \
+       preload_roundkey_enc(n + 2);
+
+#define round_enc4(n) \
+       add_roundkey_enc4(n); \
+       \
+       F4(RX0); \
+       F4(RX1); \
+       F4(RX2); \
+       F4(RX3); \
+       \
+       F4(RX0); \
+       F4(RX1); \
+       F4(RX2); \
+       F4(RX3);
+
+#define preload_roundkey_dec(n) \
+       movq p+4*((n)-1)(CTX),  RKEY; \
+       rorq $32,               RKEY;
+
+#define add_roundkey_dec4(n) \
+       add_preloaded_roundkey4(); \
+       preload_roundkey_dec(n - 2);
+
+#define round_dec4(n) \
+       add_roundkey_dec4(n); \
+       \
+       F4(RX0); \
+       F4(RX1); \
+       F4(RX2); \
+       F4(RX3); \
+       \
+       F4(RX0); \
+       F4(RX1); \
+       F4(RX2); \
+       F4(RX3);
+
+#define inbswap_block4() \
+       rorq $32,               RX0; \
+       bswapq                  RX0; \
+       rorq $32,               RX1; \
+       bswapq                  RX1; \
+       rorq $32,               RX2; \
+       bswapq                  RX2; \
+       rorq $32,               RX3; \
+       bswapq                  RX3;
+
+#define inctrswap_block4() \
+       rorq $32,               RX0; \
+       rorq $32,               RX1; \
+       rorq $32,               RX2; \
+       rorq $32,               RX3;
+
+#define outbswap_block4() \
+       bswapq                  RX0; \
+       bswapq                  RX1; \
+       bswapq                  RX2; \
+       bswapq                  RX3;
+
+.align 8
+.type   __blowfish_enc_blk4,@function;
+
+__blowfish_enc_blk4:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      RX0,RX1,RX2,RX3: four input inbswapped plaintext blocks
+        * output:
+        *      RX0,RX1,RX2,RX3: four output ciphertext blocks
+        */
+       preload_roundkey_enc(0);
+
+       round_enc4(0);
+       round_enc4(2);
+       round_enc4(4);
+       round_enc4(6);
+       round_enc4(8);
+       round_enc4(10);
+       round_enc4(12);
+       round_enc4(14);
+       add_preloaded_roundkey4();
+
+       outbswap_block4();
+
+       ret;
+.size __blowfish_enc_blk4,.-__blowfish_enc_blk4;
+
+.align 8
+.type   __blowfish_dec_blk4,@function;
+
+__blowfish_dec_blk4:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      RX0,RX1,RX2,RX3: four input ciphertext blocks
+        * output:
+        *      RX0,RX1,RX2,RX3: four output plaintext blocks
+        */
+       preload_roundkey_dec(17);
+
+       inbswap_block4();
+
+       round_dec4(17);
+       round_dec4(15);
+       round_dec4(13);
+       round_dec4(11);
+       round_dec4(9);
+       round_dec4(7);
+       round_dec4(5);
+       round_dec4(3);
+       add_preloaded_roundkey4();
+
+       outbswap_block4();
+
+       ret;
+.size __blowfish_dec_blk4,.-__blowfish_dec_blk4;
+
+.align 8
+.globl  _gcry_blowfish_amd64_ctr_enc
+.type   _gcry_blowfish_amd64_ctr_enc,@function;
+_gcry_blowfish_amd64_ctr_enc:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (4 blocks)
+        *      %rdx: src (4 blocks)
+        *      %rcx: iv (big endian, 64bit)
+        */
+       pushq %rbp;
+       pushq %rbx;
+       pushq %r12;
+       pushq %r13;
+
+       /* %r11-%r13 are not used by __blowfish_enc_blk4 */
+       movq %rcx, %r13; /*iv*/
+       movq %rdx, %r12; /*src*/
+       movq %rsi, %r11; /*dst*/
+
+       /* load IV and byteswap */
+       movq (%r13), RT0;
+       bswapq RT0;
+       movq RT0, RX0;
+
+       /* construct IVs */
+       leaq 1(RT0), RX1;
+       leaq 2(RT0), RX2;
+       leaq 3(RT0), RX3;
+       leaq 4(RT0), RT0;
+       bswapq RT0;
+
+       inctrswap_block4();
+
+       /* store new IV */
+       movq RT0, (%r13);
+
+       call __blowfish_enc_blk4;
+
+       /* XOR key-stream with plaintext */
+       xorq 0 * 8(%r12), RX0;
+       xorq 1 * 8(%r12), RX1;
+       xorq 2 * 8(%r12), RX2;
+       xorq 3 * 8(%r12), RX3;
+       movq RX0, 0 * 8(%r11);
+       movq RX1, 1 * 8(%r11);
+       movq RX2, 2 * 8(%r11);
+       movq RX3, 3 * 8(%r11);
+
+       popq %r13;
+       popq %r12;
+       popq %rbx;
+       popq %rbp;
+
+       ret;
+.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;
+_gcry_blowfish_amd64_cbc_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (4 blocks)
+        *      %rdx: src (4 blocks)
+        *      %rcx: iv (64bit)
+        */
+       pushq %rbp;
+       pushq %rbx;
+       pushq %r12;
+       pushq %r13;
+
+       /* %r11-%r13 are not used by __blowfish_dec_blk4 */
+       movq %rsi, %r11; /*dst*/
+       movq %rdx, %r12; /*src*/
+       movq %rcx, %r13; /*iv*/
+
+       /* load input */
+       movq 0 * 8(%r12), RX0;
+       movq 1 * 8(%r12), RX1;
+       movq 2 * 8(%r12), RX2;
+       movq 3 * 8(%r12), RX3;
+
+       call __blowfish_dec_blk4;
+
+       movq 3 * 8(%r12), RT0;
+       xorq      (%r13), RX0;
+       xorq 0 * 8(%r12), RX1;
+       xorq 1 * 8(%r12), RX2;
+       xorq 2 * 8(%r12), RX3;
+       movq RT0, (%r13); /* store new IV */
+
+       movq RX0, 0 * 8(%r11);
+       movq RX1, 1 * 8(%r11);
+       movq RX2, 2 * 8(%r11);
+       movq RX3, 3 * 8(%r11);
+
+       popq %r13;
+       popq %r12;
+       popq %rbx;
+       popq %rbp;
+
+       ret;
+.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;
+_gcry_blowfish_amd64_cfb_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (4 blocks)
+        *      %rdx: src (4 blocks)
+        *      %rcx: iv (64bit)
+        */
+       pushq %rbp;
+       pushq %rbx;
+       pushq %r12;
+       pushq %r13;
+
+       /* %r11-%r13 are not used by __blowfish_enc_blk4 */
+       movq %rcx, %r13; /*iv*/
+       movq %rdx, %r12; /*src*/
+       movq %rsi, %r11; /*dst*/
+
+       /* Load input */
+       movq (%r13), RX0;
+       movq 0 * 8(%r12), RX1;
+       movq 1 * 8(%r12), RX2;
+       movq 2 * 8(%r12), RX3;
+
+       inbswap_block4();
+
+       /* Update IV */
+       movq 3 * 8(%r12), RT0;
+       movq RT0, (%r13);
+
+       call __blowfish_enc_blk4;
+
+       xorq 0 * 8(%r12), RX0;
+       xorq 1 * 8(%r12), RX1;
+       xorq 2 * 8(%r12), RX2;
+       xorq 3 * 8(%r12), RX3;
+       movq RX0, 0 * 8(%r11);
+       movq RX1, 1 * 8(%r11);
+       movq RX2, 2 * 8(%r11);
+       movq RX3, 3 * 8(%r11);
+
+       popq %r13;
+       popq %r12;
+       popq %rbx;
+       popq %rbp;
+       ret;
+.size _gcry_blowfish_amd64_cfb_dec,.-_gcry_blowfish_amd64_cfb_dec;
+
+#endif /*defined(USE_BLOWFISH)*/
+#endif /*__x86_64*/
diff --git a/cipher/blowfish-arm.S b/cipher/blowfish-arm.S
new file mode 100644 (file)
index 0000000..901d0c3
--- /dev/null
@@ -0,0 +1,743 @@
+/* blowfish-arm.S  -  ARM assembly implementation of Blowfish cipher
+ *
+ * Copyright © 2013 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 crypto context */
+#define s0     0
+#define s1     (s0 + (1 * 256) * 4)
+#define s2     (s0 + (2 * 256) * 4)
+#define s3     (s0 + (3 * 256) * 4)
+#define p      (s3 + (1 * 256) * 4)
+
+/* register macros */
+#define CTXs0 %r0
+#define CTXs1 %r9
+#define CTXs2 %r8
+#define CTXs3 %r10
+#define RMASK %lr
+#define RKEYL %r2
+#define RKEYR %ip
+
+#define RL0 %r3
+#define RR0 %r4
+
+#define RL1 %r9
+#define RR1 %r10
+
+#define RT0 %r11
+#define RT1 %r7
+#define RT2 %r5
+#define RT3 %r6
+
+/* helper macros */
+#define ldr_unaligned_le(rout, rsrc, offs, rtmp) \
+       ldrb rout, [rsrc, #((offs) + 0)]; \
+       ldrb rtmp, [rsrc, #((offs) + 1)]; \
+       orr rout, rout, rtmp, lsl #8; \
+       ldrb rtmp, [rsrc, #((offs) + 2)]; \
+       orr rout, rout, rtmp, lsl #16; \
+       ldrb rtmp, [rsrc, #((offs) + 3)]; \
+       orr rout, rout, rtmp, lsl #24;
+
+#define str_unaligned_le(rin, rdst, offs, rtmp0, rtmp1) \
+       mov rtmp0, rin, lsr #8; \
+       strb rin, [rdst, #((offs) + 0)]; \
+       mov rtmp1, rin, lsr #16; \
+       strb rtmp0, [rdst, #((offs) + 1)]; \
+       mov rtmp0, rin, lsr #24; \
+       strb rtmp1, [rdst, #((offs) + 2)]; \
+       strb rtmp0, [rdst, #((offs) + 3)];
+
+#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;
+
+#define str_unaligned_be(rin, rdst, offs, rtmp0, rtmp1) \
+       mov rtmp0, rin, lsr #8; \
+       strb rin, [rdst, #((offs) + 3)]; \
+       mov rtmp1, rin, lsr #16; \
+       strb rtmp0, [rdst, #((offs) + 2)]; \
+       mov rtmp0, rin, lsr #24; \
+       strb rtmp1, [rdst, #((offs) + 1)]; \
+       strb rtmp0, [rdst, #((offs) + 0)];
+
+#ifdef __ARMEL__
+       #define ldr_unaligned_host ldr_unaligned_le
+       #define str_unaligned_host str_unaligned_le
+
+       /* bswap on little-endian */
+#ifdef HAVE_ARM_ARCH_V6
+       #define host_to_be(reg, rtmp) \
+               rev reg, reg;
+       #define be_to_host(reg, rtmp) \
+               rev reg, reg;
+#else
+       #define host_to_be(reg, rtmp) \
+               eor     rtmp, reg, reg, ror #16; \
+               mov     rtmp, rtmp, lsr #8; \
+               bic     rtmp, rtmp, #65280; \
+               eor     reg, rtmp, reg, ror #8;
+       #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
+       #define ldr_unaligned_host ldr_unaligned_be
+       #define str_unaligned_host str_unaligned_be
+
+       /* nop on big-endian */
+       #define host_to_be(reg, rtmp) /*_*/
+       #define be_to_host(reg, rtmp) /*_*/
+#endif
+
+#define host_to_host(x, y) /*_*/
+
+/***********************************************************************
+ * 1-way blowfish
+ ***********************************************************************/
+#define F(l, r) \
+       and RT0, RMASK, l, lsr#(24 - 2); \
+       and RT1, RMASK, l, lsr#(16 - 2); \
+       ldr RT0, [CTXs0, RT0]; \
+       and RT2, RMASK, l, lsr#(8 - 2); \
+       ldr RT1, [CTXs1, RT1]; \
+       and RT3, RMASK, l, lsl#2; \
+       ldr RT2, [CTXs2, RT2]; \
+       add RT0, RT1; \
+       ldr RT3, [CTXs3, RT3]; \
+       eor RT0, RT2; \
+       add RT0, RT3; \
+       eor r, RT0;
+
+#define load_roundkey_enc(n) \
+       ldr RKEYL, [CTXs2, #((p - s2) + (4 * (n) + 0))]; \
+       ldr RKEYR, [CTXs2, #((p - s2) + (4 * (n) + 4))];
+
+#define add_roundkey_enc() \
+       eor RL0, RKEYL; \
+       eor RR0, RKEYR;
+
+#define round_enc(n) \
+       add_roundkey_enc(); \
+       load_roundkey_enc(n); \
+       \
+       F(RL0, RR0); \
+       F(RR0, RL0);
+
+#define load_roundkey_dec(n) \
+       ldr RKEYL, [CTXs2, #((p - s2) + (4 * ((n) - 1) + 4))]; \
+       ldr RKEYR, [CTXs2, #((p - s2) + (4 * ((n) - 1) + 0))];
+
+#define add_roundkey_dec() \
+       eor RL0, RKEYL; \
+       eor RR0, RKEYR;
+
+#define round_dec(n) \
+       add_roundkey_dec(); \
+       load_roundkey_dec(n); \
+       \
+       F(RL0, RR0); \
+       F(RR0, RL0);
+
+#define read_block_aligned(rin, offs, l0, r0, convert, rtmp) \
+       ldr l0, [rin, #((offs) + 0)]; \
+       ldr r0, [rin, #((offs) + 4)]; \
+       convert(l0, rtmp); \
+       convert(r0, rtmp);
+
+#define write_block_aligned(rout, offs, l0, r0, convert, rtmp) \
+       convert(l0, rtmp); \
+       convert(r0, rtmp); \
+       str l0, [rout, #((offs) + 0)]; \
+       str r0, [rout, #((offs) + 4)];
+
+#ifdef __ARM_FEATURE_UNALIGNED
+       /* unaligned word reads allowed */
+       #define read_block(rin, offs, l0, r0, rtmp0) \
+               read_block_aligned(rin, offs, l0, r0, host_to_be, rtmp0)
+
+       #define write_block(rout, offs, r0, l0, rtmp0, rtmp1) \
+               write_block_aligned(rout, offs, r0, l0, be_to_host, rtmp0)
+
+       #define read_block_host(rin, offs, l0, r0, rtmp0) \
+               read_block_aligned(rin, offs, l0, r0, host_to_host, rtmp0)
+
+       #define write_block_host(rout, offs, r0, l0, rtmp0, rtmp1) \
+               write_block_aligned(rout, offs, r0, l0, host_to_host, rtmp0)
+#else
+       /* need to handle unaligned reads by byte reads */
+       #define read_block(rin, offs, l0, r0, rtmp0) \
+               tst rin, #3; \
+               beq 1f; \
+                       ldr_unaligned_be(l0, rin, (offs) + 0, rtmp0); \
+                       ldr_unaligned_be(r0, rin, (offs) + 4, rtmp0); \
+                       b 2f; \
+               1:;\
+                       read_block_aligned(rin, offs, l0, r0, host_to_be, rtmp0); \
+               2:;
+
+       #define write_block(rout, offs, l0, r0, rtmp0, rtmp1) \
+               tst rout, #3; \
+               beq 1f; \
+                       str_unaligned_be(l0, rout, (offs) + 0, rtmp0, rtmp1); \
+                       str_unaligned_be(r0, rout, (offs) + 4, rtmp0, rtmp1); \
+                       b 2f; \
+               1:;\
+                       write_block_aligned(rout, offs, l0, r0, be_to_host, rtmp0); \
+               2:;
+
+       #define read_block_host(rin, offs, l0, r0, rtmp0) \
+               tst rin, #3; \
+               beq 1f; \
+                       ldr_unaligned_host(l0, rin, (offs) + 0, rtmp0); \
+                       ldr_unaligned_host(r0, rin, (offs) + 4, rtmp0); \
+                       b 2f; \
+               1:;\
+                       read_block_aligned(rin, offs, l0, r0, host_to_host, rtmp0); \
+               2:;
+
+       #define write_block_host(rout, offs, l0, r0, rtmp0, rtmp1) \
+               tst rout, #3; \
+               beq 1f; \
+                       str_unaligned_host(l0, rout, (offs) + 0, rtmp0, rtmp1); \
+                       str_unaligned_host(r0, rout, (offs) + 4, rtmp0, rtmp1); \
+                       b 2f; \
+               1:;\
+                       write_block_aligned(rout, offs, l0, r0, host_to_host); \
+               2:;
+#endif
+
+.align 3
+.type  __blowfish_enc_blk1,%function;
+
+__blowfish_enc_blk1:
+       /* input:
+        *      preloaded: CTX
+        *      [RL0, RR0]: src
+        * output:
+        *      [RR0, RL0]: dst
+        */
+       push {%lr};
+
+       add CTXs1, CTXs0, #(s1 - s0);
+       add CTXs2, CTXs0, #(s2 - s0);
+       mov RMASK, #(0xff << 2); /* byte mask */
+       add CTXs3, CTXs1, #(s3 - s1);
+
+       load_roundkey_enc(0);
+       round_enc(2);
+       round_enc(4);
+       round_enc(6);
+       round_enc(8);
+       round_enc(10);
+       round_enc(12);
+       round_enc(14);
+       round_enc(16);
+       add_roundkey_enc();
+
+       pop {%pc};
+.size __blowfish_enc_blk1,.-__blowfish_enc_blk1;
+
+.align 8
+.globl  _gcry_blowfish_arm_do_encrypt
+.type   _gcry_blowfish_arm_do_encrypt,%function;
+
+_gcry_blowfish_arm_do_encrypt:
+       /* input:
+        *      %r0: ctx, CTX
+        *      %r1: u32 *ret_xl
+        *      %r2: u32 *ret_xr
+        */
+       push {%r2, %r4-%r11, %ip, %lr};
+
+       ldr RL0, [%r1];
+       ldr RR0, [%r2];
+
+       bl __blowfish_enc_blk1;
+
+       pop {%r2};
+       str RR0, [%r1];
+       str RL0, [%r2];
+
+       pop {%r4-%r11, %ip, %pc};
+.size _gcry_blowfish_arm_do_encrypt,.-_gcry_blowfish_arm_do_encrypt;
+
+.align 3
+.globl _gcry_blowfish_arm_encrypt_block
+.type   _gcry_blowfish_arm_encrypt_block,%function;
+
+_gcry_blowfish_arm_encrypt_block:
+       /* input:
+        *      %r0: ctx, CTX
+        *      %r1: dst
+        *      %r2: src
+        */
+       push {%r4-%r11, %ip, %lr};
+
+       read_block(%r2, 0, RL0, RR0, RT0);
+
+       bl __blowfish_enc_blk1;
+
+       write_block(%r1, 0, RR0, RL0, RT0, RT1);
+
+       pop {%r4-%r11, %ip, %pc};
+.size _gcry_blowfish_arm_encrypt_block,.-_gcry_blowfish_arm_encrypt_block;
+
+.align 3
+.globl _gcry_blowfish_arm_decrypt_block
+.type   _gcry_blowfish_arm_decrypt_block,%function;
+
+_gcry_blowfish_arm_decrypt_block:
+       /* input:
+        *      %r0: ctx, CTX
+        *      %r1: dst
+        *      %r2: src
+        */
+       push {%r4-%r11, %ip, %lr};
+
+       add CTXs1, CTXs0, #(s1 - s0);
+       add CTXs2, CTXs0, #(s2 - s0);
+       mov RMASK, #(0xff << 2); /* byte mask */
+       add CTXs3, CTXs1, #(s3 - s1);
+
+       read_block(%r2, 0, RL0, RR0, RT0);
+
+       load_roundkey_dec(17);
+       round_dec(15);
+       round_dec(13);
+       round_dec(11);
+       round_dec(9);
+       round_dec(7);
+       round_dec(5);
+       round_dec(3);
+       round_dec(1);
+       add_roundkey_dec();
+
+       write_block(%r1, 0, RR0, RL0, RT0, RT1);
+
+       pop {%r4-%r11, %ip, %pc};
+.size _gcry_blowfish_arm_decrypt_block,.-_gcry_blowfish_arm_decrypt_block;
+
+/***********************************************************************
+ * 2-way blowfish
+ ***********************************************************************/
+#define F2(n, l0, r0, l1, r1, set_nextk, dec) \
+       \
+       and RT0, RMASK, l0, lsr#(24 - 2); \
+       and RT1, RMASK, l0, lsr#(16 - 2); \
+       and RT2, RMASK, l0, lsr#(8 - 2); \
+       add RT1, #(s1 - s0); \
+       \
+       ldr RT0, [CTXs0, RT0]; \
+       and RT3, RMASK, l0, lsl#2; \
+       ldr RT1, [CTXs0, RT1]; \
+       add RT3, #(s3 - s2); \
+       ldr RT2, [CTXs2, RT2]; \
+       add RT0, RT1; \
+       ldr RT3, [CTXs2, RT3]; \
+       \
+       and RT1, RMASK, l1, lsr#(24 - 2); \
+       eor RT0, RT2; \
+       and RT2, RMASK, l1, lsr#(16 - 2); \
+       add RT0, RT3; \
+       add RT2, #(s1 - s0); \
+       and RT3, RMASK, l1, lsr#(8 - 2); \
+       eor r0, RT0; \
+       \
+       ldr RT1, [CTXs0, RT1]; \
+       and RT0, RMASK, l1, lsl#2; \
+       ldr RT2, [CTXs0, RT2]; \
+       add RT0, #(s3 - s2); \
+       ldr RT3, [CTXs2, RT3]; \
+       add RT1, RT2; \
+       ldr RT0, [CTXs2, RT0]; \
+       \
+       and RT2, RMASK, r0, lsr#(24 - 2); \
+       eor RT1, RT3; \
+       and RT3, RMASK, r0, lsr#(16 - 2); \
+       add RT1, RT0; \
+       add RT3, #(s1 - s0); \
+       and RT0, RMASK, r0, lsr#(8 - 2); \
+       eor r1, RT1; \
+       \
+       ldr RT2, [CTXs0, RT2]; \
+       and RT1, RMASK, r0, lsl#2; \
+       ldr RT3, [CTXs0, RT3]; \
+       add RT1, #(s3 - s2); \
+       ldr RT0, [CTXs2, RT0]; \
+       add RT2, RT3; \
+       ldr RT1, [CTXs2, RT1]; \
+       \
+       and RT3, RMASK, r1, lsr#(24 - 2); \
+       eor RT2, RT0; \
+       and RT0, RMASK, r1, lsr#(16 - 2); \
+       add RT2, RT1; \
+       add RT0, #(s1 - s0); \
+       and RT1, RMASK, r1, lsr#(8 - 2); \
+       eor l0, RT2; \
+       \
+       ldr RT3, [CTXs0, RT3]; \
+       and RT2, RMASK, r1, lsl#2; \
+       ldr RT0, [CTXs0, RT0]; \
+       add RT2, #(s3 - s2); \
+       ldr RT1, [CTXs2, RT1]; \
+       eor l1, RKEYL; \
+       ldr RT2, [CTXs2, RT2]; \
+       \
+       eor r0, RKEYR; \
+       add RT3, RT0; \
+       eor r1, RKEYR; \
+       eor RT3, RT1; \
+       eor l0, RKEYL; \
+       add RT3, RT2; \
+       set_nextk(RKEYL, (p - s2) + (4 * (n) + ((dec) * 4))); \
+       eor l1, RT3; \
+       set_nextk(RKEYR, (p - s2) + (4 * (n) + (!(dec) * 4)));
+
+#define load_n_add_roundkey_enc2(n) \
+       load_roundkey_enc(n); \
+       eor RL0, RKEYL; \
+       eor RR0, RKEYR; \
+       eor RL1, RKEYL; \
+       eor RR1, RKEYR; \
+       load_roundkey_enc((n) + 2);
+
+#define next_key(reg, offs) \
+       ldr reg, [CTXs2, #(offs)];
+
+#define dummy(x, y) /* do nothing */
+
+#define round_enc2(n, load_next_key) \
+       F2((n) + 2, RL0, RR0, RL1, RR1, load_next_key, 0);
+
+#define load_n_add_roundkey_dec2(n) \
+       load_roundkey_dec(n); \
+       eor RL0, RKEYL; \
+       eor RR0, RKEYR; \
+       eor RL1, RKEYL; \
+       eor RR1, RKEYR; \
+       load_roundkey_dec((n) - 2);
+
+#define round_dec2(n, load_next_key) \
+       F2((n) - 3, RL0, RR0, RL1, RR1, load_next_key, 1);
+
+#define read_block2_aligned(rin, l0, r0, l1, r1, convert, rtmp) \
+       ldr l0, [rin, #(0)]; \
+       ldr r0, [rin, #(4)]; \
+       convert(l0, rtmp); \
+       ldr l1, [rin, #(8)]; \
+       convert(r0, rtmp); \
+       ldr r1, [rin, #(12)]; \
+       convert(l1, rtmp); \
+       convert(r1, rtmp);
+
+#define write_block2_aligned(rout, l0, r0, l1, r1, convert, rtmp) \
+       convert(l0, rtmp); \
+       convert(r0, rtmp); \
+       convert(l1, rtmp); \
+       str l0, [rout, #(0)]; \
+       convert(r1, rtmp); \
+       str r0, [rout, #(4)]; \
+       str l1, [rout, #(8)]; \
+       str r1, [rout, #(12)];
+
+#ifdef __ARM_FEATURE_UNALIGNED
+       /* unaligned word reads allowed */
+       #define read_block2(rin, l0, r0, l1, r1, rtmp0) \
+               read_block2_aligned(rin, l0, r0, l1, r1, host_to_be, rtmp0)
+
+       #define write_block2(rout, l0, r0, l1, r1, rtmp0, rtmp1) \
+               write_block2_aligned(rout, l0, r0, l1, r1, be_to_host, rtmp0)
+
+       #define read_block2_host(rin, l0, r0, l1, r1, rtmp0) \
+               read_block2_aligned(rin, l0, r0, l1, r1, host_to_host, rtmp0)
+
+       #define write_block2_host(rout, l0, r0, l1, r1, rtmp0, rtmp1) \
+               write_block2_aligned(rout, l0, r0, l1, r1, host_to_host, rtmp0)
+#else
+       /* need to handle unaligned reads by byte reads */
+       #define read_block2(rin, l0, r0, l1, r1, rtmp0) \
+               tst rin, #3; \
+               beq 1f; \
+                       ldr_unaligned_be(l0, rin, 0, rtmp0); \
+                       ldr_unaligned_be(r0, rin, 4, rtmp0); \
+                       ldr_unaligned_be(l1, rin, 8, rtmp0); \
+                       ldr_unaligned_be(r1, rin, 12, rtmp0); \
+                       b 2f; \
+               1:;\
+                       read_block2_aligned(rin, l0, r0, l1, r1, host_to_be, rtmp0); \
+               2:;
+
+       #define write_block2(rout, l0, r0, l1, r1, rtmp0, rtmp1) \
+               tst rout, #3; \
+               beq 1f; \
+                       str_unaligned_be(l0, rout, 0, rtmp0, rtmp1); \
+                       str_unaligned_be(r0, rout, 4, rtmp0, rtmp1); \
+                       str_unaligned_be(l1, rout, 8, rtmp0, rtmp1); \
+                       str_unaligned_be(r1, rout, 12, rtmp0, rtmp1); \
+                       b 2f; \
+               1:;\
+                       write_block2_aligned(rout, l0, r0, l1, r1, be_to_host, rtmp0); \
+               2:;
+
+       #define read_block2_host(rin, l0, r0, l1, r1, rtmp0) \
+               tst rin, #3; \
+               beq 1f; \
+                       ldr_unaligned_host(l0, rin, 0, rtmp0); \
+                       ldr_unaligned_host(r0, rin, 4, rtmp0); \
+                       ldr_unaligned_host(l1, rin, 8, rtmp0); \
+                       ldr_unaligned_host(r1, rin, 12, rtmp0); \
+                       b 2f; \
+               1:;\
+                       read_block2_aligned(rin, l0, r0, l1, r1, host_to_host, rtmp0); \
+               2:;
+
+       #define write_block2_host(rout, l0, r0, l1, r1, rtmp0, rtmp1) \
+               tst rout, #3; \
+               beq 1f; \
+                       str_unaligned_host(l0, rout, 0, rtmp0, rtmp1); \
+                       str_unaligned_host(r0, rout, 4, rtmp0, rtmp1); \
+                       str_unaligned_host(l1, rout, 8, rtmp0, rtmp1); \
+                       str_unaligned_host(r1, rout, 12, rtmp0, rtmp1); \
+                       b 2f; \
+               1:;\
+                       write_block2_aligned(rout, l0, r0, l1, r1, host_to_host, rtmp0); \
+               2:;
+#endif
+
+.align 3
+.type  _gcry_blowfish_arm_enc_blk2,%function;
+
+_gcry_blowfish_arm_enc_blk2:
+       /* input:
+        *      preloaded: CTX
+        *      [RL0, RR0], [RL1, RR1]: src
+        * output:
+        *      [RR0, RL0], [RR1, RL1]: dst
+        */
+       push {RT0,%lr};
+
+       add CTXs2, CTXs0, #(s2 - s0);
+       mov RMASK, #(0xff << 2); /* byte mask */
+
+       load_n_add_roundkey_enc2(0);
+       round_enc2(2, next_key);
+       round_enc2(4, next_key);
+       round_enc2(6, next_key);
+       round_enc2(8, next_key);
+       round_enc2(10, next_key);
+       round_enc2(12, next_key);
+       round_enc2(14, next_key);
+       round_enc2(16, dummy);
+
+       host_to_be(RR0, RT0);
+       host_to_be(RL0, RT0);
+       host_to_be(RR1, RT0);
+       host_to_be(RL1, RT0);
+
+       pop {RT0,%pc};
+.size _gcry_blowfish_arm_enc_blk2,.-_gcry_blowfish_arm_enc_blk2;
+
+.align 3
+.globl _gcry_blowfish_arm_cfb_dec;
+.type  _gcry_blowfish_arm_cfb_dec,%function;
+
+_gcry_blowfish_arm_cfb_dec:
+       /* input:
+        *      %r0: CTX
+        *      %r1: dst (2 blocks)
+        *      %r2: src (2 blocks)
+        *      %r3: iv (64bit)
+        */
+       push {%r2, %r4-%r11, %ip, %lr};
+
+       mov %lr, %r3;
+
+       /* Load input (iv/%r3 is aligned, src/%r2 might not be) */
+       ldm %r3, {RL0, RR0};
+       host_to_be(RL0, RT0);
+       host_to_be(RR0, RT0);
+       read_block(%r2, 0, RL1, RR1, RT0);
+
+       /* Update IV, load src[1] and save to iv[0] */
+       read_block_host(%r2, 8, %r5, %r6, RT0);
+       stm %lr, {%r5, %r6};
+
+       bl _gcry_blowfish_arm_enc_blk2;
+       /* result in RR0:RL0, RR1:RL1 = %r4:%r3, %r10:%r9 */
+
+       /* %r1: dst, %r0: %src */
+       pop {%r0};
+
+       /* dst = src ^ result */
+       read_block2_host(%r0, %r5, %r6, %r7, %r8, %lr);
+       eor %r5, %r4;
+       eor %r6, %r3;
+       eor %r7, %r10;
+       eor %r8, %r9;
+       write_block2_host(%r1, %r5, %r6, %r7, %r8, %r9, %r10);
+
+       pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_blowfish_arm_cfb_dec,.-_gcry_blowfish_arm_cfb_dec;
+
+.align 3
+.globl _gcry_blowfish_arm_ctr_enc;
+.type  _gcry_blowfish_arm_ctr_enc,%function;
+
+_gcry_blowfish_arm_ctr_enc:
+       /* input:
+        *      %r0: CTX
+        *      %r1: dst (2 blocks)
+        *      %r2: src (2 blocks)
+        *      %r3: iv (64bit, big-endian)
+        */
+       push {%r2, %r4-%r11, %ip, %lr};
+
+       mov %lr, %r3;
+
+       /* Load IV (big => host endian) */
+       read_block_aligned(%lr, 0, RL0, RR0, be_to_host, RT0);
+
+       /* Construct IVs */
+       adds RR1, RR0, #1; /* +1 */
+       adc RL1, RL0, #0;
+       adds %r6, RR1, #1; /* +2 */
+       adc %r5, RL1, #0;
+
+       /* Store new IV (host => big-endian) */
+       write_block_aligned(%lr, 0, %r5, %r6, host_to_be, RT0);
+
+       bl _gcry_blowfish_arm_enc_blk2;
+       /* result in RR0:RL0, RR1:RL1 = %r4:%r3, %r10:%r9 */
+
+       /* %r1: dst, %r0: %src */
+       pop {%r0};
+
+       /* XOR key-stream with plaintext */
+       read_block2_host(%r0, %r5, %r6, %r7, %r8, %lr);
+       eor %r5, %r4;
+       eor %r6, %r3;
+       eor %r7, %r10;
+       eor %r8, %r9;
+       write_block2_host(%r1, %r5, %r6, %r7, %r8, %r9, %r10);
+
+       pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_blowfish_arm_ctr_enc,.-_gcry_blowfish_arm_ctr_enc;
+
+.align 3
+.type  _gcry_blowfish_arm_dec_blk2,%function;
+
+_gcry_blowfish_arm_dec_blk2:
+       /* input:
+        *      preloaded: CTX
+        *      [RL0, RR0], [RL1, RR1]: src
+        * output:
+        *      [RR0, RL0], [RR1, RL1]: dst
+        */
+       add CTXs2, CTXs0, #(s2 - s0);
+       mov RMASK, #(0xff << 2); /* byte mask */
+
+       load_n_add_roundkey_dec2(17);
+       round_dec2(15, next_key);
+       round_dec2(13, next_key);
+       round_dec2(11, next_key);
+       round_dec2(9, next_key);
+       round_dec2(7, next_key);
+       round_dec2(5, next_key);
+       round_dec2(3, next_key);
+       round_dec2(1, dummy);
+
+       host_to_be(RR0, RT0);
+       host_to_be(RL0, RT0);
+       host_to_be(RR1, RT0);
+       host_to_be(RL1, RT0);
+
+       b .Ldec_cbc_tail;
+.ltorg
+.size _gcry_blowfish_arm_dec_blk2,.-_gcry_blowfish_arm_dec_blk2;
+
+.align 3
+.globl _gcry_blowfish_arm_cbc_dec;
+.type  _gcry_blowfish_arm_cbc_dec,%function;
+
+_gcry_blowfish_arm_cbc_dec:
+       /* input:
+        *      %r0: CTX
+        *      %r1: dst (2 blocks)
+        *      %r2: src (2 blocks)
+        *      %r3: iv (64bit)
+        */
+       push {%r2-%r11, %ip, %lr};
+
+       read_block2(%r2, RL0, RR0, RL1, RR1, RT0);
+
+       /* dec_blk2 is only used by cbc_dec, jump directly in/out instead
+        * of function call. */
+       b _gcry_blowfish_arm_dec_blk2;
+.Ldec_cbc_tail:
+       /* result in RR0:RL0, RR1:RL1 = %r4:%r3, %r10:%r9 */
+
+       /* %r0: %src, %r1: dst, %r2: iv */
+       pop {%r0, %r2};
+
+       /* load IV+1 (src[0]) to %r7:%r8. Might be unaligned. */
+       read_block_host(%r0, 0, %r7, %r8, %r5);
+       /* load IV (iv[0]) to %r5:%r6. 'iv' is aligned. */
+       ldm %r2, {%r5, %r6};
+
+       /* out[1] ^= IV+1 */
+       eor %r10, %r7;
+       eor %r9, %r8;
+       /* out[0] ^= IV */
+       eor %r4, %r5;
+       eor %r3, %r6;
+
+       /* load IV+2 (src[1]) to %r7:%r8. Might be unaligned. */
+       read_block_host(%r0, 8, %r7, %r8, %r5);
+       /* store IV+2 to iv[0] (aligned). */
+       stm %r2, {%r7, %r8};
+
+       /* store result to dst[0-3]. Might be unaligned. */
+       write_block2_host(%r1, %r4, %r3, %r10, %r9, %r5, %r6);
+
+       pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_blowfish_arm_cbc_dec,.-_gcry_blowfish_arm_cbc_dec;
+
+#endif /*HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS*/
+#endif /*__ARM_ARCH >= 6*/
index b4d2b9c..ae470d8 100644 (file)
 #include "types.h"
 #include "g10lib.h"
 #include "cipher.h"
+#include "bufhelp.h"
+#include "cipher-selftest.h"
 
 #define BLOWFISH_BLOCKSIZE 8
 #define BLOWFISH_ROUNDS 16
 
+
+/* 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) && \
+    (BLOWFISH_ROUNDS == 16)
+# define USE_AMD64_ASM 1
+#endif
+
+/* USE_ARM_ASM indicates whether to use ARM assembly code. */
+#undef USE_ARM_ASM
+#if defined(__ARMEL__)
+# if (BLOWFISH_ROUNDS == 16) && defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS)
+#  define USE_ARM_ASM 1
+# endif
+#endif
+
 typedef struct {
     u32 s0[256];
     u32 s1[256];
@@ -49,8 +67,8 @@ typedef struct {
 } BLOWFISH_context;
 
 static gcry_err_code_t bf_setkey (void *c, const byte *key, unsigned keylen);
-static void encrypt_block (void *bc, byte *outbuf, const byte *inbuf);
-static void decrypt_block (void *bc, byte *outbuf, const byte *inbuf);
+static unsigned int encrypt_block (void *bc, byte *outbuf, const byte *inbuf);
+static unsigned int decrypt_block (void *bc, byte *outbuf, const byte *inbuf);
 
 
 /* precomputed S boxes */
@@ -240,6 +258,119 @@ static const u32 ps[BLOWFISH_ROUNDS+2] = {
     0xC0AC29B7,0xC97C50DD,0x3F84D5B5,0xB5470917,0x9216D5D9,0x8979FB1B };
 
 
+#ifdef USE_AMD64_ASM
+
+/* Assembly implementations of Blowfish. */
+extern void _gcry_blowfish_amd64_do_encrypt(BLOWFISH_context *c, u32 *ret_xl,
+                                           u32 *ret_xr);
+
+extern void _gcry_blowfish_amd64_encrypt_block(BLOWFISH_context *c, byte *out,
+                                              const byte *in);
+
+extern void _gcry_blowfish_amd64_decrypt_block(BLOWFISH_context *c, byte *out,
+                                              const byte *in);
+
+/* These assembly implementations process four blocks in parallel. */
+extern void _gcry_blowfish_amd64_ctr_enc(BLOWFISH_context *ctx, byte *out,
+                                        const byte *in, byte *ctr);
+
+extern void _gcry_blowfish_amd64_cbc_dec(BLOWFISH_context *ctx, byte *out,
+                                        const byte *in, byte *iv);
+
+extern void _gcry_blowfish_amd64_cfb_dec(BLOWFISH_context *ctx, byte *out,
+                                        const byte *in, byte *iv);
+
+static void
+do_encrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
+{
+  _gcry_blowfish_amd64_do_encrypt (bc, ret_xl, ret_xr);
+}
+
+static void
+do_encrypt_block (BLOWFISH_context *context, byte *outbuf, const byte *inbuf)
+{
+  _gcry_blowfish_amd64_encrypt_block (context, outbuf, inbuf);
+}
+
+static void
+do_decrypt_block (BLOWFISH_context *context, byte *outbuf, const byte *inbuf)
+{
+  _gcry_blowfish_amd64_decrypt_block (context, outbuf, inbuf);
+}
+
+static unsigned int
+encrypt_block (void *context , byte *outbuf, const byte *inbuf)
+{
+  BLOWFISH_context *c = (BLOWFISH_context *) context;
+  do_encrypt_block (c, outbuf, inbuf);
+  return /*burn_stack*/ (2*8);
+}
+
+static unsigned int
+decrypt_block (void *context, byte *outbuf, const byte *inbuf)
+{
+  BLOWFISH_context *c = (BLOWFISH_context *) context;
+  do_decrypt_block (c, outbuf, inbuf);
+  return /*burn_stack*/ (2*8);
+}
+
+#elif defined(USE_ARM_ASM)
+
+/* Assembly implementations of Blowfish. */
+extern void _gcry_blowfish_arm_do_encrypt(BLOWFISH_context *c, u32 *ret_xl,
+                                           u32 *ret_xr);
+
+extern void _gcry_blowfish_arm_encrypt_block(BLOWFISH_context *c, byte *out,
+                                              const byte *in);
+
+extern void _gcry_blowfish_arm_decrypt_block(BLOWFISH_context *c, byte *out,
+                                              const byte *in);
+
+/* These assembly implementations process two blocks in parallel. */
+extern void _gcry_blowfish_arm_ctr_enc(BLOWFISH_context *ctx, byte *out,
+                                        const byte *in, byte *ctr);
+
+extern void _gcry_blowfish_arm_cbc_dec(BLOWFISH_context *ctx, byte *out,
+                                        const byte *in, byte *iv);
+
+extern void _gcry_blowfish_arm_cfb_dec(BLOWFISH_context *ctx, byte *out,
+                                        const byte *in, byte *iv);
+
+static void
+do_encrypt ( BLOWFISH_context *bc, u32 *ret_xl, u32 *ret_xr )
+{
+  _gcry_blowfish_arm_do_encrypt (bc, ret_xl, ret_xr);
+}
+
+static void
+do_encrypt_block (BLOWFISH_context *context, byte *outbuf, const byte *inbuf)
+{
+  _gcry_blowfish_arm_encrypt_block (context, outbuf, inbuf);
+}
+
+static void
+do_decrypt_block (BLOWFISH_context *context, byte *outbuf, const byte *inbuf)
+{
+  _gcry_blowfish_arm_decrypt_block (context, outbuf, inbuf);
+}
+
+static unsigned int
+encrypt_block (void *context , byte *outbuf, const byte *inbuf)
+{
+  BLOWFISH_context *c = (BLOWFISH_context *) context;
+  do_encrypt_block (c, outbuf, inbuf);
+  return /*burn_stack*/ (10*4);
+}
+
+static unsigned int
+decrypt_block (void *context, byte *outbuf, const byte *inbuf)
+{
+  BLOWFISH_context *c = (BLOWFISH_context *) context;
+  do_decrypt_block (c, outbuf, inbuf);
+  return /*burn_stack*/ (10*4);
+}
+
+#else /*USE_ARM_ASM*/
 
 #if BLOWFISH_ROUNDS != 16
 static inline u32
@@ -413,25 +544,19 @@ do_encrypt_block ( BLOWFISH_context *bc, byte *outbuf, const byte *inbuf )
 {
   u32 d1, d2;
 
-  d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
-  d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
+  d1 = buf_get_be32(inbuf);
+  d2 = buf_get_be32(inbuf + 4);
   do_encrypt( bc, &d1, &d2 );
-  outbuf[0] = (d1 >> 24) & 0xff;
-  outbuf[1] = (d1 >> 16) & 0xff;
-  outbuf[2] = (d1 >>   8) & 0xff;
-  outbuf[3] =  d1         & 0xff;
-  outbuf[4] = (d2 >> 24) & 0xff;
-  outbuf[5] = (d2 >> 16) & 0xff;
-  outbuf[6] = (d2 >>   8) & 0xff;
-  outbuf[7] =  d2         & 0xff;
+  buf_put_be32(outbuf, d1);
+  buf_put_be32(outbuf + 4, d2);
 }
 
-static void
+static unsigned int
 encrypt_block (void *context, byte *outbuf, const byte *inbuf)
 {
   BLOWFISH_context *bc = (BLOWFISH_context *) context;
   do_encrypt_block (bc, outbuf, inbuf);
-  _gcry_burn_stack (64);
+  return /*burn_stack*/ (64);
 }
 
 
@@ -440,25 +565,254 @@ do_decrypt_block (BLOWFISH_context *bc, byte *outbuf, const byte *inbuf)
 {
   u32 d1, d2;
 
-  d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
-  d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
+  d1 = buf_get_be32(inbuf);
+  d2 = buf_get_be32(inbuf + 4);
   decrypt( bc, &d1, &d2 );
-  outbuf[0] = (d1 >> 24) & 0xff;
-  outbuf[1] = (d1 >> 16) & 0xff;
-  outbuf[2] = (d1 >>   8) & 0xff;
-  outbuf[3] =  d1         & 0xff;
-  outbuf[4] = (d2 >> 24) & 0xff;
-  outbuf[5] = (d2 >> 16) & 0xff;
-  outbuf[6] = (d2 >>   8) & 0xff;
-  outbuf[7] =  d2         & 0xff;
+  buf_put_be32(outbuf, d1);
+  buf_put_be32(outbuf + 4, d2);
 }
 
-static void
+static unsigned int
 decrypt_block (void *context, byte *outbuf, const byte *inbuf)
 {
   BLOWFISH_context *bc = (BLOWFISH_context *) context;
   do_decrypt_block (bc, outbuf, inbuf);
-  _gcry_burn_stack (64);
+  return /*burn_stack*/ (64);
+}
+
+#endif /*!USE_AMD64_ASM&&!USE_ARM_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 BLOWFISH_BLOCKSIZE. */
+void
+_gcry_blowfish_ctr_enc(void *context, unsigned char *ctr, void *outbuf_arg,
+                      const void *inbuf_arg, size_t nblocks)
+{
+  BLOWFISH_context *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned char tmpbuf[BLOWFISH_BLOCKSIZE];
+  int burn_stack_depth = (64) + 2 * BLOWFISH_BLOCKSIZE;
+  int i;
+
+#ifdef USE_AMD64_ASM
+  {
+    if (nblocks >= 4)
+      burn_stack_depth += 5 * sizeof(void*);
+
+    /* Process data in 4 block chunks. */
+    while (nblocks >= 4)
+      {
+        _gcry_blowfish_amd64_ctr_enc(ctx, outbuf, inbuf, ctr);
+
+        nblocks -= 4;
+        outbuf += 4 * BLOWFISH_BLOCKSIZE;
+        inbuf  += 4 * BLOWFISH_BLOCKSIZE;
+      }
+
+    /* Use generic code to handle smaller chunks... */
+    /* TODO: use caching instead? */
+  }
+#elif defined(USE_ARM_ASM)
+  {
+    /* Process data in 2 block chunks. */
+    while (nblocks >= 2)
+      {
+        _gcry_blowfish_arm_ctr_enc(ctx, outbuf, inbuf, ctr);
+
+        nblocks -= 2;
+        outbuf += 2 * BLOWFISH_BLOCKSIZE;
+        inbuf  += 2 * BLOWFISH_BLOCKSIZE;
+      }
+
+    /* Use generic code to handle smaller chunks... */
+    /* TODO: use caching instead? */
+  }
+#endif
+
+  for ( ;nblocks; nblocks-- )
+    {
+      /* Encrypt the counter. */
+      do_encrypt_block(ctx, tmpbuf, ctr);
+      /* XOR the input with the encrypted counter and store in output.  */
+      buf_xor(outbuf, tmpbuf, inbuf, BLOWFISH_BLOCKSIZE);
+      outbuf += BLOWFISH_BLOCKSIZE;
+      inbuf  += BLOWFISH_BLOCKSIZE;
+      /* Increment the counter.  */
+      for (i = BLOWFISH_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_blowfish_cbc_dec(void *context, unsigned char *iv, void *outbuf_arg,
+                      const void *inbuf_arg, size_t nblocks)
+{
+  BLOWFISH_context *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned char savebuf[BLOWFISH_BLOCKSIZE];
+  int burn_stack_depth = (64) + 2 * BLOWFISH_BLOCKSIZE;
+
+#ifdef USE_AMD64_ASM
+  {
+    if (nblocks >= 4)
+      burn_stack_depth += 5 * sizeof(void*);
+
+    /* Process data in 4 block chunks. */
+    while (nblocks >= 4)
+      {
+        _gcry_blowfish_amd64_cbc_dec(ctx, outbuf, inbuf, iv);
+
+        nblocks -= 4;
+        outbuf += 4 * BLOWFISH_BLOCKSIZE;
+        inbuf  += 4 * BLOWFISH_BLOCKSIZE;
+      }
+
+    /* Use generic code to handle smaller chunks... */
+  }
+#elif defined(USE_ARM_ASM)
+  {
+    /* Process data in 2 block chunks. */
+    while (nblocks >= 2)
+      {
+        _gcry_blowfish_arm_cbc_dec(ctx, outbuf, inbuf, iv);
+
+        nblocks -= 2;
+        outbuf += 2 * BLOWFISH_BLOCKSIZE;
+        inbuf  += 2 * BLOWFISH_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.  */
+      do_decrypt_block (ctx, savebuf, inbuf);
+
+      buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, BLOWFISH_BLOCKSIZE);
+      inbuf += BLOWFISH_BLOCKSIZE;
+      outbuf += BLOWFISH_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_blowfish_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg,
+                      const void *inbuf_arg, size_t nblocks)
+{
+  BLOWFISH_context *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  int burn_stack_depth = (64) + 2 * BLOWFISH_BLOCKSIZE;
+
+#ifdef USE_AMD64_ASM
+  {
+    if (nblocks >= 4)
+      burn_stack_depth += 5 * sizeof(void*);
+
+    /* Process data in 4 block chunks. */
+    while (nblocks >= 4)
+      {
+        _gcry_blowfish_amd64_cfb_dec(ctx, outbuf, inbuf, iv);
+
+        nblocks -= 4;
+        outbuf += 4 * BLOWFISH_BLOCKSIZE;
+        inbuf  += 4 * BLOWFISH_BLOCKSIZE;
+      }
+
+    /* Use generic code to handle smaller chunks... */
+  }
+#elif defined(USE_ARM_ASM)
+  {
+    /* Process data in 2 block chunks. */
+    while (nblocks >= 2)
+      {
+        _gcry_blowfish_arm_cfb_dec(ctx, outbuf, inbuf, iv);
+
+        nblocks -= 2;
+        outbuf += 2 * BLOWFISH_BLOCKSIZE;
+        inbuf  += 2 * BLOWFISH_BLOCKSIZE;
+      }
+
+    /* Use generic code to handle smaller chunks... */
+  }
+#endif
+
+  for ( ;nblocks; nblocks-- )
+    {
+      do_encrypt_block(ctx, iv, iv);
+      buf_xor_n_copy(outbuf, iv, inbuf, BLOWFISH_BLOCKSIZE);
+      outbuf += BLOWFISH_BLOCKSIZE;
+      inbuf  += BLOWFISH_BLOCKSIZE;
+    }
+
+  _gcry_burn_stack(burn_stack_depth);
+}
+
+
+/* Run the self-tests for BLOWFISH-CTR, tests IV increment of bulk CTR
+   encryption.  Returns NULL on success. */
+static const char *
+selftest_ctr (void)
+{
+  const int nblocks = 4+1;
+  const int blocksize = BLOWFISH_BLOCKSIZE;
+  const int context_size = sizeof(BLOWFISH_context);
+
+  return _gcry_selftest_helper_ctr("BLOWFISH", &bf_setkey,
+           &encrypt_block, &_gcry_blowfish_ctr_enc, nblocks, blocksize,
+          context_size);
+}
+
+
+/* Run the self-tests for BLOWFISH-CBC, tests bulk CBC decryption.
+   Returns NULL on success. */
+static const char *
+selftest_cbc (void)
+{
+  const int nblocks = 4+2;
+  const int blocksize = BLOWFISH_BLOCKSIZE;
+  const int context_size = sizeof(BLOWFISH_context);
+
+  return _gcry_selftest_helper_cbc("BLOWFISH", &bf_setkey,
+           &encrypt_block, &_gcry_blowfish_cbc_dec, nblocks, blocksize,
+          context_size);
+}
+
+
+/* Run the self-tests for BLOWFISH-CFB, tests bulk CBC decryption.
+   Returns NULL on success. */
+static const char *
+selftest_cfb (void)
+{
+  const int nblocks = 4+2;
+  const int blocksize = BLOWFISH_BLOCKSIZE;
+  const int context_size = sizeof(BLOWFISH_context);
+
+  return _gcry_selftest_helper_cfb("BLOWFISH", &bf_setkey,
+           &encrypt_block, &_gcry_blowfish_cfb_dec, nblocks, blocksize,
+          context_size);
 }
 
 
@@ -468,9 +822,13 @@ selftest(void)
   BLOWFISH_context c;
   byte plain[] = "BLOWFISH";
   byte buffer[8];
-  byte plain3[] = { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 };
-  byte key3[] = { 0x41, 0x79, 0x6E, 0xA0, 0x52, 0x61, 0x6E, 0xE4 };
-  byte cipher3[] = { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 };
+  static const byte plain3[] =
+    { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 };
+  static const byte key3[] =
+    { 0x41, 0x79, 0x6E, 0xA0, 0x52, 0x61, 0x6E, 0xE4 };
+  static const byte cipher3[] =
+    { 0xE1, 0x13, 0xF4, 0x10, 0x2C, 0xFC, 0xCE, 0x43 };
+  const char *r;
 
   bf_setkey( (void *) &c,
              (const unsigned char*)"abcdefghijklmnopqrstuvwxyz", 26 );
@@ -488,15 +846,81 @@ selftest(void)
   decrypt_block( (void *) &c, buffer, buffer );
   if( memcmp( buffer, plain3, 8 ) )
     return "Blowfish selftest failed (4).";
+
+  if ( (r = selftest_cbc ()) )
+    return r;
+
+  if ( (r = selftest_cfb ()) )
+    return r;
+
+  if ( (r = selftest_ctr ()) )
+    return r;
+
   return NULL;
 }
 
 
+struct hashset_elem {
+  u32 val;
+  short nidx;
+  char used;
+};
+
+static inline byte
+val_to_hidx(u32 val)
+{
+  /* bf sboxes are quite random already. */
+  return (val >> 24) ^ (val >> 16)  ^ (val >> 8) ^ val;
+}
+
+static inline int
+add_val(struct hashset_elem hset[256], u32 val, int *midx,
+       struct hashset_elem *mpool)
+{
+  struct hashset_elem *elem;
+  byte hidx;
+
+  hidx = val_to_hidx(val);
+  elem = &hset[hidx];
+
+  /* Check if first is in use. */
+  if (elem->used == 0)
+    {
+      elem->val = val;
+      elem->nidx = -1;
+      elem->used = 1;
+      return 0;
+    }
+
+  /* Check if first matches. */
+  if (elem->val == val)
+    return 1;
+
+  for (; elem->nidx >= 0; elem = &mpool[elem->nidx])
+    {
+      /* Check if elem matches. */
+      if (elem->val == val)
+        return 1;
+    }
+
+  elem->nidx = (*midx)++;
+  elem = &mpool[elem->nidx];
+
+  elem->val = val;
+  elem->nidx = -1;
+  elem->used = 1;
+
+  return 0;
+}
 
 static gcry_err_code_t
 do_bf_setkey (BLOWFISH_context *c, const byte *key, unsigned keylen)
 {
-  int i, j;
+  struct hashset_elem mempool[4 * 255]; /* Enough entries for the worst case. */
+  struct hashset_elem hset[4][256];
+  int memidx = 0;
+  int weak = 0;
+  int i, j, ret;
   u32 data, datal, datar;
   static int initialized;
   static const char *selftest_failed;
@@ -511,6 +935,8 @@ do_bf_setkey (BLOWFISH_context *c, const byte *key, unsigned keylen)
   if( selftest_failed )
     return GPG_ERR_SELFTEST_FAILED;
 
+  memset(hset, 0, sizeof(hset));
+
   for(i=0; i < BLOWFISH_ROUNDS+2; i++ )
     c->p[i] = ps[i];
   for(i=0; i < 256; i++ )
@@ -523,17 +949,10 @@ do_bf_setkey (BLOWFISH_context *c, const byte *key, unsigned keylen)
 
   for(i=j=0; i < BLOWFISH_ROUNDS+2; i++ )
     {
-#ifdef WORDS_BIGENDIAN
-      ((byte*)&data)[0] = key[j];
-      ((byte*)&data)[1] = key[(j+1)%keylen];
-      ((byte*)&data)[2] = key[(j+2)%keylen];
-      ((byte*)&data)[3] = key[(j+3)%keylen];
-#else
-      ((byte*)&data)[3] = key[j];
-      ((byte*)&data)[2] = key[(j+1)%keylen];
-      ((byte*)&data)[1] = key[(j+2)%keylen];
-      ((byte*)&data)[0] = key[(j+3)%keylen];
-#endif
+      data = ((u32)key[j] << 24) |
+             ((u32)key[(j+1)%keylen] << 16) |
+             ((u32)key[(j+2)%keylen] << 8) |
+             ((u32)key[(j+3)%keylen]);
       c->p[i] ^= data;
       j = (j+4) % keylen;
     }
@@ -550,38 +969,60 @@ do_bf_setkey (BLOWFISH_context *c, const byte *key, unsigned keylen)
       do_encrypt( c, &datal, &datar );
       c->s0[i]   = datal;
       c->s0[i+1] = datar;
+
+      /* Add values to hashset, detect duplicates (weak keys). */
+      ret = add_val (hset[0], datal, &memidx, mempool);
+      weak = ret ? 1 : weak;
+      ret = add_val (hset[0], datar, &memidx, mempool);
+      weak = ret ? 1 : weak;
     }
   for(i=0; i < 256; i += 2 )
     {
       do_encrypt( c, &datal, &datar );
       c->s1[i]   = datal;
       c->s1[i+1] = datar;
+
+      /* Add values to hashset, detect duplicates (weak keys). */
+      ret = add_val (hset[1], datal, &memidx, mempool);
+      weak = ret ? 1 : weak;
+      ret = add_val (hset[1], datar, &memidx, mempool);
+      weak = ret ? 1 : weak;
     }
   for(i=0; i < 256; i += 2 )
     {
       do_encrypt( c, &datal, &datar );
       c->s2[i]   = datal;
       c->s2[i+1] = datar;
+
+      /* Add values to hashset, detect duplicates (weak keys). */
+      ret = add_val (hset[2], datal, &memidx, mempool);
+      weak = ret ? 1 : weak;
+      ret = add_val (hset[2], datar, &memidx, mempool);
+      weak = ret ? 1 : weak;
     }
   for(i=0; i < 256; i += 2 )
     {
       do_encrypt( c, &datal, &datar );
       c->s3[i]   = datal;
       c->s3[i+1] = datar;
+
+      /* Add values to hashset, detect duplicates (weak keys). */
+      ret = add_val (hset[3], datal, &memidx, mempool);
+      weak = ret ? 1 : weak;
+      ret = add_val (hset[3], datar, &memidx, mempool);
+      weak = ret ? 1 : weak;
     }
 
+  /* Clear stack. */
+  wipememory(hset, sizeof(hset));
+  wipememory(mempool, sizeof(mempool[0]) * memidx);
+
+  _gcry_burn_stack (64);
 
   /* Check for weak key.  A weak key is a key in which a value in
      the P-array (here c) occurs more than once per table.  */
-  for(i=0; i < 255; i++ )
-    {
-      for( j=i+1; j < 256; j++)
-        {
-          if( (c->s0[i] == c->s0[j]) || (c->s1[i] == c->s1[j]) ||
-              (c->s2[i] == c->s2[j]) || (c->s3[i] == c->s3[j]) )
-            return GPG_ERR_WEAK_KEY;
-        }
-    }
+  if (weak)
+    return GPG_ERR_WEAK_KEY;
 
   return GPG_ERR_NO_ERROR;
 }
@@ -592,13 +1033,13 @@ bf_setkey (void *context, const byte *key, unsigned keylen)
 {
   BLOWFISH_context *c = (BLOWFISH_context *) context;
   gcry_err_code_t rc = do_bf_setkey (c, key, keylen);
-  _gcry_burn_stack (64);
   return rc;
 }
 
 
 gcry_cipher_spec_t _gcry_cipher_spec_blowfish =
   {
+    GCRY_CIPHER_BLOWFISH, {0, 0},
     "BLOWFISH", NULL, NULL, BLOWFISH_BLOCKSIZE, 128,
     sizeof (BLOWFISH_context),
     bf_setkey, encrypt_block, decrypt_block
diff --git a/cipher/bufhelp.h b/cipher/bufhelp.h
new file mode 100644 (file)
index 0000000..45a7209
--- /dev/null
@@ -0,0 +1,378 @@
+/* bufhelp.h  -  Some buffer manipulation helpers
+ *     Copyright © 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
+ * 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
+ */
+#ifndef G10_BUFHELP_H
+#define G10_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__)
+/* These architectures are able of unaligned memory accesses and can
+   handle those fast.
+ */
+# define BUFHELP_FAST_UNALIGNED_ACCESS 1
+#endif
+
+
+/* Optimized function for small buffer copying */
+static inline void
+buf_cpy(void *_dst, const void *_src, size_t len)
+{
+#if __GNUC__ >= 4 && (defined(__x86_64__) || defined(__i386__))
+  /* For AMD64 and i386, memcpy is faster.  */
+  memcpy(_dst, _src, len);
+#else
+  byte *dst = _dst;
+  const byte *src = _src;
+  uintptr_t *ldst;
+  const uintptr_t *lsrc;
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+  const unsigned int longmask = sizeof(uintptr_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;
+
+  for (; len >= sizeof(uintptr_t); len -= sizeof(uintptr_t))
+    *ldst++ = *lsrc++;
+
+  dst = (byte *)ldst;
+  src = (const byte *)lsrc;
+
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+do_bytes:
+#endif
+  /* Handle tail.  */
+  for (; len; len--)
+    *dst++ = *src++;
+#endif /*__GNUC__ >= 4 && (__x86_64__ || __i386__)*/
+}
+
+
+/* Optimized function for buffer xoring */
+static inline void
+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;
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+  const unsigned int longmask = sizeof(uintptr_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;
+
+  for (; len >= sizeof(uintptr_t); len -= sizeof(uintptr_t))
+    *ldst++ = *lsrc1++ ^ *lsrc2++;
+
+  dst = (byte *)ldst;
+  src1 = (const byte *)lsrc1;
+  src2 = (const byte *)lsrc2;
+
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+do_bytes:
+#endif
+  /* Handle tail.  */
+  for (; len; len--)
+    *dst++ = *src1++ ^ *src2++;
+}
+
+
+/* Optimized function for buffer xoring with two destination buffers.  Used
+   mainly by CFB mode encryption.  */
+static inline void
+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;
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+  const unsigned int longmask = sizeof(uintptr_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;
+
+  for (; len >= sizeof(uintptr_t); len -= sizeof(uintptr_t))
+    *ldst1++ = (*ldst2++ ^= *lsrc++);
+
+  dst1 = (byte *)ldst1;
+  dst2 = (byte *)ldst2;
+  src = (const byte *)lsrc;
+
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+do_bytes:
+#endif
+  /* Handle tail.  */
+  for (; len; len--)
+    *dst1++ = (*dst2++ ^= *src++);
+}
+
+
+/* Optimized function for combined buffer xoring and copying.  Used by mainly
+   CBC mode decryption.  */
+static inline void
+buf_xor_n_copy_2(void *_dst_xor, const void *_src_xor, void *_srcdst_cpy,
+                const void *_src_cpy, size_t len)
+{
+  byte *dst_xor = _dst_xor;
+  byte *srcdst_cpy = _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;
+  uintptr_t ltemp;
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+  const unsigned int longmask = sizeof(uintptr_t) - 1;
+
+  /* Skip fast processing if buffers are unaligned.  */
+  if (((uintptr_t)src_cpy | (uintptr_t)src_xor | (uintptr_t)dst_xor |
+       (uintptr_t)srcdst_cpy) & longmask)
+    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;
+
+  for (; len >= sizeof(uintptr_t); len -= sizeof(uintptr_t))
+    {
+      ltemp = *lsrc_cpy++;
+      *ldst_xor++ = *lsrcdst_cpy ^ *lsrc_xor++;
+      *lsrcdst_cpy++ = ltemp;
+    }
+
+  dst_xor = (byte *)ldst_xor;
+  src_xor = (const byte *)lsrc_xor;
+  srcdst_cpy = (byte *)lsrcdst_cpy;
+  src_cpy = (const byte *)lsrc_cpy;
+
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+do_bytes:
+#endif
+  /* Handle tail.  */
+  for (; len; len--)
+    {
+      temp = *src_cpy++;
+      *dst_xor++ = *srcdst_cpy ^ *src_xor++;
+      *srcdst_cpy++ = temp;
+    }
+}
+
+
+/* Optimized function for combined buffer xoring and copying.  Used by mainly
+   CFB mode decryption.  */
+static inline void
+buf_xor_n_copy(void *_dst_xor, void *_srcdst_cpy, const void *_src, size_t len)
+{
+  buf_xor_n_copy_2(_dst_xor, _src, _srcdst_cpy, _src, len);
+}
+
+
+/* Constant-time compare of two buffers.  Returns 1 if buffers are equal,
+   and 0 if buffers differ.  */
+static inline int
+buf_eq_const(const void *_a, const void *_b, size_t len)
+{
+  const byte *a = _a;
+  const byte *b = _b;
+  size_t diff, i;
+
+  /* Constant-time compare. */
+  for (i = 0, diff = 0; i < len; i++)
+    diff -= !!(a[i] - b[i]);
+
+  return !diff;
+}
+
+
+#ifndef BUFHELP_FAST_UNALIGNED_ACCESS
+
+/* Functions for loading and storing unaligned u32 values of different
+   endianness.  */
+static inline u32 buf_get_be32(const void *_buf)
+{
+  const byte *in = _buf;
+  return ((u32)in[0] << 24) | ((u32)in[1] << 16) | \
+         ((u32)in[2] << 8) | (u32)in[3];
+}
+
+static inline u32 buf_get_le32(const void *_buf)
+{
+  const byte *in = _buf;
+  return ((u32)in[3] << 24) | ((u32)in[2] << 16) | \
+         ((u32)in[1] << 8) | (u32)in[0];
+}
+
+static inline void buf_put_be32(void *_buf, u32 val)
+{
+  byte *out = _buf;
+  out[0] = val >> 24;
+  out[1] = val >> 16;
+  out[2] = val >> 8;
+  out[3] = val;
+}
+
+static inline void buf_put_le32(void *_buf, u32 val)
+{
+  byte *out = _buf;
+  out[3] = val >> 24;
+  out[2] = val >> 16;
+  out[1] = val >> 8;
+  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)
+{
+  const byte *in = _buf;
+  return ((u64)in[0] << 56) | ((u64)in[1] << 48) | \
+         ((u64)in[2] << 40) | ((u64)in[3] << 32) | \
+         ((u64)in[4] << 24) | ((u64)in[5] << 16) | \
+         ((u64)in[6] << 8) | (u64)in[7];
+}
+
+static inline u64 buf_get_le64(const void *_buf)
+{
+  const byte *in = _buf;
+  return ((u64)in[7] << 56) | ((u64)in[6] << 48) | \
+         ((u64)in[5] << 40) | ((u64)in[4] << 32) | \
+         ((u64)in[3] << 24) | ((u64)in[2] << 16) | \
+         ((u64)in[1] << 8) | (u64)in[0];
+}
+
+static inline void buf_put_be64(void *_buf, u64 val)
+{
+  byte *out = _buf;
+  out[0] = val >> 56;
+  out[1] = val >> 48;
+  out[2] = val >> 40;
+  out[3] = val >> 32;
+  out[4] = val >> 24;
+  out[5] = val >> 16;
+  out[6] = val >> 8;
+  out[7] = val;
+}
+
+static inline void buf_put_le64(void *_buf, u64 val)
+{
+  byte *out = _buf;
+  out[7] = val >> 56;
+  out[6] = val >> 48;
+  out[5] = val >> 40;
+  out[4] = val >> 32;
+  out[3] = val >> 24;
+  out[2] = val >> 16;
+  out[1] = val >> 8;
+  out[0] = val;
+}
+#endif /*HAVE_U64_TYPEDEF*/
+
+#else /*BUFHELP_FAST_UNALIGNED_ACCESS*/
+
+/* 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);
+}
+
+static inline u32 buf_get_le32(const void *_buf)
+{
+  return le_bswap32(*(const u32 *)_buf);
+}
+
+static inline void buf_put_be32(void *_buf, u32 val)
+{
+  u32 *out = _buf;
+  *out = be_bswap32(val);
+}
+
+static inline void buf_put_le32(void *_buf, u32 val)
+{
+  u32 *out = _buf;
+  *out = le_bswap32(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)
+{
+  return be_bswap64(*(const u64 *)_buf);
+}
+
+static inline u64 buf_get_le64(const void *_buf)
+{
+  return le_bswap64(*(const u64 *)_buf);
+}
+
+static inline void buf_put_be64(void *_buf, u64 val)
+{
+  u64 *out = _buf;
+  *out = be_bswap64(val);
+}
+
+static inline void buf_put_le64(void *_buf, u64 val)
+{
+  u64 *out = _buf;
+  *out = le_bswap64(val);
+}
+#endif /*HAVE_U64_TYPEDEF*/
+
+#endif /*BUFHELP_FAST_UNALIGNED_ACCESS*/
+
+#endif /*G10_BITHELP_H*/
diff --git a/cipher/camellia-aesni-avx-amd64.S b/cipher/camellia-aesni-avx-amd64.S
new file mode 100644 (file)
index 0000000..38ec7a3
--- /dev/null
@@ -0,0 +1,2165 @@
+/* camellia-avx-aesni-amd64.S  -  AES-NI/AVX implementation of Camellia cipher
+ *
+ * Copyright © 2013 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(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX_SUPPORT)
+
+#ifdef __PIC__
+#  define RIP (%rip)
+#else
+#  define RIP
+#endif
+
+#define CAMELLIA_TABLE_BYTE_LEN 272
+
+/* struct CAMELLIA_context: */
+#define key_table 0
+#define key_bitlength CAMELLIA_TABLE_BYTE_LEN
+
+/* register macros */
+#define CTX %rdi
+#define RIO %r8
+
+/**********************************************************************
+  helper macros
+ **********************************************************************/
+#define filter_8bit(x, lo_t, hi_t, mask4bit, tmp0) \
+       vpand x, mask4bit, tmp0; \
+       vpandn x, mask4bit, x; \
+       vpsrld $4, x, x; \
+       \
+       vpshufb tmp0, lo_t, tmp0; \
+       vpshufb x, hi_t, x; \
+       vpxor tmp0, x, x;
+
+/**********************************************************************
+  16-way camellia
+ **********************************************************************/
+
+/*
+ * IN:
+ *   x0..x7: byte-sliced AB state
+ *   mem_cd: register pointer storing CD state
+ *   key: index for key material
+ * OUT:
+ *   x0..x7: new byte-sliced CD state
+ */
+#define roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, t0, t1, t2, t3, t4, t5, t6, \
+                 t7, mem_cd, key) \
+       /* \
+        * S-function with AES subbytes \
+        */ \
+       vmovdqa .Linv_shift_row RIP, t4; \
+       vbroadcastss .L0f0f0f0f RIP, t7; \
+       vmovdqa .Lpre_tf_lo_s1 RIP, t0; \
+       vmovdqa .Lpre_tf_hi_s1 RIP, t1; \
+       \
+       /* AES inverse shift rows */ \
+       vpshufb t4, x0, x0; \
+       vpshufb t4, x7, x7; \
+       vpshufb t4, x1, x1; \
+       vpshufb t4, x4, x4; \
+       vpshufb t4, x2, x2; \
+       vpshufb t4, x5, x5; \
+       vpshufb t4, x3, x3; \
+       vpshufb t4, x6, x6; \
+       \
+       /* prefilter sboxes 1, 2 and 3 */ \
+       vmovdqa .Lpre_tf_lo_s4 RIP, t2; \
+       vmovdqa .Lpre_tf_hi_s4 RIP, t3; \
+       filter_8bit(x0, t0, t1, t7, t6); \
+       filter_8bit(x7, t0, t1, t7, t6); \
+       filter_8bit(x1, t0, t1, t7, t6); \
+       filter_8bit(x4, t0, t1, t7, t6); \
+       filter_8bit(x2, t0, t1, t7, t6); \
+       filter_8bit(x5, t0, t1, t7, t6); \
+       \
+       /* prefilter sbox 4 */ \
+       vpxor t4, t4, t4; \
+       filter_8bit(x3, t2, t3, t7, t6); \
+       filter_8bit(x6, t2, t3, t7, t6); \
+       \
+       /* AES subbytes + AES shift rows */ \
+       vmovdqa .Lpost_tf_lo_s1 RIP, t0; \
+       vmovdqa .Lpost_tf_hi_s1 RIP, t1; \
+       vaesenclast t4, x0, x0; \
+       vaesenclast t4, x7, x7; \
+       vaesenclast t4, x1, x1; \
+       vaesenclast t4, x4, x4; \
+       vaesenclast t4, x2, x2; \
+       vaesenclast t4, x5, x5; \
+       vaesenclast t4, x3, x3; \
+       vaesenclast t4, x6, x6; \
+       \
+       /* postfilter sboxes 1 and 4 */ \
+       vmovdqa .Lpost_tf_lo_s3 RIP, t2; \
+       vmovdqa .Lpost_tf_hi_s3 RIP, t3; \
+       filter_8bit(x0, t0, t1, t7, t6); \
+       filter_8bit(x7, t0, t1, t7, t6); \
+       filter_8bit(x3, t0, t1, t7, t6); \
+       filter_8bit(x6, t0, t1, t7, t6); \
+       \
+       /* postfilter sbox 3 */ \
+       vmovdqa .Lpost_tf_lo_s2 RIP, t4; \
+       vmovdqa .Lpost_tf_hi_s2 RIP, t5; \
+       filter_8bit(x2, t2, t3, t7, t6); \
+       filter_8bit(x5, t2, t3, t7, t6); \
+       \
+       vpxor t6, t6, t6; \
+       vmovq key, t0; \
+       \
+       /* postfilter sbox 2 */ \
+       filter_8bit(x1, t4, t5, t7, t2); \
+       filter_8bit(x4, t4, t5, t7, t2); \
+       \
+       vpsrldq $5, t0, t5; \
+       vpsrldq $1, t0, t1; \
+       vpsrldq $2, t0, t2; \
+       vpsrldq $3, t0, t3; \
+       vpsrldq $4, t0, t4; \
+       vpshufb t6, t0, t0; \
+       vpshufb t6, t1, t1; \
+       vpshufb t6, t2, t2; \
+       vpshufb t6, t3, t3; \
+       vpshufb t6, t4, t4; \
+       vpsrldq $2, t5, t7; \
+       vpshufb t6, t7, t7; \
+       \
+       /* P-function */ \
+       vpxor x5, x0, x0; \
+       vpxor x6, x1, x1; \
+       vpxor x7, x2, x2; \
+       vpxor x4, x3, x3; \
+       \
+       vpxor x2, x4, x4; \
+       vpxor x3, x5, x5; \
+       vpxor x0, x6, x6; \
+       vpxor x1, x7, x7; \
+       \
+       vpxor x7, x0, x0; \
+       vpxor x4, x1, x1; \
+       vpxor x5, x2, x2; \
+       vpxor x6, x3, x3; \
+       \
+       vpxor x3, x4, x4; \
+       vpxor x0, x5, x5; \
+       vpxor x1, x6, x6; \
+       vpxor x2, x7, x7; /* note: high and low parts swapped */ \
+       \
+       /* Add key material and result to CD (x becomes new CD) */ \
+       \
+       vpxor t3, x4, x4; \
+       vpxor 0 * 16(mem_cd), x4, x4; \
+       \
+       vpxor t2, x5, x5; \
+       vpxor 1 * 16(mem_cd), x5, x5; \
+       \
+       vpsrldq $1, t5, t3; \
+       vpshufb t6, t5, t5; \
+       vpshufb t6, t3, t6; \
+       \
+       vpxor t1, x6, x6; \
+       vpxor 2 * 16(mem_cd), x6, x6; \
+       \
+       vpxor t0, x7, x7; \
+       vpxor 3 * 16(mem_cd), x7, x7; \
+       \
+       vpxor t7, x0, x0; \
+       vpxor 4 * 16(mem_cd), x0, x0; \
+       \
+       vpxor t6, x1, x1; \
+       vpxor 5 * 16(mem_cd), x1, x1; \
+       \
+       vpxor t5, x2, x2; \
+       vpxor 6 * 16(mem_cd), x2, x2; \
+       \
+       vpxor t4, x3, x3; \
+       vpxor 7 * 16(mem_cd), x3, x3;
+
+/*
+ * IN/OUT:
+ *  x0..x7: byte-sliced AB state preloaded
+ *  mem_ab: byte-sliced AB state in memory
+ *  mem_cb: byte-sliced CD state in memory
+ */
+#define two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd, i, dir, store_ab) \
+       roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                 y6, y7, mem_cd, (key_table + (i) * 8)(CTX)); \
+       \
+       vmovdqu x4, 0 * 16(mem_cd); \
+       vmovdqu x5, 1 * 16(mem_cd); \
+       vmovdqu x6, 2 * 16(mem_cd); \
+       vmovdqu x7, 3 * 16(mem_cd); \
+       vmovdqu x0, 4 * 16(mem_cd); \
+       vmovdqu x1, 5 * 16(mem_cd); \
+       vmovdqu x2, 6 * 16(mem_cd); \
+       vmovdqu x3, 7 * 16(mem_cd); \
+       \
+       roundsm16(x4, x5, x6, x7, x0, x1, x2, x3, y0, y1, y2, y3, y4, y5, \
+                 y6, y7, mem_ab, (key_table + ((i) + (dir)) * 8)(CTX)); \
+       \
+       store_ab(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab);
+
+#define dummy_store(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab) /* do nothing */
+
+#define store_ab_state(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab) \
+       /* Store new AB state */ \
+       vmovdqu x0, 0 * 16(mem_ab); \
+       vmovdqu x1, 1 * 16(mem_ab); \
+       vmovdqu x2, 2 * 16(mem_ab); \
+       vmovdqu x3, 3 * 16(mem_ab); \
+       vmovdqu x4, 4 * 16(mem_ab); \
+       vmovdqu x5, 5 * 16(mem_ab); \
+       vmovdqu x6, 6 * 16(mem_ab); \
+       vmovdqu x7, 7 * 16(mem_ab);
+
+#define enc_rounds16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd, i) \
+       two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd, (i) + 2, 1, store_ab_state); \
+       two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd, (i) + 4, 1, store_ab_state); \
+       two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd, (i) + 6, 1, dummy_store);
+
+#define dec_rounds16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd, i) \
+       two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd, (i) + 7, -1, store_ab_state); \
+       two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd, (i) + 5, -1, store_ab_state); \
+       two_roundsm16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd, (i) + 3, -1, dummy_store);
+
+/*
+ * IN:
+ *  v0..3: byte-sliced 32-bit integers
+ * OUT:
+ *  v0..3: (IN <<< 1)
+ */
+#define rol32_1_16(v0, v1, v2, v3, t0, t1, t2, zero) \
+       vpcmpgtb v0, zero, t0; \
+       vpaddb v0, v0, v0; \
+       vpabsb t0, t0; \
+       \
+       vpcmpgtb v1, zero, t1; \
+       vpaddb v1, v1, v1; \
+       vpabsb t1, t1; \
+       \
+       vpcmpgtb v2, zero, t2; \
+       vpaddb v2, v2, v2; \
+       vpabsb t2, t2; \
+       \
+       vpor t0, v1, v1; \
+       \
+       vpcmpgtb v3, zero, t0; \
+       vpaddb v3, v3, v3; \
+       vpabsb t0, t0; \
+       \
+       vpor t1, v2, v2; \
+       vpor t2, v3, v3; \
+       vpor t0, v0, v0;
+
+/*
+ * IN:
+ *   r: byte-sliced AB state in memory
+ *   l: byte-sliced CD state in memory
+ * OUT:
+ *   x0..x7: new byte-sliced CD state
+ */
+#define fls16(l, l0, l1, l2, l3, l4, l5, l6, l7, r, t0, t1, t2, t3, tt0, \
+             tt1, tt2, tt3, kll, klr, krl, krr) \
+       /* \
+        * t0 = kll; \
+        * t0 &= ll; \
+        * lr ^= rol32(t0, 1); \
+        */ \
+       vpxor tt0, tt0, tt0; \
+       vmovd kll, t0; \
+       vpshufb tt0, t0, t3; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t2; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t1; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t0; \
+       \
+       vpand l0, t0, t0; \
+       vpand l1, t1, t1; \
+       vpand l2, t2, t2; \
+       vpand l3, t3, t3; \
+       \
+       rol32_1_16(t3, t2, t1, t0, tt1, tt2, tt3, tt0); \
+       \
+       vpxor l4, t0, l4; \
+       vmovdqu l4, 4 * 16(l); \
+       vpxor l5, t1, l5; \
+       vmovdqu l5, 5 * 16(l); \
+       vpxor l6, t2, l6; \
+       vmovdqu l6, 6 * 16(l); \
+       vpxor l7, t3, l7; \
+       vmovdqu l7, 7 * 16(l); \
+       \
+       /* \
+        * t2 = krr; \
+        * t2 |= rr; \
+        * rl ^= t2; \
+        */ \
+       \
+       vmovd krr, t0; \
+       vpshufb tt0, t0, t3; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t2; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t1; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t0; \
+       \
+       vpor 4 * 16(r), t0, t0; \
+       vpor 5 * 16(r), t1, t1; \
+       vpor 6 * 16(r), t2, t2; \
+       vpor 7 * 16(r), t3, t3; \
+       \
+       vpxor 0 * 16(r), t0, t0; \
+       vpxor 1 * 16(r), t1, t1; \
+       vpxor 2 * 16(r), t2, t2; \
+       vpxor 3 * 16(r), t3, t3; \
+       vmovdqu t0, 0 * 16(r); \
+       vmovdqu t1, 1 * 16(r); \
+       vmovdqu t2, 2 * 16(r); \
+       vmovdqu t3, 3 * 16(r); \
+       \
+       /* \
+        * t2 = krl; \
+        * t2 &= rl; \
+        * rr ^= rol32(t2, 1); \
+        */ \
+       vmovd krl, t0; \
+       vpshufb tt0, t0, t3; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t2; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t1; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t0; \
+       \
+       vpand 0 * 16(r), t0, t0; \
+       vpand 1 * 16(r), t1, t1; \
+       vpand 2 * 16(r), t2, t2; \
+       vpand 3 * 16(r), t3, t3; \
+       \
+       rol32_1_16(t3, t2, t1, t0, tt1, tt2, tt3, tt0); \
+       \
+       vpxor 4 * 16(r), t0, t0; \
+       vpxor 5 * 16(r), t1, t1; \
+       vpxor 6 * 16(r), t2, t2; \
+       vpxor 7 * 16(r), t3, t3; \
+       vmovdqu t0, 4 * 16(r); \
+       vmovdqu t1, 5 * 16(r); \
+       vmovdqu t2, 6 * 16(r); \
+       vmovdqu t3, 7 * 16(r); \
+       \
+       /* \
+        * t0 = klr; \
+        * t0 |= lr; \
+        * ll ^= t0; \
+        */ \
+       \
+       vmovd klr, t0; \
+       vpshufb tt0, t0, t3; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t2; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t1; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t0; \
+       \
+       vpor l4, t0, t0; \
+       vpor l5, t1, t1; \
+       vpor l6, t2, t2; \
+       vpor l7, t3, t3; \
+       \
+       vpxor l0, t0, l0; \
+       vmovdqu l0, 0 * 16(l); \
+       vpxor l1, t1, l1; \
+       vmovdqu l1, 1 * 16(l); \
+       vpxor l2, t2, l2; \
+       vmovdqu l2, 2 * 16(l); \
+       vpxor l3, t3, l3; \
+       vmovdqu l3, 3 * 16(l);
+
+#define transpose_4x4(x0, x1, x2, x3, t1, t2) \
+       vpunpckhdq x1, x0, t2; \
+       vpunpckldq x1, x0, x0; \
+       \
+       vpunpckldq x3, x2, t1; \
+       vpunpckhdq x3, x2, x2; \
+       \
+       vpunpckhqdq t1, x0, x1; \
+       vpunpcklqdq t1, x0, x0; \
+       \
+       vpunpckhqdq x2, t2, x3; \
+       vpunpcklqdq x2, t2, x2;
+
+#define byteslice_16x16b_fast(a0, b0, c0, d0, a1, b1, c1, d1, a2, b2, c2, d2, \
+                             a3, b3, c3, d3, st0, st1) \
+       vmovdqu d2, st0; \
+       vmovdqu d3, st1; \
+       transpose_4x4(a0, a1, a2, a3, d2, d3); \
+       transpose_4x4(b0, b1, b2, b3, d2, d3); \
+       vmovdqu st0, d2; \
+       vmovdqu st1, d3; \
+       \
+       vmovdqu a0, st0; \
+       vmovdqu a1, st1; \
+       transpose_4x4(c0, c1, c2, c3, a0, a1); \
+       transpose_4x4(d0, d1, d2, d3, a0, a1); \
+       \
+       vmovdqu .Lshufb_16x16b RIP, a0; \
+       vmovdqu st1, a1; \
+       vpshufb a0, a2, a2; \
+       vpshufb a0, a3, a3; \
+       vpshufb a0, b0, b0; \
+       vpshufb a0, b1, b1; \
+       vpshufb a0, b2, b2; \
+       vpshufb a0, b3, b3; \
+       vpshufb a0, a1, a1; \
+       vpshufb a0, c0, c0; \
+       vpshufb a0, c1, c1; \
+       vpshufb a0, c2, c2; \
+       vpshufb a0, c3, c3; \
+       vpshufb a0, d0, d0; \
+       vpshufb a0, d1, d1; \
+       vpshufb a0, d2, d2; \
+       vpshufb a0, d3, d3; \
+       vmovdqu d3, st1; \
+       vmovdqu st0, d3; \
+       vpshufb a0, d3, a0; \
+       vmovdqu d2, st0; \
+       \
+       transpose_4x4(a0, b0, c0, d0, d2, d3); \
+       transpose_4x4(a1, b1, c1, d1, d2, d3); \
+       vmovdqu st0, d2; \
+       vmovdqu st1, d3; \
+       \
+       vmovdqu b0, st0; \
+       vmovdqu b1, st1; \
+       transpose_4x4(a2, b2, c2, d2, b0, b1); \
+       transpose_4x4(a3, b3, c3, d3, b0, b1); \
+       vmovdqu st0, b0; \
+       vmovdqu st1, b1; \
+       /* does not adjust output bytes inside vectors */
+
+#define transpose_8x8b(a, b, c, d, e, f, g, h, t0, t1, t2, t3, t4) \
+       vpunpcklbw a, b, t0; \
+       vpunpckhbw a, b, b; \
+       \
+       vpunpcklbw c, d, t1; \
+       vpunpckhbw c, d, d; \
+       \
+       vpunpcklbw e, f, t2; \
+       vpunpckhbw e, f, f; \
+       \
+       vpunpcklbw g, h, t3; \
+       vpunpckhbw g, h, h; \
+       \
+       vpunpcklwd t0, t1, g; \
+       vpunpckhwd t0, t1, t0; \
+       \
+       vpunpcklwd b, d, t1; \
+       vpunpckhwd b, d, e; \
+       \
+       vpunpcklwd t2, t3, c; \
+       vpunpckhwd t2, t3, t2; \
+       \
+       vpunpcklwd f, h, t3; \
+       vpunpckhwd f, h, b; \
+       \
+       vpunpcklwd e, b, t4; \
+       vpunpckhwd e, b, b; \
+       \
+       vpunpcklwd t1, t3, e; \
+       vpunpckhwd t1, t3, f; \
+       \
+       vmovdqa .Ltranspose_8x8_shuf RIP, t3; \
+       \
+       vpunpcklwd g, c, d; \
+       vpunpckhwd g, c, c; \
+       \
+       vpunpcklwd t0, t2, t1; \
+       vpunpckhwd t0, t2, h; \
+       \
+       vpunpckhqdq b, h, a; \
+       vpshufb t3, a, a; \
+       vpunpcklqdq b, h, b; \
+       vpshufb t3, b, b; \
+       \
+       vpunpckhqdq e, d, g; \
+       vpshufb t3, g, g; \
+       vpunpcklqdq e, d, h; \
+       vpshufb t3, h, h; \
+       \
+       vpunpckhqdq f, c, e; \
+       vpshufb t3, e, e; \
+       vpunpcklqdq f, c, f; \
+       vpshufb t3, f, f; \
+       \
+       vpunpckhqdq t4, t1, c; \
+       vpshufb t3, c, c; \
+       vpunpcklqdq t4, t1, d; \
+       vpshufb t3, d, d;
+
+/* load blocks to registers and apply pre-whitening */
+#define inpack16_pre(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                    y6, y7, rio, key) \
+       vmovq key, x0; \
+       vpshufb .Lpack_bswap RIP, x0, x0; \
+       \
+       vpxor 0 * 16(rio), x0, y7; \
+       vpxor 1 * 16(rio), x0, y6; \
+       vpxor 2 * 16(rio), x0, y5; \
+       vpxor 3 * 16(rio), x0, y4; \
+       vpxor 4 * 16(rio), x0, y3; \
+       vpxor 5 * 16(rio), x0, y2; \
+       vpxor 6 * 16(rio), x0, y1; \
+       vpxor 7 * 16(rio), x0, y0; \
+       vpxor 8 * 16(rio), x0, x7; \
+       vpxor 9 * 16(rio), x0, x6; \
+       vpxor 10 * 16(rio), x0, x5; \
+       vpxor 11 * 16(rio), x0, x4; \
+       vpxor 12 * 16(rio), x0, x3; \
+       vpxor 13 * 16(rio), x0, x2; \
+       vpxor 14 * 16(rio), x0, x1; \
+       vpxor 15 * 16(rio), x0, x0;
+
+/* byteslice pre-whitened blocks and store to temporary memory */
+#define inpack16_post(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd) \
+       byteslice_16x16b_fast(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, \
+                             y4, y5, y6, y7, (mem_ab), (mem_cd)); \
+       \
+       vmovdqu x0, 0 * 16(mem_ab); \
+       vmovdqu x1, 1 * 16(mem_ab); \
+       vmovdqu x2, 2 * 16(mem_ab); \
+       vmovdqu x3, 3 * 16(mem_ab); \
+       vmovdqu x4, 4 * 16(mem_ab); \
+       vmovdqu x5, 5 * 16(mem_ab); \
+       vmovdqu x6, 6 * 16(mem_ab); \
+       vmovdqu x7, 7 * 16(mem_ab); \
+       vmovdqu y0, 0 * 16(mem_cd); \
+       vmovdqu y1, 1 * 16(mem_cd); \
+       vmovdqu y2, 2 * 16(mem_cd); \
+       vmovdqu y3, 3 * 16(mem_cd); \
+       vmovdqu y4, 4 * 16(mem_cd); \
+       vmovdqu y5, 5 * 16(mem_cd); \
+       vmovdqu y6, 6 * 16(mem_cd); \
+       vmovdqu y7, 7 * 16(mem_cd);
+
+/* de-byteslice, apply post-whitening and store blocks */
+#define outunpack16(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, \
+                   y5, y6, y7, key, stack_tmp0, stack_tmp1) \
+       byteslice_16x16b_fast(y0, y4, x0, x4, y1, y5, x1, x5, y2, y6, x2, x6, \
+                             y3, y7, x3, x7, stack_tmp0, stack_tmp1); \
+       \
+       vmovdqu x0, stack_tmp0; \
+       \
+       vmovq key, x0; \
+       vpshufb .Lpack_bswap RIP, x0, x0; \
+       \
+       vpxor x0, y7, y7; \
+       vpxor x0, y6, y6; \
+       vpxor x0, y5, y5; \
+       vpxor x0, y4, y4; \
+       vpxor x0, y3, y3; \
+       vpxor x0, y2, y2; \
+       vpxor x0, y1, y1; \
+       vpxor x0, y0, y0; \
+       vpxor x0, x7, x7; \
+       vpxor x0, x6, x6; \
+       vpxor x0, x5, x5; \
+       vpxor x0, x4, x4; \
+       vpxor x0, x3, x3; \
+       vpxor x0, x2, x2; \
+       vpxor x0, x1, x1; \
+       vpxor stack_tmp0, x0, x0;
+
+#define write_output(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                    y6, y7, rio) \
+       vmovdqu x0, 0 * 16(rio); \
+       vmovdqu x1, 1 * 16(rio); \
+       vmovdqu x2, 2 * 16(rio); \
+       vmovdqu x3, 3 * 16(rio); \
+       vmovdqu x4, 4 * 16(rio); \
+       vmovdqu x5, 5 * 16(rio); \
+       vmovdqu x6, 6 * 16(rio); \
+       vmovdqu x7, 7 * 16(rio); \
+       vmovdqu y0, 8 * 16(rio); \
+       vmovdqu y1, 9 * 16(rio); \
+       vmovdqu y2, 10 * 16(rio); \
+       vmovdqu y3, 11 * 16(rio); \
+       vmovdqu y4, 12 * 16(rio); \
+       vmovdqu y5, 13 * 16(rio); \
+       vmovdqu y6, 14 * 16(rio); \
+       vmovdqu y7, 15 * 16(rio);
+
+.data
+.align 16
+
+#define SHUFB_BYTES(idx) \
+       0 + (idx), 4 + (idx), 8 + (idx), 12 + (idx)
+
+.Lshufb_16x16b:
+       .byte SHUFB_BYTES(0), SHUFB_BYTES(1), SHUFB_BYTES(2), SHUFB_BYTES(3);
+
+.Lpack_bswap:
+       .long 0x00010203
+       .long 0x04050607
+       .long 0x80808080
+       .long 0x80808080
+
+/* For CTR-mode IV byteswap */
+.Lbswap128_mask:
+       .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
+
+/*
+ * pre-SubByte transform
+ *
+ * pre-lookup for sbox1, sbox2, sbox3:
+ *   swap_bitendianness(
+ *       isom_map_camellia_to_aes(
+ *           camellia_f(
+ *               swap_bitendianess(in)
+ *           )
+ *       )
+ *   )
+ *
+ * (note: '⊕ 0xc5' inside camellia_f())
+ */
+.Lpre_tf_lo_s1:
+       .byte 0x45, 0xe8, 0x40, 0xed, 0x2e, 0x83, 0x2b, 0x86
+       .byte 0x4b, 0xe6, 0x4e, 0xe3, 0x20, 0x8d, 0x25, 0x88
+.Lpre_tf_hi_s1:
+       .byte 0x00, 0x51, 0xf1, 0xa0, 0x8a, 0xdb, 0x7b, 0x2a
+       .byte 0x09, 0x58, 0xf8, 0xa9, 0x83, 0xd2, 0x72, 0x23
+
+/*
+ * pre-SubByte transform
+ *
+ * pre-lookup for sbox4:
+ *   swap_bitendianness(
+ *       isom_map_camellia_to_aes(
+ *           camellia_f(
+ *               swap_bitendianess(in <<< 1)
+ *           )
+ *       )
+ *   )
+ *
+ * (note: '⊕ 0xc5' inside camellia_f())
+ */
+.Lpre_tf_lo_s4:
+       .byte 0x45, 0x40, 0x2e, 0x2b, 0x4b, 0x4e, 0x20, 0x25
+       .byte 0x14, 0x11, 0x7f, 0x7a, 0x1a, 0x1f, 0x71, 0x74
+.Lpre_tf_hi_s4:
+       .byte 0x00, 0xf1, 0x8a, 0x7b, 0x09, 0xf8, 0x83, 0x72
+       .byte 0xad, 0x5c, 0x27, 0xd6, 0xa4, 0x55, 0x2e, 0xdf
+
+/*
+ * post-SubByte transform
+ *
+ * post-lookup for sbox1, sbox4:
+ *  swap_bitendianness(
+ *      camellia_h(
+ *          isom_map_aes_to_camellia(
+ *              swap_bitendianness(
+ *                  aes_inverse_affine_transform(in)
+ *              )
+ *          )
+ *      )
+ *  )
+ *
+ * (note: '⊕ 0x6e' inside camellia_h())
+ */
+.Lpost_tf_lo_s1:
+       .byte 0x3c, 0xcc, 0xcf, 0x3f, 0x32, 0xc2, 0xc1, 0x31
+       .byte 0xdc, 0x2c, 0x2f, 0xdf, 0xd2, 0x22, 0x21, 0xd1
+.Lpost_tf_hi_s1:
+       .byte 0x00, 0xf9, 0x86, 0x7f, 0xd7, 0x2e, 0x51, 0xa8
+       .byte 0xa4, 0x5d, 0x22, 0xdb, 0x73, 0x8a, 0xf5, 0x0c
+
+/*
+ * post-SubByte transform
+ *
+ * post-lookup for sbox2:
+ *  swap_bitendianness(
+ *      camellia_h(
+ *          isom_map_aes_to_camellia(
+ *              swap_bitendianness(
+ *                  aes_inverse_affine_transform(in)
+ *              )
+ *          )
+ *      )
+ *  ) <<< 1
+ *
+ * (note: '⊕ 0x6e' inside camellia_h())
+ */
+.Lpost_tf_lo_s2:
+       .byte 0x78, 0x99, 0x9f, 0x7e, 0x64, 0x85, 0x83, 0x62
+       .byte 0xb9, 0x58, 0x5e, 0xbf, 0xa5, 0x44, 0x42, 0xa3
+.Lpost_tf_hi_s2:
+       .byte 0x00, 0xf3, 0x0d, 0xfe, 0xaf, 0x5c, 0xa2, 0x51
+       .byte 0x49, 0xba, 0x44, 0xb7, 0xe6, 0x15, 0xeb, 0x18
+
+/*
+ * post-SubByte transform
+ *
+ * post-lookup for sbox3:
+ *  swap_bitendianness(
+ *      camellia_h(
+ *          isom_map_aes_to_camellia(
+ *              swap_bitendianness(
+ *                  aes_inverse_affine_transform(in)
+ *              )
+ *          )
+ *      )
+ *  ) >>> 1
+ *
+ * (note: '⊕ 0x6e' inside camellia_h())
+ */
+.Lpost_tf_lo_s3:
+       .byte 0x1e, 0x66, 0xe7, 0x9f, 0x19, 0x61, 0xe0, 0x98
+       .byte 0x6e, 0x16, 0x97, 0xef, 0x69, 0x11, 0x90, 0xe8
+.Lpost_tf_hi_s3:
+       .byte 0x00, 0xfc, 0x43, 0xbf, 0xeb, 0x17, 0xa8, 0x54
+       .byte 0x52, 0xae, 0x11, 0xed, 0xb9, 0x45, 0xfa, 0x06
+
+/* For isolating SubBytes from AESENCLAST, inverse shift row */
+.Linv_shift_row:
+       .byte 0x00, 0x0d, 0x0a, 0x07, 0x04, 0x01, 0x0e, 0x0b
+       .byte 0x08, 0x05, 0x02, 0x0f, 0x0c, 0x09, 0x06, 0x03
+
+/* shuffle mask for 8x8 byte transpose */
+.Ltranspose_8x8_shuf:
+       .byte 0, 1, 4, 5, 2, 3, 6, 7, 8+0, 8+1, 8+4, 8+5, 8+2, 8+3, 8+6, 8+7
+
+.align 4
+/* 4-bit mask */
+.L0f0f0f0f:
+       .long 0x0f0f0f0f
+
+.text
+
+.align 8
+.type   __camellia_enc_blk16,@function;
+
+__camellia_enc_blk16:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rax: temporary storage, 256 bytes
+        *      %xmm0..%xmm15: 16 plaintext blocks
+        * output:
+        *      %xmm0..%xmm15: 16 encrypted blocks, order swapped:
+        *       7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8
+        */
+
+       leaq 8 * 16(%rax), %rcx;
+
+       inpack16_post(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+                     %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+                     %xmm15, %rax, %rcx);
+
+       enc_rounds16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+                    %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+                    %xmm15, %rax, %rcx, 0);
+
+       fls16(%rax, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+             %rcx, %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+             %xmm15,
+             ((key_table + (8) * 8) + 0)(CTX),
+             ((key_table + (8) * 8) + 4)(CTX),
+             ((key_table + (8) * 8) + 8)(CTX),
+             ((key_table + (8) * 8) + 12)(CTX));
+
+       enc_rounds16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+                    %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+                    %xmm15, %rax, %rcx, 8);
+
+       fls16(%rax, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+             %rcx, %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+             %xmm15,
+             ((key_table + (16) * 8) + 0)(CTX),
+             ((key_table + (16) * 8) + 4)(CTX),
+             ((key_table + (16) * 8) + 8)(CTX),
+             ((key_table + (16) * 8) + 12)(CTX));
+
+       enc_rounds16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+                    %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+                    %xmm15, %rax, %rcx, 16);
+
+       movl $24, %r8d;
+       cmpl $128, key_bitlength(CTX);
+       jne .Lenc_max32;
+
+.Lenc_done:
+       /* load CD for output */
+       vmovdqu 0 * 16(%rcx), %xmm8;
+       vmovdqu 1 * 16(%rcx), %xmm9;
+       vmovdqu 2 * 16(%rcx), %xmm10;
+       vmovdqu 3 * 16(%rcx), %xmm11;
+       vmovdqu 4 * 16(%rcx), %xmm12;
+       vmovdqu 5 * 16(%rcx), %xmm13;
+       vmovdqu 6 * 16(%rcx), %xmm14;
+       vmovdqu 7 * 16(%rcx), %xmm15;
+
+       outunpack16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+                   %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+                   %xmm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 16(%rax));
+
+       ret;
+
+.align 8
+.Lenc_max32:
+       movl $32, %r8d;
+
+       fls16(%rax, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+             %rcx, %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+             %xmm15,
+             ((key_table + (24) * 8) + 0)(CTX),
+             ((key_table + (24) * 8) + 4)(CTX),
+             ((key_table + (24) * 8) + 8)(CTX),
+             ((key_table + (24) * 8) + 12)(CTX));
+
+       enc_rounds16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+                    %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+                    %xmm15, %rax, %rcx, 24);
+
+       jmp .Lenc_done;
+.size __camellia_enc_blk16,.-__camellia_enc_blk16;
+
+.align 8
+.type   __camellia_dec_blk16,@function;
+
+__camellia_dec_blk16:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rax: temporary storage, 256 bytes
+        *      %r8d: 24 for 16 byte key, 32 for larger
+        *      %xmm0..%xmm15: 16 encrypted blocks
+        * output:
+        *      %xmm0..%xmm15: 16 plaintext blocks, order swapped:
+        *       7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8
+        */
+
+       leaq 8 * 16(%rax), %rcx;
+
+       inpack16_post(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+                     %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+                     %xmm15, %rax, %rcx);
+
+       cmpl $32, %r8d;
+       je .Ldec_max32;
+
+.Ldec_max24:
+       dec_rounds16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+                    %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+                    %xmm15, %rax, %rcx, 16);
+
+       fls16(%rax, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+             %rcx, %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+             %xmm15,
+             ((key_table + (16) * 8) + 8)(CTX),
+             ((key_table + (16) * 8) + 12)(CTX),
+             ((key_table + (16) * 8) + 0)(CTX),
+             ((key_table + (16) * 8) + 4)(CTX));
+
+       dec_rounds16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+                    %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+                    %xmm15, %rax, %rcx, 8);
+
+       fls16(%rax, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+             %rcx, %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+             %xmm15,
+             ((key_table + (8) * 8) + 8)(CTX),
+             ((key_table + (8) * 8) + 12)(CTX),
+             ((key_table + (8) * 8) + 0)(CTX),
+             ((key_table + (8) * 8) + 4)(CTX));
+
+       dec_rounds16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+                    %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+                    %xmm15, %rax, %rcx, 0);
+
+       /* load CD for output */
+       vmovdqu 0 * 16(%rcx), %xmm8;
+       vmovdqu 1 * 16(%rcx), %xmm9;
+       vmovdqu 2 * 16(%rcx), %xmm10;
+       vmovdqu 3 * 16(%rcx), %xmm11;
+       vmovdqu 4 * 16(%rcx), %xmm12;
+       vmovdqu 5 * 16(%rcx), %xmm13;
+       vmovdqu 6 * 16(%rcx), %xmm14;
+       vmovdqu 7 * 16(%rcx), %xmm15;
+
+       outunpack16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+                   %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+                   %xmm15, (key_table)(CTX), (%rax), 1 * 16(%rax));
+
+       ret;
+
+.align 8
+.Ldec_max32:
+       dec_rounds16(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+                    %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+                    %xmm15, %rax, %rcx, 24);
+
+       fls16(%rax, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+             %rcx, %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+             %xmm15,
+             ((key_table + (24) * 8) + 8)(CTX),
+             ((key_table + (24) * 8) + 12)(CTX),
+             ((key_table + (24) * 8) + 0)(CTX),
+             ((key_table + (24) * 8) + 4)(CTX));
+
+       jmp .Ldec_max24;
+.size __camellia_dec_blk16,.-__camellia_dec_blk16;
+
+#define inc_le128(x, minus_one, tmp) \
+       vpcmpeqq minus_one, x, tmp; \
+       vpsubq minus_one, x, x; \
+       vpslldq $8, tmp, tmp; \
+       vpsubq tmp, x, x;
+
+.align 8
+.globl _gcry_camellia_aesni_avx_ctr_enc
+.type   _gcry_camellia_aesni_avx_ctr_enc,@function;
+
+_gcry_camellia_aesni_avx_ctr_enc:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (16 blocks)
+        *      %rdx: src (16 blocks)
+        *      %rcx: iv (big endian, 128bit)
+        */
+
+       pushq %rbp;
+       movq %rsp, %rbp;
+
+       vzeroupper;
+
+       subq $(16 * 16), %rsp;
+       andq $~31, %rsp;
+       movq %rsp, %rax;
+
+       vmovdqa .Lbswap128_mask RIP, %xmm14;
+
+       /* load IV and byteswap */
+       vmovdqu (%rcx), %xmm15;
+       vmovdqu %xmm15, 15 * 16(%rax);
+       vpshufb %xmm14, %xmm15, %xmm0; /* be => le */
+
+       vpcmpeqd %xmm15, %xmm15, %xmm15;
+       vpsrldq $8, %xmm15, %xmm15; /* low: -1, high: 0 */
+
+       /* construct IVs */
+       inc_le128(%xmm0, %xmm15, %xmm13);
+       vpshufb %xmm14, %xmm0, %xmm13;
+       vmovdqu %xmm13, 14 * 16(%rax);
+       inc_le128(%xmm0, %xmm15, %xmm13);
+       vpshufb %xmm14, %xmm0, %xmm13;
+       vmovdqu %xmm13, 13 * 16(%rax);
+       inc_le128(%xmm0, %xmm15, %xmm13);
+       vpshufb %xmm14, %xmm0, %xmm12;
+       inc_le128(%xmm0, %xmm15, %xmm13);
+       vpshufb %xmm14, %xmm0, %xmm11;
+       inc_le128(%xmm0, %xmm15, %xmm13);
+       vpshufb %xmm14, %xmm0, %xmm10;
+       inc_le128(%xmm0, %xmm15, %xmm13);
+       vpshufb %xmm14, %xmm0, %xmm9;
+       inc_le128(%xmm0, %xmm15, %xmm13);
+       vpshufb %xmm14, %xmm0, %xmm8;
+       inc_le128(%xmm0, %xmm15, %xmm13);
+       vpshufb %xmm14, %xmm0, %xmm7;
+       inc_le128(%xmm0, %xmm15, %xmm13);
+       vpshufb %xmm14, %xmm0, %xmm6;
+       inc_le128(%xmm0, %xmm15, %xmm13);
+       vpshufb %xmm14, %xmm0, %xmm5;
+       inc_le128(%xmm0, %xmm15, %xmm13);
+       vpshufb %xmm14, %xmm0, %xmm4;
+       inc_le128(%xmm0, %xmm15, %xmm13);
+       vpshufb %xmm14, %xmm0, %xmm3;
+       inc_le128(%xmm0, %xmm15, %xmm13);
+       vpshufb %xmm14, %xmm0, %xmm2;
+       inc_le128(%xmm0, %xmm15, %xmm13);
+       vpshufb %xmm14, %xmm0, %xmm1;
+       inc_le128(%xmm0, %xmm15, %xmm13);
+       vmovdqa %xmm0, %xmm13;
+       vpshufb %xmm14, %xmm0, %xmm0;
+       inc_le128(%xmm13, %xmm15, %xmm14);
+       vpshufb .Lbswap128_mask RIP, %xmm13, %xmm13; /* le => be */
+       vmovdqu %xmm13, (%rcx);
+
+       /* 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 13 * 16(%rax), %xmm15, %xmm13;
+       vpxor 14 * 16(%rax), %xmm15, %xmm14;
+       vpxor 15 * 16(%rax), %xmm15, %xmm15;
+
+       call __camellia_enc_blk16;
+
+       vpxor 0 * 16(%rdx), %xmm7, %xmm7;
+       vpxor 1 * 16(%rdx), %xmm6, %xmm6;
+       vpxor 2 * 16(%rdx), %xmm5, %xmm5;
+       vpxor 3 * 16(%rdx), %xmm4, %xmm4;
+       vpxor 4 * 16(%rdx), %xmm3, %xmm3;
+       vpxor 5 * 16(%rdx), %xmm2, %xmm2;
+       vpxor 6 * 16(%rdx), %xmm1, %xmm1;
+       vpxor 7 * 16(%rdx), %xmm0, %xmm0;
+       vpxor 8 * 16(%rdx), %xmm15, %xmm15;
+       vpxor 9 * 16(%rdx), %xmm14, %xmm14;
+       vpxor 10 * 16(%rdx), %xmm13, %xmm13;
+       vpxor 11 * 16(%rdx), %xmm12, %xmm12;
+       vpxor 12 * 16(%rdx), %xmm11, %xmm11;
+       vpxor 13 * 16(%rdx), %xmm10, %xmm10;
+       vpxor 14 * 16(%rdx), %xmm9, %xmm9;
+       vpxor 15 * 16(%rdx), %xmm8, %xmm8;
+
+       write_output(%xmm7, %xmm6, %xmm5, %xmm4, %xmm3, %xmm2, %xmm1, %xmm0,
+                    %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+                    %xmm8, %rsi);
+
+       vzeroall;
+
+       leave;
+       ret;
+.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;
+
+_gcry_camellia_aesni_avx_cbc_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (16 blocks)
+        *      %rdx: src (16 blocks)
+        *      %rcx: iv
+        */
+
+       pushq %rbp;
+       movq %rsp, %rbp;
+
+       vzeroupper;
+
+       movq %rcx, %r9;
+
+       cmpl $128, key_bitlength(CTX);
+       movl $32, %r8d;
+       movl $24, %eax;
+       cmovel %eax, %r8d; /* max */
+
+       inpack16_pre(%xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7,
+                    %xmm8, %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14,
+                    %xmm15, %rdx, (key_table)(CTX, %r8, 8));
+
+       subq $(16 * 16), %rsp;
+       andq $~31, %rsp;
+       movq %rsp, %rax;
+
+       call __camellia_dec_blk16;
+
+       /* XOR output with IV */
+       vpxor (%r9), %xmm7, %xmm7;
+       vpxor (0 * 16)(%rdx), %xmm6, %xmm6;
+       vpxor (1 * 16)(%rdx), %xmm5, %xmm5;
+       vpxor (2 * 16)(%rdx), %xmm4, %xmm4;
+       vpxor (3 * 16)(%rdx), %xmm3, %xmm3;
+       vpxor (4 * 16)(%rdx), %xmm2, %xmm2;
+       vpxor (5 * 16)(%rdx), %xmm1, %xmm1;
+       vpxor (6 * 16)(%rdx), %xmm0, %xmm0;
+       vpxor (7 * 16)(%rdx), %xmm15, %xmm15;
+       vpxor (8 * 16)(%rdx), %xmm14, %xmm14;
+       vpxor (9 * 16)(%rdx), %xmm13, %xmm13;
+       vpxor (10 * 16)(%rdx), %xmm12, %xmm12;
+       vpxor (11 * 16)(%rdx), %xmm11, %xmm11;
+       vpxor (12 * 16)(%rdx), %xmm10, %xmm10;
+       vpxor (13 * 16)(%rdx), %xmm9, %xmm9;
+       vpxor (14 * 16)(%rdx), %xmm8, %xmm8;
+       movq (15 * 16 + 0)(%rdx), %r10;
+       movq (15 * 16 + 8)(%rdx), %r11;
+
+       write_output(%xmm7, %xmm6, %xmm5, %xmm4, %xmm3, %xmm2, %xmm1, %xmm0,
+                    %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+                    %xmm8, %rsi);
+
+       /* store new IV */
+       movq %r10, (0)(%r9);
+       movq %r11, (8)(%r9);
+
+       vzeroall;
+
+       leave;
+       ret;
+.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;
+
+_gcry_camellia_aesni_avx_cfb_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (16 blocks)
+        *      %rdx: src (16 blocks)
+        *      %rcx: iv
+        */
+
+       pushq %rbp;
+       movq %rsp, %rbp;
+
+       vzeroupper;
+
+       subq $(16 * 16), %rsp;
+       andq $~31, %rsp;
+       movq %rsp, %rax;
+
+       /* inpack16_pre: */
+       vmovq (key_table)(CTX), %xmm0;
+       vpshufb .Lpack_bswap RIP, %xmm0, %xmm0;
+       vpxor (%rcx), %xmm0, %xmm15;
+       vmovdqu 15 * 16(%rdx), %xmm1;
+       vmovdqu %xmm1, (%rcx); /* store new IV */
+       vpxor 0 * 16(%rdx), %xmm0, %xmm14;
+       vpxor 1 * 16(%rdx), %xmm0, %xmm13;
+       vpxor 2 * 16(%rdx), %xmm0, %xmm12;
+       vpxor 3 * 16(%rdx), %xmm0, %xmm11;
+       vpxor 4 * 16(%rdx), %xmm0, %xmm10;
+       vpxor 5 * 16(%rdx), %xmm0, %xmm9;
+       vpxor 6 * 16(%rdx), %xmm0, %xmm8;
+       vpxor 7 * 16(%rdx), %xmm0, %xmm7;
+       vpxor 8 * 16(%rdx), %xmm0, %xmm6;
+       vpxor 9 * 16(%rdx), %xmm0, %xmm5;
+       vpxor 10 * 16(%rdx), %xmm0, %xmm4;
+       vpxor 11 * 16(%rdx), %xmm0, %xmm3;
+       vpxor 12 * 16(%rdx), %xmm0, %xmm2;
+       vpxor 13 * 16(%rdx), %xmm0, %xmm1;
+       vpxor 14 * 16(%rdx), %xmm0, %xmm0;
+
+       call __camellia_enc_blk16;
+
+       vpxor 0 * 16(%rdx), %xmm7, %xmm7;
+       vpxor 1 * 16(%rdx), %xmm6, %xmm6;
+       vpxor 2 * 16(%rdx), %xmm5, %xmm5;
+       vpxor 3 * 16(%rdx), %xmm4, %xmm4;
+       vpxor 4 * 16(%rdx), %xmm3, %xmm3;
+       vpxor 5 * 16(%rdx), %xmm2, %xmm2;
+       vpxor 6 * 16(%rdx), %xmm1, %xmm1;
+       vpxor 7 * 16(%rdx), %xmm0, %xmm0;
+       vpxor 8 * 16(%rdx), %xmm15, %xmm15;
+       vpxor 9 * 16(%rdx), %xmm14, %xmm14;
+       vpxor 10 * 16(%rdx), %xmm13, %xmm13;
+       vpxor 11 * 16(%rdx), %xmm12, %xmm12;
+       vpxor 12 * 16(%rdx), %xmm11, %xmm11;
+       vpxor 13 * 16(%rdx), %xmm10, %xmm10;
+       vpxor 14 * 16(%rdx), %xmm9, %xmm9;
+       vpxor 15 * 16(%rdx), %xmm8, %xmm8;
+
+       write_output(%xmm7, %xmm6, %xmm5, %xmm4, %xmm3, %xmm2, %xmm1, %xmm0,
+                    %xmm15, %xmm14, %xmm13, %xmm12, %xmm11, %xmm10, %xmm9,
+                    %xmm8, %rsi);
+
+       vzeroall;
+
+       leave;
+       ret;
+.size _gcry_camellia_aesni_avx_cfb_dec,.-_gcry_camellia_aesni_avx_cfb_dec;
+
+/*
+ * IN:
+ *  ab: 64-bit AB state
+ *  cd: 64-bit CD state
+ */
+#define camellia_f(ab, x, t0, t1, t2, t3, t4, inv_shift_row, sbox4mask, \
+                  _0f0f0f0fmask, pre_s1lo_mask, pre_s1hi_mask, key) \
+       vmovq key, t0; \
+       vpxor x, x, t3; \
+       \
+       vpxor ab, t0, x; \
+       \
+       /* \
+        * S-function with AES subbytes \
+        */ \
+       \
+       /* input rotation for sbox4 (<<< 1) */ \
+       vpand x, sbox4mask, t0; \
+       vpandn x, sbox4mask, x; \
+       vpaddw t0, t0, t1; \
+       vpsrlw $7, t0, t0; \
+       vpor t0, t1, t0; \
+       vpand sbox4mask, t0, t0; \
+       vpor t0, x, x; \
+       \
+       vmovdqa .Lpost_tf_lo_s1 RIP, t0; \
+       vmovdqa .Lpost_tf_hi_s1 RIP, t1; \
+       \
+       /* prefilter sboxes */ \
+       filter_8bit(x, pre_s1lo_mask, pre_s1hi_mask, _0f0f0f0fmask, t2); \
+       \
+       /* AES subbytes + AES shift rows + AES inv shift rows */ \
+       vaesenclast t3, x, x; \
+       \
+       /* postfilter sboxes */ \
+       filter_8bit(x, t0, t1, _0f0f0f0fmask, t2); \
+       \
+       /* output rotation for sbox2 (<<< 1) */ \
+       /* output rotation for sbox3 (>>> 1) */ \
+       vpshufb inv_shift_row, x, t1; \
+       vpshufb .Lsp0044440444044404mask RIP, x, t4; \
+       vpshufb .Lsp1110111010011110mask RIP, x, x; \
+       vpaddb t1, t1, t2; \
+       vpsrlw $7, t1, t0; \
+       vpsllw $7, t1, t3; \
+       vpor t0, t2, t0; \
+       vpsrlw $1, t1, t1; \
+       vpshufb .Lsp0222022222000222mask RIP, t0, t0; \
+       vpor t1, t3, t1; \
+       \
+       vpxor x, t4, t4; \
+       vpshufb .Lsp3033303303303033mask RIP, t1, t1; \
+       vpxor t4, t0, t0; \
+       vpxor t1, t0, t0; \
+       vpsrldq $8, t0, x; \
+       vpxor t0, x, x;
+
+#define vec_rol128(in, out, nrol, t0) \
+       vpshufd $0x4e, in, out; \
+       vpsllq $(nrol), in, t0; \
+       vpsrlq $(64-(nrol)), out, out; \
+       vpaddd t0, out, out;
+
+#define vec_ror128(in, out, nror, t0) \
+       vpshufd $0x4e, in, out; \
+       vpsrlq $(nror), in, t0; \
+       vpsllq $(64-(nror)), out, out; \
+       vpaddd t0, out, out;
+
+.data
+
+.align 16
+.Linv_shift_row_and_unpcklbw:
+       .byte 0x00, 0xff, 0x0d, 0xff, 0x0a, 0xff, 0x07, 0xff
+       .byte 0x04, 0xff, 0x01, 0xff, 0x0e, 0xff, 0x0b, 0xff
+.Lsp0044440444044404mask:
+       .long 0xffff0404, 0x0404ff04;
+       .long 0x0d0dff0d, 0x0d0dff0d;
+.Lsp1110111010011110mask:
+       .long 0x000000ff, 0x000000ff;
+       .long 0x0bffff0b, 0x0b0b0bff;
+.Lsp0222022222000222mask:
+       .long 0xff060606, 0xff060606;
+       .long 0x0c0cffff, 0xff0c0c0c;
+.Lsp3033303303303033mask:
+       .long 0x04ff0404, 0x04ff0404;
+       .long 0xff0a0aff, 0x0aff0a0a;
+.Lsbox4_input_mask:
+       .byte 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00;
+.Lsigma1:
+       .long 0x3BCC908B, 0xA09E667F;
+.Lsigma2:
+       .long 0x4CAA73B2, 0xB67AE858;
+.Lsigma3:
+       .long 0xE94F82BE, 0xC6EF372F;
+.Lsigma4:
+       .long 0xF1D36F1C, 0x54FF53A5;
+.Lsigma5:
+       .long 0xDE682D1D, 0x10E527FA;
+.Lsigma6:
+       .long 0xB3E6C1FD, 0xB05688C2;
+
+.text
+
+.align 8
+.type  __camellia_avx_setup128,@function;
+__camellia_avx_setup128:
+       /* input:
+        *      %rdi: ctx, CTX; subkey storage at key_table(CTX)
+        *      %xmm0: key
+        */
+#define cmll_sub(n, ctx) (key_table+((n)*8))(ctx)
+#define KL128 %xmm0
+#define KA128 %xmm2
+
+       vpshufb .Lbswap128_mask RIP, KL128, KL128;
+
+       vmovdqa .Linv_shift_row_and_unpcklbw RIP, %xmm11;
+       vmovq .Lsbox4_input_mask RIP, %xmm12;
+       vbroadcastss .L0f0f0f0f RIP, %xmm13;
+       vmovdqa .Lpre_tf_lo_s1 RIP, %xmm14;
+       vmovdqa .Lpre_tf_hi_s1 RIP, %xmm15;
+
+       /*
+        * Generate KA
+        */
+       vpsrldq $8, KL128, %xmm2;
+       vmovdqa KL128, %xmm3;
+       vpslldq $8, %xmm3, %xmm3;
+       vpsrldq $8, %xmm3, %xmm3;
+
+       camellia_f(%xmm2, %xmm4, %xmm1,
+                  %xmm5, %xmm6, %xmm7, %xmm8,
+                  %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma1 RIP);
+       vpxor %xmm4, %xmm3, %xmm3;
+       camellia_f(%xmm3, %xmm2, %xmm1,
+                  %xmm5, %xmm6, %xmm7, %xmm8,
+                  %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma2 RIP);
+       camellia_f(%xmm2, %xmm3, %xmm1,
+                  %xmm5, %xmm6, %xmm7, %xmm8,
+                  %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma3 RIP);
+       vpxor %xmm4, %xmm3, %xmm3;
+       camellia_f(%xmm3, %xmm4, %xmm1,
+                  %xmm5, %xmm6, %xmm7, %xmm8,
+                  %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma4 RIP);
+
+       vpslldq $8, %xmm3, %xmm3;
+       vpxor %xmm4, %xmm2, %xmm2;
+       vpsrldq $8, %xmm3, %xmm3;
+       vpslldq $8, %xmm2, KA128;
+       vpor %xmm3, KA128, KA128;
+
+        /*
+         * Generate subkeys
+         */
+       vmovdqu KA128, cmll_sub(24, CTX);
+       vec_rol128(KL128, %xmm3, 15, %xmm15);
+       vec_rol128(KA128, %xmm4, 15, %xmm15);
+       vec_rol128(KA128, %xmm5, 30, %xmm15);
+       vec_rol128(KL128, %xmm6, 45, %xmm15);
+       vec_rol128(KA128, %xmm7, 45, %xmm15);
+       vec_rol128(KL128, %xmm8, 60, %xmm15);
+       vec_rol128(KA128, %xmm9, 60, %xmm15);
+       vec_ror128(KL128, %xmm10, 128-77, %xmm15);
+
+       /* absorb kw2 to other subkeys */
+       vpslldq $8, KL128, %xmm15;
+       vpsrldq $8, %xmm15, %xmm15;
+       vpxor %xmm15, KA128, KA128;
+       vpxor %xmm15, %xmm3, %xmm3;
+       vpxor %xmm15, %xmm4, %xmm4;
+
+       /* subl(1) ^= subr(1) & ~subr(9); */
+       vpandn %xmm15, %xmm5, %xmm13;
+       vpslldq $12, %xmm13, %xmm13;
+       vpsrldq $8, %xmm13, %xmm13;
+       vpxor %xmm13, %xmm15, %xmm15;
+       /* dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw); */
+       vpand %xmm15, %xmm5, %xmm14;
+       vpslld $1, %xmm14, %xmm11;
+       vpsrld $31, %xmm14, %xmm14;
+       vpaddd %xmm11, %xmm14, %xmm14;
+       vpslldq $8, %xmm14, %xmm14;
+       vpsrldq $12, %xmm14, %xmm14;
+       vpxor %xmm14, %xmm15, %xmm15;
+
+       vpxor %xmm15, %xmm6, %xmm6;
+       vpxor %xmm15, %xmm8, %xmm8;
+       vpxor %xmm15, %xmm9, %xmm9;
+
+       /* subl(1) ^= subr(1) & ~subr(17); */
+       vpandn %xmm15, %xmm10, %xmm13;
+       vpslldq $12, %xmm13, %xmm13;
+       vpsrldq $8, %xmm13, %xmm13;
+       vpxor %xmm13, %xmm15, %xmm15;
+       /* dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw); */
+       vpand %xmm15, %xmm10, %xmm14;
+       vpslld $1, %xmm14, %xmm11;
+       vpsrld $31, %xmm14, %xmm14;
+       vpaddd %xmm11, %xmm14, %xmm14;
+       vpslldq $8, %xmm14, %xmm14;
+       vpsrldq $12, %xmm14, %xmm14;
+       vpxor %xmm14, %xmm15, %xmm15;
+
+       vpshufd $0x1b, KL128, KL128;
+       vpshufd $0x1b, KA128, KA128;
+       vpshufd $0x1b, %xmm3, %xmm3;
+       vpshufd $0x1b, %xmm4, %xmm4;
+       vpshufd $0x1b, %xmm5, %xmm5;
+       vpshufd $0x1b, %xmm6, %xmm6;
+       vpshufd $0x1b, %xmm7, %xmm7;
+       vpshufd $0x1b, %xmm8, %xmm8;
+       vpshufd $0x1b, %xmm9, %xmm9;
+       vpshufd $0x1b, %xmm10, %xmm10;
+
+       vmovdqu KL128, cmll_sub(0, CTX);
+       vpshufd $0x1b, KL128, KL128;
+       vmovdqu KA128, cmll_sub(2, CTX);
+       vmovdqu %xmm3, cmll_sub(4, CTX);
+       vmovdqu %xmm4, cmll_sub(6, CTX);
+       vmovdqu %xmm5, cmll_sub(8, CTX);
+       vmovdqu %xmm6, cmll_sub(10, CTX);
+       vpsrldq $8, %xmm8, %xmm8;
+       vmovq %xmm7, cmll_sub(12, CTX);
+       vmovq %xmm8, cmll_sub(13, CTX);
+       vmovdqu %xmm9, cmll_sub(14, CTX);
+       vmovdqu %xmm10, cmll_sub(16, CTX);
+
+       vmovdqu cmll_sub(24, CTX), KA128;
+
+       vec_ror128(KL128, %xmm3, 128 - 94, %xmm7);
+       vec_ror128(KA128, %xmm4, 128 - 94, %xmm7);
+       vec_ror128(KL128, %xmm5, 128 - 111, %xmm7);
+       vec_ror128(KA128, %xmm6, 128 - 111, %xmm7);
+
+       vpxor %xmm15, %xmm3, %xmm3;
+       vpxor %xmm15, %xmm4, %xmm4;
+       vpxor %xmm15, %xmm5, %xmm5;
+       vpslldq $8, %xmm15, %xmm15;
+       vpxor %xmm15, %xmm6, %xmm6;
+
+       /* absorb kw4 to other subkeys */
+       vpslldq $8, %xmm6, %xmm15;
+       vpxor %xmm15, %xmm5, %xmm5;
+       vpxor %xmm15, %xmm4, %xmm4;
+       vpxor %xmm15, %xmm3, %xmm3;
+
+       /* subl(25) ^= subr(25) & ~subr(16); */
+       vpshufd $0x1b, cmll_sub(16, CTX), %xmm10;
+       vpandn %xmm15, %xmm10, %xmm13;
+       vpslldq $4, %xmm13, %xmm13;
+       vpxor %xmm13, %xmm15, %xmm15;
+       /* dw = subl(25) & subl(16), subr(25) ^= CAMELLIA_RL1(dw); */
+       vpand %xmm15, %xmm10, %xmm14;
+       vpslld $1, %xmm14, %xmm11;
+       vpsrld $31, %xmm14, %xmm14;
+       vpaddd %xmm11, %xmm14, %xmm14;
+       vpsrldq $12, %xmm14, %xmm14;
+       vpslldq $8, %xmm14, %xmm14;
+       vpxor %xmm14, %xmm15, %xmm15;
+
+       vpshufd $0x1b, %xmm3, %xmm3;
+       vpshufd $0x1b, %xmm4, %xmm4;
+       vpshufd $0x1b, %xmm5, %xmm5;
+       vpshufd $0x1b, %xmm6, %xmm6;
+
+       vmovdqu %xmm3, cmll_sub(18, CTX);
+       vmovdqu %xmm4, cmll_sub(20, CTX);
+       vmovdqu %xmm5, cmll_sub(22, CTX);
+       vmovdqu %xmm6, cmll_sub(24, CTX);
+
+       vpshufd $0x1b, cmll_sub(14, CTX), %xmm3;
+       vpshufd $0x1b, cmll_sub(12, CTX), %xmm4;
+       vpshufd $0x1b, cmll_sub(10, CTX), %xmm5;
+       vpshufd $0x1b, cmll_sub(8, CTX), %xmm6;
+
+       vpxor %xmm15, %xmm3, %xmm3;
+       vpxor %xmm15, %xmm4, %xmm4;
+       vpxor %xmm15, %xmm5, %xmm5;
+
+       /* subl(25) ^= subr(25) & ~subr(8); */
+       vpandn %xmm15, %xmm6, %xmm13;
+       vpslldq $4, %xmm13, %xmm13;
+       vpxor %xmm13, %xmm15, %xmm15;
+       /* dw = subl(25) & subl(8), subr(25) ^= CAMELLIA_RL1(dw); */
+       vpand %xmm15, %xmm6, %xmm14;
+       vpslld $1, %xmm14, %xmm11;
+       vpsrld $31, %xmm14, %xmm14;
+       vpaddd %xmm11, %xmm14, %xmm14;
+       vpsrldq $12, %xmm14, %xmm14;
+       vpslldq $8, %xmm14, %xmm14;
+       vpxor %xmm14, %xmm15, %xmm15;
+
+       vpshufd $0x1b, %xmm3, %xmm3;
+       vpshufd $0x1b, %xmm4, %xmm4;
+       vpshufd $0x1b, %xmm5, %xmm5;
+
+       vmovdqu %xmm3, cmll_sub(14, CTX);
+       vmovdqu %xmm4, cmll_sub(12, CTX);
+       vmovdqu %xmm5, cmll_sub(10, CTX);
+
+       vpshufd $0x1b, cmll_sub(6, CTX), %xmm6;
+       vpshufd $0x1b, cmll_sub(4, CTX), %xmm4;
+       vpshufd $0x1b, cmll_sub(2, CTX), %xmm2;
+       vpshufd $0x1b, cmll_sub(0, CTX), %xmm0;
+
+       vpxor %xmm15, %xmm6, %xmm6;
+       vpxor %xmm15, %xmm4, %xmm4;
+       vpxor %xmm15, %xmm2, %xmm2;
+       vpxor %xmm15, %xmm0, %xmm0;
+
+       vpshufd $0x1b, %xmm6, %xmm6;
+       vpshufd $0x1b, %xmm4, %xmm4;
+       vpshufd $0x1b, %xmm2, %xmm2;
+       vpshufd $0x1b, %xmm0, %xmm0;
+
+       vpsrldq $8, %xmm2, %xmm3;
+       vpsrldq $8, %xmm4, %xmm5;
+       vpsrldq $8, %xmm6, %xmm7;
+
+        /*
+        * key XOR is end of F-function.
+        */
+       vpxor %xmm2, %xmm0, %xmm0;
+       vpxor %xmm4, %xmm2, %xmm2;
+
+       vmovq %xmm0, cmll_sub(0, CTX);
+       vmovq %xmm3, cmll_sub(2, CTX);
+       vpxor %xmm5, %xmm3, %xmm3;
+       vpxor %xmm6, %xmm4, %xmm4;
+       vpxor %xmm7, %xmm5, %xmm5;
+       vmovq %xmm2, cmll_sub(3, CTX);
+       vmovq %xmm3, cmll_sub(4, CTX);
+       vmovq %xmm4, cmll_sub(5, CTX);
+       vmovq %xmm5, cmll_sub(6, CTX);
+
+       vmovq cmll_sub(7, CTX), %xmm7;
+       vmovq cmll_sub(8, CTX), %xmm8;
+       vmovq cmll_sub(9, CTX), %xmm9;
+       vmovq cmll_sub(10, CTX), %xmm10;
+       /* tl = subl(10) ^ (subr(10) & ~subr(8)); */
+       vpandn %xmm10, %xmm8, %xmm15;
+       vpsrldq $4, %xmm15, %xmm15;
+       vpxor %xmm15, %xmm10, %xmm0;
+       /* dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw); */
+       vpand %xmm8, %xmm0, %xmm15;
+       vpslld $1, %xmm15, %xmm14;
+       vpsrld $31, %xmm15, %xmm15;
+       vpaddd %xmm14, %xmm15, %xmm15;
+       vpslldq $12, %xmm15, %xmm15;
+       vpsrldq $8, %xmm15, %xmm15;
+       vpxor %xmm15, %xmm0, %xmm0;
+
+       vpxor %xmm0, %xmm6, %xmm6;
+       vmovq %xmm6, cmll_sub(7, CTX);
+
+       vmovq cmll_sub(11, CTX), %xmm11;
+       vmovq cmll_sub(12, CTX), %xmm12;
+       vmovq cmll_sub(13, CTX), %xmm13;
+       vmovq cmll_sub(14, CTX), %xmm14;
+       vmovq cmll_sub(15, CTX), %xmm15;
+       /* tl = subl(7) ^ (subr(7) & ~subr(9)); */
+       vpandn %xmm7, %xmm9, %xmm1;
+       vpsrldq $4, %xmm1, %xmm1;
+       vpxor %xmm1, %xmm7, %xmm0;
+       /* dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw); */
+       vpand %xmm9, %xmm0, %xmm1;
+       vpslld $1, %xmm1, %xmm2;
+       vpsrld $31, %xmm1, %xmm1;
+       vpaddd %xmm2, %xmm1, %xmm1;
+       vpslldq $12, %xmm1, %xmm1;
+       vpsrldq $8, %xmm1, %xmm1;
+       vpxor %xmm1, %xmm0, %xmm0;
+
+       vpxor %xmm11, %xmm0, %xmm0;
+       vpxor %xmm12, %xmm10, %xmm10;
+       vpxor %xmm13, %xmm11, %xmm11;
+       vpxor %xmm14, %xmm12, %xmm12;
+       vpxor %xmm15, %xmm13, %xmm13;
+       vmovq %xmm0, cmll_sub(10, CTX);
+       vmovq %xmm10, cmll_sub(11, CTX);
+       vmovq %xmm11, cmll_sub(12, CTX);
+       vmovq %xmm12, cmll_sub(13, CTX);
+       vmovq %xmm13, cmll_sub(14, CTX);
+
+       vmovq cmll_sub(16, CTX), %xmm6;
+       vmovq cmll_sub(17, CTX), %xmm7;
+       vmovq cmll_sub(18, CTX), %xmm8;
+       vmovq cmll_sub(19, CTX), %xmm9;
+       vmovq cmll_sub(20, CTX), %xmm10;
+       /* tl = subl(18) ^ (subr(18) & ~subr(16)); */
+       vpandn %xmm8, %xmm6, %xmm1;
+       vpsrldq $4, %xmm1, %xmm1;
+       vpxor %xmm1, %xmm8, %xmm0;
+       /* dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw); */
+       vpand %xmm6, %xmm0, %xmm1;
+       vpslld $1, %xmm1, %xmm2;
+       vpsrld $31, %xmm1, %xmm1;
+       vpaddd %xmm2, %xmm1, %xmm1;
+       vpslldq $12, %xmm1, %xmm1;
+       vpsrldq $8, %xmm1, %xmm1;
+       vpxor %xmm1, %xmm0, %xmm0;
+
+       vpxor %xmm14, %xmm0, %xmm0;
+       vmovq %xmm0, cmll_sub(15, CTX);
+
+       /* tl = subl(15) ^ (subr(15) & ~subr(17)); */
+       vpandn %xmm15, %xmm7, %xmm1;
+       vpsrldq $4, %xmm1, %xmm1;
+       vpxor %xmm1, %xmm15, %xmm0;
+       /* dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw); */
+       vpand %xmm7, %xmm0, %xmm1;
+       vpslld $1, %xmm1, %xmm2;
+       vpsrld $31, %xmm1, %xmm1;
+       vpaddd %xmm2, %xmm1, %xmm1;
+       vpslldq $12, %xmm1, %xmm1;
+       vpsrldq $8, %xmm1, %xmm1;
+       vpxor %xmm1, %xmm0, %xmm0;
+
+       vmovq cmll_sub(21, CTX), %xmm1;
+       vmovq cmll_sub(22, CTX), %xmm2;
+       vmovq cmll_sub(23, CTX), %xmm3;
+       vmovq cmll_sub(24, CTX), %xmm4;
+
+       vpxor %xmm9, %xmm0, %xmm0;
+       vpxor %xmm10, %xmm8, %xmm8;
+       vpxor %xmm1, %xmm9, %xmm9;
+       vpxor %xmm2, %xmm10, %xmm10;
+       vpxor %xmm3, %xmm1, %xmm1;
+       vpxor %xmm4, %xmm3, %xmm3;
+
+       vmovq %xmm0, cmll_sub(18, CTX);
+       vmovq %xmm8, cmll_sub(19, CTX);
+       vmovq %xmm9, cmll_sub(20, CTX);
+       vmovq %xmm10, cmll_sub(21, CTX);
+       vmovq %xmm1, cmll_sub(22, CTX);
+       vmovq %xmm2, cmll_sub(23, CTX);
+       vmovq %xmm3, cmll_sub(24, CTX);
+
+       /* kw2 and kw4 are unused now. */
+       movq $0, cmll_sub(1, CTX);
+       movq $0, cmll_sub(25, CTX);
+
+       vzeroall;
+
+       ret;
+.size __camellia_avx_setup128,.-__camellia_avx_setup128;
+
+.align 8
+.type  __camellia_avx_setup256,@function;
+
+__camellia_avx_setup256:
+       /* input:
+        *      %rdi: ctx, CTX; subkey storage at key_table(CTX)
+        *      %xmm0 & %xmm1: key
+        */
+#define KL128 %xmm0
+#define KR128 %xmm1
+#define KA128 %xmm2
+#define KB128 %xmm3
+
+       vpshufb .Lbswap128_mask RIP, KL128, KL128;
+       vpshufb .Lbswap128_mask RIP, KR128, KR128;
+
+       vmovdqa .Linv_shift_row_and_unpcklbw RIP, %xmm11;
+       vmovq .Lsbox4_input_mask RIP, %xmm12;
+       vbroadcastss .L0f0f0f0f RIP, %xmm13;
+       vmovdqa .Lpre_tf_lo_s1 RIP, %xmm14;
+       vmovdqa .Lpre_tf_hi_s1 RIP, %xmm15;
+
+       /*
+        * Generate KA
+        */
+       vpxor KL128, KR128, %xmm3;
+       vpsrldq $8, KR128, %xmm6;
+       vpsrldq $8, %xmm3, %xmm2;
+       vpslldq $8, %xmm3, %xmm3;
+       vpsrldq $8, %xmm3, %xmm3;
+
+       camellia_f(%xmm2, %xmm4, %xmm5,
+                  %xmm7, %xmm8, %xmm9, %xmm10,
+                  %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma1 RIP);
+       vpxor %xmm4, %xmm3, %xmm3;
+       camellia_f(%xmm3, %xmm2, %xmm5,
+                  %xmm7, %xmm8, %xmm9, %xmm10,
+                  %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma2 RIP);
+       vpxor %xmm6, %xmm2, %xmm2;
+       camellia_f(%xmm2, %xmm3, %xmm5,
+                  %xmm7, %xmm8, %xmm9, %xmm10,
+                  %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma3 RIP);
+       vpxor %xmm4, %xmm3, %xmm3;
+       vpxor KR128, %xmm3, %xmm3;
+       camellia_f(%xmm3, %xmm4, %xmm5,
+                  %xmm7, %xmm8, %xmm9, %xmm10,
+                  %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma4 RIP);
+
+       vpslldq $8, %xmm3, %xmm3;
+       vpxor %xmm4, %xmm2, %xmm2;
+       vpsrldq $8, %xmm3, %xmm3;
+       vpslldq $8, %xmm2, KA128;
+       vpor %xmm3, KA128, KA128;
+
+       /*
+        * Generate KB
+        */
+       vpxor KA128, KR128, %xmm3;
+       vpsrldq $8, %xmm3, %xmm4;
+       vpslldq $8, %xmm3, %xmm3;
+       vpsrldq $8, %xmm3, %xmm3;
+
+       camellia_f(%xmm4, %xmm5, %xmm6,
+                  %xmm7, %xmm8, %xmm9, %xmm10,
+                  %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma5 RIP);
+       vpxor %xmm5, %xmm3, %xmm3;
+
+       camellia_f(%xmm3, %xmm5, %xmm6,
+                  %xmm7, %xmm8, %xmm9, %xmm10,
+                  %xmm11, %xmm12, %xmm13, %xmm14, %xmm15, .Lsigma6 RIP);
+       vpslldq $8, %xmm3, %xmm3;
+       vpxor %xmm5, %xmm4, %xmm4;
+       vpsrldq $8, %xmm3, %xmm3;
+       vpslldq $8, %xmm4, %xmm4;
+       vpor %xmm3, %xmm4, KB128;
+
+        /*
+         * Generate subkeys
+         */
+       vmovdqu KB128, cmll_sub(32, CTX);
+       vec_rol128(KR128, %xmm4, 15, %xmm15);
+       vec_rol128(KA128, %xmm5, 15, %xmm15);
+       vec_rol128(KR128, %xmm6, 30, %xmm15);
+       vec_rol128(KB128, %xmm7, 30, %xmm15);
+       vec_rol128(KL128, %xmm8, 45, %xmm15);
+       vec_rol128(KA128, %xmm9, 45, %xmm15);
+       vec_rol128(KL128, %xmm10, 60, %xmm15);
+       vec_rol128(KR128, %xmm11, 60, %xmm15);
+       vec_rol128(KB128, %xmm12, 60, %xmm15);
+
+       /* absorb kw2 to other subkeys */
+       vpslldq $8, KL128, %xmm15;
+       vpsrldq $8, %xmm15, %xmm15;
+       vpxor %xmm15, KB128, KB128;
+       vpxor %xmm15, %xmm4, %xmm4;
+       vpxor %xmm15, %xmm5, %xmm5;
+
+       /* subl(1) ^= subr(1) & ~subr(9); */
+       vpandn %xmm15, %xmm6, %xmm13;
+       vpslldq $12, %xmm13, %xmm13;
+       vpsrldq $8, %xmm13, %xmm13;
+       vpxor %xmm13, %xmm15, %xmm15;
+       /* dw = subl(1) & subl(9), subr(1) ^= CAMELLIA_RL1(dw); */
+       vpand %xmm15, %xmm6, %xmm14;
+       vpslld $1, %xmm14, %xmm13;
+       vpsrld $31, %xmm14, %xmm14;
+       vpaddd %xmm13, %xmm14, %xmm14;
+       vpslldq $8, %xmm14, %xmm14;
+       vpsrldq $12, %xmm14, %xmm14;
+       vpxor %xmm14, %xmm15, %xmm15;
+
+       vpxor %xmm15, %xmm7, %xmm7;
+       vpxor %xmm15, %xmm8, %xmm8;
+       vpxor %xmm15, %xmm9, %xmm9;
+
+       vpshufd $0x1b, KL128, KL128;
+       vpshufd $0x1b, KB128, KB128;
+       vpshufd $0x1b, %xmm4, %xmm4;
+       vpshufd $0x1b, %xmm5, %xmm5;
+       vpshufd $0x1b, %xmm6, %xmm6;
+       vpshufd $0x1b, %xmm7, %xmm7;
+       vpshufd $0x1b, %xmm8, %xmm8;
+       vpshufd $0x1b, %xmm9, %xmm9;
+
+       vmovdqu KL128, cmll_sub(0, CTX);
+       vpshufd $0x1b, KL128, KL128;
+       vmovdqu KB128, cmll_sub(2, CTX);
+       vmovdqu %xmm4, cmll_sub(4, CTX);
+       vmovdqu %xmm5, cmll_sub(6, CTX);
+       vmovdqu %xmm6, cmll_sub(8, CTX);
+       vmovdqu %xmm7, cmll_sub(10, CTX);
+       vmovdqu %xmm8, cmll_sub(12, CTX);
+       vmovdqu %xmm9, cmll_sub(14, CTX);
+
+       vmovdqu cmll_sub(32, CTX), KB128;
+
+       /* subl(1) ^= subr(1) & ~subr(17); */
+       vpandn %xmm15, %xmm10, %xmm13;
+       vpslldq $12, %xmm13, %xmm13;
+       vpsrldq $8, %xmm13, %xmm13;
+       vpxor %xmm13, %xmm15, %xmm15;
+       /* dw = subl(1) & subl(17), subr(1) ^= CAMELLIA_RL1(dw); */
+       vpand %xmm15, %xmm10, %xmm14;
+       vpslld $1, %xmm14, %xmm13;
+       vpsrld $31, %xmm14, %xmm14;
+       vpaddd %xmm13, %xmm14, %xmm14;
+       vpslldq $8, %xmm14, %xmm14;
+       vpsrldq $12, %xmm14, %xmm14;
+       vpxor %xmm14, %xmm15, %xmm15;
+
+       vpxor %xmm15, %xmm11, %xmm11;
+       vpxor %xmm15, %xmm12, %xmm12;
+
+       vec_ror128(KL128, %xmm4, 128-77, %xmm14);
+       vec_ror128(KA128, %xmm5, 128-77, %xmm14);
+       vec_ror128(KR128, %xmm6, 128-94, %xmm14);
+       vec_ror128(KA128, %xmm7, 128-94, %xmm14);
+       vec_ror128(KL128, %xmm8, 128-111, %xmm14);
+       vec_ror128(KB128, %xmm9, 128-111, %xmm14);
+
+       vpxor %xmm15, %xmm4, %xmm4;
+
+       vpshufd $0x1b, %xmm10, %xmm10;
+       vpshufd $0x1b, %xmm11, %xmm11;
+       vpshufd $0x1b, %xmm12, %xmm12;
+       vpshufd $0x1b, %xmm4, %xmm4;
+
+       vmovdqu %xmm10, cmll_sub(16, CTX);
+       vmovdqu %xmm11, cmll_sub(18, CTX);
+       vmovdqu %xmm12, cmll_sub(20, CTX);
+       vmovdqu %xmm4, cmll_sub(22, CTX);
+
+       /* subl(1) ^= subr(1) & ~subr(25); */
+       vpandn %xmm15, %xmm5, %xmm13;
+       vpslldq $12, %xmm13, %xmm13;
+       vpsrldq $8, %xmm13, %xmm13;
+       vpxor %xmm13, %xmm15, %xmm15;
+       /* dw = subl(1) & subl(25), subr(1) ^= CAMELLIA_RL1(dw); */
+       vpand %xmm15, %xmm5, %xmm14;
+       vpslld $1, %xmm14, %xmm13;
+       vpsrld $31, %xmm14, %xmm14;
+       vpaddd %xmm13, %xmm14, %xmm14;
+       vpslldq $8, %xmm14, %xmm14;
+       vpsrldq $12, %xmm14, %xmm14;
+       vpxor %xmm14, %xmm15, %xmm15;
+
+       vpxor %xmm15, %xmm6, %xmm6;
+       vpxor %xmm15, %xmm7, %xmm7;
+       vpxor %xmm15, %xmm8, %xmm8;
+       vpslldq $8, %xmm15, %xmm15;
+       vpxor %xmm15, %xmm9, %xmm9;
+
+       /* absorb kw4 to other subkeys */
+       vpslldq $8, %xmm9, %xmm15;
+       vpxor %xmm15, %xmm8, %xmm8;
+       vpxor %xmm15, %xmm7, %xmm7;
+       vpxor %xmm15, %xmm6, %xmm6;
+
+       /* subl(33) ^= subr(33) & ~subr(24); */
+       vpandn %xmm15, %xmm5, %xmm14;
+       vpslldq $4, %xmm14, %xmm14;
+       vpxor %xmm14, %xmm15, %xmm15;
+       /* dw = subl(33) & subl(24), subr(33) ^= CAMELLIA_RL1(dw); */
+       vpand %xmm15, %xmm5, %xmm14;
+       vpslld $1, %xmm14, %xmm13;
+       vpsrld $31, %xmm14, %xmm14;
+       vpaddd %xmm13, %xmm14, %xmm14;
+       vpsrldq $12, %xmm14, %xmm14;
+       vpslldq $8, %xmm14, %xmm14;
+       vpxor %xmm14, %xmm15, %xmm15;
+
+       vpshufd $0x1b, %xmm5, %xmm5;
+       vpshufd $0x1b, %xmm6, %xmm6;
+       vpshufd $0x1b, %xmm7, %xmm7;
+       vpshufd $0x1b, %xmm8, %xmm8;
+       vpshufd $0x1b, %xmm9, %xmm9;
+
+       vmovdqu %xmm5, cmll_sub(24, CTX);
+       vmovdqu %xmm6, cmll_sub(26, CTX);
+       vmovdqu %xmm7, cmll_sub(28, CTX);
+       vmovdqu %xmm8, cmll_sub(30, CTX);
+       vmovdqu %xmm9, cmll_sub(32, CTX);
+
+       vpshufd $0x1b, cmll_sub(22, CTX), %xmm0;
+       vpshufd $0x1b, cmll_sub(20, CTX), %xmm1;
+       vpshufd $0x1b, cmll_sub(18, CTX), %xmm2;
+       vpshufd $0x1b, cmll_sub(16, CTX), %xmm3;
+       vpshufd $0x1b, cmll_sub(14, CTX), %xmm4;
+       vpshufd $0x1b, cmll_sub(12, CTX), %xmm5;
+       vpshufd $0x1b, cmll_sub(10, CTX), %xmm6;
+       vpshufd $0x1b, cmll_sub(8, CTX), %xmm7;
+
+       vpxor %xmm15, %xmm0, %xmm0;
+       vpxor %xmm15, %xmm1, %xmm1;
+       vpxor %xmm15, %xmm2, %xmm2;
+
+       /* subl(33) ^= subr(33) & ~subr(24); */
+       vpandn %xmm15, %xmm3, %xmm14;
+       vpslldq $4, %xmm14, %xmm14;
+       vpxor %xmm14, %xmm15, %xmm15;
+       /* dw = subl(33) & subl(24), subr(33) ^= CAMELLIA_RL1(dw); */
+       vpand %xmm15, %xmm3, %xmm14;
+       vpslld $1, %xmm14, %xmm13;
+       vpsrld $31, %xmm14, %xmm14;
+       vpaddd %xmm13, %xmm14, %xmm14;
+       vpsrldq $12, %xmm14, %xmm14;
+       vpslldq $8, %xmm14, %xmm14;
+       vpxor %xmm14, %xmm15, %xmm15;
+
+       vpxor %xmm15, %xmm4, %xmm4;
+       vpxor %xmm15, %xmm5, %xmm5;
+       vpxor %xmm15, %xmm6, %xmm6;
+
+       vpshufd $0x1b, %xmm0, %xmm0;
+       vpshufd $0x1b, %xmm1, %xmm1;
+       vpshufd $0x1b, %xmm2, %xmm2;
+       vpshufd $0x1b, %xmm4, %xmm4;
+       vpshufd $0x1b, %xmm5, %xmm5;
+       vpshufd $0x1b, %xmm6, %xmm6;
+
+       vmovdqu %xmm0, cmll_sub(22, CTX);
+       vmovdqu %xmm1, cmll_sub(20, CTX);
+       vmovdqu %xmm2, cmll_sub(18, CTX);
+       vmovdqu %xmm4, cmll_sub(14, CTX);
+       vmovdqu %xmm5, cmll_sub(12, CTX);
+       vmovdqu %xmm6, cmll_sub(10, CTX);
+
+       vpshufd $0x1b, cmll_sub(6, CTX), %xmm6;
+       vpshufd $0x1b, cmll_sub(4, CTX), %xmm4;
+       vpshufd $0x1b, cmll_sub(2, CTX), %xmm2;
+       vpshufd $0x1b, cmll_sub(0, CTX), %xmm0;
+
+       /* subl(33) ^= subr(33) & ~subr(24); */
+       vpandn %xmm15, %xmm7, %xmm14;
+       vpslldq $4, %xmm14, %xmm14;
+       vpxor %xmm14, %xmm15, %xmm15;
+       /* dw = subl(33) & subl(24), subr(33) ^= CAMELLIA_RL1(dw); */
+       vpand %xmm15, %xmm7, %xmm14;
+       vpslld $1, %xmm14, %xmm13;
+       vpsrld $31, %xmm14, %xmm14;
+       vpaddd %xmm13, %xmm14, %xmm14;
+       vpsrldq $12, %xmm14, %xmm14;
+       vpslldq $8, %xmm14, %xmm14;
+       vpxor %xmm14, %xmm15, %xmm15;
+
+       vpxor %xmm15, %xmm6, %xmm6;
+       vpxor %xmm15, %xmm4, %xmm4;
+       vpxor %xmm15, %xmm2, %xmm2;
+       vpxor %xmm15, %xmm0, %xmm0;
+
+       vpshufd $0x1b, %xmm6, %xmm6;
+       vpshufd $0x1b, %xmm4, %xmm4;
+       vpshufd $0x1b, %xmm2, %xmm2;
+       vpshufd $0x1b, %xmm0, %xmm0;
+
+       vpsrldq $8, %xmm2, %xmm3;
+       vpsrldq $8, %xmm4, %xmm5;
+       vpsrldq $8, %xmm6, %xmm7;
+
+        /*
+        * key XOR is end of F-function.
+        */
+       vpxor %xmm2, %xmm0, %xmm0;
+       vpxor %xmm4, %xmm2, %xmm2;
+
+       vmovq %xmm0, cmll_sub(0, CTX);
+       vmovq %xmm3, cmll_sub(2, CTX);
+       vpxor %xmm5, %xmm3, %xmm3;
+       vpxor %xmm6, %xmm4, %xmm4;
+       vpxor %xmm7, %xmm5, %xmm5;
+       vmovq %xmm2, cmll_sub(3, CTX);
+       vmovq %xmm3, cmll_sub(4, CTX);
+       vmovq %xmm4, cmll_sub(5, CTX);
+       vmovq %xmm5, cmll_sub(6, CTX);
+
+       vmovq cmll_sub(7, CTX), %xmm7;
+       vmovq cmll_sub(8, CTX), %xmm8;
+       vmovq cmll_sub(9, CTX), %xmm9;
+       vmovq cmll_sub(10, CTX), %xmm10;
+       /* tl = subl(10) ^ (subr(10) & ~subr(8)); */
+       vpandn %xmm10, %xmm8, %xmm15;
+       vpsrldq $4, %xmm15, %xmm15;
+       vpxor %xmm15, %xmm10, %xmm0;
+       /* dw = tl & subl(8), tr = subr(10) ^ CAMELLIA_RL1(dw); */
+       vpand %xmm8, %xmm0, %xmm15;
+       vpslld $1, %xmm15, %xmm14;
+       vpsrld $31, %xmm15, %xmm15;
+       vpaddd %xmm14, %xmm15, %xmm15;
+       vpslldq $12, %xmm15, %xmm15;
+       vpsrldq $8, %xmm15, %xmm15;
+       vpxor %xmm15, %xmm0, %xmm0;
+
+       vpxor %xmm0, %xmm6, %xmm6;
+       vmovq %xmm6, cmll_sub(7, CTX);
+
+       vmovq cmll_sub(11, CTX), %xmm11;
+       vmovq cmll_sub(12, CTX), %xmm12;
+       vmovq cmll_sub(13, CTX), %xmm13;
+       vmovq cmll_sub(14, CTX), %xmm14;
+       vmovq cmll_sub(15, CTX), %xmm15;
+       /* tl = subl(7) ^ (subr(7) & ~subr(9)); */
+       vpandn %xmm7, %xmm9, %xmm1;
+       vpsrldq $4, %xmm1, %xmm1;
+       vpxor %xmm1, %xmm7, %xmm0;
+       /* dw = tl & subl(9), tr = subr(7) ^ CAMELLIA_RL1(dw); */
+       vpand %xmm9, %xmm0, %xmm1;
+       vpslld $1, %xmm1, %xmm2;
+       vpsrld $31, %xmm1, %xmm1;
+       vpaddd %xmm2, %xmm1, %xmm1;
+       vpslldq $12, %xmm1, %xmm1;
+       vpsrldq $8, %xmm1, %xmm1;
+       vpxor %xmm1, %xmm0, %xmm0;
+
+       vpxor %xmm11, %xmm0, %xmm0;
+       vpxor %xmm12, %xmm10, %xmm10;
+       vpxor %xmm13, %xmm11, %xmm11;
+       vpxor %xmm14, %xmm12, %xmm12;
+       vpxor %xmm15, %xmm13, %xmm13;
+       vmovq %xmm0, cmll_sub(10, CTX);
+       vmovq %xmm10, cmll_sub(11, CTX);
+       vmovq %xmm11, cmll_sub(12, CTX);
+       vmovq %xmm12, cmll_sub(13, CTX);
+       vmovq %xmm13, cmll_sub(14, CTX);
+
+       vmovq cmll_sub(16, CTX), %xmm6;
+       vmovq cmll_sub(17, CTX), %xmm7;
+       vmovq cmll_sub(18, CTX), %xmm8;
+       vmovq cmll_sub(19, CTX), %xmm9;
+       vmovq cmll_sub(20, CTX), %xmm10;
+       /* tl = subl(18) ^ (subr(18) & ~subr(16)); */
+       vpandn %xmm8, %xmm6, %xmm1;
+       vpsrldq $4, %xmm1, %xmm1;
+       vpxor %xmm1, %xmm8, %xmm0;
+       /* dw = tl & subl(16), tr = subr(18) ^ CAMELLIA_RL1(dw); */
+       vpand %xmm6, %xmm0, %xmm1;
+       vpslld $1, %xmm1, %xmm2;
+       vpsrld $31, %xmm1, %xmm1;
+       vpaddd %xmm2, %xmm1, %xmm1;
+       vpslldq $12, %xmm1, %xmm1;
+       vpsrldq $8, %xmm1, %xmm1;
+       vpxor %xmm1, %xmm0, %xmm0;
+
+       vpxor %xmm14, %xmm0, %xmm0;
+       vmovq %xmm0, cmll_sub(15, CTX);
+
+       /* tl = subl(15) ^ (subr(15) & ~subr(17)); */
+       vpandn %xmm15, %xmm7, %xmm1;
+       vpsrldq $4, %xmm1, %xmm1;
+       vpxor %xmm1, %xmm15, %xmm0;
+       /* dw = tl & subl(17), tr = subr(15) ^ CAMELLIA_RL1(dw); */
+       vpand %xmm7, %xmm0, %xmm1;
+       vpslld $1, %xmm1, %xmm2;
+       vpsrld $31, %xmm1, %xmm1;
+       vpaddd %xmm2, %xmm1, %xmm1;
+       vpslldq $12, %xmm1, %xmm1;
+       vpsrldq $8, %xmm1, %xmm1;
+       vpxor %xmm1, %xmm0, %xmm0;
+
+       vmovq cmll_sub(21, CTX), %xmm1;
+       vmovq cmll_sub(22, CTX), %xmm2;
+       vmovq cmll_sub(23, CTX), %xmm3;
+       vmovq cmll_sub(24, CTX), %xmm4;
+
+       vpxor %xmm9, %xmm0, %xmm0;
+       vpxor %xmm10, %xmm8, %xmm8;
+       vpxor %xmm1, %xmm9, %xmm9;
+       vpxor %xmm2, %xmm10, %xmm10;
+       vpxor %xmm3, %xmm1, %xmm1;
+
+       vmovq %xmm0, cmll_sub(18, CTX);
+       vmovq %xmm8, cmll_sub(19, CTX);
+       vmovq %xmm9, cmll_sub(20, CTX);
+       vmovq %xmm10, cmll_sub(21, CTX);
+       vmovq %xmm1, cmll_sub(22, CTX);
+
+       vmovq cmll_sub(25, CTX), %xmm5;
+       vmovq cmll_sub(26, CTX), %xmm6;
+       vmovq cmll_sub(27, CTX), %xmm7;
+       vmovq cmll_sub(28, CTX), %xmm8;
+       vmovq cmll_sub(29, CTX), %xmm9;
+       vmovq cmll_sub(30, CTX), %xmm10;
+       vmovq cmll_sub(31, CTX), %xmm11;
+       vmovq cmll_sub(32, CTX), %xmm12;
+
+       /* tl = subl(26) ^ (subr(26) & ~subr(24)); */
+       vpandn %xmm6, %xmm4, %xmm15;
+       vpsrldq $4, %xmm15, %xmm15;
+       vpxor %xmm15, %xmm6, %xmm0;
+       /* dw = tl & subl(26), tr = subr(24) ^ CAMELLIA_RL1(dw); */
+       vpand %xmm4, %xmm0, %xmm15;
+       vpslld $1, %xmm15, %xmm14;
+       vpsrld $31, %xmm15, %xmm15;
+       vpaddd %xmm14, %xmm15, %xmm15;
+       vpslldq $12, %xmm15, %xmm15;
+       vpsrldq $8, %xmm15, %xmm15;
+       vpxor %xmm15, %xmm0, %xmm0;
+
+       vpxor %xmm0, %xmm2, %xmm2;
+       vmovq %xmm2, cmll_sub(23, CTX);
+
+       /* tl = subl(23) ^ (subr(23) &  ~subr(25)); */
+       vpandn %xmm3, %xmm5, %xmm15;
+       vpsrldq $4, %xmm15, %xmm15;
+       vpxor %xmm15, %xmm3, %xmm0;
+       /* dw = tl & subl(26), tr = subr(24) ^ CAMELLIA_RL1(dw); */
+       vpand %xmm5, %xmm0, %xmm15;
+       vpslld $1, %xmm15, %xmm14;
+       vpsrld $31, %xmm15, %xmm15;
+       vpaddd %xmm14, %xmm15, %xmm15;
+       vpslldq $12, %xmm15, %xmm15;
+       vpsrldq $8, %xmm15, %xmm15;
+       vpxor %xmm15, %xmm0, %xmm0;
+
+       vpxor %xmm7, %xmm0, %xmm0;
+       vpxor %xmm8, %xmm6, %xmm6;
+       vpxor %xmm9, %xmm7, %xmm7;
+       vpxor %xmm10, %xmm8, %xmm8;
+       vpxor %xmm11, %xmm9, %xmm9;
+       vpxor %xmm12, %xmm11, %xmm11;
+
+       vmovq %xmm0, cmll_sub(26, CTX);
+       vmovq %xmm6, cmll_sub(27, CTX);
+       vmovq %xmm7, cmll_sub(28, CTX);
+       vmovq %xmm8, cmll_sub(29, CTX);
+       vmovq %xmm9, cmll_sub(30, CTX);
+       vmovq %xmm10, cmll_sub(31, CTX);
+       vmovq %xmm11, cmll_sub(32, CTX);
+
+       /* kw2 and kw4 are unused now. */
+       movq $0, cmll_sub(1, CTX);
+       movq $0, cmll_sub(33, CTX);
+
+       vzeroall;
+
+       ret;
+.size __camellia_avx_setup256,.-__camellia_avx_setup256;
+
+.align 8
+.globl _gcry_camellia_aesni_avx_keygen
+.type  _gcry_camellia_aesni_avx_keygen,@function;
+
+_gcry_camellia_aesni_avx_keygen:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: key
+        *      %rdx: keylen
+        */
+
+       vzeroupper;
+
+       vmovdqu (%rsi), %xmm0;
+       cmpl $24, %edx;
+       jb __camellia_avx_setup128;
+       je .Lprepare_key192;
+
+       vmovdqu 16(%rsi), %xmm1;
+       jmp __camellia_avx_setup256;
+
+.Lprepare_key192:
+       vpcmpeqd %xmm2, %xmm2, %xmm2;
+       vmovq 16(%rsi), %xmm1;
+
+       vpxor %xmm1, %xmm2, %xmm2;
+       vpslldq $8, %xmm2, %xmm2;
+       vpor %xmm2, %xmm1, %xmm1;
+
+       jmp __camellia_avx_setup256;
+.size _gcry_camellia_aesni_avx_keygen,.-_gcry_camellia_aesni_avx_keygen;
+
+#endif /*defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX_SUPPORT)*/
+#endif /*__x86_64*/
diff --git a/cipher/camellia-aesni-avx2-amd64.S b/cipher/camellia-aesni-avx2-amd64.S
new file mode 100644 (file)
index 0000000..1a89ff4
--- /dev/null
@@ -0,0 +1,1263 @@
+/* camellia-avx2-aesni-amd64.S  -  AES-NI/AVX2 implementation of Camellia cipher
+ *
+ * Copyright © 2013 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(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT)
+
+#ifdef __PIC__
+#  define RIP (%rip)
+#else
+#  define RIP
+#endif
+
+#define CAMELLIA_TABLE_BYTE_LEN 272
+
+/* struct CAMELLIA_context: */
+#define key_table 0
+#define key_bitlength CAMELLIA_TABLE_BYTE_LEN
+
+/* register macros */
+#define CTX %rdi
+#define RIO %r8
+
+/**********************************************************************
+  helper macros
+ **********************************************************************/
+#define filter_8bit(x, lo_t, hi_t, mask4bit, tmp0) \
+       vpand x, mask4bit, tmp0; \
+       vpandn x, mask4bit, x; \
+       vpsrld $4, x, x; \
+       \
+       vpshufb tmp0, lo_t, tmp0; \
+       vpshufb x, hi_t, x; \
+       vpxor tmp0, x, x;
+
+#define ymm0_x xmm0
+#define ymm1_x xmm1
+#define ymm2_x xmm2
+#define ymm3_x xmm3
+#define ymm4_x xmm4
+#define ymm5_x xmm5
+#define ymm6_x xmm6
+#define ymm7_x xmm7
+#define ymm8_x xmm8
+#define ymm9_x xmm9
+#define ymm10_x xmm10
+#define ymm11_x xmm11
+#define ymm12_x xmm12
+#define ymm13_x xmm13
+#define ymm14_x xmm14
+#define ymm15_x xmm15
+
+/**********************************************************************
+  32-way camellia
+ **********************************************************************/
+
+/*
+ * IN:
+ *   x0..x7: byte-sliced AB state
+ *   mem_cd: register pointer storing CD state
+ *   key: index for key material
+ * OUT:
+ *   x0..x7: new byte-sliced CD state
+ */
+#define roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, t0, t1, t2, t3, t4, t5, t6, \
+                 t7, mem_cd, key) \
+       /* \
+        * S-function with AES subbytes \
+        */ \
+       vbroadcasti128 .Linv_shift_row RIP, t4; \
+       vpbroadcastd .L0f0f0f0f RIP, t7; \
+       vbroadcasti128 .Lpre_tf_lo_s1 RIP, t5; \
+       vbroadcasti128 .Lpre_tf_hi_s1 RIP, t6; \
+       vbroadcasti128 .Lpre_tf_lo_s4 RIP, t2; \
+       vbroadcasti128 .Lpre_tf_hi_s4 RIP, t3; \
+       \
+       /* AES inverse shift rows */ \
+       vpshufb t4, x0, x0; \
+       vpshufb t4, x7, x7; \
+       vpshufb t4, x3, x3; \
+       vpshufb t4, x6, x6; \
+       vpshufb t4, x2, x2; \
+       vpshufb t4, x5, x5; \
+       vpshufb t4, x1, x1; \
+       vpshufb t4, x4, x4; \
+       \
+       /* prefilter sboxes 1, 2 and 3 */ \
+       /* prefilter sbox 4 */ \
+       filter_8bit(x0, t5, t6, t7, t4); \
+       filter_8bit(x7, t5, t6, t7, t4); \
+       vextracti128 $1, x0, t0##_x; \
+       vextracti128 $1, x7, t1##_x; \
+       filter_8bit(x3, t2, t3, t7, t4); \
+       filter_8bit(x6, t2, t3, t7, t4); \
+       vextracti128 $1, x3, t3##_x; \
+       vextracti128 $1, x6, t2##_x; \
+       filter_8bit(x2, t5, t6, t7, t4); \
+       filter_8bit(x5, t5, t6, t7, t4); \
+       filter_8bit(x1, t5, t6, t7, t4); \
+       filter_8bit(x4, t5, t6, t7, t4); \
+       \
+       vpxor t4##_x, t4##_x, t4##_x; \
+       \
+       /* AES subbytes + AES shift rows */ \
+       vextracti128 $1, x2, t6##_x; \
+       vextracti128 $1, x5, t5##_x; \
+       vaesenclast t4##_x, x0##_x, x0##_x; \
+       vaesenclast t4##_x, t0##_x, t0##_x; \
+       vaesenclast t4##_x, x7##_x, x7##_x; \
+       vaesenclast t4##_x, t1##_x, t1##_x; \
+       vaesenclast t4##_x, x3##_x, x3##_x; \
+       vaesenclast t4##_x, t3##_x, t3##_x; \
+       vaesenclast t4##_x, x6##_x, x6##_x; \
+       vaesenclast t4##_x, t2##_x, t2##_x; \
+       vinserti128 $1, t0##_x, x0, x0; \
+       vinserti128 $1, t1##_x, x7, x7; \
+       vinserti128 $1, t3##_x, x3, x3; \
+       vinserti128 $1, t2##_x, x6, x6; \
+       vextracti128 $1, x1, t3##_x; \
+       vextracti128 $1, x4, t2##_x; \
+       vbroadcasti128 .Lpost_tf_lo_s1 RIP, t0; \
+       vbroadcasti128 .Lpost_tf_hi_s1 RIP, t1; \
+       vaesenclast t4##_x, x2##_x, x2##_x; \
+       vaesenclast t4##_x, t6##_x, t6##_x; \
+       vaesenclast t4##_x, x5##_x, x5##_x; \
+       vaesenclast t4##_x, t5##_x, t5##_x; \
+       vaesenclast t4##_x, x1##_x, x1##_x; \
+       vaesenclast t4##_x, t3##_x, t3##_x; \
+       vaesenclast t4##_x, x4##_x, x4##_x; \
+       vaesenclast t4##_x, t2##_x, t2##_x; \
+       vinserti128 $1, t6##_x, x2, x2; \
+       vinserti128 $1, t5##_x, x5, x5; \
+       vinserti128 $1, t3##_x, x1, x1; \
+       vinserti128 $1, t2##_x, x4, x4; \
+       \
+       /* postfilter sboxes 1 and 4 */ \
+       vbroadcasti128 .Lpost_tf_lo_s3 RIP, t2; \
+       vbroadcasti128 .Lpost_tf_hi_s3 RIP, t3; \
+       filter_8bit(x0, t0, t1, t7, t4); \
+       filter_8bit(x7, t0, t1, t7, t4); \
+       filter_8bit(x3, t0, t1, t7, t6); \
+       filter_8bit(x6, t0, t1, t7, t6); \
+       \
+       /* postfilter sbox 3 */ \
+       vbroadcasti128 .Lpost_tf_lo_s2 RIP, t4; \
+       vbroadcasti128 .Lpost_tf_hi_s2 RIP, t5; \
+       filter_8bit(x2, t2, t3, t7, t6); \
+       filter_8bit(x5, t2, t3, t7, t6); \
+       \
+       vpbroadcastq key, t0; /* higher 64-bit duplicate ignored */ \
+       \
+       /* postfilter sbox 2 */ \
+       filter_8bit(x1, t4, t5, t7, t2); \
+       filter_8bit(x4, t4, t5, t7, t2); \
+       vpxor t7, t7, t7; \
+       \
+       vpsrldq $1, t0, t1; \
+       vpsrldq $2, t0, t2; \
+       vpshufb t7, t1, t1; \
+       vpsrldq $3, t0, t3; \
+       \
+       /* P-function */ \
+       vpxor x5, x0, x0; \
+       vpxor x6, x1, x1; \
+       vpxor x7, x2, x2; \
+       vpxor x4, x3, x3; \
+       \
+       vpshufb t7, t2, t2; \
+       vpsrldq $4, t0, t4; \
+       vpshufb t7, t3, t3; \
+       vpsrldq $5, t0, t5; \
+       vpshufb t7, t4, t4; \
+       \
+       vpxor x2, x4, x4; \
+       vpxor x3, x5, x5; \
+       vpxor x0, x6, x6; \
+       vpxor x1, x7, x7; \
+       \
+       vpsrldq $6, t0, t6; \
+       vpshufb t7, t5, t5; \
+       vpshufb t7, t6, t6; \
+       \
+       vpxor x7, x0, x0; \
+       vpxor x4, x1, x1; \
+       vpxor x5, x2, x2; \
+       vpxor x6, x3, x3; \
+       \
+       vpxor x3, x4, x4; \
+       vpxor x0, x5, x5; \
+       vpxor x1, x6, x6; \
+       vpxor x2, x7, x7; /* note: high and low parts swapped */ \
+       \
+       /* Add key material and result to CD (x becomes new CD) */ \
+       \
+       vpxor t6, x1, x1; \
+       vpxor 5 * 32(mem_cd), x1, x1; \
+       \
+       vpsrldq $7, t0, t6; \
+       vpshufb t7, t0, t0; \
+       vpshufb t7, t6, t7; \
+       \
+       vpxor t7, x0, x0; \
+       vpxor 4 * 32(mem_cd), x0, x0; \
+       \
+       vpxor t5, x2, x2; \
+       vpxor 6 * 32(mem_cd), x2, x2; \
+       \
+       vpxor t4, x3, x3; \
+       vpxor 7 * 32(mem_cd), x3, x3; \
+       \
+       vpxor t3, x4, x4; \
+       vpxor 0 * 32(mem_cd), x4, x4; \
+       \
+       vpxor t2, x5, x5; \
+       vpxor 1 * 32(mem_cd), x5, x5; \
+       \
+       vpxor t1, x6, x6; \
+       vpxor 2 * 32(mem_cd), x6, x6; \
+       \
+       vpxor t0, x7, x7; \
+       vpxor 3 * 32(mem_cd), x7, x7;
+
+/*
+ * IN/OUT:
+ *  x0..x7: byte-sliced AB state preloaded
+ *  mem_ab: byte-sliced AB state in memory
+ *  mem_cb: byte-sliced CD state in memory
+ */
+#define two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd, i, dir, store_ab) \
+       roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                 y6, y7, mem_cd, (key_table + (i) * 8)(CTX)); \
+       \
+       vmovdqu x0, 4 * 32(mem_cd); \
+       vmovdqu x1, 5 * 32(mem_cd); \
+       vmovdqu x2, 6 * 32(mem_cd); \
+       vmovdqu x3, 7 * 32(mem_cd); \
+       vmovdqu x4, 0 * 32(mem_cd); \
+       vmovdqu x5, 1 * 32(mem_cd); \
+       vmovdqu x6, 2 * 32(mem_cd); \
+       vmovdqu x7, 3 * 32(mem_cd); \
+       \
+       roundsm32(x4, x5, x6, x7, x0, x1, x2, x3, y0, y1, y2, y3, y4, y5, \
+                 y6, y7, mem_ab, (key_table + ((i) + (dir)) * 8)(CTX)); \
+       \
+       store_ab(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab);
+
+#define dummy_store(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab) /* do nothing */
+
+#define store_ab_state(x0, x1, x2, x3, x4, x5, x6, x7, mem_ab) \
+       /* Store new AB state */ \
+       vmovdqu x4, 4 * 32(mem_ab); \
+       vmovdqu x5, 5 * 32(mem_ab); \
+       vmovdqu x6, 6 * 32(mem_ab); \
+       vmovdqu x7, 7 * 32(mem_ab); \
+       vmovdqu x0, 0 * 32(mem_ab); \
+       vmovdqu x1, 1 * 32(mem_ab); \
+       vmovdqu x2, 2 * 32(mem_ab); \
+       vmovdqu x3, 3 * 32(mem_ab);
+
+#define enc_rounds32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd, i) \
+       two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd, (i) + 2, 1, store_ab_state); \
+       two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd, (i) + 4, 1, store_ab_state); \
+       two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd, (i) + 6, 1, dummy_store);
+
+#define dec_rounds32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd, i) \
+       two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd, (i) + 7, -1, store_ab_state); \
+       two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd, (i) + 5, -1, store_ab_state); \
+       two_roundsm32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd, (i) + 3, -1, dummy_store);
+
+/*
+ * IN:
+ *  v0..3: byte-sliced 32-bit integers
+ * OUT:
+ *  v0..3: (IN <<< 1)
+ */
+#define rol32_1_32(v0, v1, v2, v3, t0, t1, t2, zero) \
+       vpcmpgtb v0, zero, t0; \
+       vpaddb v0, v0, v0; \
+       vpabsb t0, t0; \
+       \
+       vpcmpgtb v1, zero, t1; \
+       vpaddb v1, v1, v1; \
+       vpabsb t1, t1; \
+       \
+       vpcmpgtb v2, zero, t2; \
+       vpaddb v2, v2, v2; \
+       vpabsb t2, t2; \
+       \
+       vpor t0, v1, v1; \
+       \
+       vpcmpgtb v3, zero, t0; \
+       vpaddb v3, v3, v3; \
+       vpabsb t0, t0; \
+       \
+       vpor t1, v2, v2; \
+       vpor t2, v3, v3; \
+       vpor t0, v0, v0;
+
+/*
+ * IN:
+ *   r: byte-sliced AB state in memory
+ *   l: byte-sliced CD state in memory
+ * OUT:
+ *   x0..x7: new byte-sliced CD state
+ */
+#define fls32(l, l0, l1, l2, l3, l4, l5, l6, l7, r, t0, t1, t2, t3, tt0, \
+             tt1, tt2, tt3, kll, klr, krl, krr) \
+       /* \
+        * t0 = kll; \
+        * t0 &= ll; \
+        * lr ^= rol32(t0, 1); \
+        */ \
+       vpbroadcastd kll, t0; /* only lowest 32-bit used */ \
+       vpxor tt0, tt0, tt0; \
+       vpshufb tt0, t0, t3; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t2; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t1; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t0; \
+       \
+       vpand l0, t0, t0; \
+       vpand l1, t1, t1; \
+       vpand l2, t2, t2; \
+       vpand l3, t3, t3; \
+       \
+       rol32_1_32(t3, t2, t1, t0, tt1, tt2, tt3, tt0); \
+       \
+       vpxor l4, t0, l4; \
+       vpbroadcastd krr, t0; /* only lowest 32-bit used */ \
+       vmovdqu l4, 4 * 32(l); \
+       vpxor l5, t1, l5; \
+       vmovdqu l5, 5 * 32(l); \
+       vpxor l6, t2, l6; \
+       vmovdqu l6, 6 * 32(l); \
+       vpxor l7, t3, l7; \
+       vmovdqu l7, 7 * 32(l); \
+       \
+       /* \
+        * t2 = krr; \
+        * t2 |= rr; \
+        * rl ^= t2; \
+        */ \
+       \
+       vpshufb tt0, t0, t3; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t2; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t1; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t0; \
+       \
+       vpor 4 * 32(r), t0, t0; \
+       vpor 5 * 32(r), t1, t1; \
+       vpor 6 * 32(r), t2, t2; \
+       vpor 7 * 32(r), t3, t3; \
+       \
+       vpxor 0 * 32(r), t0, t0; \
+       vpxor 1 * 32(r), t1, t1; \
+       vpxor 2 * 32(r), t2, t2; \
+       vpxor 3 * 32(r), t3, t3; \
+       vmovdqu t0, 0 * 32(r); \
+       vpbroadcastd krl, t0; /* only lowest 32-bit used */ \
+       vmovdqu t1, 1 * 32(r); \
+       vmovdqu t2, 2 * 32(r); \
+       vmovdqu t3, 3 * 32(r); \
+       \
+       /* \
+        * t2 = krl; \
+        * t2 &= rl; \
+        * rr ^= rol32(t2, 1); \
+        */ \
+       vpshufb tt0, t0, t3; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t2; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t1; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t0; \
+       \
+       vpand 0 * 32(r), t0, t0; \
+       vpand 1 * 32(r), t1, t1; \
+       vpand 2 * 32(r), t2, t2; \
+       vpand 3 * 32(r), t3, t3; \
+       \
+       rol32_1_32(t3, t2, t1, t0, tt1, tt2, tt3, tt0); \
+       \
+       vpxor 4 * 32(r), t0, t0; \
+       vpxor 5 * 32(r), t1, t1; \
+       vpxor 6 * 32(r), t2, t2; \
+       vpxor 7 * 32(r), t3, t3; \
+       vmovdqu t0, 4 * 32(r); \
+       vpbroadcastd klr, t0; /* only lowest 32-bit used */ \
+       vmovdqu t1, 5 * 32(r); \
+       vmovdqu t2, 6 * 32(r); \
+       vmovdqu t3, 7 * 32(r); \
+       \
+       /* \
+        * t0 = klr; \
+        * t0 |= lr; \
+        * ll ^= t0; \
+        */ \
+       \
+       vpshufb tt0, t0, t3; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t2; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t1; \
+       vpsrldq $1, t0, t0; \
+       vpshufb tt0, t0, t0; \
+       \
+       vpor l4, t0, t0; \
+       vpor l5, t1, t1; \
+       vpor l6, t2, t2; \
+       vpor l7, t3, t3; \
+       \
+       vpxor l0, t0, l0; \
+       vmovdqu l0, 0 * 32(l); \
+       vpxor l1, t1, l1; \
+       vmovdqu l1, 1 * 32(l); \
+       vpxor l2, t2, l2; \
+       vmovdqu l2, 2 * 32(l); \
+       vpxor l3, t3, l3; \
+       vmovdqu l3, 3 * 32(l);
+
+#define transpose_4x4(x0, x1, x2, x3, t1, t2) \
+       vpunpckhdq x1, x0, t2; \
+       vpunpckldq x1, x0, x0; \
+       \
+       vpunpckldq x3, x2, t1; \
+       vpunpckhdq x3, x2, x2; \
+       \
+       vpunpckhqdq t1, x0, x1; \
+       vpunpcklqdq t1, x0, x0; \
+       \
+       vpunpckhqdq x2, t2, x3; \
+       vpunpcklqdq x2, t2, x2;
+
+#define byteslice_16x16b_fast(a0, b0, c0, d0, a1, b1, c1, d1, a2, b2, c2, d2, \
+                             a3, b3, c3, d3, st0, st1) \
+       vmovdqu d2, st0; \
+       vmovdqu d3, st1; \
+       transpose_4x4(a0, a1, a2, a3, d2, d3); \
+       transpose_4x4(b0, b1, b2, b3, d2, d3); \
+       vmovdqu st0, d2; \
+       vmovdqu st1, d3; \
+       \
+       vmovdqu a0, st0; \
+       vmovdqu a1, st1; \
+       transpose_4x4(c0, c1, c2, c3, a0, a1); \
+       transpose_4x4(d0, d1, d2, d3, a0, a1); \
+       \
+       vbroadcasti128 .Lshufb_16x16b RIP, a0; \
+       vmovdqu st1, a1; \
+       vpshufb a0, a2, a2; \
+       vpshufb a0, a3, a3; \
+       vpshufb a0, b0, b0; \
+       vpshufb a0, b1, b1; \
+       vpshufb a0, b2, b2; \
+       vpshufb a0, b3, b3; \
+       vpshufb a0, a1, a1; \
+       vpshufb a0, c0, c0; \
+       vpshufb a0, c1, c1; \
+       vpshufb a0, c2, c2; \
+       vpshufb a0, c3, c3; \
+       vpshufb a0, d0, d0; \
+       vpshufb a0, d1, d1; \
+       vpshufb a0, d2, d2; \
+       vpshufb a0, d3, d3; \
+       vmovdqu d3, st1; \
+       vmovdqu st0, d3; \
+       vpshufb a0, d3, a0; \
+       vmovdqu d2, st0; \
+       \
+       transpose_4x4(a0, b0, c0, d0, d2, d3); \
+       transpose_4x4(a1, b1, c1, d1, d2, d3); \
+       vmovdqu st0, d2; \
+       vmovdqu st1, d3; \
+       \
+       vmovdqu b0, st0; \
+       vmovdqu b1, st1; \
+       transpose_4x4(a2, b2, c2, d2, b0, b1); \
+       transpose_4x4(a3, b3, c3, d3, b0, b1); \
+       vmovdqu st0, b0; \
+       vmovdqu st1, b1; \
+       /* does not adjust output bytes inside vectors */
+
+/* load blocks to registers and apply pre-whitening */
+#define inpack32_pre(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                    y6, y7, rio, key) \
+       vpbroadcastq key, x0; \
+       vpshufb .Lpack_bswap RIP, x0, x0; \
+       \
+       vpxor 0 * 32(rio), x0, y7; \
+       vpxor 1 * 32(rio), x0, y6; \
+       vpxor 2 * 32(rio), x0, y5; \
+       vpxor 3 * 32(rio), x0, y4; \
+       vpxor 4 * 32(rio), x0, y3; \
+       vpxor 5 * 32(rio), x0, y2; \
+       vpxor 6 * 32(rio), x0, y1; \
+       vpxor 7 * 32(rio), x0, y0; \
+       vpxor 8 * 32(rio), x0, x7; \
+       vpxor 9 * 32(rio), x0, x6; \
+       vpxor 10 * 32(rio), x0, x5; \
+       vpxor 11 * 32(rio), x0, x4; \
+       vpxor 12 * 32(rio), x0, x3; \
+       vpxor 13 * 32(rio), x0, x2; \
+       vpxor 14 * 32(rio), x0, x1; \
+       vpxor 15 * 32(rio), x0, x0;
+
+/* byteslice pre-whitened blocks and store to temporary memory */
+#define inpack32_post(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                     y6, y7, mem_ab, mem_cd) \
+       byteslice_16x16b_fast(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, \
+                             y4, y5, y6, y7, (mem_ab), (mem_cd)); \
+       \
+       vmovdqu x0, 0 * 32(mem_ab); \
+       vmovdqu x1, 1 * 32(mem_ab); \
+       vmovdqu x2, 2 * 32(mem_ab); \
+       vmovdqu x3, 3 * 32(mem_ab); \
+       vmovdqu x4, 4 * 32(mem_ab); \
+       vmovdqu x5, 5 * 32(mem_ab); \
+       vmovdqu x6, 6 * 32(mem_ab); \
+       vmovdqu x7, 7 * 32(mem_ab); \
+       vmovdqu y0, 0 * 32(mem_cd); \
+       vmovdqu y1, 1 * 32(mem_cd); \
+       vmovdqu y2, 2 * 32(mem_cd); \
+       vmovdqu y3, 3 * 32(mem_cd); \
+       vmovdqu y4, 4 * 32(mem_cd); \
+       vmovdqu y5, 5 * 32(mem_cd); \
+       vmovdqu y6, 6 * 32(mem_cd); \
+       vmovdqu y7, 7 * 32(mem_cd);
+
+/* de-byteslice, apply post-whitening and store blocks */
+#define outunpack32(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, \
+                   y5, y6, y7, key, stack_tmp0, stack_tmp1) \
+       byteslice_16x16b_fast(y0, y4, x0, x4, y1, y5, x1, x5, y2, y6, x2, x6, \
+                             y3, y7, x3, x7, stack_tmp0, stack_tmp1); \
+       \
+       vmovdqu x0, stack_tmp0; \
+       \
+       vpbroadcastq key, x0; \
+       vpshufb .Lpack_bswap RIP, x0, x0; \
+       \
+       vpxor x0, y7, y7; \
+       vpxor x0, y6, y6; \
+       vpxor x0, y5, y5; \
+       vpxor x0, y4, y4; \
+       vpxor x0, y3, y3; \
+       vpxor x0, y2, y2; \
+       vpxor x0, y1, y1; \
+       vpxor x0, y0, y0; \
+       vpxor x0, x7, x7; \
+       vpxor x0, x6, x6; \
+       vpxor x0, x5, x5; \
+       vpxor x0, x4, x4; \
+       vpxor x0, x3, x3; \
+       vpxor x0, x2, x2; \
+       vpxor x0, x1, x1; \
+       vpxor stack_tmp0, x0, x0;
+
+#define write_output(x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, \
+                    y6, y7, rio) \
+       vmovdqu x0, 0 * 32(rio); \
+       vmovdqu x1, 1 * 32(rio); \
+       vmovdqu x2, 2 * 32(rio); \
+       vmovdqu x3, 3 * 32(rio); \
+       vmovdqu x4, 4 * 32(rio); \
+       vmovdqu x5, 5 * 32(rio); \
+       vmovdqu x6, 6 * 32(rio); \
+       vmovdqu x7, 7 * 32(rio); \
+       vmovdqu y0, 8 * 32(rio); \
+       vmovdqu y1, 9 * 32(rio); \
+       vmovdqu y2, 10 * 32(rio); \
+       vmovdqu y3, 11 * 32(rio); \
+       vmovdqu y4, 12 * 32(rio); \
+       vmovdqu y5, 13 * 32(rio); \
+       vmovdqu y6, 14 * 32(rio); \
+       vmovdqu y7, 15 * 32(rio);
+
+.data
+.align 32
+
+#define SHUFB_BYTES(idx) \
+       0 + (idx), 4 + (idx), 8 + (idx), 12 + (idx)
+
+.Lshufb_16x16b:
+       .byte SHUFB_BYTES(0), SHUFB_BYTES(1), SHUFB_BYTES(2), SHUFB_BYTES(3)
+       .byte SHUFB_BYTES(0), SHUFB_BYTES(1), SHUFB_BYTES(2), SHUFB_BYTES(3)
+
+.Lpack_bswap:
+       .long 0x00010203, 0x04050607, 0x80808080, 0x80808080
+       .long 0x00010203, 0x04050607, 0x80808080, 0x80808080
+
+/* For CTR-mode IV byteswap */
+.Lbswap128_mask:
+       .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
+
+/*
+ * pre-SubByte transform
+ *
+ * pre-lookup for sbox1, sbox2, sbox3:
+ *   swap_bitendianness(
+ *       isom_map_camellia_to_aes(
+ *           camellia_f(
+ *               swap_bitendianess(in)
+ *           )
+ *       )
+ *   )
+ *
+ * (note: '⊕ 0xc5' inside camellia_f())
+ */
+.Lpre_tf_lo_s1:
+       .byte 0x45, 0xe8, 0x40, 0xed, 0x2e, 0x83, 0x2b, 0x86
+       .byte 0x4b, 0xe6, 0x4e, 0xe3, 0x20, 0x8d, 0x25, 0x88
+.Lpre_tf_hi_s1:
+       .byte 0x00, 0x51, 0xf1, 0xa0, 0x8a, 0xdb, 0x7b, 0x2a
+       .byte 0x09, 0x58, 0xf8, 0xa9, 0x83, 0xd2, 0x72, 0x23
+
+/*
+ * pre-SubByte transform
+ *
+ * pre-lookup for sbox4:
+ *   swap_bitendianness(
+ *       isom_map_camellia_to_aes(
+ *           camellia_f(
+ *               swap_bitendianess(in <<< 1)
+ *           )
+ *       )
+ *   )
+ *
+ * (note: '⊕ 0xc5' inside camellia_f())
+ */
+.Lpre_tf_lo_s4:
+       .byte 0x45, 0x40, 0x2e, 0x2b, 0x4b, 0x4e, 0x20, 0x25
+       .byte 0x14, 0x11, 0x7f, 0x7a, 0x1a, 0x1f, 0x71, 0x74
+.Lpre_tf_hi_s4:
+       .byte 0x00, 0xf1, 0x8a, 0x7b, 0x09, 0xf8, 0x83, 0x72
+       .byte 0xad, 0x5c, 0x27, 0xd6, 0xa4, 0x55, 0x2e, 0xdf
+
+/*
+ * post-SubByte transform
+ *
+ * post-lookup for sbox1, sbox4:
+ *  swap_bitendianness(
+ *      camellia_h(
+ *          isom_map_aes_to_camellia(
+ *              swap_bitendianness(
+ *                  aes_inverse_affine_transform(in)
+ *              )
+ *          )
+ *      )
+ *  )
+ *
+ * (note: '⊕ 0x6e' inside camellia_h())
+ */
+.Lpost_tf_lo_s1:
+       .byte 0x3c, 0xcc, 0xcf, 0x3f, 0x32, 0xc2, 0xc1, 0x31
+       .byte 0xdc, 0x2c, 0x2f, 0xdf, 0xd2, 0x22, 0x21, 0xd1
+.Lpost_tf_hi_s1:
+       .byte 0x00, 0xf9, 0x86, 0x7f, 0xd7, 0x2e, 0x51, 0xa8
+       .byte 0xa4, 0x5d, 0x22, 0xdb, 0x73, 0x8a, 0xf5, 0x0c
+
+/*
+ * post-SubByte transform
+ *
+ * post-lookup for sbox2:
+ *  swap_bitendianness(
+ *      camellia_h(
+ *          isom_map_aes_to_camellia(
+ *              swap_bitendianness(
+ *                  aes_inverse_affine_transform(in)
+ *              )
+ *          )
+ *      )
+ *  ) <<< 1
+ *
+ * (note: '⊕ 0x6e' inside camellia_h())
+ */
+.Lpost_tf_lo_s2:
+       .byte 0x78, 0x99, 0x9f, 0x7e, 0x64, 0x85, 0x83, 0x62
+       .byte 0xb9, 0x58, 0x5e, 0xbf, 0xa5, 0x44, 0x42, 0xa3
+.Lpost_tf_hi_s2:
+       .byte 0x00, 0xf3, 0x0d, 0xfe, 0xaf, 0x5c, 0xa2, 0x51
+       .byte 0x49, 0xba, 0x44, 0xb7, 0xe6, 0x15, 0xeb, 0x18
+
+/*
+ * post-SubByte transform
+ *
+ * post-lookup for sbox3:
+ *  swap_bitendianness(
+ *      camellia_h(
+ *          isom_map_aes_to_camellia(
+ *              swap_bitendianness(
+ *                  aes_inverse_affine_transform(in)
+ *              )
+ *          )
+ *      )
+ *  ) >>> 1
+ *
+ * (note: '⊕ 0x6e' inside camellia_h())
+ */
+.Lpost_tf_lo_s3:
+       .byte 0x1e, 0x66, 0xe7, 0x9f, 0x19, 0x61, 0xe0, 0x98
+       .byte 0x6e, 0x16, 0x97, 0xef, 0x69, 0x11, 0x90, 0xe8
+.Lpost_tf_hi_s3:
+       .byte 0x00, 0xfc, 0x43, 0xbf, 0xeb, 0x17, 0xa8, 0x54
+       .byte 0x52, 0xae, 0x11, 0xed, 0xb9, 0x45, 0xfa, 0x06
+
+/* For isolating SubBytes from AESENCLAST, inverse shift row */
+.Linv_shift_row:
+       .byte 0x00, 0x0d, 0x0a, 0x07, 0x04, 0x01, 0x0e, 0x0b
+       .byte 0x08, 0x05, 0x02, 0x0f, 0x0c, 0x09, 0x06, 0x03
+
+.align 4
+/* 4-bit mask */
+.L0f0f0f0f:
+       .long 0x0f0f0f0f
+
+.text
+
+.align 8
+.type   __camellia_enc_blk32,@function;
+
+__camellia_enc_blk32:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rax: temporary storage, 512 bytes
+        *      %ymm0..%ymm15: 32 plaintext blocks
+        * output:
+        *      %ymm0..%ymm15: 32 encrypted blocks, order swapped:
+        *       7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8
+        */
+
+       leaq 8 * 32(%rax), %rcx;
+
+       inpack32_post(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+                     %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+                     %ymm15, %rax, %rcx);
+
+       enc_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+                    %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+                    %ymm15, %rax, %rcx, 0);
+
+       fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+             %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+             %ymm15,
+             ((key_table + (8) * 8) + 0)(CTX),
+             ((key_table + (8) * 8) + 4)(CTX),
+             ((key_table + (8) * 8) + 8)(CTX),
+             ((key_table + (8) * 8) + 12)(CTX));
+
+       enc_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+                    %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+                    %ymm15, %rax, %rcx, 8);
+
+       fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+             %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+             %ymm15,
+             ((key_table + (16) * 8) + 0)(CTX),
+             ((key_table + (16) * 8) + 4)(CTX),
+             ((key_table + (16) * 8) + 8)(CTX),
+             ((key_table + (16) * 8) + 12)(CTX));
+
+       enc_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+                    %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+                    %ymm15, %rax, %rcx, 16);
+
+       movl $24, %r8d;
+       cmpl $128, key_bitlength(CTX);
+       jne .Lenc_max32;
+
+.Lenc_done:
+       /* load CD for output */
+       vmovdqu 0 * 32(%rcx), %ymm8;
+       vmovdqu 1 * 32(%rcx), %ymm9;
+       vmovdqu 2 * 32(%rcx), %ymm10;
+       vmovdqu 3 * 32(%rcx), %ymm11;
+       vmovdqu 4 * 32(%rcx), %ymm12;
+       vmovdqu 5 * 32(%rcx), %ymm13;
+       vmovdqu 6 * 32(%rcx), %ymm14;
+       vmovdqu 7 * 32(%rcx), %ymm15;
+
+       outunpack32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+                   %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+                   %ymm15, (key_table)(CTX, %r8, 8), (%rax), 1 * 32(%rax));
+
+       ret;
+
+.align 8
+.Lenc_max32:
+       movl $32, %r8d;
+
+       fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+             %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+             %ymm15,
+             ((key_table + (24) * 8) + 0)(CTX),
+             ((key_table + (24) * 8) + 4)(CTX),
+             ((key_table + (24) * 8) + 8)(CTX),
+             ((key_table + (24) * 8) + 12)(CTX));
+
+       enc_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+                    %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+                    %ymm15, %rax, %rcx, 24);
+
+       jmp .Lenc_done;
+.size __camellia_enc_blk32,.-__camellia_enc_blk32;
+
+.align 8
+.type   __camellia_dec_blk32,@function;
+
+__camellia_dec_blk32:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rax: temporary storage, 512 bytes
+        *      %r8d: 24 for 16 byte key, 32 for larger
+        *      %ymm0..%ymm15: 16 encrypted blocks
+        * output:
+        *      %ymm0..%ymm15: 16 plaintext blocks, order swapped:
+        *       7, 8, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8
+        */
+
+       leaq 8 * 32(%rax), %rcx;
+
+       inpack32_post(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+                     %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+                     %ymm15, %rax, %rcx);
+
+       cmpl $32, %r8d;
+       je .Ldec_max32;
+
+.Ldec_max24:
+       dec_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+                    %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+                    %ymm15, %rax, %rcx, 16);
+
+       fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+             %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+             %ymm15,
+             ((key_table + (16) * 8) + 8)(CTX),
+             ((key_table + (16) * 8) + 12)(CTX),
+             ((key_table + (16) * 8) + 0)(CTX),
+             ((key_table + (16) * 8) + 4)(CTX));
+
+       dec_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+                    %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+                    %ymm15, %rax, %rcx, 8);
+
+       fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+             %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+             %ymm15,
+             ((key_table + (8) * 8) + 8)(CTX),
+             ((key_table + (8) * 8) + 12)(CTX),
+             ((key_table + (8) * 8) + 0)(CTX),
+             ((key_table + (8) * 8) + 4)(CTX));
+
+       dec_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+                    %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+                    %ymm15, %rax, %rcx, 0);
+
+       /* load CD for output */
+       vmovdqu 0 * 32(%rcx), %ymm8;
+       vmovdqu 1 * 32(%rcx), %ymm9;
+       vmovdqu 2 * 32(%rcx), %ymm10;
+       vmovdqu 3 * 32(%rcx), %ymm11;
+       vmovdqu 4 * 32(%rcx), %ymm12;
+       vmovdqu 5 * 32(%rcx), %ymm13;
+       vmovdqu 6 * 32(%rcx), %ymm14;
+       vmovdqu 7 * 32(%rcx), %ymm15;
+
+       outunpack32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+                   %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+                   %ymm15, (key_table)(CTX), (%rax), 1 * 32(%rax));
+
+       ret;
+
+.align 8
+.Ldec_max32:
+       dec_rounds32(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+                    %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+                    %ymm15, %rax, %rcx, 24);
+
+       fls32(%rax, %ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+             %rcx, %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+             %ymm15,
+             ((key_table + (24) * 8) + 8)(CTX),
+             ((key_table + (24) * 8) + 12)(CTX),
+             ((key_table + (24) * 8) + 0)(CTX),
+             ((key_table + (24) * 8) + 4)(CTX));
+
+       jmp .Ldec_max24;
+.size __camellia_dec_blk32,.-__camellia_dec_blk32;
+
+#define inc_le128(x, minus_one, tmp) \
+       vpcmpeqq minus_one, x, tmp; \
+       vpsubq minus_one, x, x; \
+       vpslldq $8, tmp, tmp; \
+       vpsubq tmp, x, x;
+
+.align 8
+.globl _gcry_camellia_aesni_avx2_ctr_enc
+.type   _gcry_camellia_aesni_avx2_ctr_enc,@function;
+
+_gcry_camellia_aesni_avx2_ctr_enc:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (32 blocks)
+        *      %rdx: src (32 blocks)
+        *      %rcx: iv (big endian, 128bit)
+        */
+
+       pushq %rbp;
+       movq %rsp, %rbp;
+
+       movq 8(%rcx), %r11;
+       bswapq %r11;
+
+       vzeroupper;
+
+       subq $(16 * 32), %rsp;
+       andq $~63, %rsp;
+       movq %rsp, %rax;
+
+       vpcmpeqd %ymm15, %ymm15, %ymm15;
+       vpsrldq $8, %ymm15, %ymm15; /* ab: -1:0 ; cd: -1:0 */
+
+       /* load IV and byteswap */
+       vmovdqu (%rcx), %xmm0;
+       vpshufb .Lbswap128_mask RIP, %xmm0, %xmm0;
+       vmovdqa %xmm0, %xmm1;
+       inc_le128(%xmm0, %xmm15, %xmm14);
+       vbroadcasti128 .Lbswap128_mask RIP, %ymm14;
+       vinserti128 $1, %xmm0, %ymm1, %ymm0;
+       vpshufb %ymm14, %ymm0, %ymm13;
+       vmovdqu %ymm13, 15 * 32(%rax);
+
+       /* check need for handling 64-bit overflow and carry */
+       cmpq $(0xffffffffffffffff - 32), %r11;
+       ja .Lload_ctr_carry;
+
+       /* construct IVs */
+       vpaddq %ymm15, %ymm15, %ymm15; /* ab: -2:0 ; cd: -2:0 */
+       vpsubq %ymm15, %ymm0, %ymm0;
+       vpshufb %ymm14, %ymm0, %ymm13;
+       vmovdqu %ymm13, 14 * 32(%rax);
+       vpsubq %ymm15, %ymm0, %ymm0;
+       vpshufb %ymm14, %ymm0, %ymm13;
+       vmovdqu %ymm13, 13 * 32(%rax);
+       vpsubq %ymm15, %ymm0, %ymm0;
+       vpshufb %ymm14, %ymm0, %ymm12;
+       vpsubq %ymm15, %ymm0, %ymm0;
+       vpshufb %ymm14, %ymm0, %ymm11;
+       vpsubq %ymm15, %ymm0, %ymm0;
+       vpshufb %ymm14, %ymm0, %ymm10;
+       vpsubq %ymm15, %ymm0, %ymm0;
+       vpshufb %ymm14, %ymm0, %ymm9;
+       vpsubq %ymm15, %ymm0, %ymm0;
+       vpshufb %ymm14, %ymm0, %ymm8;
+       vpsubq %ymm15, %ymm0, %ymm0;
+       vpshufb %ymm14, %ymm0, %ymm7;
+       vpsubq %ymm15, %ymm0, %ymm0;
+       vpshufb %ymm14, %ymm0, %ymm6;
+       vpsubq %ymm15, %ymm0, %ymm0;
+       vpshufb %ymm14, %ymm0, %ymm5;
+       vpsubq %ymm15, %ymm0, %ymm0;
+       vpshufb %ymm14, %ymm0, %ymm4;
+       vpsubq %ymm15, %ymm0, %ymm0;
+       vpshufb %ymm14, %ymm0, %ymm3;
+       vpsubq %ymm15, %ymm0, %ymm0;
+       vpshufb %ymm14, %ymm0, %ymm2;
+       vpsubq %ymm15, %ymm0, %ymm0;
+       vpshufb %ymm14, %ymm0, %ymm1;
+       vpsubq %ymm15, %ymm0, %ymm0;  /* +30 ; +31 */
+       vpsubq %xmm15, %xmm0, %xmm13; /* +32 */
+       vpshufb %ymm14, %ymm0, %ymm0;
+       vpshufb %xmm14, %xmm13, %xmm13;
+       vmovdqu %xmm13, (%rcx);
+
+       jmp .Lload_ctr_done;
+
+.align 4
+.Lload_ctr_carry:
+       /* construct IVs */
+       inc_le128(%ymm0, %ymm15, %ymm13); /* ab: le1 ; cd: le2 */
+       inc_le128(%ymm0, %ymm15, %ymm13); /* ab: le2 ; cd: le3 */
+       vpshufb %ymm14, %ymm0, %ymm13;
+       vmovdqu %ymm13, 14 * 32(%rax);
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       vpshufb %ymm14, %ymm0, %ymm13;
+       vmovdqu %ymm13, 13 * 32(%rax);
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       vpshufb %ymm14, %ymm0, %ymm12;
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       vpshufb %ymm14, %ymm0, %ymm11;
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       vpshufb %ymm14, %ymm0, %ymm10;
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       vpshufb %ymm14, %ymm0, %ymm9;
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       vpshufb %ymm14, %ymm0, %ymm8;
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       vpshufb %ymm14, %ymm0, %ymm7;
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       vpshufb %ymm14, %ymm0, %ymm6;
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       vpshufb %ymm14, %ymm0, %ymm5;
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       vpshufb %ymm14, %ymm0, %ymm4;
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       vpshufb %ymm14, %ymm0, %ymm3;
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       vpshufb %ymm14, %ymm0, %ymm2;
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       vpshufb %ymm14, %ymm0, %ymm1;
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       inc_le128(%ymm0, %ymm15, %ymm13);
+       vextracti128 $1, %ymm0, %xmm13;
+       vpshufb %ymm14, %ymm0, %ymm0;
+       inc_le128(%xmm13, %xmm15, %xmm14);
+       vpshufb .Lbswap128_mask RIP, %xmm13, %xmm13;
+       vmovdqu %xmm13, (%rcx);
+
+.align 4
+.Lload_ctr_done:
+       /* 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(%rdx), %ymm7, %ymm7;
+       vpxor 1 * 32(%rdx), %ymm6, %ymm6;
+       vpxor 2 * 32(%rdx), %ymm5, %ymm5;
+       vpxor 3 * 32(%rdx), %ymm4, %ymm4;
+       vpxor 4 * 32(%rdx), %ymm3, %ymm3;
+       vpxor 5 * 32(%rdx), %ymm2, %ymm2;
+       vpxor 6 * 32(%rdx), %ymm1, %ymm1;
+       vpxor 7 * 32(%rdx), %ymm0, %ymm0;
+       vpxor 8 * 32(%rdx), %ymm15, %ymm15;
+       vpxor 9 * 32(%rdx), %ymm14, %ymm14;
+       vpxor 10 * 32(%rdx), %ymm13, %ymm13;
+       vpxor 11 * 32(%rdx), %ymm12, %ymm12;
+       vpxor 12 * 32(%rdx), %ymm11, %ymm11;
+       vpxor 13 * 32(%rdx), %ymm10, %ymm10;
+       vpxor 14 * 32(%rdx), %ymm9, %ymm9;
+       vpxor 15 * 32(%rdx), %ymm8, %ymm8;
+       leaq 32 * 16(%rdx), %rdx;
+
+       write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0,
+                    %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9,
+                    %ymm8, %rsi);
+
+       vzeroall;
+
+       leave;
+       ret;
+.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;
+
+_gcry_camellia_aesni_avx2_cbc_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (16 blocks)
+        *      %rdx: src (16 blocks)
+        *      %rcx: iv
+        */
+
+       pushq %rbp;
+       movq %rsp, %rbp;
+
+       vzeroupper;
+
+       movq %rcx, %r9;
+
+       cmpl $128, key_bitlength(CTX);
+       movl $32, %r8d;
+       movl $24, %eax;
+       cmovel %eax, %r8d; /* max */
+
+       subq $(16 * 32), %rsp;
+       andq $~63, %rsp;
+       movq %rsp, %rax;
+
+       inpack32_pre(%ymm0, %ymm1, %ymm2, %ymm3, %ymm4, %ymm5, %ymm6, %ymm7,
+                    %ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
+                    %ymm15, %rdx, (key_table)(CTX, %r8, 8));
+
+       call __camellia_dec_blk32;
+
+       /* XOR output with IV */
+       vmovdqu %ymm8, (%rax);
+       vmovdqu (%r9), %xmm8;
+       vinserti128 $1, (%rdx), %ymm8, %ymm8;
+       vpxor %ymm8, %ymm7, %ymm7;
+       vmovdqu (%rax), %ymm8;
+       vpxor (0 * 32 + 16)(%rdx), %ymm6, %ymm6;
+       vpxor (1 * 32 + 16)(%rdx), %ymm5, %ymm5;
+       vpxor (2 * 32 + 16)(%rdx), %ymm4, %ymm4;
+       vpxor (3 * 32 + 16)(%rdx), %ymm3, %ymm3;
+       vpxor (4 * 32 + 16)(%rdx), %ymm2, %ymm2;
+       vpxor (5 * 32 + 16)(%rdx), %ymm1, %ymm1;
+       vpxor (6 * 32 + 16)(%rdx), %ymm0, %ymm0;
+       vpxor (7 * 32 + 16)(%rdx), %ymm15, %ymm15;
+       vpxor (8 * 32 + 16)(%rdx), %ymm14, %ymm14;
+       vpxor (9 * 32 + 16)(%rdx), %ymm13, %ymm13;
+       vpxor (10 * 32 + 16)(%rdx), %ymm12, %ymm12;
+       vpxor (11 * 32 + 16)(%rdx), %ymm11, %ymm11;
+       vpxor (12 * 32 + 16)(%rdx), %ymm10, %ymm10;
+       vpxor (13 * 32 + 16)(%rdx), %ymm9, %ymm9;
+       vpxor (14 * 32 + 16)(%rdx), %ymm8, %ymm8;
+       movq (15 * 32 + 16 + 0)(%rdx), %rax;
+       movq (15 * 32 + 16 + 8)(%rdx), %rcx;
+
+       write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0,
+                    %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9,
+                    %ymm8, %rsi);
+
+       /* store new IV */
+       movq %rax, (0)(%r9);
+       movq %rcx, (8)(%r9);
+
+       vzeroall;
+
+       leave;
+       ret;
+.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;
+
+_gcry_camellia_aesni_avx2_cfb_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (16 blocks)
+        *      %rdx: src (16 blocks)
+        *      %rcx: iv
+        */
+
+       pushq %rbp;
+       movq %rsp, %rbp;
+
+       vzeroupper;
+
+       subq $(16 * 32), %rsp;
+       andq $~63, %rsp;
+       movq %rsp, %rax;
+
+       /* inpack16_pre: */
+       vpbroadcastq (key_table)(CTX), %ymm0;
+       vpshufb .Lpack_bswap RIP, %ymm0, %ymm0;
+       vmovdqu (%rcx), %xmm15;
+       vinserti128 $1, (%rdx), %ymm15, %ymm15;
+       vpxor %ymm15, %ymm0, %ymm15;
+       vmovdqu (15 * 32 + 16)(%rdx), %xmm1;
+       vmovdqu %xmm1, (%rcx); /* store new IV */
+       vpxor (0 * 32 + 16)(%rdx), %ymm0, %ymm14;
+       vpxor (1 * 32 + 16)(%rdx), %ymm0, %ymm13;
+       vpxor (2 * 32 + 16)(%rdx), %ymm0, %ymm12;
+       vpxor (3 * 32 + 16)(%rdx), %ymm0, %ymm11;
+       vpxor (4 * 32 + 16)(%rdx), %ymm0, %ymm10;
+       vpxor (5 * 32 + 16)(%rdx), %ymm0, %ymm9;
+       vpxor (6 * 32 + 16)(%rdx), %ymm0, %ymm8;
+       vpxor (7 * 32 + 16)(%rdx), %ymm0, %ymm7;
+       vpxor (8 * 32 + 16)(%rdx), %ymm0, %ymm6;
+       vpxor (9 * 32 + 16)(%rdx), %ymm0, %ymm5;
+       vpxor (10 * 32 + 16)(%rdx), %ymm0, %ymm4;
+       vpxor (11 * 32 + 16)(%rdx), %ymm0, %ymm3;
+       vpxor (12 * 32 + 16)(%rdx), %ymm0, %ymm2;
+       vpxor (13 * 32 + 16)(%rdx), %ymm0, %ymm1;
+       vpxor (14 * 32 + 16)(%rdx), %ymm0, %ymm0;
+
+       call __camellia_enc_blk32;
+
+       vpxor 0 * 32(%rdx), %ymm7, %ymm7;
+       vpxor 1 * 32(%rdx), %ymm6, %ymm6;
+       vpxor 2 * 32(%rdx), %ymm5, %ymm5;
+       vpxor 3 * 32(%rdx), %ymm4, %ymm4;
+       vpxor 4 * 32(%rdx), %ymm3, %ymm3;
+       vpxor 5 * 32(%rdx), %ymm2, %ymm2;
+       vpxor 6 * 32(%rdx), %ymm1, %ymm1;
+       vpxor 7 * 32(%rdx), %ymm0, %ymm0;
+       vpxor 8 * 32(%rdx), %ymm15, %ymm15;
+       vpxor 9 * 32(%rdx), %ymm14, %ymm14;
+       vpxor 10 * 32(%rdx), %ymm13, %ymm13;
+       vpxor 11 * 32(%rdx), %ymm12, %ymm12;
+       vpxor 12 * 32(%rdx), %ymm11, %ymm11;
+       vpxor 13 * 32(%rdx), %ymm10, %ymm10;
+       vpxor 14 * 32(%rdx), %ymm9, %ymm9;
+       vpxor 15 * 32(%rdx), %ymm8, %ymm8;
+
+       write_output(%ymm7, %ymm6, %ymm5, %ymm4, %ymm3, %ymm2, %ymm1, %ymm0,
+                    %ymm15, %ymm14, %ymm13, %ymm12, %ymm11, %ymm10, %ymm9,
+                    %ymm8, %rsi);
+
+       vzeroall;
+
+       leave;
+       ret;
+.size _gcry_camellia_aesni_avx2_cfb_dec,.-_gcry_camellia_aesni_avx2_cfb_dec;
+
+#endif /*defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT)*/
+#endif /*__x86_64*/
diff --git a/cipher/camellia-arm.S b/cipher/camellia-arm.S
new file mode 100644 (file)
index 0000000..c30d194
--- /dev/null
@@ -0,0 +1,613 @@
+/* camellia-arm.S  -  ARM assembly implementation of Camellia cipher
+ *
+ * Copyright © 2013 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
+
+/* struct camellia_ctx: */
+#define key_table 0
+
+/* register macros */
+#define CTX %r0
+#define RTAB1 %ip
+#define RTAB3 %r1
+#define RMASK %lr
+
+#define IL %r2
+#define IR %r3
+
+#define XL %r4
+#define XR %r5
+#define YL %r6
+#define YR %r7
+
+#define RT0 %r8
+#define RT1 %r9
+#define RT2 %r10
+#define RT3 %r11
+
+/* 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;
+
+#define str_unaligned_be(rin, rdst, offs, rtmp0, rtmp1) \
+       mov rtmp0, rin, lsr #8; \
+       strb rin, [rdst, #((offs) + 3)]; \
+       mov rtmp1, rin, lsr #16; \
+       strb rtmp0, [rdst, #((offs) + 2)]; \
+       mov rtmp0, rin, lsr #24; \
+       strb rtmp1, [rdst, #((offs) + 1)]; \
+       strb rtmp0, [rdst, #((offs) + 0)];
+
+#ifdef __ARMEL__
+#ifdef HAVE_ARM_ARCH_V6
+       #define host_to_be(reg, rtmp) \
+               rev reg, reg;
+       #define be_to_host(reg, rtmp) \
+               rev reg, reg;
+#else
+       #define host_to_be(reg, rtmp) \
+               eor     rtmp, reg, reg, ror #16; \
+               mov     rtmp, rtmp, lsr #8; \
+               bic     rtmp, rtmp, #65280; \
+               eor     reg, rtmp, reg, ror #8;
+       #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 host_to_be(reg, rtmp) /*_*/
+       #define be_to_host(reg, rtmp) /*_*/
+#endif
+
+#define ldr_input_aligned_be(rin, a, b, c, d, rtmp) \
+       ldr a, [rin, #0]; \
+       ldr b, [rin, #4]; \
+       be_to_host(a, rtmp); \
+       ldr c, [rin, #8]; \
+       be_to_host(b, rtmp); \
+       ldr d, [rin, #12]; \
+       be_to_host(c, rtmp); \
+       be_to_host(d, rtmp);
+
+#define str_output_aligned_be(rout, a, b, c, d, rtmp) \
+       be_to_host(a, rtmp); \
+       be_to_host(b, rtmp); \
+       str a, [rout, #0]; \
+       be_to_host(c, rtmp); \
+       str b, [rout, #4]; \
+       be_to_host(d, rtmp); \
+       str c, [rout, #8]; \
+       str d, [rout, #12];
+
+#ifdef __ARM_FEATURE_UNALIGNED
+       /* unaligned word reads/writes allowed */
+       #define ldr_input_be(rin, ra, rb, rc, rd, rtmp) \
+               ldr_input_aligned_be(rin, ra, rb, rc, rd, rtmp)
+
+       #define str_output_be(rout, ra, rb, rc, rd, rtmp0, rtmp1) \
+               str_output_aligned_be(rout, ra, rb, rc, rd, rtmp0)
+#else
+       /* need to handle unaligned reads/writes by byte reads */
+       #define ldr_input_be(rin, ra, rb, rc, rd, rtmp0) \
+               tst rin, #3; \
+               beq 1f; \
+                       ldr_unaligned_be(ra, rin, 0, rtmp0); \
+                       ldr_unaligned_be(rb, rin, 4, rtmp0); \
+                       ldr_unaligned_be(rc, rin, 8, rtmp0); \
+                       ldr_unaligned_be(rd, rin, 12, rtmp0); \
+                       b 2f; \
+               1:;\
+                       ldr_input_aligned_be(rin, ra, rb, rc, rd, rtmp0); \
+               2:;
+
+       #define str_output_be(rout, ra, rb, rc, rd, rtmp0, rtmp1) \
+               tst rout, #3; \
+               beq 1f; \
+                       str_unaligned_be(ra, rout, 0, rtmp0, rtmp1); \
+                       str_unaligned_be(rb, rout, 4, rtmp0, rtmp1); \
+                       str_unaligned_be(rc, rout, 8, rtmp0, rtmp1); \
+                       str_unaligned_be(rd, rout, 12, rtmp0, rtmp1); \
+                       b 2f; \
+               1:;\
+                       str_output_aligned_be(rout, ra, rb, rc, rd, rtmp0); \
+               2:;
+#endif
+
+/**********************************************************************
+  1-way camellia
+ **********************************************************************/
+#define roundsm(xl, xr, kl, kr, yl, yr) \
+       ldr RT2, [CTX, #(key_table + ((kl) * 4))]; \
+       and  IR, RMASK, xr, lsl#(4);      /*sp1110*/ \
+       ldr RT3, [CTX, #(key_table + ((kr) * 4))]; \
+       and  IL, RMASK, xl, lsr#(24 - 4); /*sp1110*/ \
+       and RT0, RMASK, xr, lsr#(16 - 4); /*sp3033*/ \
+       ldr  IR, [RTAB1,  IR]; \
+       and RT1, RMASK, xl, lsr#(8 - 4);  /*sp3033*/ \
+       eor yl, RT2; \
+       ldr  IL, [RTAB1,  IL]; \
+       eor yr, RT3; \
+       \
+       ldr RT0, [RTAB3, RT0]; \
+       add RTAB1, #4; \
+       ldr RT1, [RTAB3, RT1]; \
+       add RTAB3, #4; \
+       \
+       and RT2, RMASK, xr, lsr#(24 - 4); /*sp0222*/ \
+       and RT3, RMASK, xl, lsr#(16 - 4); /*sp0222*/ \
+       \
+       eor IR, RT0; \
+       eor IL, RT1; \
+       \
+       ldr RT2, [RTAB1, RT2]; \
+       and RT0, RMASK, xr, lsr#(8 - 4);  /*sp4404*/ \
+       ldr RT3, [RTAB1, RT3]; \
+       and RT1, RMASK, xl, lsl#(4);      /*sp4404*/ \
+       \
+       ldr RT0, [RTAB3, RT0]; \
+       sub RTAB1, #4; \
+       ldr RT1, [RTAB3, RT1]; \
+       sub RTAB3, #4; \
+       \
+       eor IR, RT2; \
+       eor IL, RT3; \
+       eor IR, RT0; \
+       eor IL, RT1; \
+       \
+       eor IR, IL; \
+       eor yr, yr, IL, ror#8; \
+       eor yl, IR; \
+       eor yr, IR;
+
+#define enc_rounds(n) \
+       roundsm(XL, XR, ((n) + 2) * 2 + 0, ((n) + 2) * 2 + 1, YL, YR); \
+       roundsm(YL, YR, ((n) + 3) * 2 + 0, ((n) + 3) * 2 + 1, XL, XR); \
+       roundsm(XL, XR, ((n) + 4) * 2 + 0, ((n) + 4) * 2 + 1, YL, YR); \
+       roundsm(YL, YR, ((n) + 5) * 2 + 0, ((n) + 5) * 2 + 1, XL, XR); \
+       roundsm(XL, XR, ((n) + 6) * 2 + 0, ((n) + 6) * 2 + 1, YL, YR); \
+       roundsm(YL, YR, ((n) + 7) * 2 + 0, ((n) + 7) * 2 + 1, XL, XR);
+
+#define dec_rounds(n) \
+       roundsm(XL, XR, ((n) + 7) * 2 + 0, ((n) + 7) * 2 + 1, YL, YR); \
+       roundsm(YL, YR, ((n) + 6) * 2 + 0, ((n) + 6) * 2 + 1, XL, XR); \
+       roundsm(XL, XR, ((n) + 5) * 2 + 0, ((n) + 5) * 2 + 1, YL, YR); \
+       roundsm(YL, YR, ((n) + 4) * 2 + 0, ((n) + 4) * 2 + 1, XL, XR); \
+       roundsm(XL, XR, ((n) + 3) * 2 + 0, ((n) + 3) * 2 + 1, YL, YR); \
+       roundsm(YL, YR, ((n) + 2) * 2 + 0, ((n) + 2) * 2 + 1, XL, XR);
+
+/* perform FL and FL⁻¹ */
+#define fls(ll, lr, rl, rr, kll, klr, krl, krr) \
+       ldr RT0, [CTX, #(key_table + ((kll) * 4))]; \
+       ldr RT2, [CTX, #(key_table + ((krr) * 4))]; \
+       and RT0, ll; \
+       ldr RT3, [CTX, #(key_table + ((krl) * 4))]; \
+       orr RT2, rr; \
+       ldr RT1, [CTX, #(key_table + ((klr) * 4))]; \
+       eor rl, RT2; \
+       eor lr, lr, RT0, ror#31; \
+       and RT3, rl; \
+       orr RT1, lr; \
+       eor ll, RT1; \
+       eor rr, rr, RT3, ror#31;
+
+#define enc_fls(n) \
+       fls(XL, XR, YL, YR, \
+           (n) * 2 + 0, (n) * 2 + 1, \
+           (n) * 2 + 2, (n) * 2 + 3);
+
+#define dec_fls(n) \
+       fls(XL, XR, YL, YR, \
+           (n) * 2 + 2, (n) * 2 + 3, \
+           (n) * 2 + 0, (n) * 2 + 1);
+
+#define inpack(n) \
+       ldr_input_be(%r2, XL, XR, YL, YR, RT0); \
+       ldr RT0, [CTX, #(key_table + ((n) * 8) + 0)]; \
+       ldr RT1, [CTX, #(key_table + ((n) * 8) + 4)]; \
+       eor XL, RT0; \
+       eor XR, RT1;
+
+#define outunpack(n) \
+       ldr RT0, [CTX, #(key_table + ((n) * 8) + 0)]; \
+       ldr RT1, [CTX, #(key_table + ((n) * 8) + 4)]; \
+       eor YL, RT0; \
+       eor YR, RT1; \
+       str_output_be(%r1, YL, YR, XL, XR, RT0, RT1);
+
+.align 3
+.globl _gcry_camellia_arm_encrypt_block
+.type   _gcry_camellia_arm_encrypt_block,%function;
+
+_gcry_camellia_arm_encrypt_block:
+       /* input:
+        *      %r0: keytable
+        *      %r1: dst
+        *      %r2: src
+        *      %r3: keybitlen
+        */
+       push {%r1, %r4-%r11, %ip, %lr};
+
+       ldr RTAB1, =.Lcamellia_sp1110;
+       mov RMASK, #0xff;
+       add RTAB3, RTAB1, #(2 * 4);
+       push {%r3};
+       mov RMASK, RMASK, lsl#4 /* byte mask */
+
+       inpack(0);
+
+       enc_rounds(0);
+       enc_fls(8);
+       enc_rounds(8);
+       enc_fls(16);
+       enc_rounds(16);
+
+       pop {RT0};
+       cmp RT0, #(16 * 8);
+       bne .Lenc_256;
+
+       pop {%r1};
+       outunpack(24);
+
+       pop {%r4-%r11, %ip, %pc};
+.ltorg
+
+.Lenc_256:
+       enc_fls(24);
+       enc_rounds(24);
+
+       pop {%r1};
+       outunpack(32);
+
+       pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_camellia_arm_encrypt_block,.-_gcry_camellia_arm_encrypt_block;
+
+.align 3
+.globl _gcry_camellia_arm_decrypt_block
+.type   _gcry_camellia_arm_decrypt_block,%function;
+
+_gcry_camellia_arm_decrypt_block:
+       /* input:
+        *      %r0: keytable
+        *      %r1: dst
+        *      %r2: src
+        *      %r3: keybitlen
+        */
+       push {%r1, %r4-%r11, %ip, %lr};
+
+       ldr RTAB1, =.Lcamellia_sp1110;
+       mov RMASK, #0xff;
+       add RTAB3, RTAB1, #(2 * 4);
+       mov RMASK, RMASK, lsl#4 /* byte mask */
+
+       cmp %r3, #(16 * 8);
+       bne .Ldec_256;
+
+       inpack(24);
+
+.Ldec_128:
+       dec_rounds(16);
+       dec_fls(16);
+       dec_rounds(8);
+       dec_fls(8);
+       dec_rounds(0);
+
+       pop {%r1};
+       outunpack(0);
+
+       pop {%r4-%r11, %ip, %pc};
+.ltorg
+
+.Ldec_256:
+       inpack(32);
+       dec_rounds(24);
+       dec_fls(24);
+
+       b .Ldec_128;
+.ltorg
+.size _gcry_camellia_arm_decrypt_block,.-_gcry_camellia_arm_decrypt_block;
+
+.data
+
+/* Encryption/Decryption tables */
+.align 5
+.Lcamellia_sp1110:
+.long 0x70707000
+.Lcamellia_sp0222:
+            .long 0x00e0e0e0
+.Lcamellia_sp3033:
+                        .long 0x38003838
+.Lcamellia_sp4404:
+                                    .long 0x70700070
+.long 0x82828200, 0x00050505, 0x41004141, 0x2c2c002c
+.long 0x2c2c2c00, 0x00585858, 0x16001616, 0xb3b300b3
+.long 0xececec00, 0x00d9d9d9, 0x76007676, 0xc0c000c0
+.long 0xb3b3b300, 0x00676767, 0xd900d9d9, 0xe4e400e4
+.long 0x27272700, 0x004e4e4e, 0x93009393, 0x57570057
+.long 0xc0c0c000, 0x00818181, 0x60006060, 0xeaea00ea
+.long 0xe5e5e500, 0x00cbcbcb, 0xf200f2f2, 0xaeae00ae
+.long 0xe4e4e400, 0x00c9c9c9, 0x72007272, 0x23230023
+.long 0x85858500, 0x000b0b0b, 0xc200c2c2, 0x6b6b006b
+.long 0x57575700, 0x00aeaeae, 0xab00abab, 0x45450045
+.long 0x35353500, 0x006a6a6a, 0x9a009a9a, 0xa5a500a5
+.long 0xeaeaea00, 0x00d5d5d5, 0x75007575, 0xeded00ed
+.long 0x0c0c0c00, 0x00181818, 0x06000606, 0x4f4f004f
+.long 0xaeaeae00, 0x005d5d5d, 0x57005757, 0x1d1d001d
+.long 0x41414100, 0x00828282, 0xa000a0a0, 0x92920092
+.long 0x23232300, 0x00464646, 0x91009191, 0x86860086
+.long 0xefefef00, 0x00dfdfdf, 0xf700f7f7, 0xafaf00af
+.long 0x6b6b6b00, 0x00d6d6d6, 0xb500b5b5, 0x7c7c007c
+.long 0x93939300, 0x00272727, 0xc900c9c9, 0x1f1f001f
+.long 0x45454500, 0x008a8a8a, 0xa200a2a2, 0x3e3e003e
+.long 0x19191900, 0x00323232, 0x8c008c8c, 0xdcdc00dc
+.long 0xa5a5a500, 0x004b4b4b, 0xd200d2d2, 0x5e5e005e
+.long 0x21212100, 0x00424242, 0x90009090, 0x0b0b000b
+.long 0xededed00, 0x00dbdbdb, 0xf600f6f6, 0xa6a600a6
+.long 0x0e0e0e00, 0x001c1c1c, 0x07000707, 0x39390039
+.long 0x4f4f4f00, 0x009e9e9e, 0xa700a7a7, 0xd5d500d5
+.long 0x4e4e4e00, 0x009c9c9c, 0x27002727, 0x5d5d005d
+.long 0x1d1d1d00, 0x003a3a3a, 0x8e008e8e, 0xd9d900d9
+.long 0x65656500, 0x00cacaca, 0xb200b2b2, 0x5a5a005a
+.long 0x92929200, 0x00252525, 0x49004949, 0x51510051
+.long 0xbdbdbd00, 0x007b7b7b, 0xde00dede, 0x6c6c006c
+.long 0x86868600, 0x000d0d0d, 0x43004343, 0x8b8b008b
+.long 0xb8b8b800, 0x00717171, 0x5c005c5c, 0x9a9a009a
+.long 0xafafaf00, 0x005f5f5f, 0xd700d7d7, 0xfbfb00fb
+.long 0x8f8f8f00, 0x001f1f1f, 0xc700c7c7, 0xb0b000b0
+.long 0x7c7c7c00, 0x00f8f8f8, 0x3e003e3e, 0x74740074
+.long 0xebebeb00, 0x00d7d7d7, 0xf500f5f5, 0x2b2b002b
+.long 0x1f1f1f00, 0x003e3e3e, 0x8f008f8f, 0xf0f000f0
+.long 0xcecece00, 0x009d9d9d, 0x67006767, 0x84840084
+.long 0x3e3e3e00, 0x007c7c7c, 0x1f001f1f, 0xdfdf00df
+.long 0x30303000, 0x00606060, 0x18001818, 0xcbcb00cb
+.long 0xdcdcdc00, 0x00b9b9b9, 0x6e006e6e, 0x34340034
+.long 0x5f5f5f00, 0x00bebebe, 0xaf00afaf, 0x76760076
+.long 0x5e5e5e00, 0x00bcbcbc, 0x2f002f2f, 0x6d6d006d
+.long 0xc5c5c500, 0x008b8b8b, 0xe200e2e2, 0xa9a900a9
+.long 0x0b0b0b00, 0x00161616, 0x85008585, 0xd1d100d1
+.long 0x1a1a1a00, 0x00343434, 0x0d000d0d, 0x04040004
+.long 0xa6a6a600, 0x004d4d4d, 0x53005353, 0x14140014
+.long 0xe1e1e100, 0x00c3c3c3, 0xf000f0f0, 0x3a3a003a
+.long 0x39393900, 0x00727272, 0x9c009c9c, 0xdede00de
+.long 0xcacaca00, 0x00959595, 0x65006565, 0x11110011
+.long 0xd5d5d500, 0x00ababab, 0xea00eaea, 0x32320032
+.long 0x47474700, 0x008e8e8e, 0xa300a3a3, 0x9c9c009c
+.long 0x5d5d5d00, 0x00bababa, 0xae00aeae, 0x53530053
+.long 0x3d3d3d00, 0x007a7a7a, 0x9e009e9e, 0xf2f200f2
+.long 0xd9d9d900, 0x00b3b3b3, 0xec00ecec, 0xfefe00fe
+.long 0x01010100, 0x00020202, 0x80008080, 0xcfcf00cf
+.long 0x5a5a5a00, 0x00b4b4b4, 0x2d002d2d, 0xc3c300c3
+.long 0xd6d6d600, 0x00adadad, 0x6b006b6b, 0x7a7a007a
+.long 0x51515100, 0x00a2a2a2, 0xa800a8a8, 0x24240024
+.long 0x56565600, 0x00acacac, 0x2b002b2b, 0xe8e800e8
+.long 0x6c6c6c00, 0x00d8d8d8, 0x36003636, 0x60600060
+.long 0x4d4d4d00, 0x009a9a9a, 0xa600a6a6, 0x69690069
+.long 0x8b8b8b00, 0x00171717, 0xc500c5c5, 0xaaaa00aa
+.long 0x0d0d0d00, 0x001a1a1a, 0x86008686, 0xa0a000a0
+.long 0x9a9a9a00, 0x00353535, 0x4d004d4d, 0xa1a100a1
+.long 0x66666600, 0x00cccccc, 0x33003333, 0x62620062
+.long 0xfbfbfb00, 0x00f7f7f7, 0xfd00fdfd, 0x54540054
+.long 0xcccccc00, 0x00999999, 0x66006666, 0x1e1e001e
+.long 0xb0b0b000, 0x00616161, 0x58005858, 0xe0e000e0
+.long 0x2d2d2d00, 0x005a5a5a, 0x96009696, 0x64640064
+.long 0x74747400, 0x00e8e8e8, 0x3a003a3a, 0x10100010
+.long 0x12121200, 0x00242424, 0x09000909, 0x00000000
+.long 0x2b2b2b00, 0x00565656, 0x95009595, 0xa3a300a3
+.long 0x20202000, 0x00404040, 0x10001010, 0x75750075
+.long 0xf0f0f000, 0x00e1e1e1, 0x78007878, 0x8a8a008a
+.long 0xb1b1b100, 0x00636363, 0xd800d8d8, 0xe6e600e6
+.long 0x84848400, 0x00090909, 0x42004242, 0x09090009
+.long 0x99999900, 0x00333333, 0xcc00cccc, 0xdddd00dd
+.long 0xdfdfdf00, 0x00bfbfbf, 0xef00efef, 0x87870087
+.long 0x4c4c4c00, 0x00989898, 0x26002626, 0x83830083
+.long 0xcbcbcb00, 0x00979797, 0xe500e5e5, 0xcdcd00cd
+.long 0xc2c2c200, 0x00858585, 0x61006161, 0x90900090
+.long 0x34343400, 0x00686868, 0x1a001a1a, 0x73730073
+.long 0x7e7e7e00, 0x00fcfcfc, 0x3f003f3f, 0xf6f600f6
+.long 0x76767600, 0x00ececec, 0x3b003b3b, 0x9d9d009d
+.long 0x05050500, 0x000a0a0a, 0x82008282, 0xbfbf00bf
+.long 0x6d6d6d00, 0x00dadada, 0xb600b6b6, 0x52520052
+.long 0xb7b7b700, 0x006f6f6f, 0xdb00dbdb, 0xd8d800d8
+.long 0xa9a9a900, 0x00535353, 0xd400d4d4, 0xc8c800c8
+.long 0x31313100, 0x00626262, 0x98009898, 0xc6c600c6
+.long 0xd1d1d100, 0x00a3a3a3, 0xe800e8e8, 0x81810081
+.long 0x17171700, 0x002e2e2e, 0x8b008b8b, 0x6f6f006f
+.long 0x04040400, 0x00080808, 0x02000202, 0x13130013
+.long 0xd7d7d700, 0x00afafaf, 0xeb00ebeb, 0x63630063
+.long 0x14141400, 0x00282828, 0x0a000a0a, 0xe9e900e9
+.long 0x58585800, 0x00b0b0b0, 0x2c002c2c, 0xa7a700a7
+.long 0x3a3a3a00, 0x00747474, 0x1d001d1d, 0x9f9f009f
+.long 0x61616100, 0x00c2c2c2, 0xb000b0b0, 0xbcbc00bc
+.long 0xdedede00, 0x00bdbdbd, 0x6f006f6f, 0x29290029
+.long 0x1b1b1b00, 0x00363636, 0x8d008d8d, 0xf9f900f9
+.long 0x11111100, 0x00222222, 0x88008888, 0x2f2f002f
+.long 0x1c1c1c00, 0x00383838, 0x0e000e0e, 0xb4b400b4
+.long 0x32323200, 0x00646464, 0x19001919, 0x78780078
+.long 0x0f0f0f00, 0x001e1e1e, 0x87008787, 0x06060006
+.long 0x9c9c9c00, 0x00393939, 0x4e004e4e, 0xe7e700e7
+.long 0x16161600, 0x002c2c2c, 0x0b000b0b, 0x71710071
+.long 0x53535300, 0x00a6a6a6, 0xa900a9a9, 0xd4d400d4
+.long 0x18181800, 0x00303030, 0x0c000c0c, 0xabab00ab
+.long 0xf2f2f200, 0x00e5e5e5, 0x79007979, 0x88880088
+.long 0x22222200, 0x00444444, 0x11001111, 0x8d8d008d
+.long 0xfefefe00, 0x00fdfdfd, 0x7f007f7f, 0x72720072
+.long 0x44444400, 0x00888888, 0x22002222, 0xb9b900b9
+.long 0xcfcfcf00, 0x009f9f9f, 0xe700e7e7, 0xf8f800f8
+.long 0xb2b2b200, 0x00656565, 0x59005959, 0xacac00ac
+.long 0xc3c3c300, 0x00878787, 0xe100e1e1, 0x36360036
+.long 0xb5b5b500, 0x006b6b6b, 0xda00dada, 0x2a2a002a
+.long 0x7a7a7a00, 0x00f4f4f4, 0x3d003d3d, 0x3c3c003c
+.long 0x91919100, 0x00232323, 0xc800c8c8, 0xf1f100f1
+.long 0x24242400, 0x00484848, 0x12001212, 0x40400040
+.long 0x08080800, 0x00101010, 0x04000404, 0xd3d300d3
+.long 0xe8e8e800, 0x00d1d1d1, 0x74007474, 0xbbbb00bb
+.long 0xa8a8a800, 0x00515151, 0x54005454, 0x43430043
+.long 0x60606000, 0x00c0c0c0, 0x30003030, 0x15150015
+.long 0xfcfcfc00, 0x00f9f9f9, 0x7e007e7e, 0xadad00ad
+.long 0x69696900, 0x00d2d2d2, 0xb400b4b4, 0x77770077
+.long 0x50505000, 0x00a0a0a0, 0x28002828, 0x80800080
+.long 0xaaaaaa00, 0x00555555, 0x55005555, 0x82820082
+.long 0xd0d0d000, 0x00a1a1a1, 0x68006868, 0xecec00ec
+.long 0xa0a0a000, 0x00414141, 0x50005050, 0x27270027
+.long 0x7d7d7d00, 0x00fafafa, 0xbe00bebe, 0xe5e500e5
+.long 0xa1a1a100, 0x00434343, 0xd000d0d0, 0x85850085
+.long 0x89898900, 0x00131313, 0xc400c4c4, 0x35350035
+.long 0x62626200, 0x00c4c4c4, 0x31003131, 0x0c0c000c
+.long 0x97979700, 0x002f2f2f, 0xcb00cbcb, 0x41410041
+.long 0x54545400, 0x00a8a8a8, 0x2a002a2a, 0xefef00ef
+.long 0x5b5b5b00, 0x00b6b6b6, 0xad00adad, 0x93930093
+.long 0x1e1e1e00, 0x003c3c3c, 0x0f000f0f, 0x19190019
+.long 0x95959500, 0x002b2b2b, 0xca00caca, 0x21210021
+.long 0xe0e0e000, 0x00c1c1c1, 0x70007070, 0x0e0e000e
+.long 0xffffff00, 0x00ffffff, 0xff00ffff, 0x4e4e004e
+.long 0x64646400, 0x00c8c8c8, 0x32003232, 0x65650065
+.long 0xd2d2d200, 0x00a5a5a5, 0x69006969, 0xbdbd00bd
+.long 0x10101000, 0x00202020, 0x08000808, 0xb8b800b8
+.long 0xc4c4c400, 0x00898989, 0x62006262, 0x8f8f008f
+.long 0x00000000, 0x00000000, 0x00000000, 0xebeb00eb
+.long 0x48484800, 0x00909090, 0x24002424, 0xcece00ce
+.long 0xa3a3a300, 0x00474747, 0xd100d1d1, 0x30300030
+.long 0xf7f7f700, 0x00efefef, 0xfb00fbfb, 0x5f5f005f
+.long 0x75757500, 0x00eaeaea, 0xba00baba, 0xc5c500c5
+.long 0xdbdbdb00, 0x00b7b7b7, 0xed00eded, 0x1a1a001a
+.long 0x8a8a8a00, 0x00151515, 0x45004545, 0xe1e100e1
+.long 0x03030300, 0x00060606, 0x81008181, 0xcaca00ca
+.long 0xe6e6e600, 0x00cdcdcd, 0x73007373, 0x47470047
+.long 0xdadada00, 0x00b5b5b5, 0x6d006d6d, 0x3d3d003d
+.long 0x09090900, 0x00121212, 0x84008484, 0x01010001
+.long 0x3f3f3f00, 0x007e7e7e, 0x9f009f9f, 0xd6d600d6
+.long 0xdddddd00, 0x00bbbbbb, 0xee00eeee, 0x56560056
+.long 0x94949400, 0x00292929, 0x4a004a4a, 0x4d4d004d
+.long 0x87878700, 0x000f0f0f, 0xc300c3c3, 0x0d0d000d
+.long 0x5c5c5c00, 0x00b8b8b8, 0x2e002e2e, 0x66660066
+.long 0x83838300, 0x00070707, 0xc100c1c1, 0xcccc00cc
+.long 0x02020200, 0x00040404, 0x01000101, 0x2d2d002d
+.long 0xcdcdcd00, 0x009b9b9b, 0xe600e6e6, 0x12120012
+.long 0x4a4a4a00, 0x00949494, 0x25002525, 0x20200020
+.long 0x90909000, 0x00212121, 0x48004848, 0xb1b100b1
+.long 0x33333300, 0x00666666, 0x99009999, 0x99990099
+.long 0x73737300, 0x00e6e6e6, 0xb900b9b9, 0x4c4c004c
+.long 0x67676700, 0x00cecece, 0xb300b3b3, 0xc2c200c2
+.long 0xf6f6f600, 0x00ededed, 0x7b007b7b, 0x7e7e007e
+.long 0xf3f3f300, 0x00e7e7e7, 0xf900f9f9, 0x05050005
+.long 0x9d9d9d00, 0x003b3b3b, 0xce00cece, 0xb7b700b7
+.long 0x7f7f7f00, 0x00fefefe, 0xbf00bfbf, 0x31310031
+.long 0xbfbfbf00, 0x007f7f7f, 0xdf00dfdf, 0x17170017
+.long 0xe2e2e200, 0x00c5c5c5, 0x71007171, 0xd7d700d7
+.long 0x52525200, 0x00a4a4a4, 0x29002929, 0x58580058
+.long 0x9b9b9b00, 0x00373737, 0xcd00cdcd, 0x61610061
+.long 0xd8d8d800, 0x00b1b1b1, 0x6c006c6c, 0x1b1b001b
+.long 0x26262600, 0x004c4c4c, 0x13001313, 0x1c1c001c
+.long 0xc8c8c800, 0x00919191, 0x64006464, 0x0f0f000f
+.long 0x37373700, 0x006e6e6e, 0x9b009b9b, 0x16160016
+.long 0xc6c6c600, 0x008d8d8d, 0x63006363, 0x18180018
+.long 0x3b3b3b00, 0x00767676, 0x9d009d9d, 0x22220022
+.long 0x81818100, 0x00030303, 0xc000c0c0, 0x44440044
+.long 0x96969600, 0x002d2d2d, 0x4b004b4b, 0xb2b200b2
+.long 0x6f6f6f00, 0x00dedede, 0xb700b7b7, 0xb5b500b5
+.long 0x4b4b4b00, 0x00969696, 0xa500a5a5, 0x91910091
+.long 0x13131300, 0x00262626, 0x89008989, 0x08080008
+.long 0xbebebe00, 0x007d7d7d, 0x5f005f5f, 0xa8a800a8
+.long 0x63636300, 0x00c6c6c6, 0xb100b1b1, 0xfcfc00fc
+.long 0x2e2e2e00, 0x005c5c5c, 0x17001717, 0x50500050
+.long 0xe9e9e900, 0x00d3d3d3, 0xf400f4f4, 0xd0d000d0
+.long 0x79797900, 0x00f2f2f2, 0xbc00bcbc, 0x7d7d007d
+.long 0xa7a7a700, 0x004f4f4f, 0xd300d3d3, 0x89890089
+.long 0x8c8c8c00, 0x00191919, 0x46004646, 0x97970097
+.long 0x9f9f9f00, 0x003f3f3f, 0xcf00cfcf, 0x5b5b005b
+.long 0x6e6e6e00, 0x00dcdcdc, 0x37003737, 0x95950095
+.long 0xbcbcbc00, 0x00797979, 0x5e005e5e, 0xffff00ff
+.long 0x8e8e8e00, 0x001d1d1d, 0x47004747, 0xd2d200d2
+.long 0x29292900, 0x00525252, 0x94009494, 0xc4c400c4
+.long 0xf5f5f500, 0x00ebebeb, 0xfa00fafa, 0x48480048
+.long 0xf9f9f900, 0x00f3f3f3, 0xfc00fcfc, 0xf7f700f7
+.long 0xb6b6b600, 0x006d6d6d, 0x5b005b5b, 0xdbdb00db
+.long 0x2f2f2f00, 0x005e5e5e, 0x97009797, 0x03030003
+.long 0xfdfdfd00, 0x00fbfbfb, 0xfe00fefe, 0xdada00da
+.long 0xb4b4b400, 0x00696969, 0x5a005a5a, 0x3f3f003f
+.long 0x59595900, 0x00b2b2b2, 0xac00acac, 0x94940094
+.long 0x78787800, 0x00f0f0f0, 0x3c003c3c, 0x5c5c005c
+.long 0x98989800, 0x00313131, 0x4c004c4c, 0x02020002
+.long 0x06060600, 0x000c0c0c, 0x03000303, 0x4a4a004a
+.long 0x6a6a6a00, 0x00d4d4d4, 0x35003535, 0x33330033
+.long 0xe7e7e700, 0x00cfcfcf, 0xf300f3f3, 0x67670067
+.long 0x46464600, 0x008c8c8c, 0x23002323, 0xf3f300f3
+.long 0x71717100, 0x00e2e2e2, 0xb800b8b8, 0x7f7f007f
+.long 0xbababa00, 0x00757575, 0x5d005d5d, 0xe2e200e2
+.long 0xd4d4d400, 0x00a9a9a9, 0x6a006a6a, 0x9b9b009b
+.long 0x25252500, 0x004a4a4a, 0x92009292, 0x26260026
+.long 0xababab00, 0x00575757, 0xd500d5d5, 0x37370037
+.long 0x42424200, 0x00848484, 0x21002121, 0x3b3b003b
+.long 0x88888800, 0x00111111, 0x44004444, 0x96960096
+.long 0xa2a2a200, 0x00454545, 0x51005151, 0x4b4b004b
+.long 0x8d8d8d00, 0x001b1b1b, 0xc600c6c6, 0xbebe00be
+.long 0xfafafa00, 0x00f5f5f5, 0x7d007d7d, 0x2e2e002e
+.long 0x72727200, 0x00e4e4e4, 0x39003939, 0x79790079
+.long 0x07070700, 0x000e0e0e, 0x83008383, 0x8c8c008c
+.long 0xb9b9b900, 0x00737373, 0xdc00dcdc, 0x6e6e006e
+.long 0x55555500, 0x00aaaaaa, 0xaa00aaaa, 0x8e8e008e
+.long 0xf8f8f800, 0x00f1f1f1, 0x7c007c7c, 0xf5f500f5
+.long 0xeeeeee00, 0x00dddddd, 0x77007777, 0xb6b600b6
+.long 0xacacac00, 0x00595959, 0x56005656, 0xfdfd00fd
+.long 0x0a0a0a00, 0x00141414, 0x05000505, 0x59590059
+.long 0x36363600, 0x006c6c6c, 0x1b001b1b, 0x98980098
+.long 0x49494900, 0x00929292, 0xa400a4a4, 0x6a6a006a
+.long 0x2a2a2a00, 0x00545454, 0x15001515, 0x46460046
+.long 0x68686800, 0x00d0d0d0, 0x34003434, 0xbaba00ba
+.long 0x3c3c3c00, 0x00787878, 0x1e001e1e, 0x25250025
+.long 0x38383800, 0x00707070, 0x1c001c1c, 0x42420042
+.long 0xf1f1f100, 0x00e3e3e3, 0xf800f8f8, 0xa2a200a2
+.long 0xa4a4a400, 0x00494949, 0x52005252, 0xfafa00fa
+.long 0x40404000, 0x00808080, 0x20002020, 0x07070007
+.long 0x28282800, 0x00505050, 0x14001414, 0x55550055
+.long 0xd3d3d300, 0x00a7a7a7, 0xe900e9e9, 0xeeee00ee
+.long 0x7b7b7b00, 0x00f6f6f6, 0xbd00bdbd, 0x0a0a000a
+.long 0xbbbbbb00, 0x00777777, 0xdd00dddd, 0x49490049
+.long 0xc9c9c900, 0x00939393, 0xe400e4e4, 0x68680068
+.long 0x43434300, 0x00868686, 0xa100a1a1, 0x38380038
+.long 0xc1c1c100, 0x00838383, 0xe000e0e0, 0xa4a400a4
+.long 0x15151500, 0x002a2a2a, 0x8a008a8a, 0x28280028
+.long 0xe3e3e300, 0x00c7c7c7, 0xf100f1f1, 0x7b7b007b
+.long 0xadadad00, 0x005b5b5b, 0xd600d6d6, 0xc9c900c9
+.long 0xf4f4f400, 0x00e9e9e9, 0x7a007a7a, 0xc1c100c1
+.long 0x77777700, 0x00eeeeee, 0xbb00bbbb, 0xe3e300e3
+.long 0xc7c7c700, 0x008f8f8f, 0xe300e3e3, 0xf4f400f4
+.long 0x80808000, 0x00010101, 0x40004040, 0xc7c700c7
+.long 0x9e9e9e00, 0x003d3d3d, 0x4f004f4f, 0x9e9e009e
+
+#endif /*HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS*/
+#endif /*__ARM_ARCH >= 6*/
index a263621..f18d135 100644 (file)
 #include "g10lib.h"
 #include "cipher.h"
 #include "camellia.h"
+#include "bufhelp.h"
+#include "cipher-selftest.h"
+
+/* 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_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)
+#  define USE_AESNI_AVX 1
+# endif
+#endif
+
+/* 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)
+#  define USE_AESNI_AVX2 1
+# endif
+#endif
 
 typedef struct
 {
-  int keybitlength;
   KEY_TABLE_TYPE keytable;
+  int keybitlength;
+#ifdef USE_AESNI_AVX
+  unsigned int use_aesni_avx:1;        /* AES-NI/AVX implementation shall be used.  */
+#endif /*USE_AESNI_AVX*/
+#ifdef USE_AESNI_AVX2
+  unsigned int use_aesni_avx2:1;/* AES-NI/AVX2 implementation shall be used.  */
+#endif /*USE_AESNI_AVX2*/
 } CAMELLIA_context;
 
+#ifdef USE_AESNI_AVX
+/* Assembler implementations of Camellia using AES-NI and AVX.  Process data
+   in 16 block same time.
+ */
+extern void _gcry_camellia_aesni_avx_ctr_enc(CAMELLIA_context *ctx,
+                                            unsigned char *out,
+                                            const unsigned char *in,
+                                            unsigned char *ctr);
+
+extern void _gcry_camellia_aesni_avx_cbc_dec(CAMELLIA_context *ctx,
+                                            unsigned char *out,
+                                            const unsigned char *in,
+                                            unsigned char *iv);
+
+extern void _gcry_camellia_aesni_avx_cfb_dec(CAMELLIA_context *ctx,
+                                            unsigned char *out,
+                                            const unsigned char *in,
+                                            unsigned char *iv);
+
+extern void _gcry_camellia_aesni_avx_keygen(CAMELLIA_context *ctx,
+                                           const unsigned char *key,
+                                           unsigned int keylen);
+#endif
+
+#ifdef USE_AESNI_AVX2
+/* Assembler implementations of Camellia using AES-NI and AVX2.  Process data
+   in 32 block same time.
+ */
+extern void _gcry_camellia_aesni_avx2_ctr_enc(CAMELLIA_context *ctx,
+                                             unsigned char *out,
+                                             const unsigned char *in,
+                                             unsigned char *ctr);
+
+extern void _gcry_camellia_aesni_avx2_cbc_dec(CAMELLIA_context *ctx,
+                                             unsigned char *out,
+                                             const unsigned char *in,
+                                             unsigned char *iv);
+
+extern void _gcry_camellia_aesni_avx2_cfb_dec(CAMELLIA_context *ctx,
+                                             unsigned char *out,
+                                             const unsigned char *in,
+                                             unsigned char *iv);
+#endif
+
 static const char *selftest(void);
 
 static gcry_err_code_t
@@ -77,6 +152,9 @@ camellia_setkey(void *c, const byte *key, unsigned keylen)
   CAMELLIA_context *ctx=c;
   static int initialized=0;
   static const char *selftest_failed=NULL;
+#if defined(USE_AESNI_AVX) || defined(USE_AESNI_AVX2)
+  unsigned int hwf = _gcry_get_hw_features ();
+#endif
 
   if(keylen!=16 && keylen!=24 && keylen!=32)
     return GPG_ERR_INV_KEYLEN;
@@ -92,44 +170,414 @@ camellia_setkey(void *c, const byte *key, unsigned keylen)
   if(selftest_failed)
     return GPG_ERR_SELFTEST_FAILED;
 
+#ifdef USE_AESNI_AVX
+  ctx->use_aesni_avx = (hwf & HWF_INTEL_AESNI) && (hwf & HWF_INTEL_AVX);
+#endif
+#ifdef USE_AESNI_AVX2
+  ctx->use_aesni_avx2 = (hwf & HWF_INTEL_AESNI) && (hwf & HWF_INTEL_AVX2);
+#endif
+
   ctx->keybitlength=keylen*8;
-  Camellia_Ekeygen(ctx->keybitlength,key,ctx->keytable);
-  _gcry_burn_stack
-    ((19+34+34)*sizeof(u32)+2*sizeof(void*) /* camellia_setup256 */
-     +(4+32)*sizeof(u32)+2*sizeof(void*)    /* camellia_setup192 */
-     +0+sizeof(int)+2*sizeof(void*)         /* Camellia_Ekeygen */
-     +3*2*sizeof(void*)                     /* Function calls.  */
-     );
+
+  if (0)
+    { }
+#ifdef USE_AESNI_AVX
+  else if (ctx->use_aesni_avx)
+    _gcry_camellia_aesni_avx_keygen(ctx, key, keylen);
+  else
+#endif
+    {
+      Camellia_Ekeygen(ctx->keybitlength,key,ctx->keytable);
+      _gcry_burn_stack
+        ((19+34+34)*sizeof(u32)+2*sizeof(void*) /* camellia_setup256 */
+         +(4+32)*sizeof(u32)+2*sizeof(void*)    /* camellia_setup192 */
+         +0+sizeof(int)+2*sizeof(void*)         /* Camellia_Ekeygen */
+         +3*2*sizeof(void*)                     /* Function calls.  */
+         );
+    }
 
   return 0;
 }
 
-static void
+#ifdef USE_ARM_ASM
+
+/* Assembly implementations of Camellia. */
+extern void _gcry_camellia_arm_encrypt_block(const KEY_TABLE_TYPE keyTable,
+                                              byte *outbuf, const byte *inbuf,
+                                              const int keybits);
+
+extern void _gcry_camellia_arm_decrypt_block(const KEY_TABLE_TYPE keyTable,
+                                              byte *outbuf, const byte *inbuf,
+                                              const int keybits);
+
+static void Camellia_EncryptBlock(const int keyBitLength,
+                                 const unsigned char *plaintext,
+                                 const KEY_TABLE_TYPE keyTable,
+                                 unsigned char *cipherText)
+{
+  _gcry_camellia_arm_encrypt_block(keyTable, cipherText, plaintext,
+                                    keyBitLength);
+}
+
+static void Camellia_DecryptBlock(const int keyBitLength,
+                                 const unsigned char *cipherText,
+                                 const KEY_TABLE_TYPE keyTable,
+                                 unsigned char *plaintext)
+{
+  _gcry_camellia_arm_decrypt_block(keyTable, plaintext, cipherText,
+                                    keyBitLength);
+}
+
+static unsigned int
+camellia_encrypt(void *c, byte *outbuf, const byte *inbuf)
+{
+  CAMELLIA_context *ctx = c;
+  Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
+#define CAMELLIA_encrypt_stack_burn_size (15*4)
+  return /*burn_stack*/ (CAMELLIA_encrypt_stack_burn_size);
+}
+
+static unsigned int
+camellia_decrypt(void *c, byte *outbuf, const byte *inbuf)
+{
+  CAMELLIA_context *ctx=c;
+  Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
+#define CAMELLIA_decrypt_stack_burn_size (15*4)
+  return /*burn_stack*/ (CAMELLIA_decrypt_stack_burn_size);
+}
+
+#else /*USE_ARM_ASM*/
+
+static unsigned int
 camellia_encrypt(void *c, byte *outbuf, const byte *inbuf)
 {
   CAMELLIA_context *ctx=c;
 
   Camellia_EncryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
-  _gcry_burn_stack
-    (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
-     +4*sizeof(u32)
-     +2*sizeof(u32*)+4*sizeof(u32)
-     +2*2*sizeof(void*) /* Function calls.  */
-    );
+
+#define CAMELLIA_encrypt_stack_burn_size \
+  (sizeof(int)+2*sizeof(unsigned char *)+sizeof(void*/*KEY_TABLE_TYPE*/) \
+     +4*sizeof(u32)+4*sizeof(u32) \
+     +2*sizeof(u32*)+4*sizeof(u32) \
+     +2*2*sizeof(void*) /* Function calls.  */ \
+    )
+
+  return /*burn_stack*/ (CAMELLIA_encrypt_stack_burn_size);
 }
 
-static void
+static unsigned int
 camellia_decrypt(void *c, byte *outbuf, const byte *inbuf)
 {
   CAMELLIA_context *ctx=c;
 
   Camellia_DecryptBlock(ctx->keybitlength,inbuf,ctx->keytable,outbuf);
-  _gcry_burn_stack
-    (sizeof(int)+2*sizeof(unsigned char *)+sizeof(KEY_TABLE_TYPE)
-     +4*sizeof(u32)
-     +2*sizeof(u32*)+4*sizeof(u32)
-     +2*2*sizeof(void*) /* Function calls.  */
-    );
+
+#define CAMELLIA_decrypt_stack_burn_size \
+    (sizeof(int)+2*sizeof(unsigned char *)+sizeof(void*/*KEY_TABLE_TYPE*/) \
+     +4*sizeof(u32)+4*sizeof(u32) \
+     +2*sizeof(u32*)+4*sizeof(u32) \
+     +2*2*sizeof(void*) /* Function calls.  */ \
+    )
+
+  return /*burn_stack*/ (CAMELLIA_decrypt_stack_burn_size);
+}
+
+#endif /*!USE_ARM_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 CAMELLIA_BLOCK_SIZE. */
+void
+_gcry_camellia_ctr_enc(void *context, unsigned char *ctr,
+                       void *outbuf_arg, const void *inbuf_arg,
+                       size_t nblocks)
+{
+  CAMELLIA_context *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned char tmpbuf[CAMELLIA_BLOCK_SIZE];
+  int burn_stack_depth = CAMELLIA_encrypt_stack_burn_size;
+  int i;
+
+#ifdef USE_AESNI_AVX2
+  if (ctx->use_aesni_avx2)
+    {
+      int did_use_aesni_avx2 = 0;
+
+      /* Process data in 32 block chunks. */
+      while (nblocks >= 32)
+        {
+          _gcry_camellia_aesni_avx2_ctr_enc(ctx, outbuf, inbuf, ctr);
+
+          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 + 16 +
+                                        2 * sizeof(void *);
+
+          if (burn_stack_depth < avx2_burn_stack_depth)
+            burn_stack_depth = avx2_burn_stack_depth;
+        }
+
+      /* Use generic code to handle smaller chunks... */
+      /* TODO: use caching instead? */
+    }
+#endif
+
+#ifdef USE_AESNI_AVX
+  if (ctx->use_aesni_avx)
+    {
+      int did_use_aesni_avx = 0;
+
+      /* Process data in 16 block chunks. */
+      while (nblocks >= 16)
+        {
+          _gcry_camellia_aesni_avx_ctr_enc(ctx, outbuf, inbuf, ctr);
+
+          nblocks -= 16;
+          outbuf += 16 * CAMELLIA_BLOCK_SIZE;
+          inbuf  += 16 * CAMELLIA_BLOCK_SIZE;
+          did_use_aesni_avx = 1;
+        }
+
+      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 *);
+        }
+
+      /* Use generic code to handle smaller chunks... */
+      /* TODO: use caching instead? */
+    }
+#endif
+
+  for ( ;nblocks; nblocks-- )
+    {
+      /* Encrypt the counter. */
+      Camellia_EncryptBlock(ctx->keybitlength, ctr, ctx->keytable, tmpbuf);
+      /* XOR the input with the encrypted counter and store in output.  */
+      buf_xor(outbuf, tmpbuf, inbuf, CAMELLIA_BLOCK_SIZE);
+      outbuf += CAMELLIA_BLOCK_SIZE;
+      inbuf  += CAMELLIA_BLOCK_SIZE;
+      /* Increment the counter.  */
+      for (i = CAMELLIA_BLOCK_SIZE; 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_camellia_cbc_dec(void *context, unsigned char *iv,
+                       void *outbuf_arg, const void *inbuf_arg,
+                       size_t nblocks)
+{
+  CAMELLIA_context *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned char savebuf[CAMELLIA_BLOCK_SIZE];
+  int burn_stack_depth = CAMELLIA_decrypt_stack_burn_size;
+
+#ifdef USE_AESNI_AVX2
+  if (ctx->use_aesni_avx2)
+    {
+      int did_use_aesni_avx2 = 0;
+
+      /* Process data in 32 block chunks. */
+      while (nblocks >= 32)
+        {
+          _gcry_camellia_aesni_avx2_cbc_dec(ctx, outbuf, inbuf, iv);
+
+          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 + 16 +
+                                        2 * sizeof(void *);
+
+          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;
+
+      /* Process data in 16 block chunks. */
+      while (nblocks >= 16)
+        {
+          _gcry_camellia_aesni_avx_cbc_dec(ctx, outbuf, inbuf, iv);
+
+          nblocks -= 16;
+          outbuf += 16 * CAMELLIA_BLOCK_SIZE;
+          inbuf  += 16 * CAMELLIA_BLOCK_SIZE;
+          did_use_aesni_avx = 1;
+        }
+
+      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 *);
+        }
+
+      /* 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.  */
+      Camellia_DecryptBlock(ctx->keybitlength, inbuf, ctx->keytable, savebuf);
+
+      buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, CAMELLIA_BLOCK_SIZE);
+      inbuf += CAMELLIA_BLOCK_SIZE;
+      outbuf += CAMELLIA_BLOCK_SIZE;
+    }
+
+  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_camellia_cfb_dec(void *context, unsigned char *iv,
+                       void *outbuf_arg, const void *inbuf_arg,
+                       size_t nblocks)
+{
+  CAMELLIA_context *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  int burn_stack_depth = CAMELLIA_decrypt_stack_burn_size;
+
+#ifdef USE_AESNI_AVX2
+  if (ctx->use_aesni_avx2)
+    {
+      int did_use_aesni_avx2 = 0;
+
+      /* Process data in 32 block chunks. */
+      while (nblocks >= 32)
+        {
+          _gcry_camellia_aesni_avx2_cfb_dec(ctx, outbuf, inbuf, iv);
+
+          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 + 16 +
+                                        2 * sizeof(void *);
+
+          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;
+
+      /* Process data in 16 block chunks. */
+      while (nblocks >= 16)
+        {
+          _gcry_camellia_aesni_avx_cfb_dec(ctx, outbuf, inbuf, iv);
+
+          nblocks -= 16;
+          outbuf += 16 * CAMELLIA_BLOCK_SIZE;
+          inbuf  += 16 * CAMELLIA_BLOCK_SIZE;
+          did_use_aesni_avx = 1;
+        }
+
+      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 *);
+        }
+
+      /* Use generic code to handle smaller chunks... */
+    }
+#endif
+
+  for ( ;nblocks; nblocks-- )
+    {
+      Camellia_EncryptBlock(ctx->keybitlength, iv, ctx->keytable, iv);
+      buf_xor_n_copy(outbuf, iv, inbuf, CAMELLIA_BLOCK_SIZE);
+      outbuf += CAMELLIA_BLOCK_SIZE;
+      inbuf  += CAMELLIA_BLOCK_SIZE;
+    }
+
+  _gcry_burn_stack(burn_stack_depth);
+}
+
+/* Run the self-tests for CAMELLIA-CTR-128, tests IV increment of bulk CTR
+   encryption.  Returns NULL on success. */
+static const char*
+selftest_ctr_128 (void)
+{
+  const int nblocks = 32+16+1;
+  const int blocksize = CAMELLIA_BLOCK_SIZE;
+  const int context_size = sizeof(CAMELLIA_context);
+
+  return _gcry_selftest_helper_ctr("CAMELLIA", &camellia_setkey,
+           &camellia_encrypt, &_gcry_camellia_ctr_enc, nblocks, blocksize,
+          context_size);
+}
+
+/* Run the self-tests for CAMELLIA-CBC-128, tests bulk CBC decryption.
+   Returns NULL on success. */
+static const char*
+selftest_cbc_128 (void)
+{
+  const int nblocks = 32+16+2;
+  const int blocksize = CAMELLIA_BLOCK_SIZE;
+  const int context_size = sizeof(CAMELLIA_context);
+
+  return _gcry_selftest_helper_cbc("CAMELLIA", &camellia_setkey,
+           &camellia_encrypt, &_gcry_camellia_cbc_dec, nblocks, blocksize,
+          context_size);
+}
+
+/* Run the self-tests for CAMELLIA-CFB-128, tests bulk CFB decryption.
+   Returns NULL on success. */
+static const char*
+selftest_cfb_128 (void)
+{
+  const int nblocks = 32+16+2;
+  const int blocksize = CAMELLIA_BLOCK_SIZE;
+  const int context_size = sizeof(CAMELLIA_context);
+
+  return _gcry_selftest_helper_cfb("CAMELLIA", &camellia_setkey,
+           &camellia_encrypt, &_gcry_camellia_cfb_dec, nblocks, blocksize,
+          context_size);
 }
 
 static const char *
@@ -137,40 +585,41 @@ selftest(void)
 {
   CAMELLIA_context ctx;
   byte scratch[16];
+  const char *r;
 
   /* These test vectors are from RFC-3713 */
-  const byte plaintext[]=
+  static const byte plaintext[]=
     {
       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
       0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
     };
-  const byte key_128[]=
+  static const byte key_128[]=
     {
       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
       0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10
     };
-  const byte ciphertext_128[]=
+  static const byte ciphertext_128[]=
     {
       0x67,0x67,0x31,0x38,0x54,0x96,0x69,0x73,
       0x08,0x57,0x06,0x56,0x48,0xea,0xbe,0x43
     };
-  const byte key_192[]=
+  static const byte key_192[]=
     {
       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,0x98,
       0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77
     };
-  const byte ciphertext_192[]=
+  static const byte ciphertext_192[]=
     {
       0xb4,0x99,0x34,0x01,0xb3,0xe9,0x96,0xf8,
       0x4e,0xe5,0xce,0xe7,0xd7,0x9b,0x09,0xb9
     };
-  const byte key_256[]=
+  static const byte key_256[]=
     {
       0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,0xfe,0xdc,0xba,
       0x98,0x76,0x54,0x32,0x10,0x00,0x11,0x22,0x33,0x44,0x55,
       0x66,0x77,0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
     };
-  const byte ciphertext_256[]=
+  static const byte ciphertext_256[]=
     {
       0x9a,0xcc,0x23,0x7d,0xff,0x16,0xd7,0x6c,
       0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09
@@ -200,6 +649,15 @@ selftest(void)
   if(memcmp(scratch,plaintext,sizeof(plaintext))!=0)
     return "CAMELLIA-256 test decryption failed.";
 
+  if ( (r = selftest_ctr_128 ()) )
+    return r;
+
+  if ( (r = selftest_cbc_128 ()) )
+    return r;
+
+  if ( (r = selftest_cfb_128 ()) )
+    return r;
+
   return NULL;
 }
 
@@ -236,18 +694,21 @@ static gcry_cipher_oid_spec_t camellia256_oids[] =
 
 gcry_cipher_spec_t _gcry_cipher_spec_camellia128 =
   {
+    GCRY_CIPHER_CAMELLIA128, {0, 0},
     "CAMELLIA128",NULL,camellia128_oids,CAMELLIA_BLOCK_SIZE,128,
     sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
   };
 
 gcry_cipher_spec_t _gcry_cipher_spec_camellia192 =
   {
+    GCRY_CIPHER_CAMELLIA192, {0, 0},
     "CAMELLIA192",NULL,camellia192_oids,CAMELLIA_BLOCK_SIZE,192,
     sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
   };
 
 gcry_cipher_spec_t _gcry_cipher_spec_camellia256 =
   {
+    GCRY_CIPHER_CAMELLIA256, {0, 0},
     "CAMELLIA256",NULL,camellia256_oids,CAMELLIA_BLOCK_SIZE,256,
     sizeof(CAMELLIA_context),camellia_setkey,camellia_encrypt,camellia_decrypt
   };
index 2e28bce..e7085a7 100644 (file)
@@ -14,8 +14,7 @@
  * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 /*
  *  http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
  */
 
+#include <config.h>
 #include <string.h>
 #include <stdlib.h>
 
+#include "types.h"
+#include "bufhelp.h"
 #include "camellia.h"
 
-/* u32 must be 32bit word */
-typedef unsigned int u32;
-typedef unsigned char u8;
+typedef byte u8;
 
 /* key constants */
 
@@ -60,17 +60,8 @@ typedef unsigned char u8;
 
 #else /* not MS-VC */
 
-# define GETU32(pt)                            \
-    (((u32)(pt)[0] << 24)                      \
-     ^ ((u32)(pt)[1] << 16)                    \
-     ^ ((u32)(pt)[2] <<  8)                    \
-     ^ ((u32)(pt)[3]))
-
-# define PUTU32(ct, st)  {                     \
-       (ct)[0] = (u8)((st) >> 24);             \
-       (ct)[1] = (u8)((st) >> 16);             \
-       (ct)[2] = (u8)((st) >>  8);             \
-       (ct)[3] = (u8)(st); }
+# define GETU32(pt) buf_get_be32(pt)
+# define PUTU32(ct, st) buf_put_be32(ct, st)
 
 #endif
 
@@ -151,6 +142,8 @@ typedef unsigned char u8;
 
 #define CAMELLIA_ROUNDSM(xl, xr, kl, kr, yl, yr, il, ir, t0, t1)       \
     do {                                                               \
+       yl ^= kl;                                                       \
+       yr ^= kr;                                                       \
        ir = CAMELLIA_SP1110(xr & 0xff)                                 \
            ^ CAMELLIA_SP0222((xr >> 24) & 0xff)                        \
            ^ CAMELLIA_SP3033((xr >> 16) & 0xff)                        \
@@ -159,8 +152,6 @@ typedef unsigned char u8;
            ^ CAMELLIA_SP0222((xl >> 16) & 0xff)                        \
            ^ CAMELLIA_SP3033((xl >> 8) & 0xff)                         \
            ^ CAMELLIA_SP4404(xl & 0xff);                               \
-       il ^= kl;                                                       \
-       ir ^= kr;                                                       \
        ir ^= il;                                                       \
        il = CAMELLIA_RR8(il);                                          \
        il ^= ir;                                                       \
@@ -614,44 +605,6 @@ void camellia_setup128(const unsigned char *key, u32 *subkey)
     CamelliaSubkeyL(24) = subl(24) ^ subl(23);
     CamelliaSubkeyR(24) = subr(24) ^ subr(23);
 
-    /* apply the inverse of the last half of P-function */
-    dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
-    dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
-    dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
-    dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
-    dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
-    dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
-    dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
-    dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
-    dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
-    dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
-    dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
-    dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
-    dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
-    dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
-    dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
-    dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
-    dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
-    dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
-
     return;
 }
 
@@ -888,56 +841,6 @@ void camellia_setup256(const unsigned char *key, u32 *subkey)
     CamelliaSubkeyL(32) = subl(32) ^ subl(31);
     CamelliaSubkeyR(32) = subr(32) ^ subr(31);
 
-    /* apply the inverse of the last half of P-function */
-    dw = CamelliaSubkeyL(2) ^ CamelliaSubkeyR(2), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(2) = CamelliaSubkeyL(2) ^ dw, CamelliaSubkeyL(2) = dw;
-    dw = CamelliaSubkeyL(3) ^ CamelliaSubkeyR(3), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(3) = CamelliaSubkeyL(3) ^ dw, CamelliaSubkeyL(3) = dw;
-    dw = CamelliaSubkeyL(4) ^ CamelliaSubkeyR(4), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(4) = CamelliaSubkeyL(4) ^ dw, CamelliaSubkeyL(4) = dw;
-    dw = CamelliaSubkeyL(5) ^ CamelliaSubkeyR(5), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(5) = CamelliaSubkeyL(5) ^ dw, CamelliaSubkeyL(5) = dw;
-    dw = CamelliaSubkeyL(6) ^ CamelliaSubkeyR(6), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(6) = CamelliaSubkeyL(6) ^ dw, CamelliaSubkeyL(6) = dw;
-    dw = CamelliaSubkeyL(7) ^ CamelliaSubkeyR(7), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(7) = CamelliaSubkeyL(7) ^ dw, CamelliaSubkeyL(7) = dw;
-    dw = CamelliaSubkeyL(10) ^ CamelliaSubkeyR(10), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(10) = CamelliaSubkeyL(10) ^ dw, CamelliaSubkeyL(10) = dw;
-    dw = CamelliaSubkeyL(11) ^ CamelliaSubkeyR(11), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(11) = CamelliaSubkeyL(11) ^ dw, CamelliaSubkeyL(11) = dw;
-    dw = CamelliaSubkeyL(12) ^ CamelliaSubkeyR(12), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(12) = CamelliaSubkeyL(12) ^ dw, CamelliaSubkeyL(12) = dw;
-    dw = CamelliaSubkeyL(13) ^ CamelliaSubkeyR(13), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(13) = CamelliaSubkeyL(13) ^ dw, CamelliaSubkeyL(13) = dw;
-    dw = CamelliaSubkeyL(14) ^ CamelliaSubkeyR(14), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(14) = CamelliaSubkeyL(14) ^ dw, CamelliaSubkeyL(14) = dw;
-    dw = CamelliaSubkeyL(15) ^ CamelliaSubkeyR(15), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(15) = CamelliaSubkeyL(15) ^ dw, CamelliaSubkeyL(15) = dw;
-    dw = CamelliaSubkeyL(18) ^ CamelliaSubkeyR(18), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(18) = CamelliaSubkeyL(18) ^ dw, CamelliaSubkeyL(18) = dw;
-    dw = CamelliaSubkeyL(19) ^ CamelliaSubkeyR(19), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(19) = CamelliaSubkeyL(19) ^ dw, CamelliaSubkeyL(19) = dw;
-    dw = CamelliaSubkeyL(20) ^ CamelliaSubkeyR(20), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(20) = CamelliaSubkeyL(20) ^ dw, CamelliaSubkeyL(20) = dw;
-    dw = CamelliaSubkeyL(21) ^ CamelliaSubkeyR(21), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(21) = CamelliaSubkeyL(21) ^ dw, CamelliaSubkeyL(21) = dw;
-    dw = CamelliaSubkeyL(22) ^ CamelliaSubkeyR(22), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(22) = CamelliaSubkeyL(22) ^ dw, CamelliaSubkeyL(22) = dw;
-    dw = CamelliaSubkeyL(23) ^ CamelliaSubkeyR(23), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(23) = CamelliaSubkeyL(23) ^ dw, CamelliaSubkeyL(23) = dw;
-    dw = CamelliaSubkeyL(26) ^ CamelliaSubkeyR(26), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(26) = CamelliaSubkeyL(26) ^ dw, CamelliaSubkeyL(26) = dw;
-    dw = CamelliaSubkeyL(27) ^ CamelliaSubkeyR(27), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(27) = CamelliaSubkeyL(27) ^ dw, CamelliaSubkeyL(27) = dw;
-    dw = CamelliaSubkeyL(28) ^ CamelliaSubkeyR(28), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(28) = CamelliaSubkeyL(28) ^ dw, CamelliaSubkeyL(28) = dw;
-    dw = CamelliaSubkeyL(29) ^ CamelliaSubkeyR(29), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(29) = CamelliaSubkeyL(29) ^ dw, CamelliaSubkeyL(29) = dw;
-    dw = CamelliaSubkeyL(30) ^ CamelliaSubkeyR(30), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, CamelliaSubkeyL(30) = dw;
-    dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), dw = CAMELLIA_RL8(dw);
-    CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw,CamelliaSubkeyL(31) = dw;
-
     return;
 }
 
@@ -958,14 +861,21 @@ void camellia_setup192(const unsigned char *key, u32 *subkey)
 }
 
 
+#ifndef USE_ARM_ASM
 /**
  * Stuff related to camellia encryption/decryption
  *
  * "io" must be 4byte aligned and big-endian data.
  */
-void camellia_encrypt128(const u32 *subkey, u32 *io)
+void camellia_encrypt128(const u32 *subkey, u32 *blocks)
 {
     u32 il, ir, t0, t1;
+    u32 io[4];
+
+    io[0] = blocks[0];
+    io[1] = blocks[1];
+    io[2] = blocks[2];
+    io[3] = blocks[3];
 
     /* pre whitening but absorb kw2*/
     io[0] ^= CamelliaSubkeyL(0);
@@ -1050,12 +960,23 @@ void camellia_encrypt128(const u32 *subkey, u32 *io)
     io[2] = t0;
     io[3] = t1;
 
+    blocks[0] = io[0];
+    blocks[1] = io[1];
+    blocks[2] = io[2];
+    blocks[3] = io[3];
+
     return;
 }
 
-void camellia_decrypt128(const u32 *subkey, u32 *io)
+void camellia_decrypt128(const u32 *subkey, u32 *blocks)
 {
     u32 il,ir,t0,t1;               /* temporary valiables */
+    u32 io[4];
+
+    io[0] = blocks[0];
+    io[1] = blocks[1];
+    io[2] = blocks[2];
+    io[3] = blocks[3];
 
     /* pre whitening but absorb kw2*/
     io[0] ^= CamelliaSubkeyL(24);
@@ -1140,15 +1061,26 @@ void camellia_decrypt128(const u32 *subkey, u32 *io)
     io[2] = t0;
     io[3] = t1;
 
+    blocks[0] = io[0];
+    blocks[1] = io[1];
+    blocks[2] = io[2];
+    blocks[3] = io[3];
+
     return;
 }
 
 /**
  * stuff for 192 and 256bit encryption/decryption
  */
-void camellia_encrypt256(const u32 *subkey, u32 *io)
+void camellia_encrypt256(const u32 *subkey, u32 *blocks)
 {
     u32 il,ir,t0,t1;           /* temporary valiables */
+    u32 io[4];
+
+    io[0] = blocks[0];
+    io[1] = blocks[1];
+    io[2] = blocks[2];
+    io[3] = blocks[3];
 
     /* pre whitening but absorb kw2*/
     io[0] ^= CamelliaSubkeyL(0);
@@ -1257,12 +1189,23 @@ void camellia_encrypt256(const u32 *subkey, u32 *io)
     io[2] = t0;
     io[3] = t1;
 
+    blocks[0] = io[0];
+    blocks[1] = io[1];
+    blocks[2] = io[2];
+    blocks[3] = io[3];
+
     return;
 }
 
-void camellia_decrypt256(const u32 *subkey, u32 *io)
+void camellia_decrypt256(const u32 *subkey, u32 *blocks)
 {
     u32 il,ir,t0,t1;           /* temporary valiables */
+    u32 io[4];
+
+    io[0] = blocks[0];
+    io[1] = blocks[1];
+    io[2] = blocks[2];
+    io[3] = blocks[3];
 
     /* pre whitening but absorb kw2*/
     io[0] ^= CamelliaSubkeyL(32);
@@ -1371,8 +1314,15 @@ void camellia_decrypt256(const u32 *subkey, u32 *io)
     io[2] = t0;
     io[3] = t1;
 
+    blocks[0] = io[0];
+    blocks[1] = io[1];
+    blocks[2] = io[2];
+    blocks[3] = io[3];
+
     return;
 }
+#endif /*!USE_ARM_ASM*/
+
 
 /***
  *
@@ -1399,6 +1349,7 @@ void Camellia_Ekeygen(const int keyBitLength,
 }
 
 
+#ifndef USE_ARM_ASM
 void Camellia_EncryptBlock(const int keyBitLength,
                           const unsigned char *plaintext,
                           const KEY_TABLE_TYPE keyTable,
@@ -1459,3 +1410,4 @@ void Camellia_DecryptBlock(const int keyBitLength,
     PUTU32(plaintext + 8, tmp[2]);
     PUTU32(plaintext + 12, tmp[3]);
 }
+#endif /*!USE_ARM_ASM*/
index cccf786..d0e3c18 100644 (file)
  */
 #ifdef HAVE_CONFIG_H
 #include <config.h>
+/* 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
 #endif
 #ifdef CAMELLIA_EXT_SYM_PREFIX
 #define CAMELLIA_PREFIX1(x,y) x ## y
@@ -63,6 +70,7 @@ void Camellia_Ekeygen(const int keyBitLength,
                      const unsigned char *rawKey,
                      KEY_TABLE_TYPE keyTable);
 
+#ifndef USE_ARM_ASM
 void Camellia_EncryptBlock(const int keyBitLength,
                           const unsigned char *plaintext,
                           const KEY_TABLE_TYPE keyTable,
@@ -72,6 +80,7 @@ void Camellia_DecryptBlock(const int keyBitLength,
                           const unsigned char *cipherText,
                           const KEY_TABLE_TYPE keyTable,
                           unsigned char *plaintext);
+#endif /*!USE_ARMV6_ASM*/
 
 
 #ifdef  __cplusplus
diff --git a/cipher/cast5-amd64.S b/cipher/cast5-amd64.S
new file mode 100644 (file)
index 0000000..c3b819d
--- /dev/null
@@ -0,0 +1,587 @@
+/* cast5-amd64.S  -  AMD64 assembly implementation of CAST5 cipher
+ *
+ * Copyright © 2013 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(USE_CAST5)
+
+#ifdef __PIC__
+#  define RIP %rip
+#  define GET_EXTERN_POINTER(name, reg) movq name@GOTPCREL(%rip), reg
+#else
+#  define RIP
+#  define GET_EXTERN_POINTER(name, reg) leaq name, reg
+#endif
+
+.text
+
+.extern _gcry_cast5_s1to4;
+
+#define s1 0
+#define s2 (s1 + (4 * 256))
+#define s3 (s2 + (4 * 256))
+#define s4 (s3 + (4 * 256))
+
+/* structure of CAST5_context: */
+#define Km 0
+#define Kr (Km + (16 * 4))
+
+/* register macros */
+#define CTX %rdi
+#define RIO %rsi
+#define RTAB %r8
+
+#define RLR0 %r9
+#define RLR1 %r10
+#define RLR2 %r11
+#define RLR3 %r12
+
+#define RLR0d %r9d
+#define RLR1d %r10d
+#define RLR2d %r11d
+#define RLR3d %r12d
+
+#define RX0 %rax
+#define RX1 %rbx
+#define RX2 %rdx
+
+#define RX0d %eax
+#define RX1d %ebx
+#define RX2d %edx
+
+#define RX0bl %al
+#define RX1bl %bl
+#define RX2bl %dl
+
+#define RX0bh %ah
+#define RX1bh %bh
+#define RX2bh %dh
+
+#define RKR %rcx
+#define RKRd %ecx
+#define RKRbl %cl
+
+#define RT0 %rbp
+#define RT1 %rsi
+
+#define RT0d %ebp
+#define RT1d %esi
+
+#define RKM0d %r13d
+#define RKM1d %r14d
+
+/***********************************************************************
+ * 1-way cast5
+ ***********************************************************************/
+#define dummy(x)
+
+#define shr_kr(none) \
+       shrq $8,                        RKR;
+
+#define F(km, load_next_kr, op0, op1, op2, op3) \
+       op0 ## l RLR0d,                 km ## d; \
+       roll RKRbl,                     km ## d; \
+       rorq $32,                       RLR0; \
+       movzbl km ## bh,                RT0d; \
+       movzbl km ## bl,                RT1d; \
+       roll $16,                       km ## d; \
+       movl s1(RTAB,RT0,4),            RT0d; \
+       op1 ## l s2(RTAB,RT1,4),        RT0d; \
+       load_next_kr(kr_next); \
+       movzbl km ## bh,                RT1d; \
+       movzbl km ## bl,                km ## d; \
+       op2 ## l s3(RTAB,RT1,4),        RT0d; \
+       op3 ## l s4(RTAB,km,4),         RT0d; \
+       xorq RT0,                       RLR0;
+
+#define F1(km, load_next_kr) \
+       F(##km, load_next_kr, add, xor, sub, add)
+#define F2(km, load_next_kr) \
+       F(##km, load_next_kr, xor, sub, add, xor)
+#define F3(km, load_next_kr) \
+       F(##km, load_next_kr, sub, add, xor, sub)
+
+#define get_round_km(n, km) \
+       movl Km+4*(n)(CTX),             km;
+
+#define get_round_kr_enc(n) \
+       movq $0x1010101010101010,       RKR; \
+       \
+       /* merge rorl rk and rorl $16 */ \
+       xorq Kr+(n)(CTX),               RKR;
+
+#define get_round_kr_dec(n) \
+       movq $0x1010101010101010,       RKR; \
+       \
+       /* merge rorl rk and rorl $16 */ \
+       xorq Kr+(n - 7)(CTX),           RKR; \
+       bswapq                          RKR;
+
+#define round_enc(n, FA, FB, fn1, fn2) \
+       get_round_km(n + 1, RX2d); \
+       FA(RX0, fn1); \
+       get_round_km(n + 2, RX0d); \
+       FB(RX2, fn2);
+
+#define round_enc_last(n, FXA, FXB) \
+       get_round_km(n + 1, RX2d); \
+       \
+       FXA(RX0, shr_kr); \
+       FXB(RX2, dummy);
+
+#define round_enc_1(n, FA, FB) \
+       round_enc(n, FA, FB, shr_kr, shr_kr)
+
+#define round_enc_2(n, FA, FB) \
+       round_enc(n, FA, FB, shr_kr, dummy)
+
+#define round_dec(n, FA, FB, fn1, fn2) \
+       get_round_km(n - 1, RX2d); \
+       FA(RX0, fn1); \
+       get_round_km(n - 2, RX0d); \
+       FB(RX2, fn2);
+
+#define round_dec_last(n, FXA, FXB) \
+       get_round_km(n - 1, RX2d); \
+       FXA(RX0, shr_kr); \
+       FXB(RX2, dummy);
+
+#define round_dec_1(n, FA, FB) \
+       round_dec(n, FA, FB, shr_kr, shr_kr)
+
+#define round_dec_2(n, FA, FB) \
+       round_dec(n, FA, FB, shr_kr, dummy)
+
+#define read_block() \
+       movq (RIO),             RLR0; \
+       bswapq                  RLR0;
+
+#define write_block() \
+       bswapq                  RLR0; \
+       rorq $32,               RLR0; \
+       movq RLR0,              (RIO);
+
+.align 8
+.globl _gcry_cast5_amd64_encrypt_block
+.type   _gcry_cast5_amd64_encrypt_block,@function;
+
+_gcry_cast5_amd64_encrypt_block:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst
+        *      %rdx: src
+        */
+       pushq %rbp;
+       pushq %rbx;
+
+       movq %rsi, %r10;
+
+       GET_EXTERN_POINTER(_gcry_cast5_s1to4, RTAB);
+
+       movq %rdx, RIO;
+       read_block();
+
+       get_round_km(0, RX0d);
+       get_round_kr_enc(0);
+       round_enc_1(0, F1, F2);
+       round_enc_1(2, F3, F1);
+       round_enc_1(4, F2, F3);
+       round_enc_2(6, F1, F2);
+       get_round_kr_enc(8);
+       round_enc_1(8, F3, F1);
+       round_enc_1(10, F2, F3);
+       round_enc_1(12, F1, F2);
+       round_enc_last(14, F3, F1);
+
+       movq %r10, RIO;
+       write_block();
+
+       popq %rbx;
+       popq %rbp;
+       ret;
+.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;
+
+_gcry_cast5_amd64_decrypt_block:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst
+        *      %rdx: src
+        */
+       pushq %rbp;
+       pushq %rbx;
+
+       movq %rsi, %r10;
+
+       GET_EXTERN_POINTER(_gcry_cast5_s1to4, RTAB);
+
+       movq %rdx, RIO;
+       read_block();
+
+       get_round_km(15, RX0d);
+       get_round_kr_dec(15);
+       round_dec_1(15, F1, F3);
+       round_dec_1(13, F2, F1);
+       round_dec_1(11, F3, F2);
+       round_dec_2(9, F1, F3);
+       get_round_kr_dec(7);
+       round_dec_1(7, F2, F1);
+       round_dec_1(5, F3, F2);
+       round_dec_1(3, F1, F3);
+       round_dec_last(1, F2, F1);
+
+       movq %r10, RIO;
+       write_block();
+
+       popq %rbx;
+       popq %rbp;
+       ret;
+.size _gcry_cast5_amd64_decrypt_block,.-_gcry_cast5_amd64_decrypt_block;
+
+/**********************************************************************
+  4-way cast5, four blocks parallel
+ **********************************************************************/
+#define F_tail(rlr, rx, op1, op2, op3) \
+       movzbl rx ## bh,                RT0d; \
+       movzbl rx ## bl,                RT1d; \
+       roll $16,                       rx ## d; \
+       movl s1(RTAB,RT0,4),            RT0d; \
+       op1 ## l s2(RTAB,RT1,4),        RT0d; \
+       movzbl rx ## bh,                RT1d; \
+       movzbl rx ## bl,                rx ## d; \
+       op2 ## l s3(RTAB,RT1,4),        RT0d; \
+       op3 ## l s4(RTAB,rx,4),         RT0d; \
+       xorq RT0,                       rlr;
+
+#define F4(km, load_next_kr, op0, op1, op2, op3) \
+       movl km,                        RX0d; \
+       op0 ## l RLR0d,                 RX0d; \
+       roll RKRbl,                     RX0d; \
+       rorq $32,                       RLR0; \
+       \
+       movl km,                        RX1d; \
+       op0 ## l RLR1d,                 RX1d; \
+       roll RKRbl,                     RX1d; \
+       rorq $32,                       RLR1; \
+       \
+       movl km,                        RX2d; \
+       op0 ## l RLR2d,                 RX2d; \
+       roll RKRbl,                     RX2d; \
+       rorq $32,                       RLR2; \
+       \
+       F_tail(RLR0, RX0, op1, op2, op3); \
+       F_tail(RLR1, RX1, op1, op2, op3); \
+       F_tail(RLR2, RX2, op1, op2, op3); \
+       \
+       movl km,                        RX0d; \
+       op0 ## l RLR3d,                 RX0d; \
+       roll RKRbl,                     RX0d; \
+       load_next_kr();                 \
+       rorq $32,                       RLR3; \
+       \
+       F_tail(RLR3, RX0, op1, op2, op3);
+
+#define F4_1(km, load_next_kr) \
+       F4(km, load_next_kr, add, xor, sub, add)
+#define F4_2(km, load_next_kr) \
+       F4(km, load_next_kr, xor, sub, add, xor)
+#define F4_3(km, load_next_kr) \
+       F4(km, load_next_kr, sub, add, xor, sub)
+
+#define round_enc4(n, FA, FB, fn1, fn2) \
+       get_round_km(n + 1, RKM1d); \
+       FA(RKM0d, fn1); \
+       get_round_km(n + 2, RKM0d); \
+       FB(RKM1d, fn2);
+
+#define round_enc_last4(n, FXA, FXB) \
+       get_round_km(n + 1, RKM1d); \
+       FXA(RKM0d, shr_kr); \
+       FXB(RKM1d, dummy);
+
+#define round_enc4_1(n, FA, FB) \
+       round_enc4(n, FA, FB, shr_kr, shr_kr);
+
+#define round_enc4_2(n, FA, FB) \
+       round_enc4(n, FA, FB, shr_kr, dummy);
+
+#define round_dec4(n, FA, FB, fn1, fn2) \
+       get_round_km(n - 1, RKM1d); \
+       FA(RKM0d, fn1); \
+       get_round_km(n - 2, RKM0d); \
+       FB(RKM1d, fn2);
+
+#define round_dec_last4(n, FXA, FXB) \
+       get_round_km(n - 1, RKM1d); \
+       FXA(RKM0d, shr_kr); \
+       FXB(RKM1d, dummy);
+
+#define round_dec4_1(n, FA, FB) \
+       round_dec4(n, FA, FB, shr_kr, shr_kr);
+
+#define round_dec4_2(n, FA, FB) \
+       round_dec4(n, FA, FB, shr_kr, dummy);
+
+#define inbswap_block4(a, b, c, d) \
+       bswapq                  a; \
+       bswapq                  b; \
+       bswapq                  c; \
+       bswapq                  d;
+
+#define outbswap_block4(a, b, c, d) \
+       bswapq                  a; \
+       bswapq                  b; \
+       bswapq                  c; \
+       bswapq                  d; \
+       rorq $32,               a; \
+       rorq $32,               b; \
+       rorq $32,               c; \
+       rorq $32,               d;
+
+.align 8
+.type   __cast5_enc_blk4,@function;
+
+__cast5_enc_blk4:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      RLR0,RLR1,RLR2,RLR3: four input plaintext blocks
+        * output:
+        *      RLR0,RLR1,RLR2,RLR3: four output ciphertext blocks
+        */
+       GET_EXTERN_POINTER(_gcry_cast5_s1to4, RTAB);
+
+       get_round_km(0, RKM0d);
+       get_round_kr_enc(0);
+       round_enc4_1(0, F4_1, F4_2);
+       round_enc4_1(2, F4_3, F4_1);
+       round_enc4_1(4, F4_2, F4_3);
+       round_enc4_2(6, F4_1, F4_2);
+       get_round_kr_enc(8);
+       round_enc4_1(8, F4_3, F4_1);
+       round_enc4_1(10, F4_2, F4_3);
+       round_enc4_1(12, F4_1, F4_2);
+       round_enc_last4(14, F4_3, F4_1);
+
+       outbswap_block4(RLR0, RLR1, RLR2, RLR3);
+       ret;
+.size __cast5_enc_blk4,.-__cast5_enc_blk4;
+
+.align 8
+.type   __cast5_dec_blk4,@function;
+
+__cast5_dec_blk4:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      RLR0,RLR1,RLR2,RLR3: four input ciphertext blocks
+        * output:
+        *      RLR0,RLR1,RLR2,RLR3: four output plaintext blocks
+        */
+       GET_EXTERN_POINTER(_gcry_cast5_s1to4, RTAB);
+
+       inbswap_block4(RLR0, RLR1, RLR2, RLR3);
+
+       get_round_km(15, RKM0d);
+       get_round_kr_dec(15);
+       round_dec4_1(15, F4_1, F4_3);
+       round_dec4_1(13, F4_2, F4_1);
+       round_dec4_1(11, F4_3, F4_2);
+       round_dec4_2(9, F4_1, F4_3);
+       get_round_kr_dec(7);
+       round_dec4_1(7, F4_2, F4_1);
+       round_dec4_1(5, F4_3, F4_2);
+       round_dec4_1(3, F4_1, F4_3);
+       round_dec_last4(1, F4_2, F4_1);
+
+       outbswap_block4(RLR0, RLR1, RLR2, RLR3);
+       ret;
+.size __cast5_dec_blk4,.-__cast5_dec_blk4;
+
+.align 8
+.globl _gcry_cast5_amd64_ctr_enc
+.type   _gcry_cast5_amd64_ctr_enc,@function;
+_gcry_cast5_amd64_ctr_enc:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (8 blocks)
+        *      %rdx: src (8 blocks)
+        *      %rcx: iv (big endian, 64bit)
+        */
+
+       pushq %rbp;
+       pushq %rbx;
+       pushq %r12;
+       pushq %r13;
+       pushq %r14;
+
+       pushq %rsi;
+       pushq %rdx;
+
+       /* load IV and byteswap */
+       movq (%rcx), RX0;
+       bswapq RX0;
+       movq RX0, RLR0;
+
+       /* construct IVs */
+       leaq 1(RX0), RLR1;
+       leaq 2(RX0), RLR2;
+       leaq 3(RX0), RLR3;
+       leaq 4(RX0), RX0;
+       bswapq RX0;
+
+       /* store new IV */
+       movq RX0, (%rcx);
+
+       call __cast5_enc_blk4;
+
+       popq %r14; /*src*/
+       popq %r13; /*dst*/
+
+       /* XOR key-stream with plaintext */
+       xorq 0 * 8(%r14), RLR0;
+       xorq 1 * 8(%r14), RLR1;
+       xorq 2 * 8(%r14), RLR2;
+       xorq 3 * 8(%r14), RLR3;
+       movq RLR0, 0 * 8(%r13);
+       movq RLR1, 1 * 8(%r13);
+       movq RLR2, 2 * 8(%r13);
+       movq RLR3, 3 * 8(%r13);
+
+       popq %r14;
+       popq %r13;
+       popq %r12;
+       popq %rbx;
+       popq %rbp;
+       ret
+.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;
+_gcry_cast5_amd64_cbc_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (8 blocks)
+        *      %rdx: src (8 blocks)
+        *      %rcx: iv (64bit)
+        */
+
+       pushq %rbp;
+       pushq %rbx;
+       pushq %r12;
+       pushq %r13;
+       pushq %r14;
+
+       pushq %rcx;
+       pushq %rsi;
+       pushq %rdx;
+
+       /* load input */
+       movq 0 * 8(%rdx), RLR0;
+       movq 1 * 8(%rdx), RLR1;
+       movq 2 * 8(%rdx), RLR2;
+       movq 3 * 8(%rdx), RLR3;
+
+       call __cast5_dec_blk4;
+
+       popq RX0; /*src*/
+       popq RX1; /*dst*/
+       popq RX2; /*iv*/
+
+       movq 3 * 8(RX0), %r14;
+       xorq      (RX2), RLR0;
+       xorq 0 * 8(RX0), RLR1;
+       xorq 1 * 8(RX0), RLR2;
+       xorq 2 * 8(RX0), RLR3;
+       movq %r14, (RX2); /* store new IV */
+
+       movq RLR0, 0 * 8(RX1);
+       movq RLR1, 1 * 8(RX1);
+       movq RLR2, 2 * 8(RX1);
+       movq RLR3, 3 * 8(RX1);
+
+       popq %r14;
+       popq %r13;
+       popq %r12;
+       popq %rbx;
+       popq %rbp;
+       ret;
+
+.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;
+_gcry_cast5_amd64_cfb_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (8 blocks)
+        *      %rdx: src (8 blocks)
+        *      %rcx: iv (64bit)
+        */
+
+       pushq %rbp;
+       pushq %rbx;
+       pushq %r12;
+       pushq %r13;
+       pushq %r14;
+
+       pushq %rsi;
+       pushq %rdx;
+
+       /* Load input */
+       movq (%rcx), RLR0;
+       movq 0 * 8(%rdx), RLR1;
+       movq 1 * 8(%rdx), RLR2;
+       movq 2 * 8(%rdx), RLR3;
+
+       inbswap_block4(RLR0, RLR1, RLR2, RLR3);
+
+       /* Update IV */
+       movq 3 * 8(%rdx), %rdx;
+       movq %rdx, (%rcx);
+
+       call __cast5_enc_blk4;
+
+       popq %rdx; /*src*/
+       popq %rcx; /*dst*/
+
+       xorq 0 * 8(%rdx), RLR0;
+       xorq 1 * 8(%rdx), RLR1;
+       xorq 2 * 8(%rdx), RLR2;
+       xorq 3 * 8(%rdx), RLR3;
+       movq RLR0, 0 * 8(%rcx);
+       movq RLR1, 1 * 8(%rcx);
+       movq RLR2, 2 * 8(%rcx);
+       movq RLR3, 3 * 8(%rcx);
+
+       popq %r14;
+       popq %r13;
+       popq %r12;
+       popq %rbx;
+       popq %rbp;
+       ret;
+
+.size _gcry_cast5_amd64_cfb_dec,.-_gcry_cast5_amd64_cfb_dec;
+
+#endif /*defined(USE_CAST5)*/
+#endif /*__x86_64*/
diff --git a/cipher/cast5-arm.S b/cipher/cast5-arm.S
new file mode 100644 (file)
index 0000000..ce7fa93
--- /dev/null
@@ -0,0 +1,715 @@
+/* cast5-arm.S  -  ARM assembly implementation of CAST5 cipher
+ *
+ * Copyright © 2013 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
+
+.extern _gcry_cast5_s1to4;
+
+/* structure of crypto context */
+#define Km 0
+#define Kr (Km + (16 * 4))
+#define Kr_arm_enc (Kr + (16))
+#define Kr_arm_dec (Kr_arm_enc + (16))
+
+/* register macros */
+#define CTX %r0
+#define Rs1 %r7
+#define Rs2 %r8
+#define Rs3 %r9
+#define Rs4 %r10
+#define RMASK %r11
+#define RKM %r1
+#define RKR %r2
+
+#define RL0 %r3
+#define RR0 %r4
+
+#define RL1 %r9
+#define RR1 %r10
+
+#define RT0 %lr
+#define RT1 %ip
+#define RT2 %r5
+#define RT3 %r6
+
+/* helper macros */
+#define ldr_unaligned_le(rout, rsrc, offs, rtmp) \
+       ldrb rout, [rsrc, #((offs) + 0)]; \
+       ldrb rtmp, [rsrc, #((offs) + 1)]; \
+       orr rout, rout, rtmp, lsl #8; \
+       ldrb rtmp, [rsrc, #((offs) + 2)]; \
+       orr rout, rout, rtmp, lsl #16; \
+       ldrb rtmp, [rsrc, #((offs) + 3)]; \
+       orr rout, rout, rtmp, lsl #24;
+
+#define str_unaligned_le(rin, rdst, offs, rtmp0, rtmp1) \
+       mov rtmp0, rin, lsr #8; \
+       strb rin, [rdst, #((offs) + 0)]; \
+       mov rtmp1, rin, lsr #16; \
+       strb rtmp0, [rdst, #((offs) + 1)]; \
+       mov rtmp0, rin, lsr #24; \
+       strb rtmp1, [rdst, #((offs) + 2)]; \
+       strb rtmp0, [rdst, #((offs) + 3)];
+
+#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;
+
+#define str_unaligned_be(rin, rdst, offs, rtmp0, rtmp1) \
+       mov rtmp0, rin, lsr #8; \
+       strb rin, [rdst, #((offs) + 3)]; \
+       mov rtmp1, rin, lsr #16; \
+       strb rtmp0, [rdst, #((offs) + 2)]; \
+       mov rtmp0, rin, lsr #24; \
+       strb rtmp1, [rdst, #((offs) + 1)]; \
+       strb rtmp0, [rdst, #((offs) + 0)];
+
+#ifdef __ARMEL__
+       #define ldr_unaligned_host ldr_unaligned_le
+       #define str_unaligned_host str_unaligned_le
+
+       /* bswap on little-endian */
+#ifdef HAVE_ARM_ARCH_V6
+       #define host_to_be(reg, rtmp) \
+               rev reg, reg;
+       #define be_to_host(reg, rtmp) \
+               rev reg, reg;
+#else
+       #define host_to_be(reg, rtmp) \
+               eor     rtmp, reg, reg, ror #16; \
+               mov     rtmp, rtmp, lsr #8; \
+               bic     rtmp, rtmp, #65280; \
+               eor     reg, rtmp, reg, ror #8;
+       #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
+       #define ldr_unaligned_host ldr_unaligned_be
+       #define str_unaligned_host str_unaligned_be
+
+       /* nop on big-endian */
+       #define host_to_be(reg, rtmp) /*_*/
+       #define be_to_host(reg, rtmp) /*_*/
+#endif
+
+#define host_to_host(x, y) /*_*/
+
+/**********************************************************************
+  1-way cast5
+ **********************************************************************/
+
+#define dummy(n) /*_*/
+
+#define load_kr(n) \
+       ldr RKR, [CTX, #(Kr_arm_enc + (n))]; /* Kr[n] */
+
+#define load_dec_kr(n) \
+       ldr RKR, [CTX, #(Kr_arm_dec + (n) - 3)]; /* Kr[n] */
+
+#define load_km(n) \
+       ldr RKM, [CTX, #(Km + (n) * 4)]; /* Km[n] */
+
+#define shift_kr(dummy) \
+       mov RKR, RKR, lsr #8;
+
+#define F(n, rl, rr, op1, op2, op3, op4, dec, loadkm, shiftkr, loadkr) \
+       op1 RKM, rr; \
+       mov RKM, RKM, ror RKR; \
+       \
+       and RT0, RMASK, RKM, ror #(24); \
+       and RT1, RMASK, RKM, lsr #(16); \
+       and RT2, RMASK, RKM, lsr #(8); \
+       ldr RT0, [Rs1, RT0]; \
+       and RT3, RMASK, RKM; \
+       ldr RT1, [Rs2, RT1]; \
+       shiftkr(RKR); \
+       \
+       ldr RT2, [Rs3, RT2]; \
+       \
+       op2 RT0, RT1; \
+       ldr RT3, [Rs4, RT3]; \
+       op3 RT0, RT2; \
+       loadkm((n) + (1 - ((dec) * 2))); \
+       op4 RT0, RT3; \
+       loadkr((n) + (1 - ((dec) * 2))); \
+       eor rl, RT0;
+
+#define F1(n, rl, rr, dec, loadkm, shiftkr, loadkr) \
+       F(n, rl, rr, add, eor, sub, add, dec, loadkm, shiftkr, loadkr)
+#define F2(n, rl, rr, dec, loadkm, shiftkr, loadkr) \
+       F(n, rl, rr, eor, sub, add, eor, dec, loadkm, shiftkr, loadkr)
+#define F3(n, rl, rr, dec, loadkm, shiftkr, loadkr) \
+       F(n, rl, rr, sub, add, eor, sub, dec, loadkm, shiftkr, loadkr)
+
+#define enc_round(n, Fx, rl, rr, loadkm, shiftkr, loadkr) \
+       Fx(n, rl, rr, 0, loadkm, shiftkr, loadkr)
+
+#define dec_round(n, Fx, rl, rr, loadkm, shiftkr, loadkr) \
+       Fx(n, rl, rr, 1, loadkm, shiftkr, loadkr)
+
+#define read_block_aligned(rin, offs, l0, r0, convert, rtmp) \
+       ldr l0, [rin, #((offs) + 0)]; \
+       ldr r0, [rin, #((offs) + 4)]; \
+       convert(l0, rtmp); \
+       convert(r0, rtmp);
+
+#define write_block_aligned(rout, offs, l0, r0, convert, rtmp) \
+       convert(l0, rtmp); \
+       convert(r0, rtmp); \
+       str l0, [rout, #((offs) + 0)]; \
+       str r0, [rout, #((offs) + 4)];
+
+#ifdef __ARM_FEATURE_UNALIGNED
+       /* unaligned word reads allowed */
+       #define read_block(rin, offs, l0, r0, rtmp0) \
+               read_block_aligned(rin, offs, l0, r0, host_to_be, rtmp0)
+
+       #define write_block(rout, offs, r0, l0, rtmp0, rtmp1) \
+               write_block_aligned(rout, offs, r0, l0, be_to_host, rtmp0)
+
+       #define read_block_host(rin, offs, l0, r0, rtmp0) \
+               read_block_aligned(rin, offs, l0, r0, host_to_host, rtmp0)
+
+       #define write_block_host(rout, offs, r0, l0, rtmp0, rtmp1) \
+               write_block_aligned(rout, offs, r0, l0, host_to_host, rtmp0)
+#else
+       /* need to handle unaligned reads by byte reads */
+       #define read_block(rin, offs, l0, r0, rtmp0) \
+               tst rin, #3; \
+               beq 1f; \
+                       ldr_unaligned_be(l0, rin, (offs) + 0, rtmp0); \
+                       ldr_unaligned_be(r0, rin, (offs) + 4, rtmp0); \
+                       b 2f; \
+               1:;\
+                       read_block_aligned(rin, offs, l0, r0, host_to_be, rtmp0); \
+               2:;
+
+       #define write_block(rout, offs, l0, r0, rtmp0, rtmp1) \
+               tst rout, #3; \
+               beq 1f; \
+                       str_unaligned_be(l0, rout, (offs) + 0, rtmp0, rtmp1); \
+                       str_unaligned_be(r0, rout, (offs) + 4, rtmp0, rtmp1); \
+                       b 2f; \
+               1:;\
+                       write_block_aligned(rout, offs, l0, r0, be_to_host, rtmp0); \
+               2:;
+
+       #define read_block_host(rin, offs, l0, r0, rtmp0) \
+               tst rin, #3; \
+               beq 1f; \
+                       ldr_unaligned_host(l0, rin, (offs) + 0, rtmp0); \
+                       ldr_unaligned_host(r0, rin, (offs) + 4, rtmp0); \
+                       b 2f; \
+               1:;\
+                       read_block_aligned(rin, offs, l0, r0, host_to_host, rtmp0); \
+               2:;
+
+       #define write_block_host(rout, offs, l0, r0, rtmp0, rtmp1) \
+               tst rout, #3; \
+               beq 1f; \
+                       str_unaligned_host(l0, rout, (offs) + 0, rtmp0, rtmp1); \
+                       str_unaligned_host(r0, rout, (offs) + 4, rtmp0, rtmp1); \
+                       b 2f; \
+               1:;\
+                       write_block_aligned(rout, offs, l0, r0, host_to_host, rtmp0); \
+               2:;
+#endif
+
+.align 3
+.globl _gcry_cast5_arm_encrypt_block
+.type  _gcry_cast5_arm_encrypt_block,%function;
+
+_gcry_cast5_arm_encrypt_block:
+       /* input:
+        *      %r0: CTX
+        *      %r1: dst
+        *      %r2: src
+        */
+       push {%r1, %r4-%r11, %ip, %lr};
+
+       ldr Rs1, =_gcry_cast5_s1to4;
+       mov RMASK, #(0xff << 2);
+       add Rs2, Rs1, #(0x100*4);
+       add Rs3, Rs1, #(0x100*4*2);
+       add Rs4, Rs1, #(0x100*4*3);
+
+       read_block(%r2, 0, RL0, RR0, RT0);
+
+       load_km(0);
+       load_kr(0);
+       enc_round(0, F1, RL0, RR0, load_km, shift_kr, dummy);
+       enc_round(1, F2, RR0, RL0, load_km, shift_kr, dummy);
+       enc_round(2, F3, RL0, RR0, load_km, shift_kr, dummy);
+       enc_round(3, F1, RR0, RL0, load_km, dummy, load_kr);
+       enc_round(4, F2, RL0, RR0, load_km, shift_kr, dummy);
+       enc_round(5, F3, RR0, RL0, load_km, shift_kr, dummy);
+       enc_round(6, F1, RL0, RR0, load_km, shift_kr, dummy);
+       enc_round(7, F2, RR0, RL0, load_km, dummy, load_kr);
+       enc_round(8, F3, RL0, RR0, load_km, shift_kr, dummy);
+       enc_round(9, F1, RR0, RL0, load_km, shift_kr, dummy);
+       enc_round(10, F2, RL0, RR0, load_km, shift_kr, dummy);
+       enc_round(11, F3, RR0, RL0, load_km, dummy, load_kr);
+       enc_round(12, F1, RL0, RR0, load_km, shift_kr, dummy);
+       enc_round(13, F2, RR0, RL0, load_km, shift_kr, dummy);
+       enc_round(14, F3, RL0, RR0, load_km, shift_kr, dummy);
+       enc_round(15, F1, RR0, RL0, dummy, dummy, dummy);
+
+       ldr %r1, [%sp], #4;
+       write_block(%r1, 0, RR0, RL0, RT0, RT1);
+
+       pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_cast5_arm_encrypt_block,.-_gcry_cast5_arm_encrypt_block;
+
+.align 3
+.globl _gcry_cast5_arm_decrypt_block
+.type  _gcry_cast5_arm_decrypt_block,%function;
+
+_gcry_cast5_arm_decrypt_block:
+       /* input:
+        *      %r0: CTX
+        *      %r1: dst
+        *      %r2: src
+        */
+       push {%r1, %r4-%r11, %ip, %lr};
+
+       ldr Rs1, =_gcry_cast5_s1to4;
+       mov RMASK, #(0xff << 2);
+       add Rs2, Rs1, #(0x100 * 4);
+       add Rs3, Rs1, #(0x100 * 4 * 2);
+       add Rs4, Rs1, #(0x100 * 4 * 3);
+
+       read_block(%r2, 0, RL0, RR0, RT0);
+
+       load_km(15);
+       load_dec_kr(15);
+       dec_round(15, F1, RL0, RR0, load_km, shift_kr, dummy);
+       dec_round(14, F3, RR0, RL0, load_km, shift_kr, dummy);
+       dec_round(13, F2, RL0, RR0, load_km, shift_kr, dummy);
+       dec_round(12, F1, RR0, RL0, load_km, dummy, load_dec_kr);
+       dec_round(11, F3, RL0, RR0, load_km, shift_kr, dummy);
+       dec_round(10, F2, RR0, RL0, load_km, shift_kr, dummy);
+       dec_round(9, F1, RL0, RR0, load_km, shift_kr, dummy);
+       dec_round(8, F3, RR0, RL0, load_km, dummy, load_dec_kr);
+       dec_round(7, F2, RL0, RR0, load_km, shift_kr, dummy);
+       dec_round(6, F1, RR0, RL0, load_km, shift_kr, dummy);
+       dec_round(5, F3, RL0, RR0, load_km, shift_kr, dummy);
+       dec_round(4, F2, RR0, RL0, load_km, dummy, load_dec_kr);
+       dec_round(3, F1, RL0, RR0, load_km, shift_kr, dummy);
+       dec_round(2, F3, RR0, RL0, load_km, shift_kr, dummy);
+       dec_round(1, F2, RL0, RR0, load_km, shift_kr, dummy);
+       dec_round(0, F1, RR0, RL0, dummy, dummy, dummy);
+
+       ldr %r1, [%sp], #4;
+       write_block(%r1, 0, RR0, RL0, RT0, RT1);
+
+       pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_cast5_arm_decrypt_block,.-_gcry_cast5_arm_decrypt_block;
+
+/**********************************************************************
+  2-way cast5
+ **********************************************************************/
+
+#define F_2w(n, rl0, rr0, rl1, rr1, op1, op2, op3, op4, dec, loadkm, shiftkr, \
+            loadkr) \
+       op1 RT3, RKM, rr0; \
+       op1 RKM, RKM, rr1; \
+       mov RT3, RT3, ror RKR; \
+       mov RKM, RKM, ror RKR; \
+       \
+       and RT0, RMASK, RT3, ror #(24); \
+       and RT1, RMASK, RT3, lsr #(16); \
+       and RT2, RMASK, RT3, lsr #(8); \
+       and RT3, RMASK, RT3; \
+       \
+       ldr RT0, [Rs1, RT0]; \
+       add RT2, #(0x100 * 4); \
+       ldr RT1, [Rs2, RT1]; \
+       add RT3, #(0x100 * 4 * 2); \
+       \
+       ldr RT2, [Rs2, RT2]; \
+       \
+       op2 RT0, RT1; \
+       ldr RT3, [Rs2, RT3]; \
+       and RT1, RMASK, RKM, ror #(24); \
+       op3 RT0, RT2; \
+       and RT2, RMASK, RKM, lsr #(16); \
+       op4 RT0, RT3; \
+       and RT3, RMASK, RKM, lsr #(8); \
+       eor rl0, RT0; \
+       add RT3, #(0x100 * 4); \
+       ldr RT1, [Rs1, RT1]; \
+       and RT0, RMASK, RKM; \
+       ldr RT2, [Rs2, RT2]; \
+       add RT0, #(0x100 * 4 * 2); \
+       \
+       ldr RT3, [Rs2, RT3]; \
+       \
+       op2 RT1, RT2; \
+       ldr RT0, [Rs2, RT0]; \
+       op3 RT1, RT3; \
+       loadkm((n) + (1 - ((dec) * 2))); \
+       op4 RT1, RT0; \
+       loadkr((n) + (1 - ((dec) * 2))); \
+       shiftkr(RKR); \
+       eor rl1, RT1;
+
+#define F1_2w(n, rl0, rr0, rl1, rr1, dec, loadkm, shiftkr, loadkr) \
+       F_2w(n, rl0, rr0, rl1, rr1, add, eor, sub, add, dec, \
+            loadkm, shiftkr, loadkr)
+#define F2_2w(n, rl0, rr0, rl1, rr1, dec, loadkm, shiftkr, loadkr) \
+       F_2w(n, rl0, rr0, rl1, rr1, eor, sub, add, eor, dec, \
+            loadkm, shiftkr, loadkr)
+#define F3_2w(n, rl0, rr0, rl1, rr1, dec, loadkm, shiftkr, loadkr) \
+       F_2w(n, rl0, rr0, rl1, rr1, sub, add, eor, sub, dec, \
+            loadkm, shiftkr, loadkr)
+
+#define enc_round2(n, Fx, rl, rr, loadkm, shiftkr, loadkr) \
+       Fx##_2w(n, rl##0, rr##0, rl##1, rr##1, 0, loadkm, shiftkr, loadkr)
+
+#define dec_round2(n, Fx, rl, rr, loadkm, shiftkr, loadkr) \
+       Fx##_2w(n, rl##0, rr##0, rl##1, rr##1, 1, loadkm, shiftkr, loadkr)
+
+#define read_block2_aligned(rin, l0, r0, l1, r1, convert, rtmp) \
+       ldr l0, [rin, #(0)]; \
+       ldr r0, [rin, #(4)]; \
+       convert(l0, rtmp); \
+       ldr l1, [rin, #(8)]; \
+       convert(r0, rtmp); \
+       ldr r1, [rin, #(12)]; \
+       convert(l1, rtmp); \
+       convert(r1, rtmp);
+
+#define write_block2_aligned(rout, l0, r0, l1, r1, convert, rtmp) \
+       convert(l0, rtmp); \
+       convert(r0, rtmp); \
+       convert(l1, rtmp); \
+       str l0, [rout, #(0)]; \
+       convert(r1, rtmp); \
+       str r0, [rout, #(4)]; \
+       str l1, [rout, #(8)]; \
+       str r1, [rout, #(12)];
+
+#ifdef __ARM_FEATURE_UNALIGNED
+       /* unaligned word reads allowed */
+       #define read_block2(rin, l0, r0, l1, r1, rtmp0) \
+               read_block2_aligned(rin, l0, r0, l1, r1, host_to_be, rtmp0)
+
+       #define write_block2(rout, l0, r0, l1, r1, rtmp0, rtmp1) \
+               write_block2_aligned(rout, l0, r0, l1, r1, be_to_host, rtmp0)
+
+       #define read_block2_host(rin, l0, r0, l1, r1, rtmp0) \
+               read_block2_aligned(rin, l0, r0, l1, r1, host_to_host, rtmp0)
+
+       #define write_block2_host(rout, l0, r0, l1, r1, rtmp0, rtmp1) \
+               write_block2_aligned(rout, l0, r0, l1, r1, host_to_host, rtmp0)
+#else
+       /* need to handle unaligned reads by byte reads */
+       #define read_block2(rin, l0, r0, l1, r1, rtmp0) \
+               tst rin, #3; \
+               beq 1f; \
+                       ldr_unaligned_be(l0, rin, 0, rtmp0); \
+                       ldr_unaligned_be(r0, rin, 4, rtmp0); \
+                       ldr_unaligned_be(l1, rin, 8, rtmp0); \
+                       ldr_unaligned_be(r1, rin, 12, rtmp0); \
+                       b 2f; \
+               1:;\
+                       read_block2_aligned(rin, l0, r0, l1, r1, host_to_be, rtmp0); \
+               2:;
+
+       #define write_block2(rout, l0, r0, l1, r1, rtmp0, rtmp1) \
+               tst rout, #3; \
+               beq 1f; \
+                       str_unaligned_be(l0, rout, 0, rtmp0, rtmp1); \
+                       str_unaligned_be(r0, rout, 4, rtmp0, rtmp1); \
+                       str_unaligned_be(l1, rout, 8, rtmp0, rtmp1); \
+                       str_unaligned_be(r1, rout, 12, rtmp0, rtmp1); \
+                       b 2f; \
+               1:;\
+                       write_block2_aligned(rout, l0, r0, l1, r1, be_to_host, rtmp0); \
+               2:;
+
+       #define read_block2_host(rin, l0, r0, l1, r1, rtmp0) \
+               tst rin, #3; \
+               beq 1f; \
+                       ldr_unaligned_host(l0, rin, 0, rtmp0); \
+                       ldr_unaligned_host(r0, rin, 4, rtmp0); \
+                       ldr_unaligned_host(l1, rin, 8, rtmp0); \
+                       ldr_unaligned_host(r1, rin, 12, rtmp0); \
+                       b 2f; \
+               1:;\
+                       read_block2_aligned(rin, l0, r0, l1, r1, host_to_host, rtmp0); \
+               2:;
+
+       #define write_block2_host(rout, l0, r0, l1, r1, rtmp0, rtmp1) \
+               tst rout, #3; \
+               beq 1f; \
+                       str_unaligned_host(l0, rout, 0, rtmp0, rtmp1); \
+                       str_unaligned_host(r0, rout, 4, rtmp0, rtmp1); \
+                       str_unaligned_host(l1, rout, 8, rtmp0, rtmp1); \
+                       str_unaligned_host(r1, rout, 12, rtmp0, rtmp1); \
+                       b 2f; \
+               1:;\
+                       write_block2_aligned(rout, l0, r0, l1, r1, host_to_host, rtmp0); \
+               2:;
+#endif
+
+.align 3
+.type  _gcry_cast5_arm_enc_blk2,%function;
+
+_gcry_cast5_arm_enc_blk2:
+       /* input:
+        *      preloaded: CTX
+        *      [RL0, RR0], [RL1, RR1]: src
+        * output:
+        *      [RR0, RL0], [RR1, RL1]: dst
+        */
+       push {%lr};
+
+       ldr Rs1, =_gcry_cast5_s1to4;
+       mov RMASK, #(0xff << 2);
+       add Rs2, Rs1, #(0x100 * 4);
+
+       load_km(0);
+       load_kr(0);
+       enc_round2(0, F1, RL, RR, load_km, shift_kr, dummy);
+       enc_round2(1, F2, RR, RL, load_km, shift_kr, dummy);
+       enc_round2(2, F3, RL, RR, load_km, shift_kr, dummy);
+       enc_round2(3, F1, RR, RL, load_km, dummy, load_kr);
+       enc_round2(4, F2, RL, RR, load_km, shift_kr, dummy);
+       enc_round2(5, F3, RR, RL, load_km, shift_kr, dummy);
+       enc_round2(6, F1, RL, RR, load_km, shift_kr, dummy);
+       enc_round2(7, F2, RR, RL, load_km, dummy, load_kr);
+       enc_round2(8, F3, RL, RR, load_km, shift_kr, dummy);
+       enc_round2(9, F1, RR, RL, load_km, shift_kr, dummy);
+       enc_round2(10, F2, RL, RR, load_km, shift_kr, dummy);
+       enc_round2(11, F3, RR, RL, load_km, dummy, load_kr);
+       enc_round2(12, F1, RL, RR, load_km, shift_kr, dummy);
+       enc_round2(13, F2, RR, RL, load_km, shift_kr, dummy);
+       enc_round2(14, F3, RL, RR, load_km, shift_kr, dummy);
+       enc_round2(15, F1, RR, RL, dummy, dummy, dummy);
+
+       host_to_be(RR0, RT0);
+       host_to_be(RL0, RT0);
+       host_to_be(RR1, RT0);
+       host_to_be(RL1, RT0);
+
+       pop {%pc};
+.ltorg
+.size _gcry_cast5_arm_enc_blk2,.-_gcry_cast5_arm_enc_blk2;
+
+.align 3
+.globl _gcry_cast5_arm_cfb_dec;
+.type  _gcry_cast5_arm_cfb_dec,%function;
+
+_gcry_cast5_arm_cfb_dec:
+       /* input:
+        *      %r0: CTX
+        *      %r1: dst (2 blocks)
+        *      %r2: src (2 blocks)
+        *      %r3: iv (64bit)
+        */
+       push {%r1, %r2, %r4-%r11, %ip, %lr};
+
+       mov %lr, %r3;
+
+       /* Load input (iv/%r3 is aligned, src/%r2 might not be) */
+       ldm %r3, {RL0, RR0};
+       host_to_be(RL0, RT1);
+       host_to_be(RR0, RT1);
+       read_block(%r2, 0, RL1, RR1, %ip);
+
+       /* Update IV, load src[1] and save to iv[0] */
+       read_block_host(%r2, 8, %r5, %r6, %r7);
+       stm %lr, {%r5, %r6};
+
+       bl _gcry_cast5_arm_enc_blk2;
+       /* result in RR0:RL0, RR1:RL1 = %r4:%r3, %r10:%r9 */
+
+       /* %r0: dst, %r1: %src */
+       pop {%r0, %r1};
+
+       /* dst = src ^ result */
+       read_block2_host(%r1, %r5, %r6, %r7, %r8, %lr);
+       eor %r5, %r4;
+       eor %r6, %r3;
+       eor %r7, %r10;
+       eor %r8, %r9;
+       write_block2_host(%r0, %r5, %r6, %r7, %r8, %r1, %r2);
+
+       pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_cast5_arm_cfb_dec,.-_gcry_cast5_arm_cfb_dec;
+
+.align 3
+.globl _gcry_cast5_arm_ctr_enc;
+.type  _gcry_cast5_arm_ctr_enc,%function;
+
+_gcry_cast5_arm_ctr_enc:
+       /* input:
+        *      %r0: CTX
+        *      %r1: dst (2 blocks)
+        *      %r2: src (2 blocks)
+        *      %r3: iv (64bit, big-endian)
+        */
+       push {%r1, %r2, %r4-%r11, %ip, %lr};
+
+       mov %lr, %r3;
+
+       /* Load IV (big => host endian) */
+       read_block_aligned(%lr, 0, RL0, RR0, be_to_host, RT1);
+
+       /* Construct IVs */
+       adds RR1, RR0, #1; /* +1 */
+       adc RL1, RL0, #0;
+       adds %r6, RR1, #1; /* +2 */
+       adc %r5, RL1, #0;
+
+       /* Store new IV (host => big-endian) */
+       write_block_aligned(%lr, 0, %r5, %r6, host_to_be, RT1);
+
+       bl _gcry_cast5_arm_enc_blk2;
+       /* result in RR0:RL0, RR1:RL1 = %r4:%r3, %r10:%r9 */
+
+       /* %r0: dst, %r1: %src */
+       pop {%r0, %r1};
+
+       /* XOR key-stream with plaintext */
+       read_block2_host(%r1, %r5, %r6, %r7, %r8, %lr);
+       eor %r5, %r4;
+       eor %r6, %r3;
+       eor %r7, %r10;
+       eor %r8, %r9;
+       write_block2_host(%r0, %r5, %r6, %r7, %r8, %r1, %r2);
+
+       pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_cast5_arm_ctr_enc,.-_gcry_cast5_arm_ctr_enc;
+
+.align 3
+.type  _gcry_cast5_arm_dec_blk2,%function;
+
+_gcry_cast5_arm_dec_blk2:
+       /* input:
+        *      preloaded: CTX
+        *      [RL0, RR0], [RL1, RR1]: src
+        * output:
+        *      [RR0, RL0], [RR1, RL1]: dst
+        */
+
+       ldr Rs1, =_gcry_cast5_s1to4;
+       mov RMASK, #(0xff << 2);
+       add Rs2, Rs1, #(0x100 * 4);
+
+       load_km(15);
+       load_dec_kr(15);
+       dec_round2(15, F1, RL, RR, load_km, shift_kr, dummy);
+       dec_round2(14, F3, RR, RL, load_km, shift_kr, dummy);
+       dec_round2(13, F2, RL, RR, load_km, shift_kr, dummy);
+       dec_round2(12, F1, RR, RL, load_km, dummy, load_dec_kr);
+       dec_round2(11, F3, RL, RR, load_km, shift_kr, dummy);
+       dec_round2(10, F2, RR, RL, load_km, shift_kr, dummy);
+       dec_round2(9, F1, RL, RR, load_km, shift_kr, dummy);
+       dec_round2(8, F3, RR, RL, load_km, dummy, load_dec_kr);
+       dec_round2(7, F2, RL, RR, load_km, shift_kr, dummy);
+       dec_round2(6, F1, RR, RL, load_km, shift_kr, dummy);
+       dec_round2(5, F3, RL, RR, load_km, shift_kr, dummy);
+       dec_round2(4, F2, RR, RL, load_km, dummy, load_dec_kr);
+       dec_round2(3, F1, RL, RR, load_km, shift_kr, dummy);
+       dec_round2(2, F3, RR, RL, load_km, shift_kr, dummy);
+       dec_round2(1, F2, RL, RR, load_km, shift_kr, dummy);
+       dec_round2(0, F1, RR, RL, dummy, dummy, dummy);
+
+       host_to_be(RR0, RT0);
+       host_to_be(RL0, RT0);
+       host_to_be(RR1, RT0);
+       host_to_be(RL1, RT0);
+
+       b .Ldec_cbc_tail;
+.ltorg
+.size _gcry_cast5_arm_dec_blk2,.-_gcry_cast5_arm_dec_blk2;
+
+.align 3
+.globl _gcry_cast5_arm_cbc_dec;
+.type  _gcry_cast5_arm_cbc_dec,%function;
+
+_gcry_cast5_arm_cbc_dec:
+       /* input:
+        *      %r0: CTX
+        *      %r1: dst (2 blocks)
+        *      %r2: src (2 blocks)
+        *      %r3: iv (64bit)
+        */
+       push {%r1-%r11, %ip, %lr};
+
+       read_block2(%r2, RL0, RR0, RL1, RR1, RT0);
+
+       /* dec_blk2 is only used by cbc_dec, jump directly in/out instead
+        * of function call. */
+       b _gcry_cast5_arm_dec_blk2;
+.Ldec_cbc_tail:
+       /* result in RR0:RL0, RR1:RL1 = %r4:%r3, %r10:%r9 */
+
+       /* %r0: dst, %r1: %src, %r2: iv */
+       pop {%r0-%r2};
+
+       /* load IV+1 (src[0]) to %r7:%r8. Might be unaligned. */
+       read_block_host(%r1, 0, %r7, %r8, %r5);
+       /* load IV (iv[0]) to %r5:%r6. 'iv' is aligned. */
+       ldm %r2, {%r5, %r6};
+
+       /* out[1] ^= IV+1 */
+       eor %r10, %r7;
+       eor %r9, %r8;
+       /* out[0] ^= IV */
+       eor %r4, %r5;
+       eor %r3, %r6;
+
+       /* load IV+2 (src[1]) to %r7:%r8. Might be unaligned. */
+       read_block_host(%r1, 8, %r7, %r8, %r5);
+       /* store IV+2 to iv[0] (aligned). */
+       stm %r2, {%r7, %r8};
+
+       /* store result to dst[0-3]. Might be unaligned. */
+       write_block2_host(%r0, %r4, %r3, %r10, %r9, %r5, %r6);
+
+       pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_cast5_arm_cbc_dec,.-_gcry_cast5_arm_cbc_dec;
+
+#endif /*HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS*/
+#endif /*__ARM_ARCH >= 6*/
index 9905f5c..115e1e6 100644 (file)
 #include "g10lib.h"
 #include "types.h"
 #include "cipher.h"
+#include "bithelp.h"
+#include "bufhelp.h"
+#include "cipher-selftest.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)
+# define USE_AMD64_ASM 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
 
 #define CAST5_BLOCKSIZE 8
 
 typedef struct {
     u32  Km[16];
     byte Kr[16];
+#ifdef USE_ARM_ASM
+    u32 Kr_arm_enc[16 / sizeof(u32)];
+    u32 Kr_arm_dec[16 / sizeof(u32)];
+#endif
 } CAST5_context;
 
 static gcry_err_code_t cast_setkey (void *c, const byte *key, unsigned keylen);
-static void encrypt_block (void *c, byte *outbuf, const byte *inbuf);
-static void decrypt_block (void *c, byte *outbuf, const byte *inbuf);
+static unsigned int encrypt_block (void *c, byte *outbuf, const byte *inbuf);
+static unsigned int decrypt_block (void *c, byte *outbuf, const byte *inbuf);
 
 
 
+#define s1 _gcry_cast5_s1to4[0]
+#define s2 _gcry_cast5_s1to4[1]
+#define s3 _gcry_cast5_s1to4[2]
+#define s4 _gcry_cast5_s1to4[3]
 
-static const u32 s1[256] = {
+const u32 _gcry_cast5_s1to4[4][256] = { {
 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949,
 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e,
 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d,
@@ -90,8 +115,7 @@ static const u32 s1[256] = {
 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e,
 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9,
 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf
-};
-static const u32 s2[256] = {
+}, {
 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651,
 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3,
 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb,
@@ -124,8 +148,7 @@ static const u32 s2[256] = {
 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa,
 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9,
 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1
-};
-static const u32 s3[256] = {
+}, {
 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90,
 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5,
 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e,
@@ -158,8 +181,7 @@ static const u32 s3[256] = {
 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d,
 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a,
 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783
-};
-static const u32 s4[256] = {
+}, {
 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1,
 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf,
 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15,
@@ -192,7 +214,7 @@ static const u32 s4[256] = {
 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04,
 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282,
 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2
-};
+} };
 static const u32 s5[256] = {
 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f,
 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a,
@@ -331,24 +353,107 @@ static const u32 s8[256] = {
 };
 
 
-#if defined(__GNUC__) && defined(__i386__)
-static inline u32
-rol(int n, u32 x)
+#ifdef USE_AMD64_ASM
+
+/* Assembly implementations of CAST5. */
+extern void _gcry_cast5_amd64_encrypt_block(CAST5_context *c, byte *outbuf,
+                                           const byte *inbuf);
+
+extern void _gcry_cast5_amd64_decrypt_block(CAST5_context *c, byte *outbuf,
+                                           const byte *inbuf);
+
+/* These assembly implementations process four blocks in parallel. */
+extern void _gcry_cast5_amd64_ctr_enc(CAST5_context *ctx, byte *out,
+                                     const byte *in, byte *ctr);
+
+extern void _gcry_cast5_amd64_cbc_dec(CAST5_context *ctx, byte *out,
+                                     const byte *in, byte *iv);
+
+extern void _gcry_cast5_amd64_cfb_dec(CAST5_context *ctx, byte *out,
+                                     const byte *in, byte *iv);
+
+static void
+do_encrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf)
 {
-       __asm__("roll %%cl,%0"
-               :"=r" (x)
-               :"0" (x),"c" (n));
-       return x;
+  _gcry_cast5_amd64_encrypt_block (context, outbuf, inbuf);
+}
+
+static void
+do_decrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf)
+{
+  _gcry_cast5_amd64_decrypt_block (context, outbuf, inbuf);
+}
+
+static unsigned int
+encrypt_block (void *context , byte *outbuf, const byte *inbuf)
+{
+  CAST5_context *c = (CAST5_context *) context;
+  do_encrypt_block (c, outbuf, inbuf);
+  return /*burn_stack*/ (2*8);
+}
+
+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);
+  return /*burn_stack*/ (2*8);
 }
-#else
-#define rol(n,x) ( ((x) << (n)) | ((x) >> (32-(n))) )
-#endif
 
-#define F1(D,m,r)  (  (I = ((m) + (D))), (I=rol((r),I)),   \
+#elif defined(USE_ARM_ASM)
+
+/* ARM assembly implementations of CAST5. */
+extern void _gcry_cast5_arm_encrypt_block(CAST5_context *c, byte *outbuf,
+                                           const byte *inbuf);
+
+extern void _gcry_cast5_arm_decrypt_block(CAST5_context *c, byte *outbuf,
+                                           const byte *inbuf);
+
+/* These assembly implementations process two blocks in parallel. */
+extern void _gcry_cast5_arm_ctr_enc(CAST5_context *ctx, byte *out,
+                                     const byte *in, byte *ctr);
+
+extern void _gcry_cast5_arm_cbc_dec(CAST5_context *ctx, byte *out,
+                                     const byte *in, byte *iv);
+
+extern void _gcry_cast5_arm_cfb_dec(CAST5_context *ctx, byte *out,
+                                     const byte *in, byte *iv);
+
+static void
+do_encrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf)
+{
+  _gcry_cast5_arm_encrypt_block (context, outbuf, inbuf);
+}
+
+static void
+do_decrypt_block (CAST5_context *context, byte *outbuf, const byte *inbuf)
+{
+  _gcry_cast5_arm_decrypt_block (context, outbuf, inbuf);
+}
+
+static unsigned int
+encrypt_block (void *context , byte *outbuf, const byte *inbuf)
+{
+  CAST5_context *c = (CAST5_context *) context;
+  do_encrypt_block (c, outbuf, inbuf);
+  return /*burn_stack*/ (10*4);
+}
+
+static unsigned int
+decrypt_block (void *context, byte *outbuf, const byte *inbuf)
+{
+  CAST5_context *c = (CAST5_context *) context;
+  do_decrypt_block (c, outbuf, inbuf);
+  return /*burn_stack*/ (10*4);
+}
+
+#else /*USE_ARM_ASM*/
+
+#define F1(D,m,r)  (  (I = ((m) + (D))), (I=rol(I,(r))),   \
     (((s1[I >> 24] ^ s2[(I>>16)&0xff]) - s3[(I>>8)&0xff]) + s4[I&0xff]) )
-#define F2(D,m,r)  (  (I = ((m) ^ (D))), (I=rol((r),I)),   \
+#define F2(D,m,r)  (  (I = ((m) ^ (D))), (I=rol(I,(r))),   \
     (((s1[I >> 24] - s2[(I>>16)&0xff]) + s3[(I>>8)&0xff]) ^ s4[I&0xff]) )
-#define F3(D,m,r)  (  (I = ((m) - (D))), (I=rol((r),I)),   \
+#define F3(D,m,r)  (  (I = ((m) - (D))), (I=rol(I,(r))),   \
     (((s1[I >> 24] + s2[(I>>16)&0xff]) ^ s3[(I>>8)&0xff]) - s4[I&0xff]) )
 
 static void
@@ -365,8 +470,8 @@ do_encrypt_block( CAST5_context *c, byte *outbuf, const byte *inbuf )
     /* (L0,R0) <-- (m1...m64). (Split the plaintext into left and
      * right 32-bit halves L0 = m1...m32 and R0 = m33...m64.)
      */
-    l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
-    r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
+    l = buf_get_be32(inbuf + 0);
+    r = buf_get_be32(inbuf + 4);
 
     /* (16 rounds) for i from 1 to 16, compute Li and Ri as follows:
      * Li = Ri-1;
@@ -395,22 +500,16 @@ do_encrypt_block( CAST5_context *c, byte *outbuf, const byte *inbuf )
 
     /* c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and
      * concatenate to form the ciphertext.) */
-    outbuf[0] = (r >> 24) & 0xff;
-    outbuf[1] = (r >> 16) & 0xff;
-    outbuf[2] = (r >>  8) & 0xff;
-    outbuf[3] =  r       & 0xff;
-    outbuf[4] = (l >> 24) & 0xff;
-    outbuf[5] = (l >> 16) & 0xff;
-    outbuf[6] = (l >>  8) & 0xff;
-    outbuf[7] =  l       & 0xff;
+    buf_put_be32(outbuf + 0, r);
+    buf_put_be32(outbuf + 4, l);
 }
 
-static void
+static unsigned int
 encrypt_block (void *context , byte *outbuf, const byte *inbuf)
 {
   CAST5_context *c = (CAST5_context *) context;
   do_encrypt_block (c, outbuf, inbuf);
-  _gcry_burn_stack (20+4*sizeof(void*));
+  return /*burn_stack*/ (20+4*sizeof(void*));
 }
 
 
@@ -425,8 +524,8 @@ do_decrypt_block (CAST5_context *c, byte *outbuf, const byte *inbuf )
     Km = c->Km;
     Kr = c->Kr;
 
-    l = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3];
-    r = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7];
+    l = buf_get_be32(inbuf + 0);
+    r = buf_get_be32(inbuf + 4);
 
     t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]);
     t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]);
@@ -445,22 +544,251 @@ do_decrypt_block (CAST5_context *c, byte *outbuf, const byte *inbuf )
     t = l; l = r; r = t ^ F2(r, Km[ 1], Kr[ 1]);
     t = l; l = r; r = t ^ F1(r, Km[ 0], Kr[ 0]);
 
-    outbuf[0] = (r >> 24) & 0xff;
-    outbuf[1] = (r >> 16) & 0xff;
-    outbuf[2] = (r >>  8) & 0xff;
-    outbuf[3] =  r       & 0xff;
-    outbuf[4] = (l >> 24) & 0xff;
-    outbuf[5] = (l >> 16) & 0xff;
-    outbuf[6] = (l >>  8) & 0xff;
-    outbuf[7] =  l       & 0xff;
+    buf_put_be32(outbuf + 0, r);
+    buf_put_be32(outbuf + 4, l);
 }
 
-static void
+static unsigned int
 decrypt_block (void *context, byte *outbuf, const byte *inbuf)
 {
   CAST5_context *c = (CAST5_context *) context;
   do_decrypt_block (c, outbuf, inbuf);
-  _gcry_burn_stack (20+4*sizeof(void*));
+  return /*burn_stack*/ (20+4*sizeof(void*));
+}
+
+#endif /*!USE_ARM_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 CAST5_BLOCKSIZE. */
+void
+_gcry_cast5_ctr_enc(void *context, unsigned char *ctr, void *outbuf_arg,
+                   const void *inbuf_arg, size_t nblocks)
+{
+  CAST5_context *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned char tmpbuf[CAST5_BLOCKSIZE];
+  int burn_stack_depth = (20 + 4 * sizeof(void*)) + 2 * CAST5_BLOCKSIZE;
+
+  int i;
+
+#ifdef USE_AMD64_ASM
+  {
+    if (nblocks >= 4)
+      burn_stack_depth += 8 * sizeof(void*);
+
+    /* Process data in 4 block chunks. */
+    while (nblocks >= 4)
+      {
+        _gcry_cast5_amd64_ctr_enc(ctx, outbuf, inbuf, ctr);
+
+        nblocks -= 4;
+        outbuf += 4 * CAST5_BLOCKSIZE;
+        inbuf  += 4 * CAST5_BLOCKSIZE;
+      }
+
+    /* Use generic code to handle smaller chunks... */
+    /* TODO: use caching instead? */
+  }
+#elif defined(USE_ARM_ASM)
+  {
+    /* Process data in 2 block chunks. */
+    while (nblocks >= 2)
+      {
+        _gcry_cast5_arm_ctr_enc(ctx, outbuf, inbuf, ctr);
+
+        nblocks -= 2;
+        outbuf += 2 * CAST5_BLOCKSIZE;
+        inbuf  += 2 * CAST5_BLOCKSIZE;
+      }
+
+    /* Use generic code to handle smaller chunks... */
+    /* TODO: use caching instead? */
+  }
+#endif
+
+  for ( ;nblocks; nblocks-- )
+    {
+      /* Encrypt the counter. */
+      do_encrypt_block(ctx, tmpbuf, ctr);
+      /* XOR the input with the encrypted counter and store in output.  */
+      buf_xor(outbuf, tmpbuf, inbuf, CAST5_BLOCKSIZE);
+      outbuf += CAST5_BLOCKSIZE;
+      inbuf  += CAST5_BLOCKSIZE;
+      /* Increment the counter.  */
+      for (i = CAST5_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_cast5_cbc_dec(void *context, unsigned char *iv, void *outbuf_arg,
+                   const void *inbuf_arg, size_t nblocks)
+{
+  CAST5_context *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned char savebuf[CAST5_BLOCKSIZE];
+  int burn_stack_depth = (20 + 4 * sizeof(void*)) + 2 * CAST5_BLOCKSIZE;
+
+#ifdef USE_AMD64_ASM
+  {
+    if (nblocks >= 4)
+      burn_stack_depth += 8 * sizeof(void*);
+
+    /* Process data in 4 block chunks. */
+    while (nblocks >= 4)
+      {
+        _gcry_cast5_amd64_cbc_dec(ctx, outbuf, inbuf, iv);
+
+        nblocks -= 4;
+        outbuf += 4 * CAST5_BLOCKSIZE;
+        inbuf  += 4 * CAST5_BLOCKSIZE;
+      }
+
+    /* Use generic code to handle smaller chunks... */
+  }
+#elif defined(USE_ARM_ASM)
+  {
+    /* Process data in 2 block chunks. */
+    while (nblocks >= 2)
+      {
+        _gcry_cast5_arm_cbc_dec(ctx, outbuf, inbuf, iv);
+
+        nblocks -= 2;
+        outbuf += 2 * CAST5_BLOCKSIZE;
+        inbuf  += 2 * CAST5_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.  */
+      do_decrypt_block (ctx, savebuf, inbuf);
+
+      buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, CAST5_BLOCKSIZE);
+      inbuf += CAST5_BLOCKSIZE;
+      outbuf += CAST5_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_cast5_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg,
+                   const void *inbuf_arg, size_t nblocks)
+{
+  CAST5_context *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  int burn_stack_depth = (20 + 4 * sizeof(void*)) + 2 * CAST5_BLOCKSIZE;
+
+#ifdef USE_AMD64_ASM
+  {
+    if (nblocks >= 4)
+      burn_stack_depth += 8 * sizeof(void*);
+
+    /* Process data in 4 block chunks. */
+    while (nblocks >= 4)
+      {
+        _gcry_cast5_amd64_cfb_dec(ctx, outbuf, inbuf, iv);
+
+        nblocks -= 4;
+        outbuf += 4 * CAST5_BLOCKSIZE;
+        inbuf  += 4 * CAST5_BLOCKSIZE;
+      }
+
+    /* Use generic code to handle smaller chunks... */
+  }
+#elif defined(USE_ARM_ASM)
+  {
+    /* Process data in 2 block chunks. */
+    while (nblocks >= 2)
+      {
+        _gcry_cast5_arm_cfb_dec(ctx, outbuf, inbuf, iv);
+
+        nblocks -= 2;
+        outbuf += 2 * CAST5_BLOCKSIZE;
+        inbuf  += 2 * CAST5_BLOCKSIZE;
+      }
+
+    /* Use generic code to handle smaller chunks... */
+  }
+#endif
+
+  for ( ;nblocks; nblocks-- )
+    {
+      do_encrypt_block(ctx, iv, iv);
+      buf_xor_n_copy(outbuf, iv, inbuf, CAST5_BLOCKSIZE);
+      outbuf += CAST5_BLOCKSIZE;
+      inbuf  += CAST5_BLOCKSIZE;
+    }
+
+  _gcry_burn_stack(burn_stack_depth);
+}
+
+
+/* Run the self-tests for CAST5-CTR, tests IV increment of bulk CTR
+   encryption.  Returns NULL on success. */
+static const char *
+selftest_ctr (void)
+{
+  const int nblocks = 4+1;
+  const int blocksize = CAST5_BLOCKSIZE;
+  const int context_size = sizeof(CAST5_context);
+
+  return _gcry_selftest_helper_ctr("CAST5", &cast_setkey,
+           &encrypt_block, &_gcry_cast5_ctr_enc, nblocks, blocksize,
+          context_size);
+}
+
+
+/* Run the self-tests for CAST5-CBC, tests bulk CBC decryption.
+   Returns NULL on success. */
+static const char *
+selftest_cbc (void)
+{
+  const int nblocks = 4+2;
+  const int blocksize = CAST5_BLOCKSIZE;
+  const int context_size = sizeof(CAST5_context);
+
+  return _gcry_selftest_helper_cbc("CAST5", &cast_setkey,
+           &encrypt_block, &_gcry_cast5_cbc_dec, nblocks, blocksize,
+          context_size);
+}
+
+
+/* Run the self-tests for CAST5-CFB, tests bulk CBC decryption.
+   Returns NULL on success. */
+static const char *
+selftest_cfb (void)
+{
+  const int nblocks = 4+2;
+  const int blocksize = CAST5_BLOCKSIZE;
+  const int context_size = sizeof(CAST5_context);
+
+  return _gcry_selftest_helper_cfb("CAST5", &cast_setkey,
+           &encrypt_block, &_gcry_cast5_cfb_dec, nblocks, blocksize,
+          context_size);
 }
 
 
@@ -468,11 +796,15 @@ static const char*
 selftest(void)
 {
     CAST5_context c;
-    byte key[16]  = { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
+    static const byte key[16] =
+                    { 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78,
                      0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A  };
-    byte plain[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
-    byte cipher[8]= { 0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2 };
+    static const byte plain[8] =
+                    { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
+    static const byte cipher[8] =
+                    { 0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2 };
     byte buffer[8];
+    const char *r;
 
     cast_setkey( &c, key, 16 );
     encrypt_block( &c, buffer, plain );
@@ -507,6 +839,16 @@ selftest(void)
 
     }
 #endif
+
+    if ( (r = selftest_cbc ()) )
+      return r;
+
+    if ( (r = selftest_cfb ()) )
+      return r;
+
+    if ( (r = selftest_ctr ()) )
+      return r;
+
     return NULL;
 }
 
@@ -582,10 +924,10 @@ do_cast_setkey( CAST5_context *c, const byte *key, unsigned keylen )
   if( keylen != 16 )
     return GPG_ERR_INV_KEYLEN;
 
-  x[0] = key[0]  << 24 | key[1]  << 16 | key[2]  << 8 | key[3];
-  x[1] = key[4]  << 24 | key[5]  << 16 | key[6]  << 8 | key[7];
-  x[2] = key[8]  << 24 | key[9]  << 16 | key[10] << 8 | key[11];
-  x[3] = key[12] << 24 | key[13] << 16 | key[14] << 8 | key[15];
+  x[0] = buf_get_be32(key + 0);
+  x[1] = buf_get_be32(key + 4);
+  x[2] = buf_get_be32(key + 8);
+  x[3] = buf_get_be32(key + 12);
 
   key_schedule( x, z, k );
   for(i=0; i < 16; i++ )
@@ -594,9 +936,35 @@ do_cast_setkey( CAST5_context *c, const byte *key, unsigned keylen )
   for(i=0; i < 16; i++ )
     c->Kr[i] = k[i] & 0x1f;
 
-  memset(&x,0, sizeof x);
-  memset(&z,0, sizeof z);
-  memset(&k,0, sizeof k);
+#ifdef USE_ARM_ASM
+  for (i = 0; i < 4; i++)
+    {
+      byte Kr_arm[4];
+
+      /* Convert rotate left to rotate right and add shift left
+       * by 2.  */
+      Kr_arm[0] = ((32 - c->Kr[4 * i + 0]) - 2) & 0x1f;
+      Kr_arm[1] = ((32 - c->Kr[4 * i + 1]) - 2) & 0x1f;
+      Kr_arm[2] = ((32 - c->Kr[4 * i + 2]) - 2) & 0x1f;
+      Kr_arm[3] = ((32 - c->Kr[4 * i + 3]) - 2) & 0x1f;
+
+      /* Endian friendly store.  */
+      c->Kr_arm_enc[i] = Kr_arm[0] |
+                        (Kr_arm[1] << 8) |
+                        (Kr_arm[2] << 16) |
+                        (Kr_arm[3] << 24);
+      c->Kr_arm_dec[i] = Kr_arm[3] |
+                        (Kr_arm[2] << 8) |
+                        (Kr_arm[1] << 16) |
+                        (Kr_arm[0] << 24);
+
+      wipememory(Kr_arm, sizeof(Kr_arm));
+    }
+#endif
+
+  wipememory(x, sizeof x);
+  wipememory(z, sizeof z);
+  wipememory(k, sizeof k);
 
 #undef xi
 #undef zi
@@ -608,13 +976,13 @@ cast_setkey (void *context, const byte *key, unsigned keylen )
 {
   CAST5_context *c = (CAST5_context *) context;
   gcry_err_code_t rc = do_cast_setkey (c, key, keylen);
-  _gcry_burn_stack (96+7*sizeof(void*));
   return rc;
 }
 
 
 gcry_cipher_spec_t _gcry_cipher_spec_cast5 =
   {
+    GCRY_CIPHER_CAST5, {0, 0},
     "CAST5", NULL, NULL, CAST5_BLOCKSIZE, 128, sizeof (CAST5_context),
     cast_setkey, encrypt_block, decrypt_block
   };
diff --git a/cipher/cipher-aeswrap.c b/cipher/cipher-aeswrap.c
new file mode 100644 (file)
index 0000000..50ac107
--- /dev/null
@@ -0,0 +1,210 @@
+/* cipher-aeswrap.c  - Generic AESWRAP mode implementation
+ * Copyright (C) 2009, 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/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "ath.h"
+#include "bufhelp.h"
+#include "./cipher-internal.h"
+
+
+/* Perform the AES-Wrap algorithm as specified by RFC3394.  We
+   implement this as a mode usable with any cipher algorithm of
+   blocksize 128.  */
+gcry_err_code_t
+_gcry_cipher_aeswrap_encrypt (gcry_cipher_hd_t c,
+                              byte *outbuf, size_t outbuflen,
+                              const byte *inbuf, size_t inbuflen )
+{
+  int j, x;
+  size_t n, i;
+  unsigned char *r, *a, *b;
+  unsigned char t[8];
+  unsigned int burn, nburn;
+
+#if MAX_BLOCKSIZE < 8
+#error Invalid block size
+#endif
+  /* We require a cipher with a 128 bit block length.  */
+  if (c->spec->blocksize != 16)
+    return GPG_ERR_INV_LENGTH;
+
+  /* The output buffer must be able to hold the input data plus one
+     additional block.  */
+  if (outbuflen < inbuflen + 8)
+    return GPG_ERR_BUFFER_TOO_SHORT;
+  /* Input data must be multiple of 64 bits.  */
+  if (inbuflen % 8)
+    return GPG_ERR_INV_ARG;
+
+  n = inbuflen / 8;
+
+  /* We need at least two 64 bit blocks.  */
+  if (n < 2)
+    return GPG_ERR_INV_ARG;
+
+  burn = 0;
+
+  r = outbuf;
+  a = outbuf;  /* We store A directly in OUTBUF.  */
+  b = c->u_ctr.ctr;  /* B is also used to concatenate stuff.  */
+
+  /* If an IV has been set we use that IV as the Alternative Initial
+     Value; if it has not been set we use the standard value.  */
+  if (c->marks.iv)
+    memcpy (a, c->u_iv.iv, 8);
+  else
+    memset (a, 0xa6, 8);
+
+  /* Copy the inbuf to the outbuf. */
+  memmove (r+8, inbuf, inbuflen);
+
+  memset (t, 0, sizeof t); /* t := 0.  */
+
+  for (j = 0; j <= 5; j++)
+    {
+      for (i = 1; i <= n; i++)
+        {
+          /* B := AES_k( A | R[i] ) */
+          memcpy (b, a, 8);
+          memcpy (b+8, r+i*8, 8);
+          nburn = c->spec->encrypt (&c->context.c, b, b);
+          burn = nburn > burn ? nburn : burn;
+          /* t := t + 1  */
+         for (x = 7; x >= 0; x--)
+           {
+             t[x]++;
+             if (t[x])
+               break;
+           }
+          /* A := MSB_64(B) ^ t */
+         buf_xor(a, b, t, 8);
+          /* R[i] := LSB_64(B) */
+          memcpy (r+i*8, b+8, 8);
+        }
+   }
+
+  if (burn > 0)
+    _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+  return 0;
+}
+
+/* Perform the AES-Unwrap algorithm as specified by RFC3394.  We
+   implement this as a mode usable with any cipher algorithm of
+   blocksize 128.  */
+gcry_err_code_t
+_gcry_cipher_aeswrap_decrypt (gcry_cipher_hd_t c,
+                              byte *outbuf, size_t outbuflen,
+                              const byte *inbuf, size_t inbuflen)
+{
+  int j, x;
+  size_t n, i;
+  unsigned char *r, *a, *b;
+  unsigned char t[8];
+  unsigned int burn, nburn;
+
+#if MAX_BLOCKSIZE < 8
+#error Invalid block size
+#endif
+  /* We require a cipher with a 128 bit block length.  */
+  if (c->spec->blocksize != 16)
+    return GPG_ERR_INV_LENGTH;
+
+  /* The output buffer must be able to hold the input data minus one
+     additional block.  Fixme: The caller has more restrictive checks
+     - we may want to fix them for this mode.  */
+  if (outbuflen + 8  < inbuflen)
+    return GPG_ERR_BUFFER_TOO_SHORT;
+  /* Input data must be multiple of 64 bits.  */
+  if (inbuflen % 8)
+    return GPG_ERR_INV_ARG;
+
+  n = inbuflen / 8;
+
+  /* We need at least three 64 bit blocks.  */
+  if (n < 3)
+    return GPG_ERR_INV_ARG;
+
+  burn = 0;
+
+  r = outbuf;
+  a = c->lastiv;  /* We use c->LASTIV as buffer for A.  */
+  b = c->u_ctr.ctr;     /* B is also used to concatenate stuff.  */
+
+  /* Copy the inbuf to the outbuf and save A. */
+  memcpy (a, inbuf, 8);
+  memmove (r, inbuf+8, inbuflen-8);
+  n--; /* Reduce to actual number of data blocks.  */
+
+  /* t := 6 * n  */
+  i = n * 6;  /* The range is valid because: n = inbuflen / 8 - 1.  */
+  for (x=0; x < 8 && x < sizeof (i); x++)
+    t[7-x] = i >> (8*x);
+  for (; x < 8; x++)
+    t[7-x] = 0;
+
+  for (j = 5; j >= 0; j--)
+    {
+      for (i = n; i >= 1; i--)
+        {
+          /* B := AES_k^1( (A ^ t)| R[i] ) */
+         buf_xor(b, a, t, 8);
+          memcpy (b+8, r+(i-1)*8, 8);
+          nburn = c->spec->decrypt (&c->context.c, b, b);
+          burn = nburn > burn ? nburn : burn;
+          /* t := t - 1  */
+         for (x = 7; x >= 0; x--)
+           {
+             t[x]--;
+             if (t[x] != 0xff)
+               break;
+           }
+          /* A := MSB_64(B) */
+          memcpy (a, b, 8);
+          /* R[i] := LSB_64(B) */
+          memcpy (r+(i-1)*8, b+8, 8);
+        }
+   }
+
+  /* If an IV has been set we compare against this Alternative Initial
+     Value; if it has not been set we compare against the standard IV.  */
+  if (c->marks.iv)
+    j = memcmp (a, c->u_iv.iv, 8);
+  else
+    {
+      for (j=0, x=0; x < 8; x++)
+        if (a[x] != 0xa6)
+          {
+            j=1;
+            break;
+          }
+    }
+
+  if (burn > 0)
+    _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+  return j? GPG_ERR_CHECKSUM : 0;
+}
diff --git a/cipher/cipher-cbc.c b/cipher/cipher-cbc.c
new file mode 100644 (file)
index 0000000..4b929da
--- /dev/null
@@ -0,0 +1,205 @@
+/* cipher-cbc.c  - Generic CBC mode implementation
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ *               2005, 2007, 2008, 2009, 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/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "ath.h"
+#include "./cipher-internal.h"
+#include "bufhelp.h"
+
+
+
+gcry_err_code_t
+_gcry_cipher_cbc_encrypt (gcry_cipher_hd_t c,
+                          unsigned char *outbuf, size_t outbuflen,
+                          const unsigned char *inbuf, size_t inbuflen)
+{
+  size_t n;
+  unsigned char *ivp;
+  int i;
+  size_t blocksize = c->spec->blocksize;
+  gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+  size_t nblocks = inbuflen / blocksize;
+  unsigned int burn, nburn;
+
+  if (outbuflen < ((c->flags & GCRY_CIPHER_CBC_MAC)? blocksize : inbuflen))
+    return GPG_ERR_BUFFER_TOO_SHORT;
+
+  if ((inbuflen % blocksize)
+      && !(inbuflen > blocksize
+           && (c->flags & GCRY_CIPHER_CBC_CTS)))
+    return GPG_ERR_INV_LENGTH;
+
+  burn = 0;
+
+  if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
+    {
+      if ((inbuflen % blocksize) == 0)
+       nblocks--;
+    }
+
+  if (c->bulk.cbc_enc)
+    {
+      c->bulk.cbc_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks,
+                       (c->flags & GCRY_CIPHER_CBC_MAC));
+      inbuf  += nblocks * blocksize;
+      if (!(c->flags & GCRY_CIPHER_CBC_MAC))
+        outbuf += nblocks * blocksize;
+    }
+  else
+    {
+      ivp = c->u_iv.iv;
+
+      for (n=0; n < nblocks; n++ )
+        {
+          buf_xor (outbuf, inbuf, ivp, blocksize);
+          nburn = enc_fn ( &c->context.c, outbuf, outbuf );
+          burn = nburn > burn ? nburn : burn;
+          ivp = outbuf;
+          inbuf  += blocksize;
+          if (!(c->flags & GCRY_CIPHER_CBC_MAC))
+            outbuf += blocksize;
+        }
+
+      if (ivp != c->u_iv.iv)
+        buf_cpy (c->u_iv.iv, ivp, blocksize );
+    }
+
+  if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
+    {
+      /* We have to be careful here, since outbuf might be equal to
+         inbuf.  */
+      size_t restbytes;
+      unsigned char b;
+
+      if ((inbuflen % blocksize) == 0)
+        restbytes = blocksize;
+      else
+        restbytes = inbuflen % blocksize;
+
+      outbuf -= blocksize;
+      for (ivp = c->u_iv.iv, i = 0; i < restbytes; i++)
+        {
+          b = inbuf[i];
+          outbuf[blocksize + i] = outbuf[i];
+          outbuf[i] = b ^ *ivp++;
+        }
+      for (; i < blocksize; i++)
+        outbuf[i] = 0 ^ *ivp++;
+
+      nburn = enc_fn (&c->context.c, outbuf, outbuf);
+      burn = nburn > burn ? nburn : burn;
+      buf_cpy (c->u_iv.iv, outbuf, blocksize);
+    }
+
+  if (burn > 0)
+    _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+  return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_cbc_decrypt (gcry_cipher_hd_t c,
+                          unsigned char *outbuf, size_t outbuflen,
+                          const unsigned char *inbuf, size_t inbuflen)
+{
+  size_t n;
+  int i;
+  size_t blocksize = c->spec->blocksize;
+  gcry_cipher_decrypt_t dec_fn = c->spec->decrypt;
+  size_t nblocks = inbuflen / blocksize;
+  unsigned int burn, nburn;
+
+  if (outbuflen < inbuflen)
+    return GPG_ERR_BUFFER_TOO_SHORT;
+
+  if ((inbuflen % blocksize)
+      && !(inbuflen > blocksize
+           && (c->flags & GCRY_CIPHER_CBC_CTS)))
+    return GPG_ERR_INV_LENGTH;
+
+  burn = 0;
+
+  if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
+    {
+      nblocks--;
+      if ((inbuflen % blocksize) == 0)
+       nblocks--;
+      buf_cpy (c->lastiv, c->u_iv.iv, blocksize);
+    }
+
+  if (c->bulk.cbc_dec)
+    {
+      c->bulk.cbc_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
+      inbuf  += nblocks * blocksize;
+      outbuf += nblocks * blocksize;
+    }
+  else
+    {
+      for (n=0; n < nblocks; n++ )
+        {
+          /* Because outbuf and inbuf might be the same, we must not overwrite
+             the original ciphertext block.  We use LASTIV as intermediate
+             storage here because it is not used otherwise.  */
+          nburn = dec_fn ( &c->context.c, c->lastiv, inbuf );
+          burn = nburn > burn ? nburn : burn;
+          buf_xor_n_copy_2(outbuf, c->lastiv, c->u_iv.iv, inbuf, blocksize);
+          inbuf  += blocksize;
+          outbuf += blocksize;
+        }
+    }
+
+  if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
+    {
+      size_t restbytes;
+
+      if ((inbuflen % blocksize) == 0)
+        restbytes = blocksize;
+      else
+        restbytes = inbuflen % blocksize;
+
+      buf_cpy (c->lastiv, c->u_iv.iv, blocksize );         /* Save Cn-2. */
+      buf_cpy (c->u_iv.iv, inbuf + blocksize, restbytes ); /* Save Cn. */
+
+      nburn = dec_fn ( &c->context.c, outbuf, inbuf );
+      burn = nburn > burn ? nburn : burn;
+      buf_xor(outbuf, outbuf, c->u_iv.iv, restbytes);
+
+      buf_cpy (outbuf + blocksize, outbuf, restbytes);
+      for(i=restbytes; i < blocksize; i++)
+        c->u_iv.iv[i] = outbuf[i];
+      nburn = dec_fn (&c->context.c, outbuf, c->u_iv.iv);
+      burn = nburn > burn ? nburn : burn;
+      buf_xor(outbuf, outbuf, c->lastiv, blocksize);
+      /* c->lastiv is now really lastlastiv, does this matter? */
+    }
+
+  if (burn > 0)
+    _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+  return 0;
+}
diff --git a/cipher/cipher-ccm.c b/cipher/cipher-ccm.c
new file mode 100644 (file)
index 0000000..47f2162
--- /dev/null
@@ -0,0 +1,442 @@
+/* cipher-ccm.c - CTR mode with CBC-MAC mode implementation
+ * Copyright © 2013 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 "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); \
+  (burn) = (burn) > __nburn ? (burn) : __nburn; } while (0)
+
+
+static unsigned int
+do_cbc_mac (gcry_cipher_hd_t c, const unsigned char *inbuf, size_t inlen,
+            int do_padding)
+{
+  const unsigned int blocksize = 16;
+  gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+  unsigned char tmp[blocksize];
+  unsigned int burn = 0;
+  unsigned int unused = c->u_mode.ccm.mac_unused;
+  size_t nblocks;
+
+  if (inlen == 0 && (unused == 0 || !do_padding))
+    return 0;
+
+  do
+    {
+      if (inlen + unused < blocksize || unused > 0)
+        {
+          for (; inlen && unused < blocksize; inlen--)
+            c->u_mode.ccm.macbuf[unused++] = *inbuf++;
+        }
+      if (!inlen)
+        {
+          if (!do_padding)
+            break;
+
+          while (unused < blocksize)
+            c->u_mode.ccm.macbuf[unused++] = 0;
+        }
+
+      if (unused > 0)
+        {
+          /* Process one block from macbuf.  */
+          buf_xor(c->u_iv.iv, c->u_iv.iv, c->u_mode.ccm.macbuf, blocksize);
+          set_burn (burn, enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv ));
+
+          unused = 0;
+        }
+
+      if (c->bulk.cbc_enc)
+        {
+          nblocks = inlen / blocksize;
+          c->bulk.cbc_enc (&c->context.c, c->u_iv.iv, tmp, inbuf, nblocks, 1);
+          inbuf += nblocks * blocksize;
+          inlen -= nblocks * blocksize;
+
+          wipememory (tmp, sizeof(tmp));
+        }
+      else
+        {
+          while (inlen >= blocksize)
+            {
+              buf_xor(c->u_iv.iv, c->u_iv.iv, inbuf, blocksize);
+
+              set_burn (burn, enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv ));
+
+              inlen -= blocksize;
+              inbuf += blocksize;
+            }
+        }
+    }
+  while (inlen > 0);
+
+  c->u_mode.ccm.mac_unused = unused;
+
+  if (burn)
+    burn += 4 * sizeof(void *);
+
+  return burn;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_ccm_set_nonce (gcry_cipher_hd_t c, const unsigned char *nonce,
+                            size_t noncelen)
+{
+  size_t L = 15 - noncelen;
+  size_t L_;
+
+  L_ = L - 1;
+
+  if (!nonce)
+    return GPG_ERR_INV_ARG;
+  /* Length field must be 2, 3, ..., or 8. */
+  if (L < 2 || L > 8)
+    return GPG_ERR_INV_LENGTH;
+
+  /* Reset state */
+  memset (&c->u_mode, 0, sizeof(c->u_mode));
+  memset (&c->marks, 0, sizeof(c->marks));
+  memset (&c->u_iv, 0, sizeof(c->u_iv));
+  memset (&c->u_ctr, 0, sizeof(c->u_ctr));
+  memset (c->lastiv, 0, sizeof(c->lastiv));
+  c->unused = 0;
+
+  /* Setup CTR */
+  c->u_ctr.ctr[0] = L_;
+  memcpy (&c->u_ctr.ctr[1], nonce, noncelen);
+  memset (&c->u_ctr.ctr[1 + noncelen], 0, L);
+
+  /* Setup IV */
+  c->u_iv.iv[0] = L_;
+  memcpy (&c->u_iv.iv[1], nonce, noncelen);
+  /* Add (8 * M_ + 64 * flags) to iv[0] and set iv[noncelen + 1 ... 15] later
+     in set_aad.  */
+  memset (&c->u_iv.iv[1 + noncelen], 0, L);
+
+  c->u_mode.ccm.nonce = 1;
+
+  return GPG_ERR_NO_ERROR;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_ccm_set_lengths (gcry_cipher_hd_t c, u64 encryptlen, u64 aadlen,
+                              u64 taglen)
+{
+  unsigned int burn = 0;
+  unsigned char b0[16];
+  size_t noncelen = 15 - (c->u_iv.iv[0] + 1);
+  u64 M = taglen;
+  u64 M_;
+  int i;
+
+  M_ = (M - 2) / 2;
+
+  /* Authentication field must be 4, 6, 8, 10, 12, 14 or 16. */
+  if ((M_ * 2 + 2) != M || M < 4 || M > 16)
+    return GPG_ERR_INV_LENGTH;
+  if (!c->u_mode.ccm.nonce || c->marks.tag)
+    return GPG_ERR_INV_STATE;
+  if (c->u_mode.ccm.lengths)
+    return GPG_ERR_INV_STATE;
+
+  c->u_mode.ccm.authlen = taglen;
+  c->u_mode.ccm.encryptlen = encryptlen;
+  c->u_mode.ccm.aadlen = aadlen;
+
+  /* Complete IV setup.  */
+  c->u_iv.iv[0] += (aadlen > 0) * 64 + M_ * 8;
+  for (i = 16 - 1; i >= 1 + noncelen; i--)
+    {
+      c->u_iv.iv[i] = encryptlen & 0xff;
+      encryptlen >>= 8;
+    }
+
+  memcpy (b0, c->u_iv.iv, 16);
+  memset (c->u_iv.iv, 0, 16);
+
+  set_burn (burn, do_cbc_mac (c, b0, 16, 0));
+
+  if (aadlen == 0)
+    {
+      /* Do nothing.  */
+    }
+  else if (aadlen > 0 && aadlen <= (unsigned int)0xfeff)
+    {
+      b0[0] = (aadlen >> 8) & 0xff;
+      b0[1] = aadlen & 0xff;
+      set_burn (burn, do_cbc_mac (c, b0, 2, 0));
+    }
+  else if (aadlen > 0xfeff && aadlen <= (unsigned int)0xffffffff)
+    {
+      b0[0] = 0xff;
+      b0[1] = 0xfe;
+      buf_put_be32(&b0[2], aadlen);
+      set_burn (burn, do_cbc_mac (c, b0, 6, 0));
+    }
+  else if (aadlen > (unsigned int)0xffffffff)
+    {
+      b0[0] = 0xff;
+      b0[1] = 0xff;
+      buf_put_be64(&b0[2], aadlen);
+      set_burn (burn, do_cbc_mac (c, b0, 10, 0));
+    }
+
+  /* Generate S_0 and increase counter.  */
+  set_burn (burn, c->spec->encrypt ( &c->context.c, c->u_mode.ccm.s0,
+                                     c->u_ctr.ctr ));
+  c->u_ctr.ctr[15]++;
+
+  if (burn)
+    _gcry_burn_stack (burn + sizeof(void *) * 5);
+
+  c->u_mode.ccm.lengths = 1;
+
+  return GPG_ERR_NO_ERROR;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_ccm_authenticate (gcry_cipher_hd_t c, const unsigned char *abuf,
+                               size_t abuflen)
+{
+  unsigned int burn;
+
+  if (abuflen > 0 && !abuf)
+    return GPG_ERR_INV_ARG;
+  if (!c->u_mode.ccm.nonce || !c->u_mode.ccm.lengths || c->marks.tag)
+    return GPG_ERR_INV_STATE;
+  if (abuflen > c->u_mode.ccm.aadlen)
+    return GPG_ERR_INV_LENGTH;
+
+  c->u_mode.ccm.aadlen -= abuflen;
+  burn = do_cbc_mac (c, abuf, abuflen, c->u_mode.ccm.aadlen == 0);
+
+  if (burn)
+    _gcry_burn_stack (burn + sizeof(void *) * 5);
+
+  return GPG_ERR_NO_ERROR;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_ccm_tag (gcry_cipher_hd_t c, unsigned char *outbuf,
+                     size_t outbuflen, int check)
+{
+  unsigned int burn;
+
+  if (!outbuf || outbuflen == 0)
+    return GPG_ERR_INV_ARG;
+  /* Tag length must be same as initial authlen.  */
+  if (c->u_mode.ccm.authlen != outbuflen)
+    return GPG_ERR_INV_LENGTH;
+  if (!c->u_mode.ccm.nonce || !c->u_mode.ccm.lengths || c->u_mode.ccm.aadlen > 0)
+    return GPG_ERR_INV_STATE;
+  /* Initial encrypt length must match with length of actual data processed.  */
+  if (c->u_mode.ccm.encryptlen > 0)
+    return GPG_ERR_UNFINISHED;
+
+  if (!c->marks.tag)
+    {
+      burn = do_cbc_mac (c, NULL, 0, 1); /* Perform final padding.  */
+
+      /* Add S_0 */
+      buf_xor (c->u_iv.iv, c->u_iv.iv, c->u_mode.ccm.s0, 16);
+
+      wipememory (c->u_ctr.ctr, 16);
+      wipememory (c->u_mode.ccm.s0, 16);
+      wipememory (c->u_mode.ccm.macbuf, 16);
+
+      if (burn)
+        _gcry_burn_stack (burn + sizeof(void *) * 5);
+
+      c->marks.tag = 1;
+    }
+
+  if (!check)
+    {
+      memcpy (outbuf, c->u_iv.iv, outbuflen);
+      return GPG_ERR_NO_ERROR;
+    }
+  else
+    {
+      return buf_eq_const(outbuf, c->u_iv.iv, outbuflen) ?
+             GPG_ERR_NO_ERROR : GPG_ERR_CHECKSUM;
+    }
+}
+
+
+gcry_err_code_t
+_gcry_cipher_ccm_get_tag (gcry_cipher_hd_t c, unsigned char *outtag,
+                         size_t taglen)
+{
+  return _gcry_cipher_ccm_tag (c, outtag, taglen, 0);
+}
+
+
+gcry_err_code_t
+_gcry_cipher_ccm_check_tag (gcry_cipher_hd_t c, const unsigned char *intag,
+                           size_t taglen)
+{
+  return _gcry_cipher_ccm_tag (c, (unsigned char *)intag, taglen, 1);
+}
+
+
+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)
+{
+  unsigned int burn;
+
+  if (outbuflen < inbuflen)
+    return GPG_ERR_BUFFER_TOO_SHORT;
+  if (!c->u_mode.ccm.nonce || c->marks.tag || !c->u_mode.ccm.lengths ||
+      c->u_mode.ccm.aadlen > 0)
+    return GPG_ERR_INV_STATE;
+  if (inbuflen > c->u_mode.ccm.encryptlen)
+    return GPG_ERR_INV_LENGTH;
+
+  c->u_mode.ccm.encryptlen -= inbuflen;
+  burn = do_cbc_mac (c, inbuf, inbuflen, 0);
+  if (burn)
+    _gcry_burn_stack (burn + sizeof(void *) * 5);
+
+  return _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+}
+
+
+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)
+{
+  gcry_err_code_t err;
+  unsigned int burn;
+
+  if (outbuflen < inbuflen)
+    return GPG_ERR_BUFFER_TOO_SHORT;
+  if (!c->u_mode.ccm.nonce || c->marks.tag || !c->u_mode.ccm.lengths ||
+      c->u_mode.ccm.aadlen > 0)
+    return GPG_ERR_INV_STATE;
+  if (inbuflen > c->u_mode.ccm.encryptlen)
+    return GPG_ERR_INV_LENGTH;
+
+  err = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+  if (err)
+    return err;
+
+  c->u_mode.ccm.encryptlen -= inbuflen;
+  burn = do_cbc_mac (c, outbuf, inbuflen, 0);
+  if (burn)
+    _gcry_burn_stack (burn + sizeof(void *) * 5);
+
+  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*/
diff --git a/cipher/cipher-cfb.c b/cipher/cipher-cfb.c
new file mode 100644 (file)
index 0000000..8539f54
--- /dev/null
@@ -0,0 +1,226 @@
+/* cipher-cfb.c  - Generic CFB mode implementation
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ *               2005, 2007, 2008, 2009, 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/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "ath.h"
+#include "bufhelp.h"
+#include "./cipher-internal.h"
+
+
+gcry_err_code_t
+_gcry_cipher_cfb_encrypt (gcry_cipher_hd_t c,
+                          unsigned char *outbuf, size_t outbuflen,
+                          const unsigned char *inbuf, size_t inbuflen)
+{
+  unsigned char *ivp;
+  gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+  size_t blocksize = c->spec->blocksize;
+  size_t blocksize_x_2 = blocksize + blocksize;
+  unsigned int burn, nburn;
+
+  if (outbuflen < inbuflen)
+    return GPG_ERR_BUFFER_TOO_SHORT;
+
+  if ( inbuflen <= c->unused )
+    {
+      /* Short enough to be encoded by the remaining XOR mask. */
+      /* XOR the input with the IV and store input into IV. */
+      ivp = c->u_iv.iv + blocksize - c->unused;
+      buf_xor_2dst(outbuf, ivp, inbuf, inbuflen);
+      c->unused -= inbuflen;
+      return 0;
+    }
+
+  burn = 0;
+
+  if ( c->unused )
+    {
+      /* XOR the input with the IV and store input into IV */
+      inbuflen -= c->unused;
+      ivp = c->u_iv.iv + blocksize - c->unused;
+      buf_xor_2dst(outbuf, ivp, inbuf, c->unused);
+      outbuf += c->unused;
+      inbuf += c->unused;
+      c->unused = 0;
+    }
+
+  /* Now we can process complete blocks.  We use a loop as long as we
+     have at least 2 blocks and use conditions for the rest.  This
+     also allows to use a bulk encryption function if available.  */
+  if (inbuflen >= blocksize_x_2 && c->bulk.cfb_enc)
+    {
+      size_t nblocks = inbuflen / blocksize;
+      c->bulk.cfb_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
+      outbuf += nblocks * blocksize;
+      inbuf  += nblocks * blocksize;
+      inbuflen -= nblocks * blocksize;
+    }
+  else
+    {
+      while ( inbuflen >= blocksize_x_2 )
+        {
+          /* Encrypt the IV. */
+          nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+          burn = nburn > burn ? nburn : burn;
+          /* XOR the input with the IV and store input into IV.  */
+          buf_xor_2dst(outbuf, c->u_iv.iv, inbuf, blocksize);
+          outbuf += blocksize;
+          inbuf += blocksize;
+          inbuflen -= blocksize;
+        }
+    }
+
+  if ( inbuflen >= blocksize )
+    {
+      /* Save the current IV and then encrypt the IV. */
+      buf_cpy( c->lastiv, c->u_iv.iv, blocksize );
+      nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+      burn = nburn > burn ? nburn : burn;
+      /* XOR the input with the IV and store input into IV */
+      buf_xor_2dst(outbuf, c->u_iv.iv, inbuf, blocksize);
+      outbuf += blocksize;
+      inbuf += blocksize;
+      inbuflen -= blocksize;
+    }
+  if ( inbuflen )
+    {
+      /* Save the current IV and then encrypt the IV. */
+      buf_cpy( c->lastiv, c->u_iv.iv, blocksize );
+      nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+      burn = nburn > burn ? nburn : burn;
+      c->unused = blocksize;
+      /* Apply the XOR. */
+      c->unused -= inbuflen;
+      buf_xor_2dst(outbuf, c->u_iv.iv, inbuf, inbuflen);
+      outbuf += inbuflen;
+      inbuf += inbuflen;
+      inbuflen = 0;
+    }
+
+  if (burn > 0)
+    _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+  return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_cfb_decrypt (gcry_cipher_hd_t c,
+                          unsigned char *outbuf, size_t outbuflen,
+                          const unsigned char *inbuf, size_t inbuflen)
+{
+  unsigned char *ivp;
+  gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+  size_t blocksize = c->spec->blocksize;
+  size_t blocksize_x_2 = blocksize + blocksize;
+  unsigned int burn, nburn;
+
+  if (outbuflen < inbuflen)
+    return GPG_ERR_BUFFER_TOO_SHORT;
+
+  if (inbuflen <= c->unused)
+    {
+      /* Short enough to be encoded by the remaining XOR mask. */
+      /* XOR the input with the IV and store input into IV. */
+      ivp = c->u_iv.iv + blocksize - c->unused;
+      buf_xor_n_copy(outbuf, ivp, inbuf, inbuflen);
+      c->unused -= inbuflen;
+      return 0;
+    }
+
+  burn = 0;
+
+  if (c->unused)
+    {
+      /* XOR the input with the IV and store input into IV. */
+      inbuflen -= c->unused;
+      ivp = c->u_iv.iv + blocksize - c->unused;
+      buf_xor_n_copy(outbuf, ivp, inbuf, c->unused);
+      outbuf += c->unused;
+      inbuf += c->unused;
+      c->unused = 0;
+    }
+
+  /* Now we can process complete blocks.  We use a loop as long as we
+     have at least 2 blocks and use conditions for the rest.  This
+     also allows to use a bulk encryption function if available.  */
+  if (inbuflen >= blocksize_x_2 && c->bulk.cfb_dec)
+    {
+      size_t nblocks = inbuflen / blocksize;
+      c->bulk.cfb_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
+      outbuf += nblocks * blocksize;
+      inbuf  += nblocks * blocksize;
+      inbuflen -= nblocks * blocksize;
+    }
+  else
+    {
+      while (inbuflen >= blocksize_x_2 )
+        {
+          /* Encrypt the IV. */
+          nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+          burn = nburn > burn ? nburn : burn;
+          /* XOR the input with the IV and store input into IV. */
+          buf_xor_n_copy(outbuf, c->u_iv.iv, inbuf, blocksize);
+          outbuf += blocksize;
+          inbuf += blocksize;
+          inbuflen -= blocksize;
+        }
+    }
+
+  if (inbuflen >= blocksize )
+    {
+      /* Save the current IV and then encrypt the IV. */
+      buf_cpy ( c->lastiv, c->u_iv.iv, blocksize);
+      nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+      burn = nburn > burn ? nburn : burn;
+      /* XOR the input with the IV and store input into IV */
+      buf_xor_n_copy(outbuf, c->u_iv.iv, inbuf, blocksize);
+      outbuf += blocksize;
+      inbuf += blocksize;
+      inbuflen -= blocksize;
+    }
+
+  if (inbuflen)
+    {
+      /* Save the current IV and then encrypt the IV. */
+      buf_cpy ( c->lastiv, c->u_iv.iv, blocksize );
+      nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+      burn = nburn > burn ? nburn : burn;
+      c->unused = blocksize;
+      /* Apply the XOR. */
+      c->unused -= inbuflen;
+      buf_xor_n_copy(outbuf, c->u_iv.iv, inbuf, inbuflen);
+      outbuf += inbuflen;
+      inbuf += inbuflen;
+      inbuflen = 0;
+    }
+
+  if (burn > 0)
+    _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+  return 0;
+}
diff --git a/cipher/cipher-cmac.c b/cipher/cipher-cmac.c
new file mode 100644 (file)
index 0000000..25d5db2
--- /dev/null
@@ -0,0 +1,238 @@
+/* cmac.c - CMAC, Cipher-based MAC.
+ * Copyright © 2013 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 "g10lib.h"
+#include "cipher.h"
+#include "cipher-internal.h"
+#include "bufhelp.h"
+
+
+#define set_burn(burn, nburn) do { \
+  unsigned int __nburn = (nburn); \
+  (burn) = (burn) > __nburn ? (burn) : __nburn; } while (0)
+
+
+static void
+cmac_write (gcry_cipher_hd_t c, const byte * inbuf, size_t inlen)
+{
+  gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+  const unsigned int blocksize = c->spec->blocksize;
+  byte outbuf[MAX_BLOCKSIZE];
+  unsigned int burn = 0;
+  unsigned int nblocks;
+
+  if (!inlen || !inbuf)
+    return;
+
+  /* Last block is needed for cmac_final.  */
+  if (c->unused + inlen <= blocksize)
+    {
+      for (; inlen && c->unused < blocksize; inlen--)
+        c->lastiv[c->unused++] = *inbuf++;
+      return;
+    }
+
+  if (c->unused)
+    {
+      for (; inlen && c->unused < blocksize; inlen--)
+        c->lastiv[c->unused++] = *inbuf++;
+
+      buf_xor (c->u_iv.iv, c->u_iv.iv, c->lastiv, blocksize);
+      set_burn (burn, enc_fn (&c->context.c, c->u_iv.iv, c->u_iv.iv));
+
+      c->unused = 0;
+    }
+
+  if (c->bulk.cbc_enc && inlen > blocksize)
+    {
+      nblocks = inlen / blocksize;
+      nblocks -= (nblocks * blocksize == inlen);
+
+      c->bulk.cbc_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks, 1);
+      inbuf += nblocks * blocksize;
+      inlen -= nblocks * blocksize;
+
+      wipememory (outbuf, sizeof (outbuf));
+    }
+  else
+    while (inlen > blocksize)
+      {
+        buf_xor (c->u_iv.iv, c->u_iv.iv, inbuf, blocksize);
+        set_burn (burn, enc_fn (&c->context.c, c->u_iv.iv, c->u_iv.iv));
+        inlen -= blocksize;
+        inbuf += blocksize;
+      }
+
+  /* Make sure that last block is passed to cmac_final.  */
+  if (inlen == 0)
+    BUG ();
+
+  for (; inlen && c->unused < blocksize; inlen--)
+    c->lastiv[c->unused++] = *inbuf++;
+
+  if (burn)
+    _gcry_burn_stack (burn + 4 * sizeof (void *));
+}
+
+
+static void
+cmac_generate_subkeys (gcry_cipher_hd_t c)
+{
+  const unsigned int blocksize = c->spec->blocksize;
+  byte rb, carry, t, bi;
+  unsigned int burn;
+  int i, j;
+  union
+  {
+    size_t _aligned;
+    byte buf[MAX_BLOCKSIZE];
+  } u;
+
+  if (MAX_BLOCKSIZE < blocksize)
+    BUG ();
+
+  /* encrypt zero block */
+  memset (u.buf, 0, blocksize);
+  burn = c->spec->encrypt (&c->context.c, u.buf, u.buf);
+
+  /* Currently supported blocksizes are 16 and 8. */
+  rb = blocksize == 16 ? 0x87 : 0x1B /*blocksize == 8 */ ;
+
+  for (j = 0; j < 2; j++)
+    {
+      /* Generate subkeys K1 and K2 */
+      carry = 0;
+      for (i = blocksize - 1; i >= 0; i--)
+        {
+          bi = u.buf[i];
+          t = carry | (bi << 1);
+          carry = bi >> 7;
+          u.buf[i] = t & 0xff;
+          c->u_mode.cmac.subkeys[j][i] = u.buf[i];
+        }
+      u.buf[blocksize - 1] ^= carry ? rb : 0;
+      c->u_mode.cmac.subkeys[j][blocksize - 1] = u.buf[blocksize - 1];
+    }
+
+  wipememory (&u, sizeof (u));
+  if (burn)
+    _gcry_burn_stack (burn + 4 * sizeof (void *));
+}
+
+
+static void
+cmac_final (gcry_cipher_hd_t c)
+{
+  const unsigned int blocksize = c->spec->blocksize;
+  unsigned int count = c->unused;
+  unsigned int burn;
+  byte *subkey;
+
+  if (count == blocksize)
+    subkey = c->u_mode.cmac.subkeys[0];        /* K1 */
+  else
+    {
+      subkey = c->u_mode.cmac.subkeys[1];      /* K2 */
+      c->lastiv[count++] = 0x80;
+      while (count < blocksize)
+        c->lastiv[count++] = 0;
+    }
+
+  buf_xor (c->lastiv, c->lastiv, subkey, blocksize);
+
+  buf_xor (c->u_iv.iv, c->u_iv.iv, c->lastiv, blocksize);
+  burn = c->spec->encrypt (&c->context.c, c->u_iv.iv, c->u_iv.iv);
+  if (burn)
+    _gcry_burn_stack (burn + 4 * sizeof (void *));
+
+  c->unused = 0;
+}
+
+
+static gcry_err_code_t
+cmac_tag (gcry_cipher_hd_t c, unsigned char *tag, size_t taglen, int check)
+{
+  if (!tag || taglen == 0 || taglen > c->spec->blocksize)
+    return GPG_ERR_INV_ARG;
+
+  if (!c->u_mode.cmac.tag)
+    {
+      cmac_final (c);
+      c->u_mode.cmac.tag = 1;
+    }
+
+  if (!check)
+    {
+      memcpy (tag, c->u_iv.iv, taglen);
+      return GPG_ERR_NO_ERROR;
+    }
+  else
+    {
+      return buf_eq_const (tag, c->u_iv.iv, taglen) ?
+        GPG_ERR_NO_ERROR : GPG_ERR_CHECKSUM;
+    }
+}
+
+
+gcry_err_code_t
+_gcry_cipher_cmac_authenticate (gcry_cipher_hd_t c,
+                                const unsigned char *abuf, size_t abuflen)
+{
+  if (abuflen > 0 && !abuf)
+    return GPG_ERR_INV_ARG;
+  if (c->u_mode.cmac.tag)
+    return GPG_ERR_INV_STATE;
+  /* To support new blocksize, update cmac_generate_subkeys() then add new
+     blocksize here. */
+  if (c->spec->blocksize != 16 && c->spec->blocksize != 8)
+    return GPG_ERR_INV_CIPHER_MODE;
+
+  cmac_write (c, abuf, abuflen);
+
+  return GPG_ERR_NO_ERROR;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_cmac_get_tag (gcry_cipher_hd_t c,
+                           unsigned char *outtag, size_t taglen)
+{
+  return cmac_tag (c, outtag, taglen, 0);
+}
+
+
+gcry_err_code_t
+_gcry_cipher_cmac_check_tag (gcry_cipher_hd_t c,
+                             const unsigned char *intag, size_t taglen)
+{
+  return cmac_tag (c, (unsigned char *) intag, taglen, 1);
+}
+
+gcry_err_code_t
+_gcry_cipher_cmac_set_subkeys (gcry_cipher_hd_t c)
+{
+  cmac_generate_subkeys (c);
+
+  return GPG_ERR_NO_ERROR;
+}
diff --git a/cipher/cipher-ctr.c b/cipher/cipher-ctr.c
new file mode 100644 (file)
index 0000000..1e7133c
--- /dev/null
@@ -0,0 +1,111 @@
+/* cipher-ctr.c  - Generic CTR mode implementation
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ *               2005, 2007, 2008, 2009, 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/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "ath.h"
+#include "bufhelp.h"
+#include "./cipher-internal.h"
+
+
+gcry_err_code_t
+_gcry_cipher_ctr_encrypt (gcry_cipher_hd_t c,
+                          unsigned char *outbuf, size_t outbuflen,
+                          const unsigned char *inbuf, size_t inbuflen)
+{
+  size_t n;
+  int i;
+  gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+  unsigned int blocksize = c->spec->blocksize;
+  size_t nblocks;
+  unsigned int burn, nburn;
+
+  if (outbuflen < inbuflen)
+    return GPG_ERR_BUFFER_TOO_SHORT;
+
+  burn = 0;
+
+  /* First process a left over encrypted counter.  */
+  if (c->unused)
+    {
+      gcry_assert (c->unused < blocksize);
+      i = blocksize - c->unused;
+      n = c->unused > inbuflen ? inbuflen : c->unused;
+      buf_xor(outbuf, inbuf, &c->lastiv[i], n);
+      c->unused -= n;
+      inbuf  += n;
+      outbuf += n;
+      inbuflen -= n;
+    }
+
+  /* Use a bulk method if available.  */
+  nblocks = inbuflen / blocksize;
+  if (nblocks && c->bulk.ctr_enc)
+    {
+      c->bulk.ctr_enc (&c->context.c, c->u_ctr.ctr, outbuf, inbuf, nblocks);
+      inbuf  += nblocks * blocksize;
+      outbuf += nblocks * blocksize;
+      inbuflen -= nblocks * blocksize;
+    }
+
+  /* If we don't have a bulk method use the standard method.  We also
+     use this method for the a remaining partial block.  */
+  if (inbuflen)
+    {
+      unsigned char tmp[MAX_BLOCKSIZE];
+
+      do {
+        nburn = enc_fn (&c->context.c, tmp, c->u_ctr.ctr);
+        burn = nburn > burn ? nburn : burn;
+
+        for (i = blocksize; i > 0; i--)
+          {
+            c->u_ctr.ctr[i-1]++;
+            if (c->u_ctr.ctr[i-1] != 0)
+              break;
+          }
+
+        n = blocksize < inbuflen ? blocksize : inbuflen;
+        buf_xor(outbuf, inbuf, tmp, n);
+
+        inbuflen -= n;
+        outbuf += n;
+        inbuf += n;
+      } while (inbuflen);
+
+      /* Save the unused bytes of the counter.  */
+      c->unused = blocksize - n;
+      if (c->unused)
+        buf_cpy (c->lastiv+n, tmp+n, c->unused);
+
+      wipememory (tmp, sizeof tmp);
+    }
+
+  if (burn > 0)
+    _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+  return 0;
+}
diff --git a/cipher/cipher-gcm.c b/cipher/cipher-gcm.c
new file mode 100644 (file)
index 0000000..457e337
--- /dev/null
@@ -0,0 +1,1180 @@
+/* cipher-gcm.c  - Generic Galois Counter Mode implementation
+ * Copyright (C) 2013 Dmitry Eremin-Solenikov
+ * Copyright © 2013 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 "ath.h"
+#include "bufhelp.h"
+#include "./cipher-internal.h"
+
+#ifdef GCM_USE_TABLES
+static const u16 gcmR[256] = {
+  0x0000, 0x01c2, 0x0384, 0x0246, 0x0708, 0x06ca, 0x048c, 0x054e,
+  0x0e10, 0x0fd2, 0x0d94, 0x0c56, 0x0918, 0x08da, 0x0a9c, 0x0b5e,
+  0x1c20, 0x1de2, 0x1fa4, 0x1e66, 0x1b28, 0x1aea, 0x18ac, 0x196e,
+  0x1230, 0x13f2, 0x11b4, 0x1076, 0x1538, 0x14fa, 0x16bc, 0x177e,
+  0x3840, 0x3982, 0x3bc4, 0x3a06, 0x3f48, 0x3e8a, 0x3ccc, 0x3d0e,
+  0x3650, 0x3792, 0x35d4, 0x3416, 0x3158, 0x309a, 0x32dc, 0x331e,
+  0x2460, 0x25a2, 0x27e4, 0x2626, 0x2368, 0x22aa, 0x20ec, 0x212e,
+  0x2a70, 0x2bb2, 0x29f4, 0x2836, 0x2d78, 0x2cba, 0x2efc, 0x2f3e,
+  0x7080, 0x7142, 0x7304, 0x72c6, 0x7788, 0x764a, 0x740c, 0x75ce,
+  0x7e90, 0x7f52, 0x7d14, 0x7cd6, 0x7998, 0x785a, 0x7a1c, 0x7bde,
+  0x6ca0, 0x6d62, 0x6f24, 0x6ee6, 0x6ba8, 0x6a6a, 0x682c, 0x69ee,
+  0x62b0, 0x6372, 0x6134, 0x60f6, 0x65b8, 0x647a, 0x663c, 0x67fe,
+  0x48c0, 0x4902, 0x4b44, 0x4a86, 0x4fc8, 0x4e0a, 0x4c4c, 0x4d8e,
+  0x46d0, 0x4712, 0x4554, 0x4496, 0x41d8, 0x401a, 0x425c, 0x439e,
+  0x54e0, 0x5522, 0x5764, 0x56a6, 0x53e8, 0x522a, 0x506c, 0x51ae,
+  0x5af0, 0x5b32, 0x5974, 0x58b6, 0x5df8, 0x5c3a, 0x5e7c, 0x5fbe,
+  0xe100, 0xe0c2, 0xe284, 0xe346, 0xe608, 0xe7ca, 0xe58c, 0xe44e,
+  0xef10, 0xeed2, 0xec94, 0xed56, 0xe818, 0xe9da, 0xeb9c, 0xea5e,
+  0xfd20, 0xfce2, 0xfea4, 0xff66, 0xfa28, 0xfbea, 0xf9ac, 0xf86e,
+  0xf330, 0xf2f2, 0xf0b4, 0xf176, 0xf438, 0xf5fa, 0xf7bc, 0xf67e,
+  0xd940, 0xd882, 0xdac4, 0xdb06, 0xde48, 0xdf8a, 0xddcc, 0xdc0e,
+  0xd750, 0xd692, 0xd4d4, 0xd516, 0xd058, 0xd19a, 0xd3dc, 0xd21e,
+  0xc560, 0xc4a2, 0xc6e4, 0xc726, 0xc268, 0xc3aa, 0xc1ec, 0xc02e,
+  0xcb70, 0xcab2, 0xc8f4, 0xc936, 0xcc78, 0xcdba, 0xcffc, 0xce3e,
+  0x9180, 0x9042, 0x9204, 0x93c6, 0x9688, 0x974a, 0x950c, 0x94ce,
+  0x9f90, 0x9e52, 0x9c14, 0x9dd6, 0x9898, 0x995a, 0x9b1c, 0x9ade,
+  0x8da0, 0x8c62, 0x8e24, 0x8fe6, 0x8aa8, 0x8b6a, 0x892c, 0x88ee,
+  0x83b0, 0x8272, 0x8034, 0x81f6, 0x84b8, 0x857a, 0x873c, 0x86fe,
+  0xa9c0, 0xa802, 0xaa44, 0xab86, 0xaec8, 0xaf0a, 0xad4c, 0xac8e,
+  0xa7d0, 0xa612, 0xa454, 0xa596, 0xa0d8, 0xa11a, 0xa35c, 0xa29e,
+  0xb5e0, 0xb422, 0xb664, 0xb7a6, 0xb2e8, 0xb32a, 0xb16c, 0xb0ae,
+  0xbbf0, 0xba32, 0xb874, 0xb9b6, 0xbcf8, 0xbd3a, 0xbf7c, 0xbebe,
+};
+
+#ifdef GCM_TABLES_USE_U64
+static void
+bshift (u64 * b0, u64 * b1)
+{
+  u64 t[2], mask;
+
+  t[0] = *b0;
+  t[1] = *b1;
+  mask = t[1] & 1 ? 0xe1 : 0;
+  mask <<= 56;
+
+  *b1 = (t[1] >> 1) ^ (t[0] << 63);
+  *b0 = (t[0] >> 1) ^ mask;
+}
+
+static void
+do_fillM (unsigned char *h, u64 *M)
+{
+  int i, j;
+
+  M[0 + 0] = 0;
+  M[0 + 16] = 0;
+
+  M[8 + 0] = buf_get_be64 (h + 0);
+  M[8 + 16] = buf_get_be64 (h + 8);
+
+  for (i = 4; i > 0; i /= 2)
+    {
+      M[i + 0] = M[2 * i + 0];
+      M[i + 16] = M[2 * i + 16];
+
+      bshift (&M[i], &M[i + 16]);
+    }
+
+  for (i = 2; i < 16; i *= 2)
+    for (j = 1; j < i; j++)
+      {
+        M[(i + j) + 0] = M[i + 0] ^ M[j + 0];
+        M[(i + j) + 16] = M[i + 16] ^ M[j + 16];
+      }
+}
+
+static inline unsigned int
+do_ghash (unsigned char *result, const unsigned char *buf, const u64 *gcmM)
+{
+  u64 V[2];
+  u64 tmp[2];
+  const u64 *M;
+  u64 T;
+  u32 A;
+  int i;
+
+  buf_xor (V, result, buf, 16);
+  V[0] = be_bswap64 (V[0]);
+  V[1] = be_bswap64 (V[1]);
+
+  /* First round can be manually tweaked based on fact that 'tmp' is zero. */
+  i = 15;
+
+  M = &gcmM[(V[1] & 0xf)];
+  V[1] >>= 4;
+  tmp[0] = (M[0] >> 4) ^ ((u64) gcmR[(M[16] & 0xf) << 4] << 48);
+  tmp[1] = (M[16] >> 4) ^ (M[0] << 60);
+  tmp[0] ^= gcmM[(V[1] & 0xf) + 0];
+  tmp[1] ^= gcmM[(V[1] & 0xf) + 16];
+  V[1] >>= 4;
+
+  --i;
+  while (1)
+    {
+      M = &gcmM[(V[1] & 0xf)];
+      V[1] >>= 4;
+
+      A = tmp[1] & 0xff;
+      T = tmp[0];
+      tmp[0] = (T >> 8) ^ ((u64) gcmR[A] << 48) ^ gcmM[(V[1] & 0xf) + 0];
+      tmp[1] = (T << 56) ^ (tmp[1] >> 8) ^ gcmM[(V[1] & 0xf) + 16];
+
+      tmp[0] ^= (M[0] >> 4) ^ ((u64) gcmR[(M[16] & 0xf) << 4] << 48);
+      tmp[1] ^= (M[16] >> 4) ^ (M[0] << 60);
+
+      if (i == 0)
+        break;
+      else if (i == 8)
+        V[1] = V[0];
+      else
+        V[1] >>= 4;
+      --i;
+    }
+
+  buf_put_be64 (result + 0, tmp[0]);
+  buf_put_be64 (result + 8, tmp[1]);
+
+  return (sizeof(V) + sizeof(T) + sizeof(tmp) +
+          sizeof(int)*2 + sizeof(void*)*5);
+}
+
+#else
+
+static void
+bshift (u32 * M, int i)
+{
+  u32 t[4], mask;
+
+  t[0] = M[i * 4 + 0];
+  t[1] = M[i * 4 + 1];
+  t[2] = M[i * 4 + 2];
+  t[3] = M[i * 4 + 3];
+  mask = t[3] & 1 ? 0xe1 : 0;
+
+  M[i * 4 + 3] = (t[3] >> 1) ^ (t[2] << 31);
+  M[i * 4 + 2] = (t[2] >> 1) ^ (t[1] << 31);
+  M[i * 4 + 1] = (t[1] >> 1) ^ (t[0] << 31);
+  M[i * 4 + 0] = (t[0] >> 1) ^ (mask << 24);
+}
+
+static void
+do_fillM (unsigned char *h, u32 *M)
+{
+  int i, j;
+
+  M[0 * 4 + 0] = 0;
+  M[0 * 4 + 1] = 0;
+  M[0 * 4 + 2] = 0;
+  M[0 * 4 + 3] = 0;
+
+  M[8 * 4 + 0] = buf_get_be32 (h + 0);
+  M[8 * 4 + 1] = buf_get_be32 (h + 4);
+  M[8 * 4 + 2] = buf_get_be32 (h + 8);
+  M[8 * 4 + 3] = buf_get_be32 (h + 12);
+
+  for (i = 4; i > 0; i /= 2)
+    {
+      M[i * 4 + 0] = M[2 * i * 4 + 0];
+      M[i * 4 + 1] = M[2 * i * 4 + 1];
+      M[i * 4 + 2] = M[2 * i * 4 + 2];
+      M[i * 4 + 3] = M[2 * i * 4 + 3];
+
+      bshift (M, i);
+    }
+
+  for (i = 2; i < 16; i *= 2)
+    for (j = 1; j < i; j++)
+      {
+        M[(i + j) * 4 + 0] = M[i * 4 + 0] ^ M[j * 4 + 0];
+        M[(i + j) * 4 + 1] = M[i * 4 + 1] ^ M[j * 4 + 1];
+        M[(i + j) * 4 + 2] = M[i * 4 + 2] ^ M[j * 4 + 2];
+        M[(i + j) * 4 + 3] = M[i * 4 + 3] ^ M[j * 4 + 3];
+      }
+}
+
+static inline unsigned int
+do_ghash (unsigned char *result, const unsigned char *buf, const u32 *gcmM)
+{
+  byte V[16];
+  u32 tmp[4];
+  u32 v;
+  const u32 *M, *m;
+  u32 T[3];
+  int i;
+
+  buf_xor (V, result, buf, 16); /* V is big-endian */
+
+  /* First round can be manually tweaked based on fact that 'tmp' is zero. */
+  i = 15;
+
+  v = V[i];
+  M = &gcmM[(v & 0xf) * 4];
+  v = (v & 0xf0) >> 4;
+  m = &gcmM[v * 4];
+  v = V[--i];
+
+  tmp[0] = (M[0] >> 4) ^ ((u64) gcmR[(M[3] << 4) & 0xf0] << 16) ^ m[0];
+  tmp[1] = (M[1] >> 4) ^ (M[0] << 28) ^ m[1];
+  tmp[2] = (M[2] >> 4) ^ (M[1] << 28) ^ m[2];
+  tmp[3] = (M[3] >> 4) ^ (M[2] << 28) ^ m[3];
+
+  while (1)
+    {
+      M = &gcmM[(v & 0xf) * 4];
+      v = (v & 0xf0) >> 4;
+      m = &gcmM[v * 4];
+
+      T[0] = tmp[0];
+      T[1] = tmp[1];
+      T[2] = tmp[2];
+      tmp[0] = (T[0] >> 8) ^ ((u32) gcmR[tmp[3] & 0xff] << 16) ^ m[0];
+      tmp[1] = (T[0] << 24) ^ (tmp[1] >> 8) ^ m[1];
+      tmp[2] = (T[1] << 24) ^ (tmp[2] >> 8) ^ m[2];
+      tmp[3] = (T[2] << 24) ^ (tmp[3] >> 8) ^ m[3];
+
+      tmp[0] ^= (M[0] >> 4) ^ ((u64) gcmR[(M[3] << 4) & 0xf0] << 16);
+      tmp[1] ^= (M[1] >> 4) ^ (M[0] << 28);
+      tmp[2] ^= (M[2] >> 4) ^ (M[1] << 28);
+      tmp[3] ^= (M[3] >> 4) ^ (M[2] << 28);
+
+      if (i == 0)
+        break;
+
+      v = V[--i];
+    }
+
+  buf_put_be32 (result + 0, tmp[0]);
+  buf_put_be32 (result + 4, tmp[1]);
+  buf_put_be32 (result + 8, tmp[2]);
+  buf_put_be32 (result + 12, tmp[3]);
+
+  return (sizeof(V) + sizeof(T) + sizeof(tmp) +
+          sizeof(int)*2 + sizeof(void*)*6);
+}
+#endif /* !HAVE_U64_TYPEDEF || SIZEOF_UNSIGNED_LONG != 8 */
+
+#define fillM(c, h) do_fillM (h, c->u_mode.gcm.gcm_table)
+#define GHASH(c, result, buf) do_ghash (result, buf, c->u_mode.gcm.gcm_table)
+
+#else
+
+static unsigned long
+bshift (unsigned long *b)
+{
+  unsigned long c;
+  int i;
+  c = b[3] & 1;
+  for (i = 3; i > 0; i--)
+    {
+      b[i] = (b[i] >> 1) | (b[i - 1] << 31);
+    }
+  b[i] >>= 1;
+  return c;
+}
+
+static unsigned int
+do_ghash (unsigned char *hsub, unsigned char *result, const unsigned char *buf)
+{
+  unsigned long V[4];
+  int i, j;
+  byte *p;
+
+#ifdef WORDS_BIGENDIAN
+  p = result;
+#else
+  unsigned long T[4];
+
+  buf_xor (V, result, buf, 16);
+  for (i = 0; i < 4; i++)
+    {
+      V[i] = (V[i] & 0x00ff00ff) << 8 | (V[i] & 0xff00ff00) >> 8;
+      V[i] = (V[i] & 0x0000ffff) << 16 | (V[i] & 0xffff0000) >> 16;
+    }
+  p = (byte *) T;
+#endif
+
+  memset (p, 0, 16);
+
+  for (i = 0; i < 16; i++)
+    {
+      for (j = 0x80; j; j >>= 1)
+        {
+          if (hsub[i] & j)
+            buf_xor (p, p, V, 16);
+          if (bshift (V))
+            V[0] ^= 0xe1000000;
+        }
+    }
+#ifndef WORDS_BIGENDIAN
+  for (i = 0, p = (byte *) T; i < 16; i += 4, p += 4)
+    {
+      result[i + 0] = p[3];
+      result[i + 1] = p[2];
+      result[i + 2] = p[1];
+      result[i + 3] = p[0];
+    }
+#endif
+
+  return (sizeof(V) + sizeof(T) + sizeof(int)*2 + sizeof(void*)*5);
+}
+
+#define fillM(c, h) 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)
+{
+  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;
+        }
+
+      /* 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)
+        {
+          burn = GHASH (c, result, buf);
+          buf += blocksize;
+          nblocks--;
+        }
+    }
+
+  return burn + (burn ? 5*sizeof(void*) : 0);
+}
+
+
+static void
+setupM (gcry_cipher_hd_t c, byte *h)
+{
+  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));
+    }
+#endif
+  else
+    fillM (c, h);
+}
+
+
+static inline void
+gcm_bytecounter_add (u32 ctr[2], size_t add)
+{
+  if (sizeof(add) > sizeof(u32))
+    {
+      u32 high_add = ((add >> 31) >> 1) & 0xffffffff;
+      ctr[1] += high_add;
+    }
+
+  ctr[0] += add;
+  if (ctr[0] >= add)
+    return;
+  ++ctr[1];
+}
+
+
+static inline u32
+gcm_add32_be128 (byte *ctr, unsigned int add)
+{
+  /* 'ctr' must be aligned to four bytes. */
+  const unsigned int blocksize = GCRY_GCM_BLOCK_LEN;
+  u32 *pval = (u32 *)(void *)(ctr + blocksize - sizeof(u32));
+  u32 val;
+
+  val = be_bswap32(*pval) + add;
+  *pval = be_bswap32(val);
+
+  return val; /* return result as host-endian value */
+}
+
+
+static inline int
+gcm_check_datalen (u32 ctr[2])
+{
+  /* len(plaintext) <= 2^39-256 bits == 2^36-32 bytes == 2^32-2 blocks */
+  if (ctr[1] > 0xfU)
+    return 0;
+  if (ctr[1] < 0xfU)
+    return 1;
+
+  if (ctr[0] <= 0xffffffe0U)
+    return 1;
+
+  return 0;
+}
+
+
+static inline int
+gcm_check_aadlen_or_ivlen (u32 ctr[2])
+{
+  /* len(aad/iv) <= 2^64-1 bits ~= 2^61-1 bytes */
+  if (ctr[1] > 0x1fffffffU)
+    return 0;
+  if (ctr[1] < 0x1fffffffU)
+    return 1;
+
+  if (ctr[0] <= 0xffffffffU)
+    return 1;
+
+  return 0;
+}
+
+
+static void
+do_ghash_buf(gcry_cipher_hd_t c, byte *hash, const byte *buf,
+             size_t buflen, int do_padding)
+{
+  unsigned int blocksize = GCRY_GCM_BLOCK_LEN;
+  unsigned int unused = c->u_mode.gcm.mac_unused;
+  size_t nblocks, n;
+  unsigned int burn = 0;
+
+  if (buflen == 0 && (unused == 0 || !do_padding))
+    return;
+
+  do
+    {
+      if (buflen + unused < blocksize || unused > 0)
+        {
+          n = blocksize - unused;
+          n = n < buflen ? n : buflen;
+
+          buf_cpy (&c->u_mode.gcm.macbuf[unused], buf, n);
+
+          unused += n;
+          buf += n;
+          buflen -= n;
+        }
+      if (!buflen)
+        {
+          if (!do_padding)
+            break;
+
+          while (unused < blocksize)
+            c->u_mode.gcm.macbuf[unused++] = 0;
+        }
+
+      if (unused > 0)
+        {
+          gcry_assert (unused == blocksize);
+
+          /* Process one block from macbuf.  */
+          burn = ghash (c, hash, c->u_mode.gcm.macbuf, 1);
+          unused = 0;
+        }
+
+      nblocks = buflen / blocksize;
+
+      if (nblocks)
+        {
+          burn = ghash (c, hash, buf, nblocks);
+          buf += blocksize * nblocks;
+          buflen -= blocksize * nblocks;
+        }
+    }
+  while (buflen > 0);
+
+  c->u_mode.gcm.mac_unused = unused;
+
+  if (burn)
+    _gcry_burn_stack (burn);
+}
+
+
+gcry_err_code_t
+_gcry_cipher_gcm_encrypt (gcry_cipher_hd_t c,
+                          byte *outbuf, size_t outbuflen,
+                          const byte *inbuf, size_t inbuflen)
+{
+  static const unsigned char zerobuf[MAX_BLOCKSIZE];
+  gcry_err_code_t err;
+
+  if (c->spec->blocksize != GCRY_GCM_BLOCK_LEN)
+    return GPG_ERR_CIPHER_ALGO;
+  if (outbuflen < inbuflen)
+    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)
+    return GPG_ERR_INV_STATE;
+
+  if (!c->marks.iv)
+    _gcry_cipher_gcm_setiv (c, zerobuf, GCRY_GCM_BLOCK_LEN);
+
+  if (c->u_mode.gcm.disallow_encryption_because_of_setiv_in_fips_mode)
+    return GPG_ERR_INV_STATE;
+
+  if (!c->u_mode.gcm.ghash_aad_finalized)
+    {
+      /* Start of encryption marks end of AAD stream. */
+      do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, NULL, 0, 1);
+      c->u_mode.gcm.ghash_aad_finalized = 1;
+    }
+
+  gcm_bytecounter_add(c->u_mode.gcm.datalen, inbuflen);
+  if (!gcm_check_datalen(c->u_mode.gcm.datalen))
+    {
+      c->u_mode.gcm.datalen_over_limits = 1;
+      return GPG_ERR_INV_LENGTH;
+    }
+
+  err = _gcry_cipher_ctr_encrypt(c, outbuf, outbuflen, inbuf, inbuflen);
+  if (err != 0)
+    return err;
+
+  do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, outbuf, inbuflen, 0);
+
+  return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_gcm_decrypt (gcry_cipher_hd_t c,
+                          byte *outbuf, size_t outbuflen,
+                          const byte *inbuf, size_t inbuflen)
+{
+  static const unsigned char zerobuf[MAX_BLOCKSIZE];
+
+  if (c->spec->blocksize != GCRY_GCM_BLOCK_LEN)
+    return GPG_ERR_CIPHER_ALGO;
+  if (outbuflen < inbuflen)
+    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)
+    return GPG_ERR_INV_STATE;
+
+  if (!c->marks.iv)
+    _gcry_cipher_gcm_setiv (c, zerobuf, GCRY_GCM_BLOCK_LEN);
+
+  if (!c->u_mode.gcm.ghash_aad_finalized)
+    {
+      /* Start of decryption marks end of AAD stream. */
+      do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, NULL, 0, 1);
+      c->u_mode.gcm.ghash_aad_finalized = 1;
+    }
+
+  gcm_bytecounter_add(c->u_mode.gcm.datalen, inbuflen);
+  if (!gcm_check_datalen(c->u_mode.gcm.datalen))
+    {
+      c->u_mode.gcm.datalen_over_limits = 1;
+      return GPG_ERR_INV_LENGTH;
+    }
+
+  do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, inbuf, inbuflen, 0);
+
+  return _gcry_cipher_ctr_encrypt(c, outbuf, outbuflen, inbuf, inbuflen);
+}
+
+
+gcry_err_code_t
+_gcry_cipher_gcm_authenticate (gcry_cipher_hd_t c,
+                               const byte * aadbuf, size_t aadbuflen)
+{
+  static const unsigned char zerobuf[MAX_BLOCKSIZE];
+
+  if (c->spec->blocksize != GCRY_GCM_BLOCK_LEN)
+    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)
+    return GPG_ERR_INV_STATE;
+
+  if (!c->marks.iv)
+    _gcry_cipher_gcm_setiv (c, zerobuf, GCRY_GCM_BLOCK_LEN);
+
+  gcm_bytecounter_add(c->u_mode.gcm.aadlen, aadbuflen);
+  if (!gcm_check_aadlen_or_ivlen(c->u_mode.gcm.aadlen))
+    {
+      c->u_mode.gcm.datalen_over_limits = 1;
+      return GPG_ERR_INV_LENGTH;
+    }
+
+  do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, aadbuf, aadbuflen, 0);
+
+  return 0;
+}
+
+
+void
+_gcry_cipher_gcm_setkey (gcry_cipher_hd_t c)
+{
+  memset (c->u_mode.gcm.u_ghash_key.key, 0, GCRY_GCM_BLOCK_LEN);
+
+  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);
+}
+
+
+static gcry_err_code_t
+_gcry_cipher_gcm_initiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen)
+{
+  memset (c->u_mode.gcm.aadlen, 0, sizeof(c->u_mode.gcm.aadlen));
+  memset (c->u_mode.gcm.datalen, 0, sizeof(c->u_mode.gcm.datalen));
+  memset (c->u_mode.gcm.u_tag.tag, 0, GCRY_GCM_BLOCK_LEN);
+  c->u_mode.gcm.datalen_over_limits = 0;
+  c->u_mode.gcm.ghash_data_finalized = 0;
+  c->u_mode.gcm.ghash_aad_finalized = 0;
+
+  if (ivlen == 0)
+    return GPG_ERR_INV_LENGTH;
+
+  if (ivlen != GCRY_GCM_BLOCK_LEN - 4)
+    {
+      u32 iv_bytes[2] = {0, 0};
+      u32 bitlengths[2][2];
+
+      memset(c->u_ctr.ctr, 0, GCRY_GCM_BLOCK_LEN);
+
+      gcm_bytecounter_add(iv_bytes, ivlen);
+      if (!gcm_check_aadlen_or_ivlen(iv_bytes))
+        {
+          c->u_mode.gcm.datalen_over_limits = 1;
+          return GPG_ERR_INV_LENGTH;
+        }
+
+      do_ghash_buf(c, c->u_ctr.ctr, iv, ivlen, 1);
+
+      /* iv length, 64-bit */
+      bitlengths[1][1] = be_bswap32(iv_bytes[0] << 3);
+      bitlengths[1][0] = be_bswap32((iv_bytes[0] >> 29) |
+                                    (iv_bytes[1] << 3));
+      /* zeros, 64-bit */
+      bitlengths[0][1] = 0;
+      bitlengths[0][0] = 0;
+
+      do_ghash_buf(c, c->u_ctr.ctr, (byte*)bitlengths, GCRY_GCM_BLOCK_LEN, 1);
+
+      wipememory (iv_bytes, sizeof iv_bytes);
+      wipememory (bitlengths, sizeof bitlengths);
+    }
+  else
+    {
+      /* 96-bit IV is handled differently. */
+      memcpy (c->u_ctr.ctr, iv, ivlen);
+      c->u_ctr.ctr[12] = c->u_ctr.ctr[13] = c->u_ctr.ctr[14] = 0;
+      c->u_ctr.ctr[15] = 1;
+    }
+
+  c->spec->encrypt (&c->context.c, c->u_mode.gcm.tagiv, c->u_ctr.ctr);
+
+  gcm_add32_be128 (c->u_ctr.ctr, 1);
+
+  c->unused = 0;
+  c->marks.iv = 1;
+  c->marks.tag = 0;
+
+  return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_gcm_setiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen)
+{
+  c->marks.iv = 0;
+  c->marks.tag = 0;
+  c->u_mode.gcm.disallow_encryption_because_of_setiv_in_fips_mode = 0;
+
+  if (fips_mode ())
+    {
+      /* Direct invocation of GCM setiv in FIPS mode disables encryption. */
+      c->u_mode.gcm.disallow_encryption_because_of_setiv_in_fips_mode = 1;
+    }
+
+  return _gcry_cipher_gcm_initiv (c, iv, ivlen);
+}
+
+
+#if 0 && TODO
+void
+_gcry_cipher_gcm_geniv (gcry_cipher_hd_t c,
+                        byte *ivout, size_t ivoutlen, const byte *nonce,
+                        size_t noncelen)
+{
+  /* nonce:    user provided part (might be null) */
+  /* noncelen: check if proper length (if nonce not null) */
+  /* ivout:    iv used to initialize gcm, output to user */
+  /* ivoutlen: check correct size */
+  byte iv[IVLEN];
+
+  if (!ivout)
+    return GPG_ERR_INV_ARG;
+  if (ivoutlen != IVLEN)
+    return GPG_ERR_INV_LENGTH;
+  if (nonce != NULL && !is_nonce_ok_len(noncelen))
+    return GPG_ERR_INV_ARG;
+
+  gcm_generate_iv(iv, nonce, noncelen);
+
+  c->marks.iv = 0;
+  c->marks.tag = 0;
+  c->u_mode.gcm.disallow_encryption_because_of_setiv_in_fips_mode = 0;
+
+  _gcry_cipher_gcm_initiv (c, iv, IVLEN);
+
+  buf_cpy(ivout, iv, IVLEN);
+  wipememory(iv, sizeof(iv));
+}
+#endif
+
+
+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 (c->u_mode.gcm.datalen_over_limits)
+    return GPG_ERR_INV_LENGTH;
+
+  if (!c->marks.tag)
+    {
+      u32 bitlengths[2][2];
+
+      /* 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) |
+                                    (c->u_mode.gcm.aadlen[1] << 3));
+      /* data length */
+      bitlengths[1][1] = be_bswap32(c->u_mode.gcm.datalen[0] << 3);
+      bitlengths[1][0] = be_bswap32((c->u_mode.gcm.datalen[0] >> 29) |
+                                    (c->u_mode.gcm.datalen[1] << 3));
+
+      /* Finalize data-stream. */
+      do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, NULL, 0, 1);
+      c->u_mode.gcm.ghash_aad_finalized = 1;
+      c->u_mode.gcm.ghash_data_finalized = 1;
+
+      /* Add bitlengths to tag. */
+      do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, (byte*)bitlengths,
+                   GCRY_GCM_BLOCK_LEN, 1);
+      buf_xor (c->u_mode.gcm.u_tag.tag, c->u_mode.gcm.tagiv,
+               c->u_mode.gcm.u_tag.tag, GCRY_GCM_BLOCK_LEN);
+      c->marks.tag = 1;
+
+      wipememory (bitlengths, sizeof (bitlengths));
+      wipememory (c->u_mode.gcm.macbuf, GCRY_GCM_BLOCK_LEN);
+      wipememory (c->u_mode.gcm.tagiv, GCRY_GCM_BLOCK_LEN);
+      wipememory (c->u_mode.gcm.aadlen, sizeof (c->u_mode.gcm.aadlen));
+      wipememory (c->u_mode.gcm.datalen, sizeof (c->u_mode.gcm.datalen));
+    }
+
+  if (!check)
+    {
+      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;
+    }
+
+  return 0;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_gcm_get_tag (gcry_cipher_hd_t c, unsigned char *outtag,
+                          size_t taglen)
+{
+  /* Outputting authentication tag is part of encryption. */
+  if (c->u_mode.gcm.disallow_encryption_because_of_setiv_in_fips_mode)
+    return GPG_ERR_INV_STATE;
+
+  return _gcry_cipher_gcm_tag (c, outtag, taglen, 0);
+}
+
+gcry_err_code_t
+_gcry_cipher_gcm_check_tag (gcry_cipher_hd_t c, const unsigned char *intag,
+                            size_t taglen)
+{
+  return _gcry_cipher_gcm_tag (c, (unsigned char *) intag, taglen, 1);
+}
diff --git a/cipher/cipher-internal.h b/cipher/cipher-internal.h
new file mode 100644 (file)
index 0000000..cdac445
--- /dev/null
@@ -0,0 +1,322 @@
+/* cipher-internal.h  - Internal defs for cipher.c
+ * Copyright (C) 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 G10_CIPHER_INTERNAL_H
+#define G10_CIPHER_INTERNAL_H
+
+/* The maximum supported size of a block in bytes.  */
+#define MAX_BLOCKSIZE 16
+
+/* Magic values for the context structure.  */
+#define CTX_MAGIC_NORMAL 0x24091964
+#define CTX_MAGIC_SECURE 0x46919042
+
+/* Try to use 16 byte aligned cipher context for better performance.
+   We use the aligned attribute, thus it is only possible to implement
+   this with gcc.  */
+#undef NEED_16BYTE_ALIGNED_CONTEXT
+#ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
+# define NEED_16BYTE_ALIGNED_CONTEXT 1
+#endif
+
+/* Undef this symbol to trade GCM speed for 256 bytes of memory per context */
+#define GCM_USE_TABLES 1
+
+
+/* GCM_USE_INTEL_PCLMUL inidicates whether to compile GCM with Intel PCLMUL
+   code.  */
+#undef GCM_USE_INTEL_PCLMUL
+#if defined(ENABLE_PCLMUL_SUPPORT) && defined(GCM_USE_TABLES)
+# if ((defined(__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__))
+#  if __GNUC__ >= 4
+#   define GCM_USE_INTEL_PCLMUL 1
+#  endif
+# endif
+#endif /* GCM_USE_INTEL_PCLMUL */
+
+
+/* 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
+   context, the align attribute as used in rijndael.c does not work on
+   its own.  Thus we need to make sure that the entire context
+   structure is a aligned on that boundary.  We achieve this by
+   defining a new type and use that instead of our usual alignment
+   type.  */
+typedef union
+{
+  PROPERLY_ALIGNED_TYPE foo;
+#ifdef NEED_16BYTE_ALIGNED_CONTEXT
+  char bar[16] __attribute__ ((aligned (16)));
+#endif
+  char c[1];
+} cipher_context_alignment_t;
+
+
+/* The handle structure.  */
+struct gcry_cipher_handle
+{
+  int magic;
+  size_t actual_handle_size;     /* Allocated size of this handle. */
+  size_t handle_offset;          /* Offset to the malloced block.  */
+  gcry_cipher_spec_t *spec;
+
+  /* The algorithm id.  This is a hack required because the module
+     interface does not easily allow to retrieve this value. */
+  int algo;
+
+  /* A structure with function pointers for bulk operations.  Due to
+     limitations of the module system (we don't want to change the
+     API) we need to keep these function pointers here.  The cipher
+     open function intializes them and the actual encryption routines
+     use them if they are not NULL.  */
+  struct {
+    void (*cfb_enc)(void *context, unsigned char *iv,
+                    void *outbuf_arg, const void *inbuf_arg,
+                    size_t nblocks);
+    void (*cfb_dec)(void *context, unsigned char *iv,
+                    void *outbuf_arg, const void *inbuf_arg,
+                    size_t nblocks);
+    void (*cbc_enc)(void *context, unsigned char *iv,
+                    void *outbuf_arg, const void *inbuf_arg,
+                    size_t nblocks, int cbc_mac);
+    void (*cbc_dec)(void *context, unsigned char *iv,
+                    void *outbuf_arg, const void *inbuf_arg,
+                    size_t nblocks);
+    void (*ctr_enc)(void *context, unsigned char *iv,
+                    void *outbuf_arg, const void *inbuf_arg,
+                    size_t nblocks);
+  } bulk;
+
+
+  int mode;
+  unsigned int flags;
+
+  struct {
+    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. */
+  } 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.  */
+  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.  */
+  union {
+    cipher_context_alignment_t iv_align;
+    unsigned char ctr[MAX_BLOCKSIZE];
+  } u_ctr;
+
+  /* Space to save an IV or CTR for chaining operations.  */
+  unsigned char lastiv[MAX_BLOCKSIZE];
+  int unused;  /* Number of unused bytes in LASTIV. */
+
+  union {
+#ifdef HAVE_U64_TYPEDEF
+    /* Mode specific storage for CCM mode. */
+    struct {
+      u64 encryptlen;
+      u64 aadlen;
+      unsigned int authlen;
+
+      /* Space to save partial input lengths for MAC. */
+      unsigned char macbuf[GCRY_CCM_BLOCK_LEN];
+      int mac_unused;  /* Number of unprocessed bytes in MACBUF. */
+
+      unsigned char s0[GCRY_CCM_BLOCK_LEN];
+
+      unsigned int nonce:1;/* Set to 1 if nonce has been set.  */
+      unsigned int lengths:1; /* Set to 1 if CCM length parameters has been
+                                 processed.  */
+    } ccm;
+#endif
+
+    /* Mode specific storage for CMAC mode. */
+    struct {
+      unsigned int tag:1; /* Set to 1 if tag has been finalized.  */
+
+      /* Subkeys for tag creation, not cleared by gcry_cipher_reset. */
+      unsigned char subkeys[2][MAX_BLOCKSIZE];
+    } cmac;
+
+    /* Mode specific storage for GCM mode. */
+    struct {
+      /* The interim tag for GCM mode.  */
+      union {
+        cipher_context_alignment_t iv_align;
+        unsigned char tag[MAX_BLOCKSIZE];
+      } u_tag;
+
+      /* Space to save partial input lengths for MAC. */
+      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];
+
+      /* encrypted tag counter */
+      unsigned char tagiv[MAX_BLOCKSIZE];
+
+      unsigned int ghash_data_finalized:1;
+      unsigned int ghash_aad_finalized:1;
+
+      unsigned int datalen_over_limits:1;
+      unsigned int disallow_encryption_because_of_setiv_in_fips_mode:1;
+
+      /* --- Following members are not cleared in gcry_cipher_reset --- */
+
+      /* GHASH multiplier from key.  */
+      union {
+        cipher_context_alignment_t iv_align;
+        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
+
+      /* Pre-calculated table for GCM. */
+#ifdef GCM_USE_TABLES
+ #if defined(HAVE_U64_TYPEDEF) && (SIZEOF_UNSIGNED_LONG == 8 \
+                                   || defined(__x86_64__))
+      #define GCM_TABLES_USE_U64 1
+      u64 gcm_table[2 * 16];
+ #else
+      #undef GCM_TABLES_USE_U64
+      u32 gcm_table[4 * 16];
+ #endif
+#endif
+    } gcm;
+  } u_mode;
+
+  /* What follows are two contexts of the cipher in use.  The first
+     one needs to be aligned well enough for the cipher operation
+     whereas the second one is a copy created by cipher_setkey and
+     used by cipher_reset.  That second copy has no need for proper
+     aligment because it is only accessed by memcpy.  */
+  cipher_context_alignment_t context;
+};
+
+
+/*-- cipher-cbc.c --*/
+gcry_err_code_t _gcry_cipher_cbc_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_cbc_decrypt
+/*           */ (gcry_cipher_hd_t c,
+                 unsigned char *outbuf, size_t outbuflen,
+                 const unsigned char *inbuf, size_t inbuflen);
+
+/*-- cipher-cfb.c --*/
+gcry_err_code_t _gcry_cipher_cfb_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_cfb_decrypt
+/*           */ (gcry_cipher_hd_t c,
+                 unsigned char *outbuf, size_t outbuflen,
+                 const unsigned char *inbuf, size_t inbuflen);
+
+
+/*-- cipher-ofb.c --*/
+gcry_err_code_t _gcry_cipher_ofb_encrypt
+/*           */ (gcry_cipher_hd_t c,
+                 unsigned char *outbuf, size_t outbuflen,
+                 const unsigned char *inbuf, size_t inbuflen);
+
+/*-- cipher-ctr.c --*/
+gcry_err_code_t _gcry_cipher_ctr_encrypt
+/*           */ (gcry_cipher_hd_t c,
+                 unsigned char *outbuf, size_t outbuflen,
+                 const unsigned char *inbuf, size_t inbuflen);
+
+
+/*-- cipher-aeswrap.c --*/
+gcry_err_code_t _gcry_cipher_aeswrap_encrypt
+/*           */   (gcry_cipher_hd_t c,
+                   byte *outbuf, size_t outbuflen,
+                   const byte *inbuf, size_t inbuflen);
+gcry_err_code_t _gcry_cipher_aeswrap_decrypt
+/*           */   (gcry_cipher_hd_t c,
+                   byte *outbuf, size_t outbuflen,
+                   const byte *inbuf, size_t inbuflen);
+
+
+/*-- cipher-ccm.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);
+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);
+gcry_err_code_t _gcry_cipher_ccm_set_nonce
+/*           */ (gcry_cipher_hd_t c, const unsigned char *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);
+gcry_err_code_t _gcry_cipher_ccm_check_tag
+/*           */ (gcry_cipher_hd_t c,
+                 const unsigned char *intag, size_t taglen);
+
+
+/*-- cipher-gcm.c --*/
+gcry_err_code_t _gcry_cipher_gcm_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_gcm_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_gcm_setiv
+/*           */   (gcry_cipher_hd_t c,
+                   const unsigned char *iv, size_t ivlen);
+gcry_err_code_t _gcry_cipher_gcm_authenticate
+/*           */   (gcry_cipher_hd_t c,
+                   const unsigned char *aadbuf, size_t aadbuflen);
+gcry_err_code_t _gcry_cipher_gcm_get_tag
+/*           */   (gcry_cipher_hd_t c,
+                   unsigned char *outtag, size_t taglen);
+gcry_err_code_t _gcry_cipher_gcm_check_tag
+/*           */   (gcry_cipher_hd_t c,
+                   const unsigned char *intag, size_t taglen);
+void _gcry_cipher_gcm_setkey
+/*           */   (gcry_cipher_hd_t c);
+
+
+#endif /*G10_CIPHER_INTERNAL_H*/
diff --git a/cipher/cipher-ofb.c b/cipher/cipher-ofb.c
new file mode 100644 (file)
index 0000000..3842774
--- /dev/null
@@ -0,0 +1,96 @@
+/* cipher-ofb.c  - Generic OFB mode implementation
+ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
+ *               2005, 2007, 2008, 2009, 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/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "ath.h"
+#include "bufhelp.h"
+#include "./cipher-internal.h"
+
+
+gcry_err_code_t
+_gcry_cipher_ofb_encrypt (gcry_cipher_hd_t c,
+                          unsigned char *outbuf, size_t outbuflen,
+                          const unsigned char *inbuf, size_t inbuflen)
+{
+  unsigned char *ivp;
+  gcry_cipher_encrypt_t enc_fn = c->spec->encrypt;
+  size_t blocksize = c->spec->blocksize;
+  unsigned int burn, nburn;
+
+  if (outbuflen < inbuflen)
+    return GPG_ERR_BUFFER_TOO_SHORT;
+
+  if ( inbuflen <= c->unused )
+    {
+      /* Short enough to be encoded by the remaining XOR mask. */
+      /* XOR the input with the IV */
+      ivp = c->u_iv.iv + blocksize - c->unused;
+      buf_xor(outbuf, ivp, inbuf, inbuflen);
+      c->unused -= inbuflen;
+      return 0;
+    }
+
+  burn = 0;
+
+  if( c->unused )
+    {
+      inbuflen -= c->unused;
+      ivp = c->u_iv.iv + blocksize - c->unused;
+      buf_xor(outbuf, ivp, inbuf, c->unused);
+      outbuf += c->unused;
+      inbuf += c->unused;
+      c->unused = 0;
+    }
+
+  /* Now we can process complete blocks. */
+  while ( inbuflen >= blocksize )
+    {
+      /* Encrypt the IV (and save the current one). */
+      nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+      burn = nburn > burn ? nburn : burn;
+      buf_xor(outbuf, c->u_iv.iv, inbuf, blocksize);
+      outbuf += blocksize;
+      inbuf += blocksize;
+      inbuflen -= blocksize;
+    }
+  if ( inbuflen )
+    { /* process the remaining bytes */
+      nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
+      burn = nburn > burn ? nburn : burn;
+      c->unused = blocksize;
+      c->unused -= inbuflen;
+      buf_xor(outbuf, c->u_iv.iv, inbuf, inbuflen);
+      outbuf += inbuflen;
+      inbuf += inbuflen;
+      inbuflen = 0;
+    }
+
+  if (burn > 0)
+    _gcry_burn_stack (burn + 4 * sizeof(void *));
+
+  return 0;
+}
diff --git a/cipher/cipher-selftest.c b/cipher/cipher-selftest.c
new file mode 100644 (file)
index 0000000..bb33d94
--- /dev/null
@@ -0,0 +1,470 @@
+/* cipher-selftest.c - Helper functions for bulk encryption selftests.
+ *     Copyright © 2013 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>
+#ifdef HAVE_SYSLOG
+# include <syslog.h>
+#endif /*HAVE_SYSLOG*/
+
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+#include "cipher-selftest.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
+
+/* 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
+
+
+/* Run the self-tests for <block cipher>-CBC-<block size>, tests bulk CBC
+   decryption.  Returns NULL on success. */
+const char *
+_gcry_selftest_helper_cbc (const char *cipher, gcry_cipher_setkey_t setkey_func,
+                          gcry_cipher_encrypt_t encrypt_one,
+                          gcry_cipher_bulk_cbc_dec_t bulk_cbc_dec,
+                          const int nblocks, const int blocksize,
+                          const int context_size)
+{
+  int i, offs;
+  unsigned char *ctx, *plaintext, *plaintext2, *ciphertext, *iv, *iv2, *mem;
+  unsigned int ctx_aligned_size, memsize;
+
+  static const unsigned char key[16] ATTR_ALIGNED_16 = {
+      0x66,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,
+      0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x22
+    };
+
+  /* Allocate buffers, align first two elements to 16 bytes and latter to
+     block size.  */
+  ctx_aligned_size = context_size + 15;
+  ctx_aligned_size -= ctx_aligned_size & 0xf;
+
+  memsize = ctx_aligned_size + (blocksize * 2) + (blocksize * nblocks * 3) + 16;
+
+  mem = xtrycalloc (1, memsize);
+  if (!mem)
+    return "failed to allocate memory";
+
+  offs = (16 - ((uintptr_t)mem & 15)) & 15;
+  ctx = (void*)(mem + offs);
+  iv = ctx + ctx_aligned_size;
+  iv2 = iv + blocksize;
+  plaintext = iv2 + blocksize;
+  plaintext2 = plaintext + nblocks * blocksize;
+  ciphertext = plaintext2 + nblocks * blocksize;
+
+  /* Initialize ctx */
+  setkey_func (ctx, key, sizeof(key));
+
+  /* Test single block code path */
+  memset (iv, 0x4e, blocksize);
+  memset (iv2, 0x4e, blocksize);
+  for (i = 0; i < blocksize; i++)
+    plaintext[i] = i;
+
+  /* CBC manually.  */
+  buf_xor (ciphertext, iv, plaintext, blocksize);
+  encrypt_one (ctx, ciphertext, ciphertext);
+  memcpy (iv, ciphertext, blocksize);
+
+  /* CBC decrypt.  */
+  bulk_cbc_dec (ctx, iv2, plaintext2, ciphertext, 1);
+  if (memcmp (plaintext2, plaintext, blocksize))
+    {
+      xfree (mem);
+#ifdef HAVE_SYSLOG
+      syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+              "%s-CBC-%d test failed (plaintext mismatch)", cipher,
+             blocksize * 8);
+#endif
+      return "selftest for CBC failed - see syslog for details";
+    }
+
+  if (memcmp (iv2, iv, blocksize))
+    {
+      xfree (mem);
+#ifdef HAVE_SYSLOG
+      syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+              "%s-CBC-%d test failed (IV mismatch)", cipher, blocksize * 8);
+#endif
+      return "selftest for CBC failed - see syslog for details";
+    }
+
+  /* Test parallelized code paths */
+  memset (iv, 0x5f, blocksize);
+  memset (iv2, 0x5f, blocksize);
+
+  for (i = 0; i < nblocks * blocksize; i++)
+    plaintext[i] = i;
+
+  /* Create CBC ciphertext manually.  */
+  for (i = 0; i < nblocks * blocksize; i+=blocksize)
+    {
+      buf_xor (&ciphertext[i], iv, &plaintext[i], blocksize);
+      encrypt_one (ctx, &ciphertext[i], &ciphertext[i]);
+      memcpy (iv, &ciphertext[i], blocksize);
+    }
+
+  /* Decrypt using bulk CBC and compare result.  */
+  bulk_cbc_dec (ctx, iv2, plaintext2, ciphertext, nblocks);
+
+  if (memcmp (plaintext2, plaintext, nblocks * blocksize))
+    {
+      xfree (mem);
+#ifdef HAVE_SYSLOG
+      syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+              "%s-CBC-%d test failed (plaintext mismatch, parallel path)",
+             cipher, blocksize * 8);
+#endif
+      return "selftest for CBC failed - see syslog for details";
+    }
+  if (memcmp (iv2, iv, blocksize))
+    {
+      xfree (mem);
+#ifdef HAVE_SYSLOG
+      syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+              "%s-CBC-%d test failed (IV mismatch, parallel path)",
+             cipher, blocksize * 8);
+#endif
+      return "selftest for CBC failed - see syslog for details";
+    }
+
+  xfree (mem);
+  return NULL;
+}
+
+/* Run the self-tests for <block cipher>-CFB-<block size>, tests bulk CFB
+   decryption.  Returns NULL on success. */
+const char *
+_gcry_selftest_helper_cfb (const char *cipher, gcry_cipher_setkey_t setkey_func,
+                          gcry_cipher_encrypt_t encrypt_one,
+                          gcry_cipher_bulk_cfb_dec_t bulk_cfb_dec,
+                          const int nblocks, const int blocksize,
+                          const int context_size)
+{
+  int i, offs;
+  unsigned char *ctx, *plaintext, *plaintext2, *ciphertext, *iv, *iv2, *mem;
+  unsigned int ctx_aligned_size, memsize;
+
+  static const unsigned char key[16] ATTR_ALIGNED_16 = {
+      0x11,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,
+      0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x33
+    };
+
+  /* Allocate buffers, align first two elements to 16 bytes and latter to
+     block size.  */
+  ctx_aligned_size = context_size + 15;
+  ctx_aligned_size -= ctx_aligned_size & 0xf;
+
+  memsize = ctx_aligned_size + (blocksize * 2) + (blocksize * nblocks * 3) + 16;
+
+  mem = xtrycalloc (1, memsize);
+  if (!mem)
+    return "failed to allocate memory";
+
+  offs = (16 - ((uintptr_t)mem & 15)) & 15;
+  ctx = (void*)(mem + offs);
+  iv = ctx + ctx_aligned_size;
+  iv2 = iv + blocksize;
+  plaintext = iv2 + blocksize;
+  plaintext2 = plaintext + nblocks * blocksize;
+  ciphertext = plaintext2 + nblocks * blocksize;
+
+  /* Initialize ctx */
+  setkey_func (ctx, key, sizeof(key));
+
+  /* Test single block code path */
+  memset(iv, 0xd3, blocksize);
+  memset(iv2, 0xd3, blocksize);
+  for (i = 0; i < blocksize; i++)
+    plaintext[i] = i;
+
+  /* CFB manually.  */
+  encrypt_one (ctx, ciphertext, iv);
+  buf_xor_2dst (iv, ciphertext, plaintext, blocksize);
+
+  /* CFB decrypt.  */
+  bulk_cfb_dec (ctx, iv2, plaintext2, ciphertext, 1);
+  if (memcmp(plaintext2, plaintext, blocksize))
+    {
+      xfree(mem);
+#ifdef HAVE_SYSLOG
+      syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+              "%s-CFB-%d test failed (plaintext mismatch)", cipher,
+             blocksize * 8);
+#endif
+      return "selftest for CFB failed - see syslog for details";
+    }
+
+  if (memcmp(iv2, iv, blocksize))
+    {
+      xfree(mem);
+#ifdef HAVE_SYSLOG
+      syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+              "%s-CFB-%d test failed (IV mismatch)", cipher, blocksize * 8);
+#endif
+      return "selftest for CFB failed - see syslog for details";
+    }
+
+  /* Test parallelized code paths */
+  memset(iv, 0xe6, blocksize);
+  memset(iv2, 0xe6, blocksize);
+
+  for (i = 0; i < nblocks * blocksize; i++)
+    plaintext[i] = i;
+
+  /* Create CFB ciphertext manually.  */
+  for (i = 0; i < nblocks * blocksize; i+=blocksize)
+    {
+      encrypt_one (ctx, &ciphertext[i], iv);
+      buf_xor_2dst (iv, &ciphertext[i], &plaintext[i], blocksize);
+    }
+
+  /* Decrypt using bulk CBC and compare result.  */
+  bulk_cfb_dec (ctx, iv2, plaintext2, ciphertext, nblocks);
+
+  if (memcmp(plaintext2, plaintext, nblocks * blocksize))
+    {
+      xfree(mem);
+#ifdef HAVE_SYSLOG
+      syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+              "%s-CFB-%d test failed (plaintext mismatch, parallel path)",
+              cipher, blocksize * 8);
+#endif
+      return "selftest for CFB failed - see syslog for details";
+    }
+  if (memcmp(iv2, iv, blocksize))
+    {
+      xfree(mem);
+#ifdef HAVE_SYSLOG
+      syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+              "%s-CFB-%d test failed (IV mismatch, parallel path)", cipher,
+             blocksize * 8);
+#endif
+      return "selftest for CFB failed - see syslog for details";
+    }
+
+  xfree(mem);
+  return NULL;
+}
+
+/* Run the self-tests for <block cipher>-CTR-<block size>, tests IV increment
+   of bulk CTR encryption.  Returns NULL on success. */
+const char *
+_gcry_selftest_helper_ctr (const char *cipher, gcry_cipher_setkey_t setkey_func,
+                          gcry_cipher_encrypt_t encrypt_one,
+                          gcry_cipher_bulk_ctr_enc_t bulk_ctr_enc,
+                          const int nblocks, const int blocksize,
+                          const int context_size)
+{
+  int i, j, offs, diff;
+  unsigned char *ctx, *plaintext, *plaintext2, *ciphertext, *ciphertext2,
+                *iv, *iv2, *mem;
+  unsigned int ctx_aligned_size, memsize;
+
+  static const unsigned char key[16] ATTR_ALIGNED_16 = {
+      0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,
+      0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21
+    };
+
+  /* Allocate buffers, align first two elements to 16 bytes and latter to
+     block size.  */
+  ctx_aligned_size = context_size + 15;
+  ctx_aligned_size -= ctx_aligned_size & 0xf;
+
+  memsize = ctx_aligned_size + (blocksize * 2) + (blocksize * nblocks * 4) + 16;
+
+  mem = xtrycalloc (1, memsize);
+  if (!mem)
+    return "failed to allocate memory";
+
+  offs = (16 - ((uintptr_t)mem & 15)) & 15;
+  ctx = (void*)(mem + offs);
+  iv = ctx + ctx_aligned_size;
+  iv2 = iv + blocksize;
+  plaintext = iv2 + blocksize;
+  plaintext2 = plaintext + nblocks * blocksize;
+  ciphertext = plaintext2 + nblocks * blocksize;
+  ciphertext2 = ciphertext + nblocks * blocksize;
+
+  /* Initialize ctx */
+  setkey_func (ctx, key, sizeof(key));
+
+  /* Test single block code path */
+  memset (iv, 0xff, blocksize);
+  for (i = 0; i < blocksize; i++)
+    plaintext[i] = i;
+
+  /* CTR manually.  */
+  encrypt_one (ctx, ciphertext, iv);
+  for (i = 0; i < blocksize; i++)
+    ciphertext[i] ^= plaintext[i];
+  for (i = blocksize; i > 0; i--)
+    {
+      iv[i-1]++;
+      if (iv[i-1])
+        break;
+    }
+
+  memset (iv2, 0xff, blocksize);
+  bulk_ctr_enc (ctx, iv2, plaintext2, ciphertext, 1);
+
+  if (memcmp (plaintext2, plaintext, blocksize))
+    {
+      xfree (mem);
+#ifdef HAVE_SYSLOG
+      syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+              "%s-CTR-%d test failed (plaintext mismatch)", cipher,
+             blocksize * 8);
+#endif
+      return "selftest for CTR failed - see syslog for details";
+    }
+
+  if (memcmp (iv2, iv, blocksize))
+    {
+      xfree (mem);
+#ifdef HAVE_SYSLOG
+      syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+              "%s-CTR-%d test failed (IV mismatch)", cipher,
+             blocksize * 8);
+#endif
+      return "selftest for CTR failed - see syslog for details";
+    }
+
+  /* Test bulk encryption with typical IV. */
+  memset(iv, 0x57, blocksize-4);
+  iv[blocksize-1] = 1;
+  iv[blocksize-2] = 0;
+  iv[blocksize-3] = 0;
+  iv[blocksize-4] = 0;
+  memset(iv2, 0x57, blocksize-4);
+  iv2[blocksize-1] = 1;
+  iv2[blocksize-2] = 0;
+  iv2[blocksize-3] = 0;
+  iv2[blocksize-4] = 0;
+
+  for (i = 0; i < blocksize * nblocks; i++)
+    plaintext2[i] = plaintext[i] = i;
+
+  /* Create CTR ciphertext manually.  */
+  for (i = 0; i < blocksize * nblocks; i+=blocksize)
+    {
+      encrypt_one (ctx, &ciphertext[i], iv);
+      for (j = 0; j < blocksize; j++)
+        ciphertext[i+j] ^= plaintext[i+j];
+      for (j = blocksize; j > 0; j--)
+        {
+          iv[j-1]++;
+          if (iv[j-1])
+            break;
+        }
+    }
+
+  bulk_ctr_enc (ctx, iv2, ciphertext2, plaintext2, nblocks);
+
+  if (memcmp (ciphertext2, ciphertext, blocksize * nblocks))
+    {
+      xfree (mem);
+#ifdef HAVE_SYSLOG
+      syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+              "%s-CTR-%d test failed (ciphertext mismatch, bulk)", cipher,
+              blocksize * 8);
+#endif
+      return "selftest for CTR failed - see syslog for details";
+    }
+  if (memcmp(iv2, iv, blocksize))
+    {
+      xfree (mem);
+#ifdef HAVE_SYSLOG
+      syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+              "%s-CTR-%d test failed (IV mismatch, bulk)", cipher,
+              blocksize * 8);
+#endif
+      return "selftest for CTR failed - see syslog for details";
+    }
+
+  /* Test parallelized code paths (check counter overflow handling) */
+  for (diff = 0; diff < nblocks; diff++) {
+    memset(iv, 0xff, blocksize);
+    iv[blocksize-1] -= diff;
+    iv[0] = iv[1] = 0;
+    iv[2] = 0x07;
+
+    for (i = 0; i < blocksize * nblocks; i++)
+      plaintext[i] = i;
+
+    /* Create CTR ciphertext manually.  */
+    for (i = 0; i < blocksize * nblocks; i+=blocksize)
+      {
+        encrypt_one (ctx, &ciphertext[i], iv);
+        for (j = 0; j < blocksize; j++)
+          ciphertext[i+j] ^= plaintext[i+j];
+        for (j = blocksize; j > 0; j--)
+          {
+            iv[j-1]++;
+            if (iv[j-1])
+              break;
+          }
+      }
+
+    /* Decrypt using bulk CTR and compare result.  */
+    memset(iv2, 0xff, blocksize);
+    iv2[blocksize-1] -= diff;
+    iv2[0] = iv2[1] = 0;
+    iv2[2] = 0x07;
+
+    bulk_ctr_enc (ctx, iv2, plaintext2, ciphertext, nblocks);
+
+    if (memcmp (plaintext2, plaintext, blocksize * nblocks))
+      {
+        xfree (mem);
+#ifdef HAVE_SYSLOG
+        syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+                "%s-CTR-%d test failed (plaintext mismatch, diff: %d)", cipher,
+               blocksize * 8, diff);
+#endif
+        return "selftest for CTR failed - see syslog for details";
+      }
+    if (memcmp(iv2, iv, blocksize))
+      {
+        xfree (mem);
+#ifdef HAVE_SYSLOG
+        syslog (LOG_USER|LOG_WARNING, "Libgcrypt warning: "
+                "%s-CTR-%d test failed (IV mismatch, diff: %d)", cipher,
+               blocksize * 8, diff);
+#endif
+        return "selftest for CTR failed - see syslog for details";
+      }
+  }
+
+  xfree (mem);
+  return NULL;
+}
diff --git a/cipher/cipher-selftest.h b/cipher/cipher-selftest.h
new file mode 100644 (file)
index 0000000..3a0fe98
--- /dev/null
@@ -0,0 +1,67 @@
+/* cipher-selftest.h - Helper functions for bulk encryption selftests.
+ *     Copyright © 2013 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_SELFTEST_HELP_H
+#define G10_SELFTEST_HELP_H
+
+#include <config.h>
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+
+typedef void (*gcry_cipher_bulk_cbc_dec_t)(void *context, unsigned char *iv,
+                                          void *outbuf_arg,
+                                          const void *inbuf_arg,
+                                          size_t nblocks);
+
+typedef void (*gcry_cipher_bulk_cfb_dec_t)(void *context, unsigned char *iv,
+                                          void *outbuf_arg,
+                                          const void *inbuf_arg,
+                                          size_t nblocks);
+
+typedef void (*gcry_cipher_bulk_ctr_enc_t)(void *context, unsigned char *iv,
+                                          void *outbuf_arg,
+                                          const void *inbuf_arg,
+                                          size_t nblocks);
+
+/* Helper function for bulk CBC decryption selftest */
+const char *
+_gcry_selftest_helper_cbc (const char *cipher, gcry_cipher_setkey_t setkey,
+                          gcry_cipher_encrypt_t encrypt_one,
+                          gcry_cipher_bulk_cbc_dec_t bulk_cbc_dec,
+                          const int nblocks, const int blocksize,
+                          const int context_size);
+
+/* Helper function for bulk CFB decryption selftest */
+const char *
+_gcry_selftest_helper_cfb (const char *cipher, gcry_cipher_setkey_t setkey,
+                          gcry_cipher_encrypt_t encrypt_one,
+                          gcry_cipher_bulk_cfb_dec_t bulk_cfb_dec,
+                          const int nblocks, const int blocksize,
+                          const int context_size);
+
+/* Helper function for bulk CTR encryption selftest */
+const char *
+_gcry_selftest_helper_ctr (const char *cipher, gcry_cipher_setkey_t setkey,
+                          gcry_cipher_encrypt_t encrypt_one,
+                          gcry_cipher_bulk_ctr_enc_t bulk_ctr_enc,
+                          const int nblocks, const int blocksize,
+                          const int context_size);
+
+#endif /*G10_SELFTEST_HELP_H*/
index b0a532a..8c5a0b4 100644 (file)
@@ -1,6 +1,7 @@
 /* cipher.c  - cipher dispatcher
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
- *               2005, 2007, 2008, 2009 Free Software Foundation, Inc.
+ *               2005, 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2013 g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
 #include "g10lib.h"
 #include "cipher.h"
 #include "ath.h"
+#include "./cipher-internal.h"
 
-#define MAX_BLOCKSIZE 16
-#define TABLE_SIZE 14
-#define CTX_MAGIC_NORMAL 0x24091964
-#define CTX_MAGIC_SECURE 0x46919042
-
-/* Try to use 16 byte aligned cipher context for better performance.
-   We use the aligned attribute, thus it is only possible to implement
-   this with gcc.  */
-#undef NEED_16BYTE_ALIGNED_CONTEXT
-#if defined (__GNUC__)
-# define NEED_16BYTE_ALIGNED_CONTEXT 1
-#endif
-
-/* A dummy extraspec so that we do not need to tests the extraspec
-   field from the module specification against NULL and instead
-   directly test the respective fields of extraspecs.  */
-static cipher_extra_spec_t dummy_extra_spec;
 
 /* This is the list of the default ciphers, which are included in
    libgcrypt.  */
-static struct cipher_table_entry
-{
-  gcry_cipher_spec_t *cipher;
-  cipher_extra_spec_t *extraspec;
-  unsigned int algorithm;
-  int fips_allowed;
-} cipher_table[] =
+static gcry_cipher_spec_t *cipher_list[] =
   {
 #if USE_BLOWFISH
-    { &_gcry_cipher_spec_blowfish,
-      &dummy_extra_spec,                  GCRY_CIPHER_BLOWFISH },
+     &_gcry_cipher_spec_blowfish,
 #endif
 #if USE_DES
-    { &_gcry_cipher_spec_des,
-      &dummy_extra_spec,                  GCRY_CIPHER_DES },
-    { &_gcry_cipher_spec_tripledes,
-      &_gcry_cipher_extraspec_tripledes,  GCRY_CIPHER_3DES, 1 },
+     &_gcry_cipher_spec_des,
+     &_gcry_cipher_spec_tripledes,
 #endif
 #if USE_ARCFOUR
-    { &_gcry_cipher_spec_arcfour,
-      &dummy_extra_spec,                  GCRY_CIPHER_ARCFOUR },
+     &_gcry_cipher_spec_arcfour,
 #endif
 #if USE_CAST5
-    { &_gcry_cipher_spec_cast5,
-      &dummy_extra_spec,                  GCRY_CIPHER_CAST5 },
+     &_gcry_cipher_spec_cast5,
 #endif
 #if USE_AES
-    { &_gcry_cipher_spec_aes,
-      &_gcry_cipher_extraspec_aes,        GCRY_CIPHER_AES,    1 },
-    { &_gcry_cipher_spec_aes192,
-      &_gcry_cipher_extraspec_aes192,     GCRY_CIPHER_AES192, 1 },
-    { &_gcry_cipher_spec_aes256,
-      &_gcry_cipher_extraspec_aes256,     GCRY_CIPHER_AES256, 1 },
+     &_gcry_cipher_spec_aes,
+     &_gcry_cipher_spec_aes192,
+     &_gcry_cipher_spec_aes256,
 #endif
 #if USE_TWOFISH
-    { &_gcry_cipher_spec_twofish,
-      &dummy_extra_spec,                  GCRY_CIPHER_TWOFISH },
-    { &_gcry_cipher_spec_twofish128,
-      &dummy_extra_spec,                  GCRY_CIPHER_TWOFISH128 },
+     &_gcry_cipher_spec_twofish,
+     &_gcry_cipher_spec_twofish128,
 #endif
 #if USE_SERPENT
-    { &_gcry_cipher_spec_serpent128,
-      &dummy_extra_spec,                  GCRY_CIPHER_SERPENT128 },
-    { &_gcry_cipher_spec_serpent192,
-      &dummy_extra_spec,                  GCRY_CIPHER_SERPENT192 },
-    { &_gcry_cipher_spec_serpent256,
-      &dummy_extra_spec,                  GCRY_CIPHER_SERPENT256 },
+     &_gcry_cipher_spec_serpent128,
+     &_gcry_cipher_spec_serpent192,
+     &_gcry_cipher_spec_serpent256,
 #endif
 #if USE_RFC2268
-    { &_gcry_cipher_spec_rfc2268_40,
-      &dummy_extra_spec,                  GCRY_CIPHER_RFC2268_40 },
+     &_gcry_cipher_spec_rfc2268_40,
+     &_gcry_cipher_spec_rfc2268_128,
 #endif
 #if USE_SEED
-    { &_gcry_cipher_spec_seed,
-      &dummy_extra_spec,                  GCRY_CIPHER_SEED },
+     &_gcry_cipher_spec_seed,
 #endif
 #if USE_CAMELLIA
-    { &_gcry_cipher_spec_camellia128,
-      &dummy_extra_spec,                  GCRY_CIPHER_CAMELLIA128 },
-    { &_gcry_cipher_spec_camellia192,
-      &dummy_extra_spec,                  GCRY_CIPHER_CAMELLIA192 },
-    { &_gcry_cipher_spec_camellia256,
-      &dummy_extra_spec,                  GCRY_CIPHER_CAMELLIA256 },
+     &_gcry_cipher_spec_camellia128,
+     &_gcry_cipher_spec_camellia192,
+     &_gcry_cipher_spec_camellia256,
 #endif
-    { NULL                    }
-  };
-
-/* List of registered ciphers.  */
-static gcry_module_t ciphers_registered;
-
-/* This is the lock protecting CIPHERS_REGISTERED.  */
-static ath_mutex_t ciphers_registered_lock = ATH_MUTEX_INITIALIZER;
-
-/* Flag to check whether the default ciphers have already been
-   registered.  */
-static int default_ciphers_registered;
-
-/* Convenient macro for registering the default ciphers.  */
-#define REGISTER_DEFAULT_CIPHERS                   \
-  do                                               \
-    {                                              \
-      ath_mutex_lock (&ciphers_registered_lock);   \
-      if (! default_ciphers_registered)            \
-        {                                          \
-          cipher_register_default ();              \
-          default_ciphers_registered = 1;          \
-        }                                          \
-      ath_mutex_unlock (&ciphers_registered_lock); \
-    }                                              \
-  while (0)
-
-
-/* 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
-   context, the align attribute as used in rijndael.c does not work on
-   its own.  Thus we need to make sure that the entire context
-   structure is a aligned on that boundary.  We achieve this by
-   defining a new type and use that instead of our usual alignment
-   type.  */
-typedef union
-{
-  PROPERLY_ALIGNED_TYPE foo;
-#ifdef NEED_16BYTE_ALIGNED_CONTEXT
-  char bar[16] __attribute__ ((aligned (16)));
+#ifdef USE_IDEA
+     &_gcry_cipher_spec_idea,
 #endif
-  char c[1];
-} cipher_context_alignment_t;
-
+#if USE_SALSA20
+     &_gcry_cipher_spec_salsa20,
+     &_gcry_cipher_spec_salsa20r12,
+#endif
+#if USE_GOST28147
+     &_gcry_cipher_spec_gost28147,
+#endif
+    NULL
+  };
 
-/* The handle structure.  */
-struct gcry_cipher_handle
-{
-  int magic;
-  size_t actual_handle_size;     /* Allocated size of this handle. */
-  size_t handle_offset;          /* Offset to the malloced block.  */
-  gcry_cipher_spec_t *cipher;
-  cipher_extra_spec_t *extraspec;
-  gcry_module_t module;
-
-  /* The algorithm id.  This is a hack required because the module
-     interface does not easily allow to retrieve this value. */
-  int algo;
-
-  /* A structure with function pointers for bulk operations.  Due to
-     limitations of the module system (we don't want to change the
-     API) we need to keep these function pointers here.  The cipher
-     open function intializes them and the actual encryption routines
-     use them if they are not NULL.  */
-  struct {
-    void (*cfb_enc)(void *context, unsigned char *iv,
-                    void *outbuf_arg, const void *inbuf_arg,
-                    unsigned int nblocks);
-    void (*cfb_dec)(void *context, unsigned char *iv,
-                    void *outbuf_arg, const void *inbuf_arg,
-                    unsigned int nblocks);
-    void (*cbc_enc)(void *context, unsigned char *iv,
-                    void *outbuf_arg, const void *inbuf_arg,
-                    unsigned int nblocks, int cbc_mac);
-    void (*cbc_dec)(void *context, unsigned char *iv,
-                    void *outbuf_arg, const void *inbuf_arg,
-                    unsigned int nblocks);
-    void (*ctr_enc)(void *context, unsigned char *iv,
-                    void *outbuf_arg, const void *inbuf_arg,
-                    unsigned int nblocks);
-  } bulk;
-
-
-  int mode;
-  unsigned int flags;
-
-  struct {
-    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.  */
-  } 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.  */
-  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.  */
-  union {
-    cipher_context_alignment_t iv_align;
-    unsigned char ctr[MAX_BLOCKSIZE];
-  } u_ctr;
-
-  /* Space to save an IV or CTR for chaining operations.  */
-  unsigned char lastiv[MAX_BLOCKSIZE];
-  int unused;  /* Number of unused bytes in LASTIV. */
-
-  /* What follows are two contexts of the cipher in use.  The first
-     one needs to be aligned well enough for the cipher operation
-     whereas the second one is a copy created by cipher_setkey and
-     used by cipher_reset.  That second copy has no need for proper
-     aligment because it is only accessed by memcpy.  */
-  cipher_context_alignment_t context;
-};
 
 
 \f
-/* These dummy functions are used in case a cipher implementation
-   refuses to provide it's own functions.  */
-
-static gcry_err_code_t
-dummy_setkey (void *c, const unsigned char *key, unsigned int keylen)
+static int
+map_algo (int algo)
 {
-  (void)c;
-  (void)key;
-  (void)keylen;
-  return GPG_ERR_NO_ERROR;
+  return algo;
 }
 
-static void
-dummy_encrypt_block (void *c,
-                    unsigned char *outbuf, const unsigned char *inbuf)
-{
-  (void)c;
-  (void)outbuf;
-  (void)inbuf;
-  BUG();
-}
 
-static void
-dummy_decrypt_block (void *c,
-                    unsigned char *outbuf, const unsigned char *inbuf)
+/* Return the spec structure for the cipher algorithm ALGO.  For
+   an unknown algorithm NULL is returned.  */
+static gcry_cipher_spec_t *
+spec_from_algo (int algo)
 {
-  (void)c;
-  (void)outbuf;
-  (void)inbuf;
-  BUG();
-}
+  int idx;
+  gcry_cipher_spec_t *spec;
 
-static void
-dummy_encrypt_stream (void *c,
-                     unsigned char *outbuf, const unsigned char *inbuf,
-                     unsigned int n)
-{
-  (void)c;
-  (void)outbuf;
-  (void)inbuf;
-  (void)n;
-  BUG();
-}
+  algo = map_algo (algo);
 
-static void
-dummy_decrypt_stream (void *c,
-                     unsigned char *outbuf, const unsigned char *inbuf,
-                     unsigned int n)
-{
-  (void)c;
-  (void)outbuf;
-  (void)inbuf;
-  (void)n;
-  BUG();
+  for (idx = 0; (spec = cipher_list[idx]); idx++)
+    if (algo == spec->algo)
+      return spec;
+  return NULL;
 }
 
-\f
-/* Internal function.  Register all the ciphers included in
-   CIPHER_TABLE.  Note, that this function gets only used by the macro
-   REGISTER_DEFAULT_CIPHERS which protects it using a mutex. */
-static void
-cipher_register_default (void)
+
+/* Lookup a cipher's spec by its name.  */
+static gcry_cipher_spec_t *
+spec_from_name (const char *name)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  int i;
+  gcry_cipher_spec_t *spec;
+  int idx;
+  const char **aliases;
 
-  for (i = 0; !err && cipher_table[i].cipher; i++)
+  for (idx=0; (spec = cipher_list[idx]); idx++)
     {
-      if (! cipher_table[i].cipher->setkey)
-       cipher_table[i].cipher->setkey = dummy_setkey;
-      if (! cipher_table[i].cipher->encrypt)
-       cipher_table[i].cipher->encrypt = dummy_encrypt_block;
-      if (! cipher_table[i].cipher->decrypt)
-       cipher_table[i].cipher->decrypt = dummy_decrypt_block;
-      if (! cipher_table[i].cipher->stencrypt)
-       cipher_table[i].cipher->stencrypt = dummy_encrypt_stream;
-      if (! cipher_table[i].cipher->stdecrypt)
-       cipher_table[i].cipher->stdecrypt = dummy_decrypt_stream;
-
-      if ( fips_mode () && !cipher_table[i].fips_allowed )
-        continue;
-
-      err = _gcry_module_add (&ciphers_registered,
-                             cipher_table[i].algorithm,
-                             (void *) cipher_table[i].cipher,
-                             (void *) cipher_table[i].extraspec,
-                             NULL);
+      if (!stricmp (name, spec->name))
+        return spec;
+      if (spec->aliases)
+        {
+          for (aliases = spec->aliases; *aliases; aliases++)
+            if (!stricmp (name, *aliases))
+              return spec;
+        }
     }
 
-  if (err)
-    BUG ();
+  return NULL;
 }
 
-/* Internal callback function.  Used via _gcry_module_lookup.  */
-static int
-gcry_cipher_lookup_func_name (void *spec, void *data)
-{
-  gcry_cipher_spec_t *cipher = (gcry_cipher_spec_t *) spec;
-  char *name = (char *) data;
-  const char **aliases = cipher->aliases;
-  int i, ret = ! stricmp (name, cipher->name);
-
-  if (aliases)
-    for (i = 0; aliases[i] && (! ret); i++)
-      ret = ! stricmp (name, aliases[i]);
-
-  return ret;
-}
-
-/* Internal callback function.  Used via _gcry_module_lookup.  */
-static int
-gcry_cipher_lookup_func_oid (void *spec, void *data)
-{
-  gcry_cipher_spec_t *cipher = (gcry_cipher_spec_t *) spec;
-  char *oid = (char *) data;
-  gcry_cipher_oid_spec_t *oid_specs = cipher->oids;
-  int ret = 0, i;
-
-  if (oid_specs)
-    for (i = 0; oid_specs[i].oid && (! ret); i++)
-      if (! stricmp (oid, oid_specs[i].oid))
-       ret = 1;
-
-  return ret;
-}
-
-/* Internal function.  Lookup a cipher entry by it's name.  */
-static gcry_module_t
-gcry_cipher_lookup_name (const char *name)
-{
-  gcry_module_t cipher;
-
-  cipher = _gcry_module_lookup (ciphers_registered, (void *) name,
-                               gcry_cipher_lookup_func_name);
-
-  return cipher;
-}
 
-/* Internal function.  Lookup a cipher entry by it's oid.  */
-static gcry_module_t
-gcry_cipher_lookup_oid (const char *oid)
+/* Lookup a cipher's spec by its OID.  */
+static gcry_cipher_spec_t *
+spec_from_oid (const char *oid)
 {
-  gcry_module_t cipher;
+  gcry_cipher_spec_t *spec;
+  gcry_cipher_oid_spec_t *oid_specs;
+  int idx, j;
 
-  cipher = _gcry_module_lookup (ciphers_registered, (void *) oid,
-                               gcry_cipher_lookup_func_oid);
-
-  return cipher;
-}
-
-/* Register a new cipher module whose specification can be found in
-   CIPHER.  On success, a new algorithm ID is stored in ALGORITHM_ID
-   and a pointer representhing this module is stored in MODULE.  */
-gcry_error_t
-_gcry_cipher_register (gcry_cipher_spec_t *cipher,
-                       cipher_extra_spec_t *extraspec,
-                       int *algorithm_id,
-                       gcry_module_t *module)
-{
-  gcry_err_code_t err = 0;
-  gcry_module_t mod;
-
-  /* We do not support module loading in fips mode.  */
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
-
-  ath_mutex_lock (&ciphers_registered_lock);
-  err = _gcry_module_add (&ciphers_registered, 0,
-                         (void *)cipher,
-                         (void *)(extraspec? extraspec : &dummy_extra_spec),
-                          &mod);
-  ath_mutex_unlock (&ciphers_registered_lock);
-
-  if (! err)
+  for (idx=0; (spec = cipher_list[idx]); idx++)
     {
-      *module = mod;
-      *algorithm_id = mod->mod_id;
+      oid_specs = spec->oids;
+      if (oid_specs)
+        {
+          for (j = 0; oid_specs[j].oid; j++)
+            if (!stricmp (oid, oid_specs[j].oid))
+              return spec;
+        }
     }
 
-  return gcry_error (err);
+  return NULL;
 }
 
-/* Unregister the cipher identified by MODULE, which must have been
-   registered with gcry_cipher_register.  */
-void
-gcry_cipher_unregister (gcry_module_t module)
-{
-  ath_mutex_lock (&ciphers_registered_lock);
-  _gcry_module_release (module);
-  ath_mutex_unlock (&ciphers_registered_lock);
-}
 
-/* Locate the OID in the oid table and return the index or -1 when not
-   found.  An opitonal "oid." or "OID." prefix in OID is ignored, the
-   OID is expected to be in standard IETF dotted notation.  The
-   internal algorithm number is returned in ALGORITHM unless it
-   ispassed as NULL.  A pointer to the specification of the module
-   implementing this algorithm is return in OID_SPEC unless passed as
-   NULL.*/
-static int
-search_oid (const char *oid, int *algorithm, gcry_cipher_oid_spec_t *oid_spec)
+/* Locate the OID in the oid table and return the spec or NULL if not
+   found.  An optional "oid." or "OID." prefix in OID is ignored, the
+   OID is expected to be in standard IETF dotted notation.  A pointer
+   to the OID specification of the module implementing this algorithm
+   is return in OID_SPEC unless passed as NULL.*/
+static gcry_cipher_spec_t *
+search_oid (const char *oid, gcry_cipher_oid_spec_t *oid_spec)
 {
-  gcry_module_t module;
-  int ret = 0;
+  gcry_cipher_spec_t *spec;
+  int i;
 
   if (oid && ((! strncmp (oid, "oid.", 4))
              || (! strncmp (oid, "OID.", 4))))
     oid += 4;
 
-  module = gcry_cipher_lookup_oid (oid);
-  if (module)
+  spec = spec_from_oid (oid);
+  if (spec && spec->oids)
     {
-      gcry_cipher_spec_t *cipher = module->spec;
-      int i;
-
-      for (i = 0; cipher->oids[i].oid && !ret; i++)
-       if (! stricmp (oid, cipher->oids[i].oid))
+      for (i = 0; spec->oids[i].oid; i++)
+       if (!stricmp (oid, spec->oids[i].oid))
          {
-           if (algorithm)
-             *algorithm = module->mod_id;
            if (oid_spec)
-             *oid_spec = cipher->oids[i];
-           ret = 1;
+             *oid_spec = spec->oids[i];
+            return spec;
          }
-      _gcry_module_release (module);
     }
 
-  return ret;
+  return NULL;
 }
 
+
 /* Map STRING to the cipher algorithm identifier.  Returns the
    algorithm ID of the cipher for the given name or 0 if the name is
    not known.  It is valid to pass NULL for STRING which results in a
    return value of 0. */
 int
-gcry_cipher_map_name (const char *string)
+_gcry_cipher_map_name (const char *string)
 {
-  gcry_module_t cipher;
-  int ret, algorithm = 0;
+  gcry_cipher_spec_t *spec;
 
-  if (! string)
+  if (!string)
     return 0;
 
-  REGISTER_DEFAULT_CIPHERS;
-
   /* If the string starts with a digit (optionally prefixed with
      either "OID." or "oid."), we first look into our table of ASN.1
      object identifiers to figure out the algorithm */
 
-  ath_mutex_lock (&ciphers_registered_lock);
-
-  ret = search_oid (string, &algorithm, NULL);
-  if (! ret)
-    {
-      cipher = gcry_cipher_lookup_name (string);
-      if (cipher)
-       {
-         algorithm = cipher->mod_id;
-         _gcry_module_release (cipher);
-       }
-    }
+  spec = search_oid (string, NULL);
+  if (spec)
+    return spec->algo;
 
-  ath_mutex_unlock (&ciphers_registered_lock);
+  spec = spec_from_name (string);
+  if (spec)
+    return spec->algo;
 
-  return algorithm;
+  return 0;
 }
 
 
@@ -506,80 +225,48 @@ gcry_cipher_map_name (const char *string)
    with that OID or 0 if no mode is known.  Passing NULL for string
    yields a return value of 0. */
 int
-gcry_cipher_mode_from_oid (const char *string)
+_gcry_cipher_mode_from_oid (const char *string)
 {
+  gcry_cipher_spec_t *spec;
   gcry_cipher_oid_spec_t oid_spec;
-  int ret = 0, mode = 0;
 
   if (!string)
     return 0;
 
-  ath_mutex_lock (&ciphers_registered_lock);
-  ret = search_oid (string, NULL, &oid_spec);
-  if (ret)
-    mode = oid_spec.mode;
-  ath_mutex_unlock (&ciphers_registered_lock);
+  spec = search_oid (string, &oid_spec);
+  if (spec)
+    return oid_spec.mode;
 
-  return mode;
+  return 0;
 }
 
 
-/* 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 "?".  */
-static const char *
-cipher_algo_to_string (int algorithm)
-{
-  gcry_module_t cipher;
-  const char *name;
-
-  REGISTER_DEFAULT_CIPHERS;
-
-  ath_mutex_lock (&ciphers_registered_lock);
-  cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
-  if (cipher)
-    {
-      name = ((gcry_cipher_spec_t *) cipher->spec)->name;
-      _gcry_module_release (cipher);
-    }
-  else
-    name = "?";
-  ath_mutex_unlock (&ciphers_registered_lock);
-
-  return name;
-}
-
 /* Map the cipher algorithm identifier ALGORITHM to a string
    representing this algorithm.  This string is the default name as
-   used by Libgcrypt.  An pointer to an empty string is returned for
-   an unknown algorithm.  NULL is never returned. */
+   used by Libgcrypt.  A "?" is returned for an unknown algorithm.
+   NULL is never returned. */
 const char *
-gcry_cipher_algo_name (int algorithm)
+_gcry_cipher_algo_name (int algorithm)
 {
-  return cipher_algo_to_string (algorithm);
+  gcry_cipher_spec_t *spec;
+
+  spec = spec_from_algo (algorithm);
+  return spec? spec->name : "?";
 }
 
 
 /* Flag the cipher algorithm with the identifier ALGORITHM as
    disabled.  There is no error return, the function does nothing for
-   unknown algorithms.  Disabled algorithms are vitually not available
-   in Libgcrypt. */
+   unknown algorithms.  Disabled algorithms are virtually not
+   available in Libgcrypt.  This is not thread safe and should thus be
+   called early. */
 static void
-disable_cipher_algo (int algorithm)
+disable_cipher_algo (int algo)
 {
-  gcry_module_t cipher;
-
-  REGISTER_DEFAULT_CIPHERS;
+  gcry_cipher_spec_t *spec = spec_from_algo (algo);
 
-  ath_mutex_lock (&ciphers_registered_lock);
-  cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
-  if (cipher)
-    {
-      if (! (cipher->flags & FLAG_MODULE_DISABLED))
-       cipher->flags |= FLAG_MODULE_DISABLED;
-      _gcry_module_release (cipher);
-    }
-  ath_mutex_unlock (&ciphers_registered_lock);
+  if (spec)
+    spec->flags.disabled = 1;
 }
 
 
@@ -589,79 +276,51 @@ disable_cipher_algo (int algorithm)
 static gcry_err_code_t
 check_cipher_algo (int algorithm)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  gcry_module_t cipher;
-
-  REGISTER_DEFAULT_CIPHERS;
+  gcry_cipher_spec_t *spec;
 
-  ath_mutex_lock (&ciphers_registered_lock);
-  cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
-  if (cipher)
-    {
-      if (cipher->flags & FLAG_MODULE_DISABLED)
-       err = GPG_ERR_CIPHER_ALGO;
-      _gcry_module_release (cipher);
-    }
-  else
-    err = GPG_ERR_CIPHER_ALGO;
-  ath_mutex_unlock (&ciphers_registered_lock);
+  spec = spec_from_algo (algorithm);
+  if (spec && !spec->flags.disabled)
+    return 0;
 
-  return err;
+  return GPG_ERR_CIPHER_ALGO;
 }
 
 
-/* Return the standard length of the key for the cipher algorithm with
-   the identifier ALGORITHM.  This function expects a valid algorithm
-   and will abort if the algorithm is not available or the length of
-   the key is not known. */
+/* Return the standard length in bits of the key for the cipher
+   algorithm with the identifier ALGORITHM.  */
 static unsigned int
 cipher_get_keylen (int algorithm)
 {
-  gcry_module_t cipher;
+  gcry_cipher_spec_t *spec;
   unsigned len = 0;
 
-  REGISTER_DEFAULT_CIPHERS;
-
-  ath_mutex_lock (&ciphers_registered_lock);
-  cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
-  if (cipher)
+  spec = spec_from_algo (algorithm);
+  if (spec)
     {
-      len = ((gcry_cipher_spec_t *) cipher->spec)->keylen;
+      len = spec->keylen;
       if (!len)
        log_bug ("cipher %d w/o key length\n", algorithm);
-      _gcry_module_release (cipher);
     }
-  else
-    log_bug ("cipher %d not found\n", algorithm);
-  ath_mutex_unlock (&ciphers_registered_lock);
 
   return len;
 }
 
+
 /* Return the block length of the cipher algorithm with the identifier
-   ALGORITHM.  This function expects a valid algorithm and will abort
-   if the algorithm is not available or the length of the key is not
-   known. */
+   ALGORITHM.  This function return 0 for an invalid algorithm.  */
 static unsigned int
 cipher_get_blocksize (int algorithm)
 {
-  gcry_module_t cipher;
+  gcry_cipher_spec_t *spec;
   unsigned len = 0;
 
-  REGISTER_DEFAULT_CIPHERS;
-
-  ath_mutex_lock (&ciphers_registered_lock);
-  cipher = _gcry_module_lookup_id (ciphers_registered, algorithm);
-  if (cipher)
+  spec = spec_from_algo (algorithm);
+  if (spec)
     {
-      len = ((gcry_cipher_spec_t *) cipher->spec)->blocksize;
-      if (! len)
-         log_bug ("cipher %d w/o blocksize\n", algorithm);
-      _gcry_module_release (cipher);
+      len = spec->blocksize;
+      if (!len)
+        log_bug ("cipher %d w/o blocksize\n", algorithm);
     }
-  else
-    log_bug ("cipher %d not found\n", algorithm);
-  ath_mutex_unlock (&ciphers_registered_lock);
 
   return len;
 }
@@ -681,45 +340,44 @@ cipher_get_blocksize (int algorithm)
 
    Values for these flags may be combined using OR.
  */
-gcry_error_t
-gcry_cipher_open (gcry_cipher_hd_t *handle,
-                 int algo, int mode, unsigned int flags)
+gcry_err_code_t
+_gcry_cipher_open (gcry_cipher_hd_t *handle,
+                   int algo, int mode, unsigned int flags)
+{
+  gcry_err_code_t rc;
+  gcry_cipher_hd_t h = NULL;
+
+  if (mode >= GCRY_CIPHER_MODE_INTERNAL)
+    rc = GPG_ERR_INV_CIPHER_MODE;
+  else
+    rc = _gcry_cipher_open_internal (&h, algo, mode, flags);
+
+  *handle = rc ? NULL : h;
+
+  return rc;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_open_internal (gcry_cipher_hd_t *handle,
+                           int algo, int mode, unsigned int flags)
 {
   int secure = (flags & GCRY_CIPHER_SECURE);
-  gcry_cipher_spec_t *cipher = NULL;
-  cipher_extra_spec_t *extraspec = NULL;
-  gcry_module_t module = NULL;
+  gcry_cipher_spec_t *spec;
   gcry_cipher_hd_t h = NULL;
-  gcry_err_code_t err = 0;
+  gcry_err_code_t err;
 
   /* If the application missed to call the random poll function, we do
      it here to ensure that it is used once in a while. */
   _gcry_fast_random_poll ();
 
-  REGISTER_DEFAULT_CIPHERS;
-
-  /* Fetch the according module and check whether the cipher is marked
-     available for use.  */
-  ath_mutex_lock (&ciphers_registered_lock);
-  module = _gcry_module_lookup_id (ciphers_registered, algo);
-  if (module)
-    {
-      /* Found module.  */
-
-      if (module->flags & FLAG_MODULE_DISABLED)
-       {
-         /* Not available for use.  */
-         err = GPG_ERR_CIPHER_ALGO;
-       }
-      else
-        {
-          cipher = (gcry_cipher_spec_t *) module->spec;
-          extraspec = module->extraspec;
-        }
-    }
-  else
+  spec = spec_from_algo (algo);
+  if (!spec)
+    err = GPG_ERR_CIPHER_ALGO;
+  else if (spec->flags.disabled)
     err = GPG_ERR_CIPHER_ALGO;
-  ath_mutex_unlock (&ciphers_registered_lock);
+  else
+    err = 0;
 
   /* check flags */
   if ((! err)
@@ -735,20 +393,31 @@ gcry_cipher_open (gcry_cipher_hd_t *handle,
   if (! err)
     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:
       case GCRY_CIPHER_MODE_CFB:
       case GCRY_CIPHER_MODE_OFB:
       case GCRY_CIPHER_MODE_CTR:
       case GCRY_CIPHER_MODE_AESWRAP:
-       if ((cipher->encrypt == dummy_encrypt_block)
-           || (cipher->decrypt == dummy_decrypt_block))
+      case GCRY_CIPHER_MODE_CMAC:
+      case GCRY_CIPHER_MODE_GCM:
+       if (!spec->encrypt || !spec->decrypt)
          err = GPG_ERR_INV_CIPHER_MODE;
        break;
 
       case GCRY_CIPHER_MODE_STREAM:
-       if ((cipher->stencrypt == dummy_encrypt_stream)
-           || (cipher->stdecrypt == dummy_decrypt_stream))
+       if (!spec->stencrypt || !spec->stdecrypt)
          err = GPG_ERR_INV_CIPHER_MODE;
        break;
 
@@ -767,13 +436,12 @@ gcry_cipher_open (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)
     {
       size_t size = (sizeof (*h)
-                     + 2 * cipher->contextsize
+                     + 2 * spec->contextsize
                      - sizeof (cipher_context_alignment_t)
 #ifdef NEED_16BYTE_ALIGNED_CONTEXT
                      + 15  /* Space for leading alignment gap.  */
@@ -781,9 +449,9 @@ gcry_cipher_open (gcry_cipher_hd_t *handle,
                      );
 
       if (secure)
-       h = gcry_calloc_secure (1, size);
+       h = xtrycalloc_secure (1, size);
       else
-       h = gcry_calloc (1, size);
+       h = xtrycalloc (1, size);
 
       if (! h)
        err = gpg_err_code_from_syserror ();
@@ -804,9 +472,7 @@ gcry_cipher_open (gcry_cipher_hd_t *handle,
          h->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
           h->actual_handle_size = size - off;
           h->handle_offset = off;
-         h->cipher = cipher;
-         h->extraspec = extraspec;
-         h->module = module;
+         h->spec = spec;
           h->algo = algo;
          h->mode = mode;
          h->flags = flags;
@@ -825,6 +491,46 @@ gcry_cipher_open (gcry_cipher_hd_t *handle,
               h->bulk.ctr_enc = _gcry_aes_ctr_enc;
               break;
 #endif /*USE_AES*/
+#ifdef USE_BLOWFISH
+           case GCRY_CIPHER_BLOWFISH:
+              h->bulk.cfb_dec = _gcry_blowfish_cfb_dec;
+              h->bulk.cbc_dec = _gcry_blowfish_cbc_dec;
+              h->bulk.ctr_enc = _gcry_blowfish_ctr_enc;
+              break;
+#endif /*USE_BLOWFISH*/
+#ifdef USE_CAST5
+           case GCRY_CIPHER_CAST5:
+              h->bulk.cfb_dec = _gcry_cast5_cfb_dec;
+              h->bulk.cbc_dec = _gcry_cast5_cbc_dec;
+              h->bulk.ctr_enc = _gcry_cast5_ctr_enc;
+              break;
+#endif /*USE_CAMELLIA*/
+#ifdef USE_CAMELLIA
+           case GCRY_CIPHER_CAMELLIA128:
+           case GCRY_CIPHER_CAMELLIA192:
+           case GCRY_CIPHER_CAMELLIA256:
+              h->bulk.cbc_dec = _gcry_camellia_cbc_dec;
+              h->bulk.cfb_dec = _gcry_camellia_cfb_dec;
+              h->bulk.ctr_enc = _gcry_camellia_ctr_enc;
+              break;
+#endif /*USE_CAMELLIA*/
+#ifdef USE_SERPENT
+           case GCRY_CIPHER_SERPENT128:
+           case GCRY_CIPHER_SERPENT192:
+           case GCRY_CIPHER_SERPENT256:
+              h->bulk.cbc_dec = _gcry_serpent_cbc_dec;
+              h->bulk.cfb_dec = _gcry_serpent_cfb_dec;
+              h->bulk.ctr_enc = _gcry_serpent_ctr_enc;
+              break;
+#endif /*USE_SERPENT*/
+#ifdef USE_TWOFISH
+           case GCRY_CIPHER_TWOFISH:
+           case GCRY_CIPHER_TWOFISH128:
+              h->bulk.cbc_dec = _gcry_twofish_cbc_dec;
+              h->bulk.cfb_dec = _gcry_twofish_cfb_dec;
+              h->bulk.ctr_enc = _gcry_twofish_ctr_enc;
+              break;
+#endif /*USE_TWOFISH*/
 
             default:
               break;
@@ -834,17 +540,6 @@ gcry_cipher_open (gcry_cipher_hd_t *handle,
 
   /* Done.  */
 
-  if (err)
-    {
-      if (module)
-       {
-         /* Release module.  */
-         ath_mutex_lock (&ciphers_registered_lock);
-         _gcry_module_release (module);
-         ath_mutex_unlock (&ciphers_registered_lock);
-       }
-    }
-
   *handle = err ? NULL : h;
 
   return gcry_error (err);
@@ -854,7 +549,7 @@ gcry_cipher_open (gcry_cipher_hd_t *handle,
 /* Release all resources associated with the cipher handle H. H may be
    NULL in which case this is a no-operation. */
 void
-gcry_cipher_close (gcry_cipher_hd_t h)
+_gcry_cipher_close (gcry_cipher_hd_t h)
 {
   size_t off;
 
@@ -868,11 +563,6 @@ gcry_cipher_close (gcry_cipher_hd_t h)
   else
     h->magic = 0;
 
-  /* Release module.  */
-  ath_mutex_lock (&ciphers_registered_lock);
-  _gcry_module_release (h->module);
-  ath_mutex_unlock (&ciphers_registered_lock);
-
   /* We always want to wipe out the memory even when the context has
      been allocated in secure memory.  The user might have disabled
      secure memory or is using his own implementation which does not
@@ -882,814 +572,183 @@ gcry_cipher_close (gcry_cipher_hd_t h)
   off = h->handle_offset;
   wipememory (h, h->actual_handle_size);
 
-  gcry_free ((char*)h - off);
-}
-
-
-/* Set the key to be used for the encryption context C to KEY with
-   length KEYLEN.  The length should match the required length. */
-static gcry_error_t
-cipher_setkey (gcry_cipher_hd_t c, byte *key, unsigned int keylen)
-{
-  gcry_err_code_t ret;
-
-  ret = (*c->cipher->setkey) (&c->context.c, key, keylen);
-  if (!ret)
-    {
-      /* Duplicate initial context.  */
-      memcpy ((void *) ((char *) &c->context.c + c->cipher->contextsize),
-              (void *) &c->context.c,
-              c->cipher->contextsize);
-      c->marks.key = 1;
-    }
-  else
-    c->marks.key = 0;
-
-  return gcry_error (ret);
-}
-
-
-/* Set the IV to be used for the encryption context C to IV with
-   length IVLEN.  The length should match the required length. */
-static void
-cipher_setiv( gcry_cipher_hd_t c, const byte *iv, unsigned ivlen )
-{
-  memset (c->u_iv.iv, 0, c->cipher->blocksize);
-  if (iv)
-    {
-      if (ivlen != c->cipher->blocksize)
-        {
-          log_info ("WARNING: cipher_setiv: ivlen=%u blklen=%u\n",
-                    ivlen, (unsigned int)c->cipher->blocksize);
-          fips_signal_error ("IV length does not match blocklength");
-        }
-      if (ivlen > c->cipher->blocksize)
-        ivlen = c->cipher->blocksize;
-      memcpy (c->u_iv.iv, iv, ivlen);
-      c->marks.iv = 1;
-    }
-  else
-      c->marks.iv = 0;
-  c->unused = 0;
-}
-
-
-/* Reset the cipher context to the initial context.  This is basically
-   the same as an release followed by a new. */
-static void
-cipher_reset (gcry_cipher_hd_t c)
-{
-  memcpy (&c->context.c,
-         (char *) &c->context.c + c->cipher->contextsize,
-         c->cipher->contextsize);
-  memset (&c->marks, 0, sizeof c->marks);
-  memset (c->u_iv.iv, 0, c->cipher->blocksize);
-  memset (c->lastiv, 0, c->cipher->blocksize);
-  memset (c->u_ctr.ctr, 0, c->cipher->blocksize);
-}
-
-
-\f
-static gcry_err_code_t
-do_ecb_encrypt (gcry_cipher_hd_t c,
-                unsigned char *outbuf, unsigned int outbuflen,
-                const unsigned char *inbuf, unsigned int inbuflen)
-{
-  unsigned int blocksize = c->cipher->blocksize;
-  unsigned int n, nblocks;
-
-  if (outbuflen < inbuflen)
-    return GPG_ERR_BUFFER_TOO_SHORT;
-  if ((inbuflen % blocksize))
-    return GPG_ERR_INV_LENGTH;
-
-  nblocks = inbuflen / c->cipher->blocksize;
-
-  for (n=0; n < nblocks; n++ )
-    {
-      c->cipher->encrypt (&c->context.c, outbuf, (byte*)/*arggg*/inbuf);
-      inbuf  += blocksize;
-      outbuf += blocksize;
-    }
-  return 0;
-}
-
-static gcry_err_code_t
-do_ecb_decrypt (gcry_cipher_hd_t c,
-                unsigned char *outbuf, unsigned int outbuflen,
-                const unsigned char *inbuf, unsigned int inbuflen)
-{
-  unsigned int blocksize = c->cipher->blocksize;
-  unsigned int n, nblocks;
-
-  if (outbuflen < inbuflen)
-    return GPG_ERR_BUFFER_TOO_SHORT;
-  if ((inbuflen % blocksize))
-    return GPG_ERR_INV_LENGTH;
-  nblocks = inbuflen / c->cipher->blocksize;
-
-  for (n=0; n < nblocks; n++ )
-    {
-      c->cipher->decrypt (&c->context.c, outbuf, (byte*)/*arggg*/inbuf );
-      inbuf  += blocksize;
-      outbuf += blocksize;
-    }
-
-  return 0;
-}
-
-
-static gcry_err_code_t
-do_cbc_encrypt (gcry_cipher_hd_t c,
-                unsigned char *outbuf, unsigned int outbuflen,
-                const unsigned char *inbuf, unsigned int inbuflen)
-{
-  unsigned int n;
-  unsigned char *ivp;
-  int i;
-  size_t blocksize = c->cipher->blocksize;
-  unsigned nblocks = inbuflen / blocksize;
-
-  if (outbuflen < ((c->flags & GCRY_CIPHER_CBC_MAC)? blocksize : inbuflen))
-    return GPG_ERR_BUFFER_TOO_SHORT;
-
-  if ((inbuflen % c->cipher->blocksize)
-      && !(inbuflen > c->cipher->blocksize
-           && (c->flags & GCRY_CIPHER_CBC_CTS)))
-    return GPG_ERR_INV_LENGTH;
-
-  if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
-    {
-      if ((inbuflen % blocksize) == 0)
-       nblocks--;
-    }
-
-  if (c->bulk.cbc_enc)
-    {
-      c->bulk.cbc_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks,
-                       (c->flags & GCRY_CIPHER_CBC_MAC));
-      inbuf  += nblocks * blocksize;
-      if (!(c->flags & GCRY_CIPHER_CBC_MAC))
-        outbuf += nblocks * blocksize;
-    }
-  else
-    {
-      for (n=0; n < nblocks; n++ )
-        {
-          for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
-            outbuf[i] = inbuf[i] ^ *ivp++;
-          c->cipher->encrypt ( &c->context.c, outbuf, outbuf );
-          memcpy (c->u_iv.iv, outbuf, blocksize );
-          inbuf  += blocksize;
-          if (!(c->flags & GCRY_CIPHER_CBC_MAC))
-            outbuf += blocksize;
-        }
-    }
-
-  if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
-    {
-      /* We have to be careful here, since outbuf might be equal to
-         inbuf.  */
-      int restbytes;
-      unsigned char b;
-
-      if ((inbuflen % blocksize) == 0)
-        restbytes = blocksize;
-      else
-        restbytes = inbuflen % blocksize;
-
-      outbuf -= blocksize;
-      for (ivp = c->u_iv.iv, i = 0; i < restbytes; i++)
-        {
-          b = inbuf[i];
-          outbuf[blocksize + i] = outbuf[i];
-          outbuf[i] = b ^ *ivp++;
-        }
-      for (; i < blocksize; i++)
-        outbuf[i] = 0 ^ *ivp++;
-
-      c->cipher->encrypt (&c->context.c, outbuf, outbuf);
-      memcpy (c->u_iv.iv, outbuf, blocksize);
-    }
-
-  return 0;
-}
-
-
-static gcry_err_code_t
-do_cbc_decrypt (gcry_cipher_hd_t c,
-                unsigned char *outbuf, unsigned int outbuflen,
-                const unsigned char *inbuf, unsigned int inbuflen)
-{
-  unsigned int n;
-  unsigned char *ivp;
-  int i;
-  size_t blocksize = c->cipher->blocksize;
-  unsigned int nblocks = inbuflen / blocksize;
-
-  if (outbuflen < inbuflen)
-    return GPG_ERR_BUFFER_TOO_SHORT;
-
-  if ((inbuflen % c->cipher->blocksize)
-      && !(inbuflen > c->cipher->blocksize
-           && (c->flags & GCRY_CIPHER_CBC_CTS)))
-    return GPG_ERR_INV_LENGTH;
-
-  if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
-    {
-      nblocks--;
-      if ((inbuflen % blocksize) == 0)
-       nblocks--;
-      memcpy (c->lastiv, c->u_iv.iv, blocksize);
-    }
-
-  if (c->bulk.cbc_dec)
-    {
-      c->bulk.cbc_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
-      inbuf  += nblocks * blocksize;
-      outbuf += nblocks * blocksize;
-    }
-  else
-    {
-      for (n=0; n < nblocks; n++ )
-        {
-          /* Because outbuf and inbuf might be the same, we have to
-           * save the original ciphertext block.  We use LASTIV for
-           * this here because it is not used otherwise. */
-          memcpy (c->lastiv, inbuf, blocksize);
-          c->cipher->decrypt ( &c->context.c, outbuf, inbuf );
-          for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
-           outbuf[i] ^= *ivp++;
-          memcpy(c->u_iv.iv, c->lastiv, blocksize );
-          inbuf  += c->cipher->blocksize;
-          outbuf += c->cipher->blocksize;
-        }
-    }
-
-  if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
-    {
-      int restbytes;
-
-      if ((inbuflen % blocksize) == 0)
-        restbytes = blocksize;
-      else
-        restbytes = inbuflen % blocksize;
-
-      memcpy (c->lastiv, c->u_iv.iv, blocksize );         /* Save Cn-2. */
-      memcpy (c->u_iv.iv, inbuf + blocksize, restbytes ); /* Save Cn. */
-
-      c->cipher->decrypt ( &c->context.c, outbuf, inbuf );
-      for (ivp=c->u_iv.iv,i=0; i < restbytes; i++ )
-        outbuf[i] ^= *ivp++;
-
-      memcpy(outbuf + blocksize, outbuf, restbytes);
-      for(i=restbytes; i < blocksize; i++)
-        c->u_iv.iv[i] = outbuf[i];
-      c->cipher->decrypt (&c->context.c, outbuf, c->u_iv.iv);
-      for(ivp=c->lastiv,i=0; i < blocksize; i++ )
-        outbuf[i] ^= *ivp++;
-      /* c->lastiv is now really lastlastiv, does this matter? */
-    }
-
-  return 0;
-}
-
-
-static gcry_err_code_t
-do_cfb_encrypt (gcry_cipher_hd_t c,
-                unsigned char *outbuf, unsigned int outbuflen,
-                const unsigned char *inbuf, unsigned int inbuflen)
-{
-  unsigned char *ivp;
-  size_t blocksize = c->cipher->blocksize;
-  size_t blocksize_x_2 = blocksize + blocksize;
-
-  if (outbuflen < inbuflen)
-    return GPG_ERR_BUFFER_TOO_SHORT;
-
-  if ( inbuflen <= c->unused )
-    {
-      /* Short enough to be encoded by the remaining XOR mask. */
-      /* XOR the input with the IV and store input into IV. */
-      for (ivp=c->u_iv.iv+c->cipher->blocksize - c->unused;
-           inbuflen;
-           inbuflen--, c->unused-- )
-        *outbuf++ = (*ivp++ ^= *inbuf++);
-      return 0;
-    }
-
-  if ( c->unused )
-    {
-      /* XOR the input with the IV and store input into IV */
-      inbuflen -= c->unused;
-      for(ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
-        *outbuf++ = (*ivp++ ^= *inbuf++);
-    }
-
-  /* Now we can process complete blocks.  We use a loop as long as we
-     have at least 2 blocks and use conditions for the rest.  This
-     also allows to use a bulk encryption function if available.  */
-  if (inbuflen >= blocksize_x_2 && c->bulk.cfb_enc)
-    {
-      unsigned int nblocks = inbuflen / blocksize;
-      c->bulk.cfb_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
-      outbuf += nblocks * blocksize;
-      inbuf  += nblocks * blocksize;
-      inbuflen -= nblocks * blocksize;
-    }
-  else
-    {
-      while ( inbuflen >= blocksize_x_2 )
-        {
-          int i;
-          /* Encrypt the IV. */
-          c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-          /* XOR the input with the IV and store input into IV.  */
-          for(ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
-            *outbuf++ = (*ivp++ ^= *inbuf++);
-          inbuflen -= blocksize;
-        }
-    }
-
-  if ( inbuflen >= blocksize )
-    {
-      int i;
-      /* Save the current IV and then encrypt the IV. */
-      memcpy( c->lastiv, c->u_iv.iv, blocksize );
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-      /* XOR the input with the IV and store input into IV */
-      for(ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
-        *outbuf++ = (*ivp++ ^= *inbuf++);
-      inbuflen -= blocksize;
-    }
-  if ( inbuflen )
-    {
-      /* Save the current IV and then encrypt the IV. */
-      memcpy( c->lastiv, c->u_iv.iv, blocksize );
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-      c->unused = blocksize;
-      /* Apply the XOR. */
-      c->unused -= inbuflen;
-      for(ivp=c->u_iv.iv; inbuflen; inbuflen-- )
-        *outbuf++ = (*ivp++ ^= *inbuf++);
-    }
-  return 0;
-}
-
-
-static gcry_err_code_t
-do_cfb_decrypt (gcry_cipher_hd_t c,
-                unsigned char *outbuf, unsigned int outbuflen,
-                const unsigned char *inbuf, unsigned int inbuflen)
-{
-  unsigned char *ivp;
-  unsigned long temp;
-  int i;
-  size_t blocksize = c->cipher->blocksize;
-  size_t blocksize_x_2 = blocksize + blocksize;
-
-  if (outbuflen < inbuflen)
-    return GPG_ERR_BUFFER_TOO_SHORT;
-
-  if (inbuflen <= c->unused)
-    {
-      /* Short enough to be encoded by the remaining XOR mask. */
-      /* XOR the input with the IV and store input into IV. */
-      for (ivp=c->u_iv.iv+blocksize - c->unused;
-           inbuflen;
-           inbuflen--, c->unused--)
-        {
-          temp = *inbuf++;
-          *outbuf++ = *ivp ^ temp;
-          *ivp++ = temp;
-        }
-      return 0;
-    }
-
-  if (c->unused)
-    {
-      /* XOR the input with the IV and store input into IV. */
-      inbuflen -= c->unused;
-      for (ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
-        {
-          temp = *inbuf++;
-          *outbuf++ = *ivp ^ temp;
-          *ivp++ = temp;
-        }
-    }
-
-  /* Now we can process complete blocks.  We use a loop as long as we
-     have at least 2 blocks and use conditions for the rest.  This
-     also allows to use a bulk encryption function if available.  */
-  if (inbuflen >= blocksize_x_2 && c->bulk.cfb_dec)
-    {
-      unsigned int nblocks = inbuflen / blocksize;
-      c->bulk.cfb_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
-      outbuf += nblocks * blocksize;
-      inbuf  += nblocks * blocksize;
-      inbuflen -= nblocks * blocksize;
-    }
-  else
-    {
-      while (inbuflen >= blocksize_x_2 )
-        {
-          /* Encrypt the IV. */
-          c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-          /* XOR the input with the IV and store input into IV. */
-          for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
-            {
-              temp = *inbuf++;
-              *outbuf++ = *ivp ^ temp;
-              *ivp++ = temp;
-            }
-          inbuflen -= blocksize;
-        }
-    }
-
-  if (inbuflen >= blocksize )
-    {
-      /* Save the current IV and then encrypt the IV. */
-      memcpy ( c->lastiv, c->u_iv.iv, blocksize);
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-      /* XOR the input with the IV and store input into IV */
-      for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
-        {
-          temp = *inbuf++;
-          *outbuf++ = *ivp ^ temp;
-          *ivp++ = temp;
-        }
-      inbuflen -= blocksize;
-    }
-
-  if (inbuflen)
-    {
-      /* Save the current IV and then encrypt the IV. */
-      memcpy ( c->lastiv, c->u_iv.iv, blocksize );
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-      c->unused = blocksize;
-      /* Apply the XOR. */
-      c->unused -= inbuflen;
-      for (ivp=c->u_iv.iv; inbuflen; inbuflen-- )
-        {
-          temp = *inbuf++;
-          *outbuf++ = *ivp ^ temp;
-          *ivp++ = temp;
-        }
-    }
-  return 0;
-}
-
-
-static gcry_err_code_t
-do_ofb_encrypt (gcry_cipher_hd_t c,
-                unsigned char *outbuf, unsigned int outbuflen,
-                const unsigned char *inbuf, unsigned int inbuflen)
-{
-  unsigned char *ivp;
-  size_t blocksize = c->cipher->blocksize;
-
-  if (outbuflen < inbuflen)
-    return GPG_ERR_BUFFER_TOO_SHORT;
-
-  if ( inbuflen <= c->unused )
-    {
-      /* Short enough to be encoded by the remaining XOR mask. */
-      /* XOR the input with the IV */
-      for (ivp=c->u_iv.iv+c->cipher->blocksize - c->unused;
-           inbuflen;
-           inbuflen--, c->unused-- )
-        *outbuf++ = (*ivp++ ^ *inbuf++);
-      return 0;
-    }
-
-  if( c->unused )
-    {
-      inbuflen -= c->unused;
-      for(ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
-        *outbuf++ = (*ivp++ ^ *inbuf++);
-    }
-
-  /* Now we can process complete blocks. */
-  while ( inbuflen >= blocksize )
-    {
-      int i;
-      /* Encrypt the IV (and save the current one). */
-      memcpy( c->lastiv, c->u_iv.iv, blocksize );
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-
-      for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
-        *outbuf++ = (*ivp++ ^ *inbuf++);
-      inbuflen -= blocksize;
-    }
-  if ( inbuflen )
-    { /* process the remaining bytes */
-      memcpy( c->lastiv, c->u_iv.iv, blocksize );
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-      c->unused = blocksize;
-      c->unused -= inbuflen;
-      for(ivp=c->u_iv.iv; inbuflen; inbuflen-- )
-        *outbuf++ = (*ivp++ ^ *inbuf++);
-    }
-  return 0;
+  xfree ((char*)h - off);
 }
 
+
+/* Set the key to be used for the encryption context C to KEY with
+   length KEYLEN.  The length should match the required length. */
 static gcry_err_code_t
-do_ofb_decrypt (gcry_cipher_hd_t c,
-                unsigned char *outbuf, unsigned int outbuflen,
-                const unsigned char *inbuf, unsigned int inbuflen)
+cipher_setkey (gcry_cipher_hd_t c, byte *key, size_t keylen)
 {
-  unsigned char *ivp;
-  size_t blocksize = c->cipher->blocksize;
-
-  if (outbuflen < inbuflen)
-    return GPG_ERR_BUFFER_TOO_SHORT;
+  gcry_err_code_t rc;
 
-  if( inbuflen <= c->unused )
+  rc = c->spec->setkey (&c->context.c, key, keylen);
+  if (!rc)
     {
-      /* Short enough to be encoded by the remaining XOR mask. */
-      for (ivp=c->u_iv.iv+blocksize - c->unused; inbuflen; inbuflen--,c->unused--)
-        *outbuf++ = *ivp++ ^ *inbuf++;
-      return 0;
-    }
+      /* Duplicate initial context.  */
+      memcpy ((void *) ((char *) &c->context.c + c->spec->contextsize),
+              (void *) &c->context.c,
+              c->spec->contextsize);
+      c->marks.key = 1;
 
-  if ( c->unused )
-    {
-      inbuflen -= c->unused;
-      for (ivp=c->u_iv.iv+blocksize - c->unused; c->unused; c->unused-- )
-        *outbuf++ = *ivp++ ^ *inbuf++;
-    }
+      switch (c->mode)
+        {
+        case GCRY_CIPHER_MODE_CMAC:
+          _gcry_cipher_cmac_set_subkeys (c);
+          break;
 
-  /* Now we can process complete blocks. */
-  while ( inbuflen >= blocksize )
-    {
-      int i;
-      /* Encrypt the IV (and save the current one). */
-      memcpy( c->lastiv, c->u_iv.iv, blocksize );
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-      for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
-        *outbuf++ = *ivp++ ^ *inbuf++;
-      inbuflen -= blocksize;
-    }
-  if ( inbuflen )
-    { /* Process the remaining bytes. */
-      /* Encrypt the IV (and save the current one). */
-      memcpy( c->lastiv, c->u_iv.iv, blocksize );
-      c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-      c->unused = blocksize;
-      c->unused -= inbuflen;
-      for (ivp=c->u_iv.iv; inbuflen; inbuflen-- )
-        *outbuf++ = *ivp++ ^ *inbuf++;
+        case GCRY_CIPHER_MODE_GCM:
+          _gcry_cipher_gcm_setkey (c);
+          break;
+
+        default:
+          break;
+        };
     }
-  return 0;
+  else
+    c->marks.key = 0;
+
+  return rc;
 }
 
 
+/* Set the IV to be used for the encryption context C to IV with
+   length IVLEN.  The length should match the required length. */
 static gcry_err_code_t
-do_ctr_encrypt (gcry_cipher_hd_t c,
-                unsigned char *outbuf, unsigned int outbuflen,
-                const unsigned char *inbuf, unsigned int inbuflen)
+cipher_setiv (gcry_cipher_hd_t c, const byte *iv, size_t ivlen)
 {
-  unsigned int n;
-  int i;
-  unsigned int blocksize = c->cipher->blocksize;
-  unsigned int nblocks;
-
-  if (outbuflen < inbuflen)
-    return GPG_ERR_BUFFER_TOO_SHORT;
-
-  /* First process a left over encrypted counter.  */
-  if (c->unused)
-    {
-      gcry_assert (c->unused < blocksize);
-      i = blocksize - c->unused;
-      for (n=0; c->unused && n < inbuflen; c->unused--, n++, i++)
-        {
-          /* XOR input with encrypted counter and store in output.  */
-          outbuf[n] = inbuf[n] ^ c->lastiv[i];
-        }
-      inbuf  += n;
-      outbuf += n;
-      inbuflen -= n;
-    }
+  /* GCM has its own IV handler */
+  if (c->mode == GCRY_CIPHER_MODE_GCM)
+    return _gcry_cipher_gcm_setiv (c, iv, ivlen);
 
-
-  /* Use a bulk method if available.  */
-  nblocks = inbuflen / blocksize;
-  if (nblocks && c->bulk.ctr_enc)
+  /* 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)
     {
-      c->bulk.ctr_enc (&c->context.c, c->u_ctr.ctr, outbuf, inbuf, nblocks);
-      inbuf  += nblocks * blocksize;
-      outbuf += nblocks * blocksize;
-      inbuflen -= nblocks * blocksize;
+      c->spec->setiv (&c->context.c, iv, ivlen);
+      return 0;
     }
 
-  /* If we don't have a bulk method use the standard method.  We also
-     use this method for the a remaining partial block.  */
-  if (inbuflen)
+  memset (c->u_iv.iv, 0, c->spec->blocksize);
+  if (iv)
     {
-      unsigned char tmp[MAX_BLOCKSIZE];
-
-      for (n=0; n < inbuflen; n++)
+      if (ivlen != c->spec->blocksize)
         {
-          if ((n % blocksize) == 0)
-            {
-              c->cipher->encrypt (&c->context.c, tmp, c->u_ctr.ctr);
-
-              for (i = blocksize; i > 0; i--)
-                {
-                  c->u_ctr.ctr[i-1]++;
-                  if (c->u_ctr.ctr[i-1] != 0)
-                    break;
-                }
-            }
-
-          /* XOR input with encrypted counter and store in output.  */
-          outbuf[n] = inbuf[n] ^ tmp[n % blocksize];
+          log_info ("WARNING: cipher_setiv: ivlen=%u blklen=%u\n",
+                    (unsigned int)ivlen, (unsigned int)c->spec->blocksize);
+          fips_signal_error ("IV length does not match blocklength");
         }
-
-      /* Save the unused bytes of the counter.  */
-      n %= blocksize;
-      c->unused = (blocksize - n) % blocksize;
-      if (c->unused)
-        memcpy (c->lastiv+n, tmp+n, c->unused);
-
-      wipememory (tmp, sizeof tmp);
+      if (ivlen > c->spec->blocksize)
+        ivlen = c->spec->blocksize;
+      memcpy (c->u_iv.iv, iv, ivlen);
+      c->marks.iv = 1;
     }
+  else
+      c->marks.iv = 0;
+  c->unused = 0;
 
   return 0;
 }
 
-static gcry_err_code_t
-do_ctr_decrypt (gcry_cipher_hd_t c,
-                unsigned char *outbuf, unsigned int outbuflen,
-                const unsigned char *inbuf, unsigned int inbuflen)
-{
-  return do_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
-}
-
 
-/* Perform the AES-Wrap algorithm as specified by RFC3394.  We
-   implement this as a mode usable with any cipher algorithm of
-   blocksize 128.  */
-static gcry_err_code_t
-do_aeswrap_encrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
-                    const byte *inbuf, unsigned int inbuflen )
+/* Reset the cipher context to the initial context.  This is basically
+   the same as an release followed by a new. */
+static void
+cipher_reset (gcry_cipher_hd_t c)
 {
-  int j, x;
-  unsigned int n, i;
-  unsigned char *r, *a, *b;
-  unsigned char t[8];
+  unsigned int marks_key;
 
-#if MAX_BLOCKSIZE < 8
-#error Invalid block size
-#endif
-  /* We require a cipher with a 128 bit block length.  */
-  if (c->cipher->blocksize != 16)
-    return GPG_ERR_INV_LENGTH;
-
-  /* The output buffer must be able to hold the input data plus one
-     additional block.  */
-  if (outbuflen < inbuflen + 8)
-    return GPG_ERR_BUFFER_TOO_SHORT;
-  /* Input data must be multiple of 64 bits.  */
-  if (inbuflen % 8)
-    return GPG_ERR_INV_ARG;
-
-  n = inbuflen / 8;
+  marks_key = c->marks.key;
 
-  /* We need at least two 64 bit blocks.  */
-  if (n < 2)
-    return GPG_ERR_INV_ARG;
+  memcpy (&c->context.c,
+         (char *) &c->context.c + c->spec->contextsize,
+         c->spec->contextsize);
+  memset (&c->marks, 0, sizeof c->marks);
+  memset (c->u_iv.iv, 0, c->spec->blocksize);
+  memset (c->lastiv, 0, c->spec->blocksize);
+  memset (c->u_ctr.ctr, 0, c->spec->blocksize);
+  c->unused = 0;
 
-  r = outbuf;
-  a = outbuf;  /* We store A directly in OUTBUF.  */
-  b = c->u_ctr.ctr;  /* B is also used to concatenate stuff.  */
+  c->marks.key = marks_key;
 
-  /* If an IV has been set we use that IV as the Alternative Initial
-     Value; if it has not been set we use the standard value.  */
-  if (c->marks.iv)
-    memcpy (a, c->u_iv.iv, 8);
-  else
-    memset (a, 0xa6, 8);
+  switch (c->mode)
+    {
+    case GCRY_CIPHER_MODE_CMAC:
+      /* Only clear 'tag' for cmac, keep subkeys. */
+      c->u_mode.cmac.tag = 0;
+      break;
 
-  /* Copy the inbuf to the outbuf. */
-  memmove (r+8, inbuf, inbuflen);
+    case GCRY_CIPHER_MODE_GCM:
+      /* Only clear head of u_mode, keep ghash_key and gcm_table. */
+      {
+        byte *u_mode_pos = (void *)&c->u_mode;
+        byte *ghash_key_pos = c->u_mode.gcm.u_ghash_key.key;
+        size_t u_mode_head_length = ghash_key_pos - u_mode_pos;
 
-  memset (t, 0, sizeof t); /* t := 0.  */
+        memset (&c->u_mode, 0, u_mode_head_length);
+      }
+      break;
 
-  for (j = 0; j <= 5; j++)
-    {
-      for (i = 1; i <= n; i++)
-        {
-          /* B := AES_k( A | R[i] ) */
-          memcpy (b, a, 8);
-          memcpy (b+8, r+i*8, 8);
-          c->cipher->encrypt (&c->context.c, b, b);
-          /* t := t + 1  */
-         for (x = 7; x >= 0; x--)
-           {
-             t[x]++;
-             if (t[x])
-               break;
-           }
-          /* A := MSB_64(B) ^ t */
-          for (x=0; x < 8; x++)
-            a[x] = b[x] ^ t[x];
-          /* R[i] := LSB_64(B) */
-          memcpy (r+i*8, b+8, 8);
-        }
-   }
+#ifdef HAVE_U64_TYPEDEF
+    case GCRY_CIPHER_MODE_CCM:
+      memset (&c->u_mode.ccm, 0, sizeof c->u_mode.ccm);
+      break;
+#endif
 
-  return 0;
+    default:
+      break; /* u_mode unused by other modes. */
+    }
 }
 
-/* Perform the AES-Unwrap algorithm as specified by RFC3394.  We
-   implement this as a mode usable with any cipher algorithm of
-   blocksize 128.  */
+
+\f
 static gcry_err_code_t
-do_aeswrap_decrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
-                    const byte *inbuf, unsigned int inbuflen)
+do_ecb_crypt (gcry_cipher_hd_t c,
+              unsigned char *outbuf, size_t outbuflen,
+              const unsigned char *inbuf, size_t inbuflen,
+              gcry_cipher_encrypt_t crypt_fn)
 {
-  int j, x;
-  unsigned int n, i;
-  unsigned char *r, *a, *b;
-  unsigned char t[8];
-
-#if MAX_BLOCKSIZE < 8
-#error Invalid block size
-#endif
-  /* We require a cipher with a 128 bit block length.  */
-  if (c->cipher->blocksize != 16)
-    return GPG_ERR_INV_LENGTH;
+  unsigned int blocksize = c->spec->blocksize;
+  size_t n, nblocks;
+  unsigned int burn, nburn;
 
-  /* The output buffer must be able to hold the input data minus one
-     additional block.  Fixme: The caller has more restrictive checks
-     - we may want to fix them for this mode.  */
-  if (outbuflen + 8  < inbuflen)
+  if (outbuflen < inbuflen)
     return GPG_ERR_BUFFER_TOO_SHORT;
-  /* Input data must be multiple of 64 bits.  */
-  if (inbuflen % 8)
-    return GPG_ERR_INV_ARG;
-
-  n = inbuflen / 8;
+  if ((inbuflen % blocksize))
+    return GPG_ERR_INV_LENGTH;
 
-  /* We need at least three 64 bit blocks.  */
-  if (n < 3)
-    return GPG_ERR_INV_ARG;
+  nblocks = inbuflen / blocksize;
+  burn = 0;
 
-  r = outbuf;
-  a = c->lastiv;  /* We use c->LASTIV as buffer for A.  */
-  b = c->u_ctr.ctr;     /* B is also used to concatenate stuff.  */
+  for (n=0; n < nblocks; n++ )
+    {
+      nburn = crypt_fn (&c->context.c, outbuf, inbuf);
+      burn = nburn > burn ? nburn : burn;
+      inbuf  += blocksize;
+      outbuf += blocksize;
+    }
 
-  /* Copy the inbuf to the outbuf and save A. */
-  memcpy (a, inbuf, 8);
-  memmove (r, inbuf+8, inbuflen-8);
-  n--; /* Reduce to actual number of data blocks.  */
+  if (burn > 0)
+    _gcry_burn_stack (burn + 4 * sizeof(void *));
 
-  /* t := 6 * n  */
-  i = n * 6;  /* The range is valid because: n = inbuflen / 8 - 1.  */
-  for (x=0; x < 8 && x < sizeof (i); x++)
-    t[7-x] = i >> (8*x);
-  for (; x < 8; x++)
-    t[7-x] = 0;
+  return 0;
+}
 
-  for (j = 5; j >= 0; j--)
-    {
-      for (i = n; i >= 1; i--)
-        {
-          /* B := AES_k^1( (A ^ t)| R[i] ) */
-          for (x = 0; x < 8; x++)
-            b[x] = a[x] ^ t[x];
-          memcpy (b+8, r+(i-1)*8, 8);
-          c->cipher->decrypt (&c->context.c, b, b);
-          /* t := t - 1  */
-         for (x = 7; x >= 0; x--)
-           {
-             t[x]--;
-             if (t[x] != 0xff)
-               break;
-           }
-          /* A := MSB_64(B) */
-          memcpy (a, b, 8);
-          /* R[i] := LSB_64(B) */
-          memcpy (r+(i-1)*8, b+8, 8);
-        }
-   }
+static gcry_err_code_t
+do_ecb_encrypt (gcry_cipher_hd_t c,
+                unsigned char *outbuf, size_t outbuflen,
+                const unsigned char *inbuf, size_t inbuflen)
+{
+  return do_ecb_crypt (c, outbuf, outbuflen, inbuf, inbuflen, c->spec->encrypt);
+}
 
-  /* If an IV has been set we compare against this Alternative Initial
-     Value; if it has not been set we compare against the standard IV.  */
-  if (c->marks.iv)
-    j = memcmp (a, c->u_iv.iv, 8);
-  else
-    {
-      for (j=0, x=0; x < 8; x++)
-        if (a[x] != 0xa6)
-          {
-            j=1;
-            break;
-          }
-    }
-  return j? GPG_ERR_CHECKSUM : 0;
+static gcry_err_code_t
+do_ecb_decrypt (gcry_cipher_hd_t c,
+                unsigned char *outbuf, size_t outbuflen,
+                const unsigned char *inbuf, size_t inbuflen)
+{
+  return do_ecb_crypt (c, outbuf, outbuflen, inbuf, inbuflen, c->spec->decrypt);
 }
 
 
@@ -1699,8 +758,8 @@ do_aeswrap_decrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
  * Depending on the mode some constraints apply to INBUFLEN.
  */
 static gcry_err_code_t
-cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
-               const byte *inbuf, unsigned int inbuflen)
+cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen,
+               const byte *inbuf, size_t inbuflen)
 {
   gcry_err_code_t rc;
 
@@ -1711,28 +770,41 @@ cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
       break;
 
     case GCRY_CIPHER_MODE_CBC:
-      rc = do_cbc_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+      rc = _gcry_cipher_cbc_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
       break;
 
     case GCRY_CIPHER_MODE_CFB:
-      rc = do_cfb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+      rc = _gcry_cipher_cfb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
       break;
 
     case GCRY_CIPHER_MODE_OFB:
-      rc = do_ofb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+      rc = _gcry_cipher_ofb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
       break;
 
     case GCRY_CIPHER_MODE_CTR:
-      rc = do_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+      rc = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
       break;
 
     case GCRY_CIPHER_MODE_AESWRAP:
-      rc = do_aeswrap_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+      rc = _gcry_cipher_aeswrap_encrypt (c, outbuf, outbuflen,
+                                         inbuf, inbuflen);
+      break;
+
+    case GCRY_CIPHER_MODE_CCM:
+      rc = _gcry_cipher_ccm_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+      break;
+
+    case GCRY_CIPHER_MODE_CMAC:
+      rc = GPG_ERR_INV_CIPHER_MODE;
+      break;
+
+    case GCRY_CIPHER_MODE_GCM:
+      rc = _gcry_cipher_gcm_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
       break;
 
     case GCRY_CIPHER_MODE_STREAM:
-      c->cipher->stencrypt (&c->context.c,
-                            outbuf, (byte*)/*arggg*/inbuf, inbuflen);
+      c->spec->stencrypt (&c->context.c,
+                          outbuf, (byte*)/*arggg*/inbuf, inbuflen);
       rc = 0;
       break;
 
@@ -1764,23 +836,26 @@ cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
  * Encrypt IN and write it to OUT.  If IN is NULL, in-place encryption has
  * been requested.
  */
-gcry_error_t
-gcry_cipher_encrypt (gcry_cipher_hd_t h, void *out, size_t outsize,
-                     const void *in, size_t inlen)
+gcry_err_code_t
+_gcry_cipher_encrypt (gcry_cipher_hd_t h, void *out, size_t outsize,
+                      const void *in, size_t inlen)
 {
-  gcry_err_code_t err;
+  gcry_err_code_t rc;
 
   if (!in)  /* Caller requested in-place encryption.  */
-    err = cipher_encrypt (h, out, outsize, out, outsize);
-  else
-    err = cipher_encrypt (h, out, outsize, in, inlen);
+    {
+      in = out;
+      inlen = outsize;
+    }
+
+  rc = cipher_encrypt (h, out, outsize, in, inlen);
 
   /* Failsafe: Make sure that the plaintext will never make it into
      OUT if the encryption returned an error.  */
-  if (err && out)
+  if (rc && out)
     memset (out, 0x42, outsize);
 
-  return gcry_error (err);
+  return rc;
 }
 
 
@@ -1791,8 +866,8 @@ gcry_cipher_encrypt (gcry_cipher_hd_t h, void *out, size_t outsize,
  * Depending on the mode some some contraints apply to INBUFLEN.
  */
 static gcry_err_code_t
-cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
-                const byte *inbuf, unsigned int inbuflen)
+cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen,
+                const byte *inbuf, size_t inbuflen)
 {
   gcry_err_code_t rc;
 
@@ -1803,28 +878,41 @@ cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
       break;
 
     case GCRY_CIPHER_MODE_CBC:
-      rc = do_cbc_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+      rc = _gcry_cipher_cbc_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
       break;
 
     case GCRY_CIPHER_MODE_CFB:
-      rc = do_cfb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+      rc = _gcry_cipher_cfb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
       break;
 
     case GCRY_CIPHER_MODE_OFB:
-      rc = do_ofb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+      rc = _gcry_cipher_ofb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
       break;
 
     case GCRY_CIPHER_MODE_CTR:
-      rc = do_ctr_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+      rc = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
       break;
 
     case GCRY_CIPHER_MODE_AESWRAP:
-      rc = do_aeswrap_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+      rc = _gcry_cipher_aeswrap_decrypt (c, outbuf, outbuflen,
+                                         inbuf, inbuflen);
+      break;
+
+    case GCRY_CIPHER_MODE_CCM:
+      rc = _gcry_cipher_ccm_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
+      break;
+
+    case GCRY_CIPHER_MODE_CMAC:
+      rc = GPG_ERR_INV_CIPHER_MODE;
+      break;
+
+    case GCRY_CIPHER_MODE_GCM:
+      rc = _gcry_cipher_gcm_decrypt (c, outbuf, outbuflen, inbuf, inbuflen);
       break;
 
     case GCRY_CIPHER_MODE_STREAM:
-      c->cipher->stdecrypt (&c->context.c,
-                            outbuf, (byte*)/*arggg*/inbuf, inbuflen);
+      c->spec->stdecrypt (&c->context.c,
+                          outbuf, (byte*)/*arggg*/inbuf, inbuflen);
       rc = 0;
       break;
 
@@ -1852,18 +940,17 @@ cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, unsigned int outbuflen,
 }
 
 
-gcry_error_t
-gcry_cipher_decrypt (gcry_cipher_hd_t h, void *out, size_t outsize,
-                    const void *in, size_t inlen)
+gcry_err_code_t
+_gcry_cipher_decrypt (gcry_cipher_hd_t h, void *out, size_t outsize,
+                      const void *in, size_t inlen)
 {
-  gcry_err_code_t err;
-
   if (!in) /* Caller requested in-place encryption. */
-    err = cipher_decrypt (h, out, outsize, out, outsize);
-  else
-    err = cipher_decrypt (h, out, outsize, in, inlen);
+    {
+      in = out;
+      inlen = outsize;
+    }
 
-  return gcry_error (err);
+  return cipher_decrypt (h, out, outsize, in, inlen);
 }
 
 
@@ -1878,65 +965,157 @@ cipher_sync (gcry_cipher_hd_t c)
   if ((c->flags & GCRY_CIPHER_ENABLE_SYNC) && c->unused)
     {
       memmove (c->u_iv.iv + c->unused,
-               c->u_iv.iv, c->cipher->blocksize - c->unused);
+               c->u_iv.iv, c->spec->blocksize - c->unused);
       memcpy (c->u_iv.iv,
-              c->lastiv + c->cipher->blocksize - c->unused, c->unused);
+              c->lastiv + c->spec->blocksize - c->unused, c->unused);
       c->unused = 0;
     }
 }
 
 
-gcry_error_t
+gcry_err_code_t
 _gcry_cipher_setkey (gcry_cipher_hd_t hd, const void *key, size_t keylen)
 {
   return cipher_setkey (hd, (void*)key, keylen);
 }
 
 
-gcry_error_t
+gcry_err_code_t
 _gcry_cipher_setiv (gcry_cipher_hd_t hd, const void *iv, size_t ivlen)
 {
-  cipher_setiv (hd, iv, ivlen);
-  return 0;
+  gcry_err_code_t rc = 0;
+
+  switch (hd->mode)
+    {
+      case GCRY_CIPHER_MODE_CCM:
+        rc = _gcry_cipher_ccm_set_nonce (hd, iv, ivlen);
+        break;
+
+      default:
+        rc = cipher_setiv (hd, iv, ivlen);
+        break;
+    }
+  return rc;
 }
 
 /* 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
+gpg_err_code_t
 _gcry_cipher_setctr (gcry_cipher_hd_t hd, const void *ctr, size_t ctrlen)
 {
-  if (ctr && ctrlen == hd->cipher->blocksize)
+  if (ctr && ctrlen == hd->spec->blocksize)
     {
-      memcpy (hd->u_ctr.ctr, ctr, hd->cipher->blocksize);
+      memcpy (hd->u_ctr.ctr, ctr, hd->spec->blocksize);
       hd->unused = 0;
     }
   else if (!ctr || !ctrlen)
     {
-      memset (hd->u_ctr.ctr, 0, hd->cipher->blocksize);
+      memset (hd->u_ctr.ctr, 0, hd->spec->blocksize);
       hd->unused = 0;
     }
   else
-    return gpg_error (GPG_ERR_INV_ARG);
+    return GPG_ERR_INV_ARG;
+
   return 0;
 }
 
 
-gcry_error_t
-gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
+gcry_err_code_t
+_gcry_cipher_authenticate (gcry_cipher_hd_t hd, const void *abuf,
+                           size_t abuflen)
 {
-  gcry_err_code_t rc = GPG_ERR_NO_ERROR;
+  gcry_err_code_t rc;
 
-  switch (cmd)
+  switch (hd->mode)
+    {
+    case GCRY_CIPHER_MODE_CCM:
+      rc = _gcry_cipher_ccm_authenticate (hd, abuf, abuflen);
+      break;
+
+    case GCRY_CIPHER_MODE_CMAC:
+      rc = _gcry_cipher_cmac_authenticate (hd, abuf, abuflen);
+      break;
+
+    case GCRY_CIPHER_MODE_GCM:
+      rc = _gcry_cipher_gcm_authenticate (hd, abuf, abuflen);
+      break;
+
+    default:
+      log_error ("gcry_cipher_authenticate: invalid mode %d\n", hd->mode);
+      rc = GPG_ERR_INV_CIPHER_MODE;
+      break;
+    }
+
+  return rc;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_gettag (gcry_cipher_hd_t hd, void *outtag, size_t taglen)
+{
+  gcry_err_code_t rc;
+
+  switch (hd->mode)
+    {
+    case GCRY_CIPHER_MODE_CCM:
+      rc = _gcry_cipher_ccm_get_tag (hd, outtag, taglen);
+      break;
+
+    case GCRY_CIPHER_MODE_CMAC:
+      rc = _gcry_cipher_cmac_get_tag (hd, outtag, taglen);
+      break;
+
+    case GCRY_CIPHER_MODE_GCM:
+      rc = _gcry_cipher_gcm_get_tag (hd, outtag, taglen);
+      break;
+
+    default:
+      log_error ("gcry_cipher_gettag: invalid mode %d\n", hd->mode);
+      rc = GPG_ERR_INV_CIPHER_MODE;
+      break;
+    }
+
+  return rc;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag, size_t taglen)
+{
+  gcry_err_code_t rc;
+
+  switch (hd->mode)
     {
-    case GCRYCTL_SET_KEY:  /* Deprecated; use gcry_cipher_setkey.  */
-      rc = cipher_setkey( h, buffer, buflen );
+    case GCRY_CIPHER_MODE_CCM:
+      rc = _gcry_cipher_ccm_check_tag (hd, intag, taglen);
+      break;
+
+    case GCRY_CIPHER_MODE_CMAC:
+      rc = _gcry_cipher_cmac_check_tag (hd, intag, taglen);
       break;
 
-    case GCRYCTL_SET_IV:   /* Deprecated; use gcry_cipher_setiv.  */
-      cipher_setiv( h, buffer, buflen );
+    case GCRY_CIPHER_MODE_GCM:
+      rc = _gcry_cipher_gcm_check_tag (hd, intag, taglen);
       break;
 
+    default:
+      log_error ("gcry_cipher_checktag: invalid mode %d\n", hd->mode);
+      rc = GPG_ERR_INV_CIPHER_MODE;
+      break;
+    }
+
+  return rc;
+}
+
+
+gcry_err_code_t
+_gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
+{
+  gcry_err_code_t rc = 0;
+
+  switch (cmd)
+    {
     case GCRYCTL_RESET:
       cipher_reset (h);
       break;
@@ -1965,6 +1144,34 @@ gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
        h->flags &= ~GCRY_CIPHER_CBC_MAC;
       break;
 
+    case GCRYCTL_SET_CCM_LENGTHS:
+#ifdef HAVE_U64_TYPEDEF
+      {
+        u64 params[3];
+        size_t encryptedlen;
+        size_t aadlen;
+        size_t authtaglen;
+
+        if (h->mode != GCRY_CIPHER_MODE_CCM)
+          return gcry_error (GPG_ERR_INV_CIPHER_MODE);
+
+        if (!buffer || buflen != 3 * sizeof(u64))
+          return gcry_error (GPG_ERR_INV_ARG);
+
+        /* This command is used to pass additional length parameters needed
+           by CCM mode to initialize CBC-MAC.  */
+        memcpy (params, buffer, sizeof(params));
+        encryptedlen = params[0];
+        aadlen = params[1];
+        authtaglen = params[2];
+
+        rc = _gcry_cipher_ccm_set_lengths (h, encryptedlen, aadlen, authtaglen);
+      }
+#else
+      rc = GPG_ERR_NOT_SUPPORTED;
+#endif
+      break;
+
     case GCRYCTL_DISABLE_ALGO:
       /* This command expects NULL for H and BUFFER to point to an
          integer with the algo number.  */
@@ -1973,13 +1180,9 @@ gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
       disable_cipher_algo( *(int*)buffer );
       break;
 
-    case GCRYCTL_SET_CTR: /* Deprecated; use gcry_cipher_setctr.  */
-      rc = gpg_err_code (_gcry_cipher_setctr (h, buffer, buflen));
-      break;
-
     case 61:  /* Disable weak key detection (private).  */
-      if (h->extraspec->set_extra_info)
-        rc = h->extraspec->set_extra_info
+      if (h->spec->set_extra_info)
+        rc = h->spec->set_extra_info
           (&h->context.c, CIPHER_INFO_NO_WEAK_KEY, NULL, 0);
       else
         rc = GPG_ERR_NOT_SUPPORTED;
@@ -1991,7 +1194,7 @@ gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
            1 byte  Actual length of the block in bytes.
            n byte  The block.
          If the provided buffer is too short, an error is returned. */
-      if (buflen < (1 + h->cipher->blocksize))
+      if (buflen < (1 + h->spec->blocksize))
         rc = GPG_ERR_TOO_SHORT;
       else
         {
@@ -2000,10 +1203,10 @@ gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
           int n = h->unused;
 
           if (!n)
-            n = h->cipher->blocksize;
-          gcry_assert (n <= h->cipher->blocksize);
+            n = h->spec->blocksize;
+          gcry_assert (n <= h->spec->blocksize);
           *dst++ = n;
-          ivp = h->u_iv.iv + h->cipher->blocksize - n;
+          ivp = h->u_iv.iv + h->spec->blocksize - n;
           while (n--)
             *dst++ = *ivp++;
         }
@@ -2013,7 +1216,7 @@ gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
       rc = GPG_ERR_INV_OP;
     }
 
-  return gcry_error (rc);
+  return rc;
 }
 
 
@@ -2025,10 +1228,10 @@ gcry_cipher_ctl( gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
    The function always returns GPG_ERR_INV_OP.
 
  */
-gcry_error_t
-gcry_cipher_info (gcry_cipher_hd_t h, int cmd, void *buffer, size_t *nbytes)
+gcry_err_code_t
+_gcry_cipher_info (gcry_cipher_hd_t h, int cmd, void *buffer, size_t *nbytes)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_err_code_t rc = 0;
 
   (void)h;
   (void)buffer;
@@ -2037,10 +1240,10 @@ gcry_cipher_info (gcry_cipher_hd_t h, int cmd, void *buffer, size_t *nbytes)
   switch (cmd)
     {
     default:
-      err = GPG_ERR_INV_OP;
+      rc = GPG_ERR_INV_OP;
     }
 
-  return gcry_error (err);
+  return rc;
 }
 
 /* Return information about the given cipher algorithm ALGO.
@@ -2067,56 +1270,57 @@ gcry_cipher_info (gcry_cipher_hd_t h, int cmd, void *buffer, size_t *nbytes)
    and thereby detecting whether a error occurred or not (i.e. while
    checking the block size)
  */
-gcry_error_t
-gcry_cipher_algo_info (int algo, int what, void *buffer, size_t *nbytes)
+gcry_err_code_t
+_gcry_cipher_algo_info (int algo, int what, void *buffer, size_t *nbytes)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_err_code_t rc = 0;
   unsigned int ui;
 
   switch (what)
     {
     case GCRYCTL_GET_KEYLEN:
       if (buffer || (! nbytes))
-       err = GPG_ERR_CIPHER_ALGO;
+       rc = GPG_ERR_CIPHER_ALGO;
       else
        {
          ui = cipher_get_keylen (algo);
          if ((ui > 0) && (ui <= 512))
            *nbytes = (size_t) ui / 8;
          else
-           /* The only reason is an invalid algo or a strange
-              blocksize.  */
-           err = GPG_ERR_CIPHER_ALGO;
+           /* The only reason for an error is an invalid algo.  */
+           rc = GPG_ERR_CIPHER_ALGO;
        }
       break;
 
     case GCRYCTL_GET_BLKLEN:
       if (buffer || (! nbytes))
-       err = GPG_ERR_CIPHER_ALGO;
+       rc = GPG_ERR_CIPHER_ALGO;
       else
        {
          ui = cipher_get_blocksize (algo);
          if ((ui > 0) && (ui < 10000))
            *nbytes = ui;
          else
-           /* The only reason is an invalid algo or a strange
-              blocksize.  */
-           err = GPG_ERR_CIPHER_ALGO;
+            {
+              /* The only reason is an invalid algo or a strange
+                 blocksize.  */
+              rc = GPG_ERR_CIPHER_ALGO;
+            }
        }
       break;
 
     case GCRYCTL_TEST_ALGO:
       if (buffer || nbytes)
-       err = GPG_ERR_INV_ARG;
+       rc = GPG_ERR_INV_ARG;
       else
-       err = check_cipher_algo (algo);
+       rc = check_cipher_algo (algo);
       break;
 
       default:
-       err = GPG_ERR_INV_OP;
+       rc = GPG_ERR_INV_OP;
     }
 
-  return gcry_error (err);
+  return rc;
 }
 
 
@@ -2129,15 +1333,16 @@ gcry_cipher_algo_info (int algo, int what, void *buffer, size_t *nbytes)
    gcry_cipher_algo_info because it allows for proper type
    checking.  */
 size_t
-gcry_cipher_get_algo_keylen (int algo)
+_gcry_cipher_get_algo_keylen (int algo)
 {
   size_t n;
 
-  if (gcry_cipher_algo_info (algo, GCRYCTL_GET_KEYLEN, NULL, &n))
+  if (_gcry_cipher_algo_info (algo, GCRYCTL_GET_KEYLEN, NULL, &n))
     n = 0;
   return n;
 }
 
+
 /* This functions returns the blocklength of the algorithm ALGO
    counted in octets.  On error 0 is returned.
 
@@ -2145,42 +1350,21 @@ gcry_cipher_get_algo_keylen (int algo)
    gcry_cipher_algo_info because it allows for proper type
    checking.  */
 size_t
-gcry_cipher_get_algo_blklen (int algo)
+_gcry_cipher_get_algo_blklen (int algo)
 {
   size_t n;
 
-  if (gcry_cipher_algo_info( algo, GCRYCTL_GET_BLKLEN, NULL, &n))
+  if (_gcry_cipher_algo_info( algo, GCRYCTL_GET_BLKLEN, NULL, &n))
     n = 0;
   return n;
 }
 
+
 /* Explicitly initialize this module.  */
 gcry_err_code_t
 _gcry_cipher_init (void)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
-  REGISTER_DEFAULT_CIPHERS;
-
-  return err;
-}
-
-/* Get a list consisting of the IDs of the loaded cipher modules.  If
-   LIST is zero, write the number of loaded cipher modules to
-   LIST_LENGTH and return.  If LIST is non-zero, the first
-   *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
-   according size.  In case there are less cipher modules than
-   *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
-gcry_error_t
-gcry_cipher_list (int *list, int *list_length)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
-  ath_mutex_lock (&ciphers_registered_lock);
-  err = _gcry_module_list (ciphers_registered, list, list_length);
-  ath_mutex_unlock (&ciphers_registered_lock);
-
-  return err;
+  return 0;
 }
 
 
@@ -2189,34 +1373,21 @@ gcry_cipher_list (int *list, int *list_length)
 gpg_error_t
 _gcry_cipher_selftest (int algo, int extended, selftest_report_func_t report)
 {
-  gcry_module_t module = NULL;
-  cipher_extra_spec_t *extraspec = NULL;
   gcry_err_code_t ec = 0;
+  gcry_cipher_spec_t *spec;
 
-  REGISTER_DEFAULT_CIPHERS;
-
-  ath_mutex_lock (&ciphers_registered_lock);
-  module = _gcry_module_lookup_id (ciphers_registered, algo);
-  if (module && !(module->flags & FLAG_MODULE_DISABLED))
-    extraspec = module->extraspec;
-  ath_mutex_unlock (&ciphers_registered_lock);
-  if (extraspec && extraspec->selftest)
-    ec = extraspec->selftest (algo, extended, report);
+  spec = spec_from_algo (algo);
+  if (spec && !spec->flags.disabled && spec->selftest)
+    ec = spec->selftest (algo, extended, report);
   else
     {
       ec = GPG_ERR_CIPHER_ALGO;
       if (report)
         report ("cipher", algo, "module",
-                module && !(module->flags & FLAG_MODULE_DISABLED)?
+                (spec && !spec->flags.disabled)?
                 "no selftest available" :
-                module? "algorithm disabled" : "algorithm not found");
+                spec? "algorithm disabled" : "algorithm not found");
     }
 
-  if (module)
-    {
-      ath_mutex_lock (&ciphers_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&ciphers_registered_lock);
-    }
   return gpg_error (ec);
 }
index 9e406f1..1322f0d 100644 (file)
@@ -149,9 +149,12 @@ CRC_CONTEXT;
 /* CRC32 */
 
 static void
-crc32_init (void *context)
+crc32_init (void *context, unsigned int flags)
 {
   CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+
+  (void)flags;
+
   ctx->CRC = 0 ^ 0xffffffffL;
 }
 
@@ -184,9 +187,12 @@ crc32_final (void *context)
 
 /* CRC32 a'la RFC 1510 */
 static void
-crc32rfc1510_init (void *context)
+crc32rfc1510_init (void *context, unsigned int flags)
 {
   CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+
+  (void)flags;
+
   ctx->CRC = 0;
 }
 
@@ -237,9 +243,12 @@ crc32rfc1510_final (void *context)
 #define CRC24_POLY 0x1864cfbL
 
 static void
-crc24rfc2440_init (void *context)
+crc24rfc2440_init (void *context, unsigned int flags)
 {
   CRC_CONTEXT *ctx = (CRC_CONTEXT *) context;
+
+  (void)flags;
+
   ctx->CRC = CRC24_INIT;
 }
 
@@ -272,8 +281,12 @@ crc24rfc2440_final (void *context)
   ctx->buf[2] = (ctx->CRC      ) & 0xFF;
 }
 
+/* We allow the CRC algorithms even in FIPS mode because they are
+   actually no cryptographic primitives.  */
+
 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,
     sizeof (CRC_CONTEXT)
@@ -281,6 +294,7 @@ gcry_md_spec_t _gcry_digest_spec_crc32 =
 
 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,
@@ -289,6 +303,7 @@ gcry_md_spec_t _gcry_digest_spec_crc32_rfc1510 =
 
 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,
index 96b06ae..6611fd3 100644 (file)
 #include "types.h"             /* for byte and u32 typedefs */
 #include "g10lib.h"
 #include "cipher.h"
+#include "bufhelp.h"
 
 #if defined(__GNUC__) && defined(__GNU_LIBRARY__)
 #define working_memcmp memcmp
@@ -455,14 +456,12 @@ static unsigned char weak_keys_chksum[20] = {
  * Macros to convert 8 bytes from/to 32bit words.
  */
 #define READ_64BIT_DATA(data, left, right)                                \
-    left  = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];  \
-    right = (data[4] << 24) | (data[5] << 16) | (data[6] << 8) | data[7];
+    left = buf_get_be32(data + 0);                                        \
+    right = buf_get_be32(data + 4);
 
 #define WRITE_64BIT_DATA(data, left, right)                               \
-    data[0] = (left >> 24) &0xff; data[1] = (left >> 16) &0xff;           \
-    data[2] = (left >> 8) &0xff; data[3] = left &0xff;                    \
-    data[4] = (right >> 24) &0xff; data[5] = (right >> 16) &0xff;         \
-    data[6] = (right >> 8) &0xff; data[7] = right &0xff;
+    buf_put_be32(data + 0, left);                                         \
+    buf_put_be32(data + 4, right);
 
 /*
  * Handy macros for encryption and decryption of data
@@ -894,7 +893,8 @@ selftest (void)
    * thanks to Jeroen C. van Gelderen.
    */
   {
-    struct { byte key[24]; byte plain[8]; byte cipher[8]; } testdata[] = {
+    static const struct { byte key[24]; byte plain[8]; byte cipher[8]; }
+      testdata[] = {
       { { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
           0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
           0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01  },
@@ -1054,21 +1054,21 @@ do_tripledes_set_extra_info (void *context, int what,
 }
 
 
-static void
+static unsigned int
 do_tripledes_encrypt( void *context, byte *outbuf, const byte *inbuf )
 {
   struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context;
 
   tripledes_ecb_encrypt ( ctx, inbuf, outbuf );
-  _gcry_burn_stack (32);
+  return /*burn_stack*/ (32);
 }
 
-static void
+static unsigned int
 do_tripledes_decrypt( void *context, byte *outbuf, const byte *inbuf )
 {
   struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context;
   tripledes_ecb_decrypt ( ctx, inbuf, outbuf );
-  _gcry_burn_stack (32);
+  return /*burn_stack*/ (32);
 }
 
 static gcry_err_code_t
@@ -1091,22 +1091,22 @@ do_des_setkey (void *context, const byte *key, unsigned keylen)
 }
 
 
-static void
+static unsigned int
 do_des_encrypt( void *context, byte *outbuf, const byte *inbuf )
 {
   struct _des_ctx *ctx = (struct _des_ctx *) context;
 
   des_ecb_encrypt ( ctx, inbuf, outbuf );
-  _gcry_burn_stack (32);
+  return /*burn_stack*/ (32);
 }
 
-static void
+static unsigned int
 do_des_decrypt( void *context, byte *outbuf, const byte *inbuf )
 {
   struct _des_ctx *ctx = (struct _des_ctx *) context;
 
   des_ecb_decrypt ( ctx, inbuf, outbuf );
-  _gcry_burn_stack (32);
+  return /*burn_stack*/ (32);
 }
 
 
@@ -1169,6 +1169,7 @@ run_selftests (int algo, int extended, selftest_report_func_t report)
 \f
 gcry_cipher_spec_t _gcry_cipher_spec_des =
   {
+    GCRY_CIPHER_DES, {0, 0},
     "DES", NULL, NULL, 8, 64, sizeof (struct _des_ctx),
     do_des_setkey, do_des_encrypt, do_des_decrypt
   };
@@ -1185,12 +1186,10 @@ static gcry_cipher_oid_spec_t oids_tripledes[] =
 
 gcry_cipher_spec_t _gcry_cipher_spec_tripledes =
   {
+    GCRY_CIPHER_3DES, {0, 1},
     "3DES", NULL, oids_tripledes, 8, 192, sizeof (struct _tripledes_ctx),
-    do_tripledes_setkey, do_tripledes_encrypt, do_tripledes_decrypt
-  };
-
-cipher_extra_spec_t _gcry_cipher_extraspec_tripledes =
-  {
+    do_tripledes_setkey, do_tripledes_encrypt, do_tripledes_decrypt,
+    NULL, NULL,
     run_selftests,
     do_tripledes_set_extra_info
   };
diff --git a/cipher/dsa-common.c b/cipher/dsa-common.c
new file mode 100644 (file)
index 0000000..a5e42a2
--- /dev/null
@@ -0,0 +1,394 @@
+/* dsa-common.c - Common code for DSA
+ * Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+ * Copyright (C) 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/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "pubkey-internal.h"
+
+
+/*
+ * Generate a random secret exponent K less than Q.
+ * Note that ECDSA uses this code also to generate D.
+ */
+gcry_mpi_t
+_gcry_dsa_gen_k (gcry_mpi_t q, int security_level)
+{
+  gcry_mpi_t k        = mpi_alloc_secure (mpi_get_nlimbs (q));
+  unsigned int nbits  = mpi_get_nbits (q);
+  unsigned int nbytes = (nbits+7)/8;
+  char *rndbuf = NULL;
+
+  /* To learn why we don't use mpi_mod to get the requested bit size,
+     read the paper: "The Insecurity of the Digital Signature
+     Algorithm with Partially Known Nonces" by Nguyen and Shparlinski.
+     Journal of Cryptology, New York. Vol 15, nr 3 (2003)  */
+
+  if (DBG_CIPHER)
+    log_debug ("choosing a random k of %u bits at seclevel %d\n",
+               nbits, security_level);
+  for (;;)
+    {
+      if ( !rndbuf || nbits < 32 )
+        {
+          xfree (rndbuf);
+          rndbuf = _gcry_random_bytes_secure (nbytes, security_level);
+       }
+      else
+        { /* Change only some of the higher bits.  We could improve
+            this by directly requesting more memory at the first call
+            to get_random_bytes() and use these extra bytes here.
+            However the required management code is more complex and
+            thus we better use this simple method.  */
+          char *pp = _gcry_random_bytes_secure (4, security_level);
+          memcpy (rndbuf, pp, 4);
+          xfree (pp);
+       }
+      _gcry_mpi_set_buffer (k, rndbuf, nbytes, 0);
+
+      /* Make sure we have the requested number of bits.  This code
+         looks a bit funny but it is easy to understand if you
+         consider that mpi_set_highbit clears all higher bits.  We
+         don't have a clear_highbit, thus we first set the high bit
+         and then clear it again.  */
+      if (mpi_test_bit (k, nbits-1))
+        mpi_set_highbit (k, nbits-1);
+      else
+        {
+          mpi_set_highbit (k, nbits-1);
+          mpi_clear_bit (k, nbits-1);
+       }
+
+      if (!(mpi_cmp (k, q) < 0))    /* check: k < q */
+        {
+          if (DBG_CIPHER)
+            log_debug ("\tk too large - again\n");
+          continue; /* no  */
+        }
+      if (!(mpi_cmp_ui (k, 0) > 0)) /* check: k > 0 */
+        {
+          if (DBG_CIPHER)
+            log_debug ("\tk is zero - again\n");
+          continue; /* no */
+        }
+      break;   /* okay */
+    }
+  xfree (rndbuf);
+
+  return k;
+}
+
+
+/* Turn VALUE into an octet string and store it in an allocated buffer
+   at R_FRAME.  If the resulting octet string is shorter than NBYTES
+   the result will be left padded with zeroes.  If VALUE does not fit
+   into NBYTES an error code is returned.  */
+static gpg_err_code_t
+int2octets (unsigned char **r_frame, gcry_mpi_t value, size_t nbytes)
+{
+  gpg_err_code_t rc;
+  size_t nframe, noff, n;
+  unsigned char *frame;
+
+  rc = _gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &nframe, value);
+  if (rc)
+    return rc;
+  if (nframe > nbytes)
+    return GPG_ERR_TOO_LARGE; /* Value too long to fit into NBYTES.  */
+
+  noff = (nframe < nbytes)? nbytes - nframe : 0;
+  n = nframe + noff;
+  frame = mpi_is_secure (value)? xtrymalloc_secure (n) : xtrymalloc (n);
+  if (!frame)
+    return gpg_err_code_from_syserror ();
+  if (noff)
+    memset (frame, 0, noff);
+  nframe += noff;
+  rc = _gcry_mpi_print (GCRYMPI_FMT_USG, frame+noff, nframe-noff, NULL, value);
+  if (rc)
+    {
+      xfree (frame);
+      return rc;
+    }
+
+  *r_frame = frame;
+  return 0;
+}
+
+
+/* Connert the bit string BITS of length NBITS into an octet string
+   with a length of (QBITS+7)/8 bytes.  On success store the result at
+   R_FRAME.  */
+static gpg_err_code_t
+bits2octets (unsigned char **r_frame,
+             const void *bits, unsigned int nbits,
+             gcry_mpi_t q, unsigned int qbits)
+{
+  gpg_err_code_t rc;
+  gcry_mpi_t z1;
+
+  /* z1 = bits2int (b) */
+  rc = _gcry_mpi_scan (&z1, GCRYMPI_FMT_USG, bits, (nbits+7)/8, NULL);
+  if (rc)
+    return rc;
+  if (nbits > qbits)
+    mpi_rshift (z1, z1, nbits - qbits);
+
+  /* z2 - z1 mod q */
+  if (mpi_cmp (z1, q) >= 0)
+    mpi_sub (z1, z1, q);
+
+  /* Convert to an octet string.  */
+  rc = int2octets (r_frame, z1, (qbits+7)/8);
+
+  mpi_free (z1);
+  return rc;
+}
+
+
+/*
+ * Generate a deterministic secret exponent K less than DSA_Q.  H1 is
+ * the to be signed digest with a length of HLEN bytes.  HALGO is the
+ * algorithm used to create the hash.  On success the value for K is
+ * stored at R_K.
+ */
+gpg_err_code_t
+_gcry_dsa_gen_rfc6979_k (gcry_mpi_t *r_k,
+                         gcry_mpi_t dsa_q, gcry_mpi_t dsa_x,
+                         const unsigned char *h1, unsigned int hlen,
+                         int halgo, unsigned int extraloops)
+{
+  gpg_err_code_t rc;
+  unsigned char *V = NULL;
+  unsigned char *K = NULL;
+  unsigned char *x_buf = NULL;
+  unsigned char *h1_buf = NULL;
+  gcry_md_hd_t hd = NULL;
+  unsigned char *t = NULL;
+  gcry_mpi_t k = NULL;
+  unsigned int tbits, qbits;
+  int i;
+
+  qbits = mpi_get_nbits (dsa_q);
+
+  if (!qbits || !h1 || !hlen)
+    return GPG_ERR_EINVAL;
+
+  if (_gcry_md_get_algo_dlen (halgo) != hlen)
+    return GPG_ERR_DIGEST_ALGO;
+
+  /* Step b:  V = 0x01 0x01 0x01 ... 0x01 */
+  V = xtrymalloc (hlen);
+  if (!V)
+    {
+      rc = gpg_err_code_from_syserror ();
+      goto leave;
+    }
+  for (i=0; i < hlen; i++)
+    V[i] = 1;
+
+  /* Step c:  K = 0x00 0x00 0x00 ... 0x00 */
+  K = xtrycalloc (1, hlen);
+  if (!K)
+    {
+      rc = gpg_err_code_from_syserror ();
+      goto leave;
+    }
+
+  rc = int2octets (&x_buf, dsa_x, (qbits+7)/8);
+  if (rc)
+    goto leave;
+
+  rc = bits2octets (&h1_buf, h1, hlen*8, dsa_q, qbits);
+  if (rc)
+    goto leave;
+
+  /* Create a handle to compute the HMACs.  */
+  rc = _gcry_md_open (&hd, halgo, (GCRY_MD_FLAG_SECURE | GCRY_MD_FLAG_HMAC));
+  if (rc)
+    goto leave;
+
+  /* Step d:  K = HMAC_K(V || 0x00 || int2octets(x) || bits2octets(h1) */
+  rc = _gcry_md_setkey (hd, K, hlen);
+  if (rc)
+    goto leave;
+  _gcry_md_write (hd, V, hlen);
+  _gcry_md_write (hd, "", 1);
+  _gcry_md_write (hd, x_buf, (qbits+7)/8);
+  _gcry_md_write (hd, h1_buf, (qbits+7)/8);
+  memcpy (K, _gcry_md_read (hd, 0), hlen);
+
+  /* Step e:  V = HMAC_K(V) */
+  rc = _gcry_md_setkey (hd, K, hlen);
+  if (rc)
+    goto leave;
+  _gcry_md_write (hd, V, hlen);
+  memcpy (V, _gcry_md_read (hd, 0), hlen);
+
+  /* Step f:  K = HMAC_K(V || 0x01 || int2octets(x) || bits2octets(h1) */
+  rc = _gcry_md_setkey (hd, K, hlen);
+  if (rc)
+    goto leave;
+  _gcry_md_write (hd, V, hlen);
+  _gcry_md_write (hd, "\x01", 1);
+  _gcry_md_write (hd, x_buf, (qbits+7)/8);
+  _gcry_md_write (hd, h1_buf, (qbits+7)/8);
+  memcpy (K, _gcry_md_read (hd, 0), hlen);
+
+  /* Step g:  V = HMAC_K(V) */
+  rc = _gcry_md_setkey (hd, K, hlen);
+  if (rc)
+    goto leave;
+  _gcry_md_write (hd, V, hlen);
+  memcpy (V, _gcry_md_read (hd, 0), hlen);
+
+  /* Step h. */
+  t = xtrymalloc ((qbits+7)/8+hlen);
+  if (!t)
+    {
+      rc = gpg_err_code_from_syserror ();
+      goto leave;
+    }
+
+ again:
+  for (tbits = 0; tbits < qbits;)
+    {
+      /* V = HMAC_K(V) */
+      rc = _gcry_md_setkey (hd, K, hlen);
+      if (rc)
+        goto leave;
+      _gcry_md_write (hd, V, hlen);
+      memcpy (V, _gcry_md_read (hd, 0), hlen);
+
+      /* T = T || V */
+      memcpy (t+(tbits+7)/8, V, hlen);
+      tbits += 8*hlen;
+    }
+
+  /* k = bits2int (T) */
+  mpi_free (k);
+  k = NULL;
+  rc = _gcry_mpi_scan (&k, GCRYMPI_FMT_USG, t, (tbits+7)/8, NULL);
+  if (rc)
+    goto leave;
+  if (tbits > qbits)
+    mpi_rshift (k, k, tbits - qbits);
+
+  /* Check: k < q and k > 1 */
+  if (!(mpi_cmp (k, dsa_q) < 0 && mpi_cmp_ui (k, 0) > 0))
+    {
+      /* K = HMAC_K(V || 0x00) */
+      rc = _gcry_md_setkey (hd, K, hlen);
+      if (rc)
+        goto leave;
+      _gcry_md_write (hd, V, hlen);
+      _gcry_md_write (hd, "", 1);
+      memcpy (K, _gcry_md_read (hd, 0), hlen);
+
+      /* V = HMAC_K(V) */
+      rc = _gcry_md_setkey (hd, K, hlen);
+      if (rc)
+        goto leave;
+      _gcry_md_write (hd, V, hlen);
+      memcpy (V, _gcry_md_read (hd, 0), hlen);
+
+      goto again;
+    }
+
+  /* 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
+     is very unlikely we implement it in a straightforward way.  */
+  if (extraloops)
+    {
+      extraloops--;
+
+      /* K = HMAC_K(V || 0x00) */
+      rc = _gcry_md_setkey (hd, K, hlen);
+      if (rc)
+        goto leave;
+      _gcry_md_write (hd, V, hlen);
+      _gcry_md_write (hd, "", 1);
+      memcpy (K, _gcry_md_read (hd, 0), hlen);
+
+      /* V = HMAC_K(V) */
+      rc = _gcry_md_setkey (hd, K, hlen);
+      if (rc)
+        goto leave;
+      _gcry_md_write (hd, V, hlen);
+      memcpy (V, _gcry_md_read (hd, 0), hlen);
+
+      goto again;
+    }
+
+  /* log_mpidump ("  k", k); */
+
+ leave:
+  xfree (t);
+  _gcry_md_close (hd);
+  xfree (h1_buf);
+  xfree (x_buf);
+  xfree (K);
+  xfree (V);
+
+  if (rc)
+    mpi_free (k);
+  else
+    *r_k = k;
+  return rc;
+}
+
+/*
+ * Truncate opaque hash value to qbits for DSA.
+ * Non-opaque input is not truncated, in hope that user
+ * knows what is passed. It is not possible to correctly
+ * trucate non-opaque inputs.
+ */
+gpg_err_code_t
+_gcry_dsa_normalize_hash (gcry_mpi_t input,
+                          gcry_mpi_t *out,
+                          unsigned int qbits)
+{
+  gpg_err_code_t rc = 0;
+  const void *abuf;
+  unsigned int abits;
+  gcry_mpi_t hash;
+
+  if (mpi_is_opaque (input))
+    {
+      abuf = mpi_get_opaque (input, &abits);
+      rc = _gcry_mpi_scan (&hash, GCRYMPI_FMT_USG, abuf, (abits+7)/8, NULL);
+      if (rc)
+        return rc;
+      if (abits > qbits)
+        mpi_rshift (hash, hash, abits - qbits);
+    }
+  else
+    hash = input;
+
+  *out = hash;
+
+  return rc;
+}
index 883a815..1707d8c 100644 (file)
@@ -1,6 +1,7 @@
 /* dsa.c - DSA signature algorithm
  * Copyright (C) 1998, 2000, 2001, 2002, 2003,
  *               2006, 2008  Free Software Foundation, Inc.
+ * Copyright (C) 2013 g10 Code GmbH.
  *
  * This file is part of Libgcrypt.
  *
@@ -26,6 +27,8 @@
 #include "g10lib.h"
 #include "mpi.h"
 #include "cipher.h"
+#include "pubkey-internal.h"
+
 
 typedef struct
 {
@@ -55,6 +58,14 @@ typedef struct
 } dsa_domain_t;
 
 
+static const char *dsa_names[] =
+  {
+    "dsa",
+    "openpgp-dsa",
+    NULL,
+  };
+
+
 /* A sample 1024 bit DSA key used for the selftests.  */
 static const char sample_secret_key[] =
 "(private-key"
@@ -94,7 +105,6 @@ static const char sample_public_key[] =
 
 
 \f
-static gcry_mpi_t gen_k (gcry_mpi_t q);
 static int test_keys (DSA_secret_key *sk, unsigned int qbits);
 static int check_secret_key (DSA_secret_key *sk);
 static gpg_err_code_t generate (DSA_secret_key *sk,
@@ -103,10 +113,12 @@ static gpg_err_code_t generate (DSA_secret_key *sk,
                                 int transient_key,
                                 dsa_domain_t *domain,
                                 gcry_mpi_t **ret_factors);
-static void sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
-                  DSA_secret_key *skey);
-static int verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
+static gpg_err_code_t sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
+                            DSA_secret_key *skey, int flags, int hashalgo);
+static gpg_err_code_t verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input,
                    DSA_public_key *pkey);
+static unsigned int dsa_get_nbits (gcry_sexp_t parms);
+
 
 static void (*progress_cb) (void *,const char *, int, int, int );
 static void *progress_cb_data;
@@ -130,90 +142,15 @@ progress (int c)
 }
 
 
-/*
- * Generate a random secret exponent k less than q.
- */
-static gcry_mpi_t
-gen_k( gcry_mpi_t q )
-{
-  gcry_mpi_t k = mpi_alloc_secure( mpi_get_nlimbs(q) );
-  unsigned int nbits = mpi_get_nbits(q);
-  unsigned int nbytes = (nbits+7)/8;
-  char *rndbuf = NULL;
-
-  /* To learn why we don't use mpi_mod to get the requested bit size,
-     read the paper: "The Insecurity of the Digital Signature
-     Algorithm with Partially Known Nonces" by Nguyen and Shparlinski.
-     Journal of Cryptology, New York. Vol 15, nr 3 (2003)  */
-
-  if ( DBG_CIPHER )
-    log_debug("choosing a random k ");
-  for (;;)
-    {
-      if( DBG_CIPHER )
-        progress('.');
-
-      if ( !rndbuf || nbits < 32 )
-        {
-          gcry_free(rndbuf);
-          rndbuf = gcry_random_bytes_secure( (nbits+7)/8, GCRY_STRONG_RANDOM );
-       }
-      else
-        { /* Change only some of the higher bits.  We could improve
-            this by directly requesting more memory at the first call
-            to get_random_bytes() and use these extra bytes here.
-            However the required management code is more complex and
-            thus we better use this simple method.  */
-          char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
-          memcpy( rndbuf,pp, 4 );
-          gcry_free(pp);
-       }
-      _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
-
-      /* Make sure we have the requested number of bits.  This code
-         looks a bit funny but it is easy to understand if you
-         consider that mpi_set_highbit clears all higher bits.  We
-         don't have a clear_highbit, thus we first set the high bit
-         and then clear it again.  */
-      if ( mpi_test_bit( k, nbits-1 ) )
-        mpi_set_highbit( k, nbits-1 );
-      else
-        {
-          mpi_set_highbit( k, nbits-1 );
-          mpi_clear_bit( k, nbits-1 );
-       }
-
-      if( !(mpi_cmp( k, q ) < 0) ) /* check: k < q */
-        {
-          if( DBG_CIPHER )
-            progress('+');
-          continue; /* no  */
-        }
-      if( !(mpi_cmp_ui( k, 0 ) > 0) )  /* check: k > 0 */
-        {
-          if( DBG_CIPHER )
-            progress('-');
-          continue; /* no */
-        }
-      break;   /* okay */
-    }
-  gcry_free(rndbuf);
-  if( DBG_CIPHER )
-    progress('\n');
-
-  return k;
-}
-
-
 /* Check that a freshly generated key actually works.  Returns 0 on success. */
 static int
 test_keys (DSA_secret_key *sk, unsigned int qbits)
 {
   int result = -1;  /* Default to failure.  */
   DSA_public_key pk;
-  gcry_mpi_t data  = gcry_mpi_new (qbits);
-  gcry_mpi_t sig_a = gcry_mpi_new (qbits);
-  gcry_mpi_t sig_b = gcry_mpi_new (qbits);
+  gcry_mpi_t data  = mpi_new (qbits);
+  gcry_mpi_t sig_a = mpi_new (qbits);
+  gcry_mpi_t sig_b = mpi_new (qbits);
 
   /* Put the relevant parameters into a public key structure.  */
   pk.p = sk->p;
@@ -222,26 +159,26 @@ test_keys (DSA_secret_key *sk, unsigned int qbits)
   pk.y = sk->y;
 
   /* Create a random plaintext.  */
-  gcry_mpi_randomize (data, qbits, GCRY_WEAK_RANDOM);
+  _gcry_mpi_randomize (data, qbits, GCRY_WEAK_RANDOM);
 
   /* Sign DATA using the secret key.  */
-  sign (sig_a, sig_b, data, sk);
+  sign (sig_a, sig_b, data, sk, 0, 0);
 
   /* Verify the signature using the public key.  */
-  if ( !verify (sig_a, sig_b, data, &pk) )
+  if ( verify (sig_a, sig_b, data, &pk) )
     goto leave; /* Signature does not match.  */
 
   /* Modify the data and check that the signing fails.  */
-  gcry_mpi_add_ui (data, data, 1);
-  if ( verify (sig_a, sig_b, data, &pk) )
+  mpi_add_ui (data, data, 1);
+  if ( !verify (sig_a, sig_b, data, &pk) )
     goto leave; /* Signature matches but should not.  */
 
   result = 0; /* The test succeeded.  */
 
  leave:
-  gcry_mpi_release (sig_b);
-  gcry_mpi_release (sig_a);
-  gcry_mpi_release (data);
+  _gcry_mpi_release (sig_b);
+  _gcry_mpi_release (sig_a);
+  _gcry_mpi_release (data);
   return result;
 }
 
@@ -326,18 +263,25 @@ generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
         {
           mpi_add_ui (h, h, 1);
           /* g = h^e mod p */
-          gcry_mpi_powm (g, h, e, p);
+          mpi_powm (g, h, e, p);
         }
       while (!mpi_cmp_ui (g, 1));  /* Continue until g != 1. */
     }
 
   /* Select a random number X with the property:
    *    0 < x < q-1
+   *
+   * FIXME: Why do we use the requirement x < q-1 ? It should be
+   * sufficient to test for x < q.  FIPS-186-3 check x < q-1 but it
+   * does not check for 0 < x because it makes sure that Q is unsigned
+   * and finally adds one to the result so that 0 will never be
+   * returned.  We should replace the code below with _gcry_dsa_gen_k.
+   *
    * This must be a very good random number because this is the secret
    * part.  The random quality depends on the transient_key flag.  */
   random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
   if (DBG_CIPHER)
-    log_debug("choosing a random x%s", transient_key? " (transient-key)":"");
+    log_debug("choosing a random x%s\n", transient_key? " (transient-key)":"");
   gcry_assert( qbits >= 160 );
   x = mpi_alloc_secure( mpi_get_nlimbs(q) );
   mpi_sub_ui( h, q, 1 );  /* put q-1 into h */
@@ -347,25 +291,25 @@ generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
       if( DBG_CIPHER )
         progress('.');
       if( !rndbuf )
-        rndbuf = gcry_random_bytes_secure ((qbits+7)/8, random_level);
+        rndbuf = _gcry_random_bytes_secure ((qbits+7)/8, random_level);
       else
         { /* Change only some of the higher bits (= 2 bytes)*/
-          char *r = gcry_random_bytes_secure (2, random_level);
+          char *r = _gcry_random_bytes_secure (2, random_level);
           memcpy(rndbuf, r, 2 );
-          gcry_free(r);
+          xfree(r);
         }
 
       _gcry_mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 );
       mpi_clear_highbit( x, qbits+1 );
     }
   while ( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) );
-  gcry_free(rndbuf);
+  xfree(rndbuf);
   mpi_free( e );
   mpi_free( h );
 
   /* y = g^x mod p */
   y = mpi_alloc( mpi_get_nlimbs(p) );
-  gcry_mpi_powm( y, g, x, p );
+  mpi_powm (y, g, x, p);
 
   if( DBG_CIPHER )
     {
@@ -387,11 +331,11 @@ generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
   /* Now we can test our keys (this should never fail!). */
   if ( test_keys (sk, qbits) )
     {
-      gcry_mpi_release (sk->p); sk->p = NULL;
-      gcry_mpi_release (sk->q); sk->q = NULL;
-      gcry_mpi_release (sk->g); sk->g = NULL;
-      gcry_mpi_release (sk->y); sk->y = NULL;
-      gcry_mpi_release (sk->x); sk->x = NULL;
+      _gcry_mpi_release (sk->p); sk->p = NULL;
+      _gcry_mpi_release (sk->q); sk->q = NULL;
+      _gcry_mpi_release (sk->g); sk->g = NULL;
+      _gcry_mpi_release (sk->y); sk->y = NULL;
+      _gcry_mpi_release (sk->x); sk->x = NULL;
       fips_signal_error ("self-test after key generation failed");
       return GPG_ERR_SELFTEST_FAILED;
     }
@@ -474,9 +418,9 @@ generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
       /* Get an initial seed value.  */
       if (deriveparms)
         {
-          initial_seed.sexp = gcry_sexp_find_token (deriveparms, "seed", 0);
+          initial_seed.sexp = sexp_find_token (deriveparms, "seed", 0);
           if (initial_seed.sexp)
-            initial_seed.seed = gcry_sexp_nth_data (initial_seed.sexp, 1,
+            initial_seed.seed = sexp_nth_data (initial_seed.sexp, 1,
                                                     &initial_seed.seedlen);
         }
 
@@ -495,7 +439,7 @@ generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
       /*                                          &prime_q, &prime_p, */
       /*                                          r_counter, */
       /*                                          r_seed, r_seedlen, NULL); */
-      gcry_sexp_release (initial_seed.sexp);
+      sexp_release (initial_seed.sexp);
       if (ec)
         goto leave;
 
@@ -517,19 +461,19 @@ generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
 
 
   /* Select a random number x with:  0 < x < q  */
-  value_x = gcry_mpi_snew (qbits);
+  value_x = mpi_snew (qbits);
   do
     {
       if( DBG_CIPHER )
         progress('.');
-      gcry_mpi_randomize (value_x, qbits, GCRY_VERY_STRONG_RANDOM);
+      _gcry_mpi_randomize (value_x, qbits, GCRY_VERY_STRONG_RANDOM);
       mpi_clear_highbit (value_x, qbits+1);
     }
   while (!(mpi_cmp_ui (value_x, 0) > 0 && mpi_cmp (value_x, prime_q) < 0));
 
   /* y = g^x mod p */
   value_y = mpi_alloc_like (prime_p);
-  gcry_mpi_powm (value_y, value_g, value_x, prime_p);
+  mpi_powm (value_y, value_g, value_x, prime_p);
 
   if (DBG_CIPHER)
     {
@@ -551,22 +495,22 @@ generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
   *r_h = value_h; value_h = NULL;
 
  leave:
-  gcry_mpi_release (prime_p);
-  gcry_mpi_release (prime_q);
-  gcry_mpi_release (value_g);
-  gcry_mpi_release (value_y);
-  gcry_mpi_release (value_x);
-  gcry_mpi_release (value_h);
-  gcry_mpi_release (value_e);
+  _gcry_mpi_release (prime_p);
+  _gcry_mpi_release (prime_q);
+  _gcry_mpi_release (value_g);
+  _gcry_mpi_release (value_y);
+  _gcry_mpi_release (value_x);
+  _gcry_mpi_release (value_h);
+  _gcry_mpi_release (value_e);
 
   /* As a last step test this keys (this should never fail of course). */
   if (!ec && test_keys (sk, qbits) )
     {
-      gcry_mpi_release (sk->p); sk->p = NULL;
-      gcry_mpi_release (sk->q); sk->q = NULL;
-      gcry_mpi_release (sk->g); sk->g = NULL;
-      gcry_mpi_release (sk->y); sk->y = NULL;
-      gcry_mpi_release (sk->x); sk->x = NULL;
+      _gcry_mpi_release (sk->p); sk->p = NULL;
+      _gcry_mpi_release (sk->q); sk->q = NULL;
+      _gcry_mpi_release (sk->g); sk->g = NULL;
+      _gcry_mpi_release (sk->y); sk->y = NULL;
+      _gcry_mpi_release (sk->x); sk->x = NULL;
       fips_signal_error ("self-test after key generation failed");
       ec = GPG_ERR_SELFTEST_FAILED;
     }
@@ -574,9 +518,9 @@ generate_fips186 (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits,
   if (ec)
     {
       *r_counter = 0;
-      gcry_free (*r_seed); *r_seed = NULL;
+      xfree (*r_seed); *r_seed = NULL;
       *r_seedlen = 0;
-      gcry_mpi_release (*r_h); *r_h = NULL;
+      _gcry_mpi_release (*r_h); *r_h = NULL;
     }
 
   return ec;
@@ -594,7 +538,7 @@ check_secret_key( DSA_secret_key *sk )
   int rc;
   gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) );
 
-  gcry_mpi_powm( y, sk->g, sk->x, sk->p );
+  mpi_powm( y, sk->g, sk->x, sk->p );
   rc = !mpi_cmp( y, sk->y );
   mpi_free( y );
   return rc;
@@ -603,20 +547,63 @@ check_secret_key( DSA_secret_key *sk )
 
 
 /*
-   Make a DSA signature from HASH and put it into r and s.
+   Make a DSA signature from INPUT and put it into r and s.
+
+   INPUT may either be a plain MPI or an opaque MPI which is then
+   internally converted to a plain MPI.  FLAGS and HASHALGO may both
+   be 0 for standard operation mode.
+
+   The return value is 0 on success or an error code.  Note that for
+   backward compatibility the function will not return any error if
+   FLAGS and HASHALGO are both 0 and INPUT is a plain MPI.
  */
-static void
-sign(gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_secret_key *skey )
+static gpg_err_code_t
+sign (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input, DSA_secret_key *skey,
+      int flags, int hashalgo)
 {
+  gpg_err_code_t rc;
+  gcry_mpi_t hash;
   gcry_mpi_t k;
   gcry_mpi_t kinv;
   gcry_mpi_t tmp;
+  const void *abuf;
+  unsigned int abits, qbits;
+  int extraloops = 0;
+
+  qbits = mpi_get_nbits (skey->q);
+
+  /* Convert the INPUT into an MPI.  */
+  rc = _gcry_dsa_normalize_hash (input, &hash, qbits);
+  if (rc)
+    return rc;
 
-  /* Select a random k with 0 < k < q */
-  k = gen_k( skey->q );
+ again:
+  /* Create the K value.  */
+  if ((flags & PUBKEY_FLAG_RFC6979) && hashalgo)
+    {
+      /* Use Pornin's method for deterministic DSA.  If this flag is
+         set, it is expected that HASH is an opaque MPI with the to be
+         signed hash.  That hash is also used as h1 from 3.2.a.  */
+      if (!mpi_is_opaque (input))
+        {
+          rc = GPG_ERR_CONFLICT;
+          goto leave;
+        }
+
+      abuf = mpi_get_opaque (input, &abits);
+      rc = _gcry_dsa_gen_rfc6979_k (&k, skey->q, skey->x,
+                                    abuf, (abits+7)/8, hashalgo, extraloops);
+      if (rc)
+        goto leave;
+    }
+  else
+    {
+      /* Select a random k with 0 < k < q */
+      k = _gcry_dsa_gen_k (skey->q, GCRY_STRONG_RANDOM);
+    }
 
   /* r = (a^k mod p) mod q */
-  gcry_mpi_powm( r, skey->g, k, skey->p );
+  mpi_powm( r, skey->g, k, skey->p );
   mpi_fdiv_r( r, r, skey->q );
 
   /* kinv = k^(-1) mod q */
@@ -632,24 +619,46 @@ sign(gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_secret_key *skey )
   mpi_free(k);
   mpi_free(kinv);
   mpi_free(tmp);
+
+  if (!mpi_cmp_ui (r, 0))
+    {
+      /* This is a highly unlikely code path.  */
+      extraloops++;
+      goto again;
+    }
+
+  rc = 0;
+
+ leave:
+  if (hash != input)
+    mpi_free (hash);
+
+  return rc;
 }
 
 
 /*
    Returns true if the signature composed from R and S is valid.
  */
-static int
-verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_public_key *pkey )
+static gpg_err_code_t
+verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t input, DSA_public_key *pkey )
 {
-  int rc;
+  gpg_err_code_t rc = 0;
   gcry_mpi_t w, u1, u2, v;
   gcry_mpi_t base[3];
   gcry_mpi_t ex[3];
+  gcry_mpi_t hash;
+  unsigned int nbits;
 
   if( !(mpi_cmp_ui( r, 0 ) > 0 && mpi_cmp( r, pkey->q ) < 0) )
-    return 0; /* assertion     0 < r < q  failed */
+    return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < r < n  failed.  */
   if( !(mpi_cmp_ui( s, 0 ) > 0 && mpi_cmp( s, pkey->q ) < 0) )
-    return 0; /* assertion     0 < s < q  failed */
+    return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < s < n  failed.  */
+
+  nbits = mpi_get_nbits (pkey->q);
+  rc = _gcry_dsa_normalize_hash (input, &hash, nbits);
+  if (rc)
+    return rc;
 
   w  = mpi_alloc( mpi_get_nlimbs(pkey->q) );
   u1 = mpi_alloc( mpi_get_nlimbs(pkey->q) );
@@ -672,12 +681,25 @@ verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_public_key *pkey )
   mpi_mulpowm( v, base, ex, pkey->p );
   mpi_fdiv_r( v, v, pkey->q );
 
-  rc = !mpi_cmp( v, r );
+  if (mpi_cmp( v, r ))
+    {
+      if (DBG_CIPHER)
+        {
+          log_mpidump ("     i", input);
+          log_mpidump ("     h", hash);
+          log_mpidump ("     v", v);
+          log_mpidump ("     r", r);
+          log_mpidump ("     s", s);
+        }
+      rc = GPG_ERR_BAD_SIGNATURE;
+    }
 
   mpi_free(w);
   mpi_free(u1);
   mpi_free(u2);
   mpi_free(v);
+  if (hash != input)
+    mpi_free (hash);
 
   return rc;
 }
@@ -688,349 +710,441 @@ verify (gcry_mpi_t r, gcry_mpi_t s, gcry_mpi_t hash, DSA_public_key *pkey )
  *********************************************/
 
 static gcry_err_code_t
-dsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
-                  const gcry_sexp_t genparms,
-                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
-                  gcry_sexp_t *r_extrainfo)
+dsa_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
 {
-  gpg_err_code_t ec;
+  gpg_err_code_t rc;
+  unsigned int nbits;
+  gcry_sexp_t domainsexp;
   DSA_secret_key sk;
   gcry_sexp_t l1;
   unsigned int qbits = 0;
   gcry_sexp_t deriveparms = NULL;
   gcry_sexp_t seedinfo = NULL;
-  int transient_key = 0;
-  int use_fips186_2 = 0;
-  int use_fips186 = 0;
+  gcry_sexp_t misc_info = NULL;
+  int flags = 0;
   dsa_domain_t domain;
+  gcry_mpi_t *factors = NULL;
 
-  (void)algo;    /* No need to check it.  */
-  (void)evalue;  /* Not required for DSA. */
-
+  memset (&sk, 0, sizeof sk);
   memset (&domain, 0, sizeof domain);
 
-  if (genparms)
+  rc = _gcry_pk_util_get_nbits (genparms, &nbits);
+  if (rc)
+    return rc;
+
+  /* Parse the optional flags list.  */
+  l1 = sexp_find_token (genparms, "flags", 0);
+  if (l1)
     {
-      gcry_sexp_t domainsexp;
+      rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
+      sexp_release (l1);
+      if (rc)
+        return rc;\
+    }
 
-      /* Parse the optional qbits element.  */
-      l1 = gcry_sexp_find_token (genparms, "qbits", 0);
-      if (l1)
-        {
-          char buf[50];
-          const char *s;
-          size_t n;
+  /* Parse the optional qbits element.  */
+  l1 = sexp_find_token (genparms, "qbits", 0);
+  if (l1)
+    {
+      char buf[50];
+      const char *s;
+      size_t n;
 
-          s = gcry_sexp_nth_data (l1, 1, &n);
-          if (!s || n >= DIM (buf) - 1 )
-            {
-              gcry_sexp_release (l1);
-              return GPG_ERR_INV_OBJ; /* No value or value too large.  */
-            }
-          memcpy (buf, s, n);
-          buf[n] = 0;
-          qbits = (unsigned int)strtoul (buf, NULL, 0);
-          gcry_sexp_release (l1);
+      s = sexp_nth_data (l1, 1, &n);
+      if (!s || n >= DIM (buf) - 1 )
+        {
+          sexp_release (l1);
+          return GPG_ERR_INV_OBJ; /* No value or value too large.  */
         }
+      memcpy (buf, s, n);
+      buf[n] = 0;
+      qbits = (unsigned int)strtoul (buf, NULL, 0);
+      sexp_release (l1);
+    }
 
-      /* Parse the optional transient-key flag.  */
-      l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
+  /* Parse the optional transient-key flag.  */
+  if (!(flags & PUBKEY_FLAG_TRANSIENT_KEY))
+    {
+      l1 = sexp_find_token (genparms, "transient-key", 0);
       if (l1)
         {
-          transient_key = 1;
-          gcry_sexp_release (l1);
+          flags |= PUBKEY_FLAG_TRANSIENT_KEY;
+          sexp_release (l1);
         }
+    }
 
-      /* Get the optional derive parameters.  */
-      deriveparms = gcry_sexp_find_token (genparms, "derive-parms", 0);
+  /* Get the optional derive parameters.  */
+  deriveparms = sexp_find_token (genparms, "derive-parms", 0);
 
-      /* Parse the optional "use-fips186" flags.  */
-      l1 = gcry_sexp_find_token (genparms, "use-fips186", 0);
+  /* Parse the optional "use-fips186" flags.  */
+  if (!(flags & PUBKEY_FLAG_USE_FIPS186))
+    {
+      l1 = sexp_find_token (genparms, "use-fips186", 0);
       if (l1)
         {
-          use_fips186 = 1;
-          gcry_sexp_release (l1);
+          flags |= PUBKEY_FLAG_USE_FIPS186;
+          sexp_release (l1);
         }
-      l1 = gcry_sexp_find_token (genparms, "use-fips186-2", 0);
+    }
+  if (!(flags & PUBKEY_FLAG_USE_FIPS186_2))
+    {
+      l1 = sexp_find_token (genparms, "use-fips186-2", 0);
       if (l1)
         {
-          use_fips186_2 = 1;
-          gcry_sexp_release (l1);
+          flags |= PUBKEY_FLAG_USE_FIPS186_2;
+          sexp_release (l1);
         }
+    }
 
-      /* Check whether domain parameters are given.  */
-      domainsexp = gcry_sexp_find_token (genparms, "domain", 0);
-      if (domainsexp)
+  /* Check whether domain parameters are given.  */
+  domainsexp = sexp_find_token (genparms, "domain", 0);
+  if (domainsexp)
+    {
+      /* DERIVEPARMS can't be used together with domain parameters.
+         NBITS abnd QBITS may not be specified because there values
+         are derived from the domain parameters.  */
+      if (deriveparms || qbits || nbits)
         {
-          /* DERIVEPARMS can't be used together with domain
-             parameters.  NBITS abnd QBITS may not be specified
-             because there values are derived from the domain
-             parameters.  */
-          if (deriveparms || qbits || nbits)
-            {
-              gcry_sexp_release (domainsexp);
-              gcry_sexp_release (deriveparms);
-              return GPG_ERR_INV_VALUE;
-            }
-
-          /* Put all domain parameters into the domain object.  */
-          l1 = gcry_sexp_find_token (domainsexp, "p", 0);
-          domain.p = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
-          gcry_sexp_release (l1);
-          l1 = gcry_sexp_find_token (domainsexp, "q", 0);
-          domain.q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
-          gcry_sexp_release (l1);
-          l1 = gcry_sexp_find_token (domainsexp, "g", 0);
-          domain.g = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
-          gcry_sexp_release (l1);
-          gcry_sexp_release (domainsexp);
-
-          /* Check that all domain parameters are available.  */
-          if (!domain.p || !domain.q || !domain.g)
-            {
-              gcry_mpi_release (domain.p);
-              gcry_mpi_release (domain.q);
-              gcry_mpi_release (domain.g);
-              gcry_sexp_release (deriveparms);
-              return GPG_ERR_MISSING_VALUE;
-            }
+          sexp_release (domainsexp);
+          sexp_release (deriveparms);
+          return GPG_ERR_INV_VALUE;
+        }
 
-          /* Get NBITS and QBITS from the domain parameters.  */
-          nbits = mpi_get_nbits (domain.p);
-          qbits = mpi_get_nbits (domain.q);
+      /* Put all domain parameters into the domain object.  */
+      l1 = sexp_find_token (domainsexp, "p", 0);
+      domain.p = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+      sexp_release (l1);
+      l1 = sexp_find_token (domainsexp, "q", 0);
+      domain.q = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+      sexp_release (l1);
+      l1 = sexp_find_token (domainsexp, "g", 0);
+      domain.g = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+      sexp_release (l1);
+      sexp_release (domainsexp);
+
+      /* Check that all domain parameters are available.  */
+      if (!domain.p || !domain.q || !domain.g)
+        {
+          _gcry_mpi_release (domain.p);
+          _gcry_mpi_release (domain.q);
+          _gcry_mpi_release (domain.g);
+          sexp_release (deriveparms);
+          return GPG_ERR_MISSING_VALUE;
         }
+
+      /* Get NBITS and QBITS from the domain parameters.  */
+      nbits = mpi_get_nbits (domain.p);
+      qbits = mpi_get_nbits (domain.q);
     }
 
-  if (deriveparms || use_fips186 || use_fips186_2 || fips_mode ())
+  if (deriveparms
+      || (flags & PUBKEY_FLAG_USE_FIPS186)
+      || (flags & PUBKEY_FLAG_USE_FIPS186_2)
+      || fips_mode ())
     {
       int counter;
       void *seed;
       size_t seedlen;
       gcry_mpi_t h_value;
 
-      ec = generate_fips186 (&sk, nbits, qbits, deriveparms, use_fips186_2,
+      rc = generate_fips186 (&sk, nbits, qbits, deriveparms,
+                             !!(flags & PUBKEY_FLAG_USE_FIPS186_2),
                              &domain,
                              &counter, &seed, &seedlen, &h_value);
-      gcry_sexp_release (deriveparms);
-      if (!ec && h_value)
+      if (!rc && h_value)
         {
           /* Format the seed-values unless domain parameters are used
              for which a H_VALUE of NULL is an indication.  */
-          ec = gpg_err_code (gcry_sexp_build
-                             (&seedinfo, NULL,
-                              "(seed-values(counter %d)(seed %b)(h %m))",
-                              counter, (int)seedlen, seed, h_value));
-          if (ec)
-            {
-              gcry_mpi_release (sk.p); sk.p = NULL;
-              gcry_mpi_release (sk.q); sk.q = NULL;
-              gcry_mpi_release (sk.g); sk.g = NULL;
-              gcry_mpi_release (sk.y); sk.y = NULL;
-              gcry_mpi_release (sk.x); sk.x = NULL;
-            }
-          gcry_free (seed);
-          gcry_mpi_release (h_value);
+          rc = sexp_build (&seedinfo, NULL,
+                           "(seed-values(counter %d)(seed %b)(h %m))",
+                           counter, (int)seedlen, seed, h_value);
+          xfree (seed);
+          _gcry_mpi_release (h_value);
         }
     }
   else
     {
-      ec = generate (&sk, nbits, qbits, transient_key, &domain, retfactors);
+      rc = generate (&sk, nbits, qbits,
+                     !!(flags & PUBKEY_FLAG_TRANSIENT_KEY),
+                     &domain, &factors);
     }
 
-  gcry_mpi_release (domain.p);
-  gcry_mpi_release (domain.q);
-  gcry_mpi_release (domain.g);
-
-  if (!ec)
+  if (!rc)
     {
-      skey[0] = sk.p;
-      skey[1] = sk.q;
-      skey[2] = sk.g;
-      skey[3] = sk.y;
-      skey[4] = sk.x;
-
-      if (!r_extrainfo)
-        {
-          /* Old style interface - return the factors - if any - at
-             retfactors.  */
-        }
-      else if (!*retfactors && !seedinfo)
-        {
-          /* No factors and no seedinfo, thus there is nothing to return.  */
-          *r_extrainfo = NULL;
-        }
+      /* Put the factors into MISC_INFO.  Note that the factors are
+         not confidential thus we can store them in standard memory.  */
+      int nfactors, i, j;
+      char *p;
+      char *format = NULL;
+      void **arg_list = NULL;
+
+      for (nfactors=0; factors && factors[nfactors]; nfactors++)
+        ;
+      /* Allocate space for the format string:
+         "(misc-key-info%S(pm1-factors%m))"
+         with one "%m" for each factor and construct it.  */
+      format = xtrymalloc (50 + 2*nfactors);
+      if (!format)
+        rc = gpg_err_code_from_syserror ();
       else
         {
-          /* Put the factors into extrainfo and set retfactors to NULL
-             to make use of the new interface.  Note that the factors
-             are not confidential thus we can store them in standard
-             memory.  */
-          int nfactors, i, j;
-          char *p;
-          char *format = NULL;
-          void **arg_list = NULL;
-
-          for (nfactors=0; *retfactors && (*retfactors)[nfactors]; nfactors++)
-            ;
-          /* Allocate space for the format string:
-               "(misc-key-info%S(pm1-factors%m))"
-             with one "%m" for each factor and construct it.  */
-          format = gcry_malloc (50 + 2*nfactors);
-          if (!format)
-            ec = gpg_err_code_from_syserror ();
-          else
+          p = stpcpy (format, "(misc-key-info");
+          if (seedinfo)
+            p = stpcpy (p, "%S");
+          if (nfactors)
             {
-              p = stpcpy (format, "(misc-key-info");
-              if (seedinfo)
-                p = stpcpy (p, "%S");
-              if (nfactors)
-                {
-                  p = stpcpy (p, "(pm1-factors");
-                  for (i=0; i < nfactors; i++)
-                    p = stpcpy (p, "%m");
-                  p = stpcpy (p, ")");
-                }
+              p = stpcpy (p, "(pm1-factors");
+              for (i=0; i < nfactors; i++)
+                p = stpcpy (p, "%m");
               p = stpcpy (p, ")");
-
-              /* Allocate space for the list of factors plus one for
-                 an S-expression plus an extra NULL entry for safety
-                 and fill it with the factors.  */
-              arg_list = gcry_calloc (nfactors+1+1, sizeof *arg_list);
-              if (!arg_list)
-                ec = gpg_err_code_from_syserror ();
-              else
-                {
-                  i = 0;
-                  if (seedinfo)
-                    arg_list[i++] = &seedinfo;
-                  for (j=0; j < nfactors; j++)
-                    arg_list[i++] = (*retfactors) + j;
-                  arg_list[i] = NULL;
-
-                  ec = gpg_err_code (gcry_sexp_build_array
-                                     (r_extrainfo, NULL, format, arg_list));
-                }
-            }
-
-          gcry_free (arg_list);
-          gcry_free (format);
-          for (i=0; i < nfactors; i++)
-            {
-              gcry_mpi_release ((*retfactors)[i]);
-              (*retfactors)[i] = NULL;
             }
-          gcry_free (*retfactors);
-          *retfactors = NULL;
-          if (ec)
+          p = stpcpy (p, ")");
+
+          /* Allocate space for the list of factors plus one for the
+             seedinfo s-exp plus an extra NULL entry for safety and
+             fill it with the factors.  */
+          arg_list = xtrycalloc (nfactors+1+1, sizeof *arg_list);
+          if (!arg_list)
+            rc = gpg_err_code_from_syserror ();
+          else
             {
-              for (i=0; i < 5; i++)
-                {
-                  gcry_mpi_release (skey[i]);
-                  skey[i] = NULL;
-                }
+              i = 0;
+              if (seedinfo)
+                arg_list[i++] = &seedinfo;
+              for (j=0; j < nfactors; j++)
+                arg_list[i++] = factors + j;
+              arg_list[i] = NULL;
+
+              rc = sexp_build_array (&misc_info, NULL, format, arg_list);
             }
         }
-    }
-
-  gcry_sexp_release (seedinfo);
-  return ec;
-}
 
+      xfree (arg_list);
+      xfree (format);
+    }
 
-static gcry_err_code_t
-dsa_generate (int algo, unsigned int nbits, unsigned long evalue,
-              gcry_mpi_t *skey, gcry_mpi_t **retfactors)
-{
-  (void)evalue;
-  return dsa_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL);
+  if (!rc)
+    rc = sexp_build (r_skey, NULL,
+                     "(key-data"
+                     " (public-key"
+                     "  (dsa(p%m)(q%m)(g%m)(y%m)))"
+                     " (private-key"
+                     "  (dsa(p%m)(q%m)(g%m)(y%m)(x%m)))"
+                     " %S)",
+                     sk.p, sk.q, sk.g, sk.y,
+                     sk.p, sk.q, sk.g, sk.y, sk.x,
+                     misc_info);
+
+
+  _gcry_mpi_release (sk.p);
+  _gcry_mpi_release (sk.q);
+  _gcry_mpi_release (sk.g);
+  _gcry_mpi_release (sk.y);
+  _gcry_mpi_release (sk.x);
+
+  _gcry_mpi_release (domain.p);
+  _gcry_mpi_release (domain.q);
+  _gcry_mpi_release (domain.g);
+
+  sexp_release (seedinfo);
+  sexp_release (misc_info);
+  sexp_release (deriveparms);
+  if (factors)
+    {
+      gcry_mpi_t *mp;
+      for (mp = factors; *mp; mp++)
+        mpi_free (*mp);
+      xfree (factors);
+    }
+  return rc;
 }
 
 
 
 static gcry_err_code_t
-dsa_check_secret_key (int algo, gcry_mpi_t *skey)
+dsa_check_secret_key (gcry_sexp_t keyparms)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  DSA_secret_key sk;
+  gcry_err_code_t rc;
+  DSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL};
 
-  (void)algo;
+  rc = _gcry_sexp_extract_param (keyparms, NULL, "pqgyx",
+                                 &sk.p, &sk.q, &sk.g, &sk.y, &sk.x,
+                                 NULL);
+  if (rc)
+    goto leave;
 
-  if ((! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]) || (! skey[4]))
-    err = GPG_ERR_BAD_MPI;
-  else
-    {
-      sk.p = skey[0];
-      sk.q = skey[1];
-      sk.g = skey[2];
-      sk.y = skey[3];
-      sk.x = skey[4];
-      if (! check_secret_key (&sk))
-       err = GPG_ERR_BAD_SECKEY;
-    }
+  if (!check_secret_key (&sk))
+    rc = GPG_ERR_BAD_SECKEY;
 
-  return err;
+ leave:
+  _gcry_mpi_release (sk.p);
+  _gcry_mpi_release (sk.q);
+  _gcry_mpi_release (sk.g);
+  _gcry_mpi_release (sk.y);
+  _gcry_mpi_release (sk.x);
+  if (DBG_CIPHER)
+    log_debug ("dsa_testkey    => %s\n", gpg_strerror (rc));
+  return rc;
 }
 
 
 static gcry_err_code_t
-dsa_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
+dsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  DSA_secret_key sk;
+  gcry_err_code_t rc;
+  struct pk_encoding_ctx ctx;
+  gcry_mpi_t data = NULL;
+  DSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL};
+  gcry_mpi_t sig_r = NULL;
+  gcry_mpi_t sig_s = NULL;
+
+  _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN,
+                                   dsa_get_nbits (keyparms));
+
+  /* Extract the data.  */
+  rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    log_mpidump ("dsa_sign   data", data);
 
-  (void)algo;
+  /* Extract the key.  */
+  rc = _gcry_sexp_extract_param (keyparms, NULL, "pqgyx",
+                                 &sk.p, &sk.q, &sk.g, &sk.y, &sk.x, NULL);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    {
+      log_mpidump ("dsa_sign      p", sk.p);
+      log_mpidump ("dsa_sign      q", sk.q);
+      log_mpidump ("dsa_sign      g", sk.g);
+      log_mpidump ("dsa_sign      y", sk.y);
+      if (!fips_mode ())
+        log_mpidump ("dsa_sign      x", sk.x);
+    }
 
-  if ((! data)
-      || (! skey[0]) || (! skey[1]) || (! skey[2])
-      || (! skey[3]) || (! skey[4]))
-    err = GPG_ERR_BAD_MPI;
-  else
+  sig_r = mpi_new (0);
+  sig_s = mpi_new (0);
+  rc = sign (sig_r, sig_s, data, &sk, ctx.flags, ctx.hash_algo);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
     {
-      sk.p = skey[0];
-      sk.q = skey[1];
-      sk.g = skey[2];
-      sk.y = skey[3];
-      sk.x = skey[4];
-      resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.p));
-      resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.p));
-      sign (resarr[0], resarr[1], data, &sk);
+      log_mpidump ("dsa_sign  sig_r", sig_r);
+      log_mpidump ("dsa_sign  sig_s", sig_s);
     }
-  return err;
+  rc = sexp_build (r_sig, NULL, "(sig-val(dsa(r%M)(s%M)))", sig_r, sig_s);
+
+ leave:
+  _gcry_mpi_release (sig_r);
+  _gcry_mpi_release (sig_s);
+  _gcry_mpi_release (sk.p);
+  _gcry_mpi_release (sk.q);
+  _gcry_mpi_release (sk.g);
+  _gcry_mpi_release (sk.y);
+  _gcry_mpi_release (sk.x);
+  _gcry_mpi_release (data);
+  _gcry_pk_util_free_encoding_ctx (&ctx);
+  if (DBG_CIPHER)
+    log_debug ("dsa_sign      => %s\n", gpg_strerror (rc));
+  return rc;
 }
 
+
 static gcry_err_code_t
-dsa_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
-            int (*cmp) (void *, gcry_mpi_t), void *opaquev)
+dsa_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  DSA_public_key pk;
-
-  (void)algo;
-  (void)cmp;
-  (void)opaquev;
+  gcry_err_code_t rc;
+  struct pk_encoding_ctx ctx;
+  gcry_sexp_t l1 = NULL;
+  gcry_mpi_t sig_r = NULL;
+  gcry_mpi_t sig_s = NULL;
+  gcry_mpi_t data = NULL;
+  DSA_public_key pk = { NULL, NULL, NULL, NULL };
+
+  _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY,
+                                   dsa_get_nbits (s_keyparms));
+
+  /* Extract the data.  */
+  rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    log_mpidump ("dsa_verify data", data);
+
+  /* Extract the signature value.  */
+  rc = _gcry_pk_util_preparse_sigval (s_sig, dsa_names, &l1, NULL);
+  if (rc)
+    goto leave;
+  rc = _gcry_sexp_extract_param (l1, NULL, "rs", &sig_r, &sig_s, NULL);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    {
+      log_mpidump ("dsa_verify  s_r", sig_r);
+      log_mpidump ("dsa_verify  s_s", sig_s);
+    }
 
-  if ((! data[0]) || (! data[1]) || (! hash)
-      || (! pkey[0]) || (! pkey[1]) || (! pkey[2]) || (! pkey[3]))
-    err = GPG_ERR_BAD_MPI;
-  else
+  /* Extract the key.  */
+  rc = _gcry_sexp_extract_param (s_keyparms, NULL, "pqgy",
+                                 &pk.p, &pk.q, &pk.g, &pk.y, NULL);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
     {
-      pk.p = pkey[0];
-      pk.q = pkey[1];
-      pk.g = pkey[2];
-      pk.y = pkey[3];
-      if (! verify (data[0], data[1], hash, &pk))
-       err = GPG_ERR_BAD_SIGNATURE;
+      log_mpidump ("dsa_verify    p", pk.p);
+      log_mpidump ("dsa_verify    q", pk.q);
+      log_mpidump ("dsa_verify    g", pk.g);
+      log_mpidump ("dsa_verify    y", pk.y);
     }
-  return err;
+
+  /* Verify the signature.  */
+  rc = verify (sig_r, sig_s, data, &pk);
+
+ leave:
+  _gcry_mpi_release (pk.p);
+  _gcry_mpi_release (pk.q);
+  _gcry_mpi_release (pk.g);
+  _gcry_mpi_release (pk.y);
+  _gcry_mpi_release (data);
+  _gcry_mpi_release (sig_r);
+  _gcry_mpi_release (sig_s);
+  sexp_release (l1);
+  _gcry_pk_util_free_encoding_ctx (&ctx);
+  if (DBG_CIPHER)
+    log_debug ("dsa_verify    => %s\n", rc?gpg_strerror (rc):"Good");
+  return rc;
 }
 
 
+/* Return the number of bits for the key described by PARMS.  On error
+ * 0 is returned.  The format of PARMS starts with the algorithm name;
+ * for example:
+ *
+ *   (dsa
+ *     (p <mpi>)
+ *     (q <mpi>)
+ *     (g <mpi>)
+ *     (y <mpi>))
+ *
+ * More parameters may be given but we only need P here.
+ */
 static unsigned int
-dsa_get_nbits (int algo, gcry_mpi_t *pkey)
+dsa_get_nbits (gcry_sexp_t parms)
 {
-  (void)algo;
-
-  return mpi_get_nbits (pkey[0]);
+  gcry_sexp_t l1;
+  gcry_mpi_t p;
+  unsigned int nbits;
+
+  l1 = sexp_find_token (parms, "p", 1);
+  if (!l1)
+    return 0; /* Parameter P not found.  */
+
+  p = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+  sexp_release (l1);
+  nbits = p? mpi_get_nbits (p) : 0;
+  _gcry_mpi_release (p);
+  return nbits;
 }
 
 
@@ -1055,30 +1169,29 @@ selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
   gcry_sexp_t data_bad = NULL;
   gcry_sexp_t sig = NULL;
 
-  err = gcry_sexp_sscan (&data, NULL,
-                         sample_data, strlen (sample_data));
+  err = sexp_sscan (&data, NULL, sample_data, strlen (sample_data));
   if (!err)
-    err = gcry_sexp_sscan (&data_bad, NULL,
-                           sample_data_bad, strlen (sample_data_bad));
+    err = sexp_sscan (&data_bad, NULL,
+                      sample_data_bad, strlen (sample_data_bad));
   if (err)
     {
       errtxt = "converting data failed";
       goto leave;
     }
 
-  err = gcry_pk_sign (&sig, data, skey);
+  err = _gcry_pk_sign (&sig, data, skey);
   if (err)
     {
       errtxt = "signing failed";
       goto leave;
     }
-  err = gcry_pk_verify (sig, data, pkey);
+  err = _gcry_pk_verify (sig, data, pkey);
   if (err)
     {
       errtxt = "verify failed";
       goto leave;
     }
-  err = gcry_pk_verify (sig, data_bad, pkey);
+  err = _gcry_pk_verify (sig, data_bad, pkey);
   if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
     {
       errtxt = "bad signature not detected";
@@ -1087,9 +1200,9 @@ selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
 
 
  leave:
-  gcry_sexp_release (sig);
-  gcry_sexp_release (data_bad);
-  gcry_sexp_release (data);
+  sexp_release (sig);
+  sexp_release (data_bad);
+  sexp_release (data);
   return errtxt;
 }
 
@@ -1105,22 +1218,21 @@ selftests_dsa (selftest_report_func_t report)
 
   /* Convert the S-expressions into the internal representation.  */
   what = "convert";
-  err = gcry_sexp_sscan (&skey, NULL,
-                         sample_secret_key, strlen (sample_secret_key));
+  err = sexp_sscan (&skey, NULL, sample_secret_key, strlen (sample_secret_key));
   if (!err)
-    err = gcry_sexp_sscan (&pkey, NULL,
-                           sample_public_key, strlen (sample_public_key));
+    err = sexp_sscan (&pkey, NULL,
+                      sample_public_key, strlen (sample_public_key));
   if (err)
     {
-      errtxt = gcry_strerror (err);
+      errtxt = _gcry_strerror (err);
       goto failed;
     }
 
   what = "key consistency";
-  err = gcry_pk_testkey (skey);
+  err = _gcry_pk_testkey (skey);
   if (err)
     {
-      errtxt = gcry_strerror (err);
+      errtxt = _gcry_strerror (err);
       goto failed;
     }
 
@@ -1129,13 +1241,13 @@ selftests_dsa (selftest_report_func_t report)
   if (errtxt)
     goto failed;
 
-  gcry_sexp_release (pkey);
-  gcry_sexp_release (skey);
+  sexp_release (pkey);
+  sexp_release (skey);
   return 0; /* Succeeded. */
 
  failed:
-  gcry_sexp_release (pkey);
-  gcry_sexp_release (skey);
+  sexp_release (pkey);
+  sexp_release (skey);
   if (report)
     report ("pubkey", GCRY_PK_DSA, what, errtxt);
   return GPG_ERR_SELFTEST_FAILED;
@@ -1166,28 +1278,18 @@ run_selftests (int algo, int extended, selftest_report_func_t report)
 
 
 \f
-static const char *dsa_names[] =
-  {
-    "dsa",
-    "openpgp-dsa",
-    NULL,
-  };
-
 gcry_pk_spec_t _gcry_pubkey_spec_dsa =
   {
+    GCRY_PK_DSA, { 0, 1 },
+    GCRY_PK_USAGE_SIGN,
     "DSA", dsa_names,
     "pqgy", "pqgyx", "", "rs", "pqgy",
-    GCRY_PK_USAGE_SIGN,
     dsa_generate,
     dsa_check_secret_key,
     NULL,
     NULL,
     dsa_sign,
     dsa_verify,
-    dsa_get_nbits
-  };
-pk_extra_spec_t _gcry_pubkey_extraspec_dsa =
-  {
-    run_selftests,
-    dsa_generate_ext
+    dsa_get_nbits,
+    run_selftests
   };
diff --git a/cipher/ecc-common.h b/cipher/ecc-common.h
new file mode 100644 (file)
index 0000000..c407c74
--- /dev/null
@@ -0,0 +1,141 @@
+/* ecc-common.h - Declarations of common ECC code
+ * Copyright (C) 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/>.
+ */
+
+#ifndef GCRY_ECC_COMMON_H
+#define GCRY_ECC_COMMON_H
+
+
+/* Definition of a curve.  */
+typedef struct
+{
+  enum gcry_mpi_ec_models model;/* The model descrinbing this curve.  */
+  enum ecc_dialects dialect;    /* The dialect used with the curve.   */
+  gcry_mpi_t p;         /* Prime specifying the field GF(p).  */
+  gcry_mpi_t a;         /* First coefficient of the Weierstrass equation.  */
+  gcry_mpi_t b;         /* Second coefficient of the Weierstrass equation.
+                           or d as used by Twisted Edwards curves.  */
+  mpi_point_struct G;   /* Base point (generator).  */
+  gcry_mpi_t n;         /* Order of G.  */
+  const char *name;     /* Name of the curve or NULL.  */
+} elliptic_curve_t;
+
+
+typedef struct
+{
+  elliptic_curve_t E;
+  mpi_point_struct Q; /* Q = [d]G  */
+} ECC_public_key;
+
+
+typedef struct
+{
+  elliptic_curve_t E;
+  mpi_point_struct Q;
+  gcry_mpi_t d;
+} ECC_secret_key;
+
+
+
+/* Set the value from S into D.  */
+static inline void
+point_set (mpi_point_t d, mpi_point_t s)
+{
+  mpi_set (d->x, s->x);
+  mpi_set (d->y, s->y);
+  mpi_set (d->z, s->z);
+}
+
+#define point_init(a)  _gcry_mpi_point_init ((a))
+#define point_free(a)  _gcry_mpi_point_free_parts ((a))
+
+
+/*-- ecc-curves.c --*/
+gpg_err_code_t _gcry_ecc_fill_in_curve (unsigned int nbits,
+                                        const char *name,
+                                        elliptic_curve_t *curve,
+                                        unsigned int *r_nbits);
+gpg_err_code_t _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);
+
+const char *_gcry_ecc_get_curve (gcry_sexp_t keyparms,
+                                 int iterator,
+                                 unsigned int *r_nbits);
+gcry_sexp_t _gcry_ecc_get_param_sexp (const char *name);
+
+/*-- ecc-misc.c --*/
+void _gcry_ecc_curve_free (elliptic_curve_t *E);
+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 --*/
+gpg_err_code_t _gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey,
+                                     gcry_mpi_t r, gcry_mpi_t s,
+                                     int flags, int hashalgo);
+gpg_err_code_t _gcry_ecc_ecdsa_verify (gcry_mpi_t input, ECC_public_key *pkey,
+                                       gcry_mpi_t r, gcry_mpi_t s);
+
+/*-- ecc-eddsa.c --*/
+gpg_err_code_t _gcry_ecc_eddsa_recover_x (gcry_mpi_t x, gcry_mpi_t y, int sign,
+                                          mpi_ec_t ec);
+gpg_err_code_t _gcry_ecc_eddsa_encodepoint (mpi_point_t point, mpi_ec_t ctx,
+                                            gcry_mpi_t x, gcry_mpi_t y,
+                                            unsigned char **r_buffer,
+                                            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);
+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,
+                                     int hashalgo, gcry_mpi_t pk);
+gpg_err_code_t _gcry_ecc_eddsa_verify (gcry_mpi_t input,
+                                       ECC_public_key *pk,
+                                       gcry_mpi_t r, gcry_mpi_t s,
+                                       int hashalgo, gcry_mpi_t pkmpi);
+
+/*-- ecc-gost.c --*/
+gpg_err_code_t _gcry_ecc_gost_sign (gcry_mpi_t input, ECC_secret_key *skey,
+                                    gcry_mpi_t r, gcry_mpi_t s);
+gpg_err_code_t _gcry_ecc_gost_verify (gcry_mpi_t input, ECC_public_key *pkey,
+                                      gcry_mpi_t r, gcry_mpi_t s);
+
+
+#endif /*GCRY_ECC_COMMON_H*/
diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c
new file mode 100644 (file)
index 0000000..41adfd1
--- /dev/null
@@ -0,0 +1,1162 @@
+/* ecc-curves.c  -  Elliptic Curve parameter mangement
+ * Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 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/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "context.h"
+#include "ec-context.h"
+#include "pubkey-internal.h"
+#include "ecc-common.h"
+
+
+/* This tables defines aliases for curve names.  */
+static const struct
+{
+  const char *name;  /* Our name.  */
+  const char *other; /* Other name. */
+} curve_aliases[] =
+  {
+  /*{ "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  */
+    { "NIST P-192", "prime192v1" },          /* X9.62 name.  */
+    { "NIST P-192", "secp192r1"  },          /* SECP name.  */
+    { "NIST P-192", "nistp192"   },          /* rfc5656.  */
+
+    { "NIST P-224", "secp224r1" },
+    { "NIST P-224", "1.3.132.0.33" },        /* SECP OID.  */
+    { "NIST P-224", "nistp224"   },          /* rfc5656.  */
+
+    { "NIST P-256", "1.2.840.10045.3.1.7" }, /* From NIST SP 800-78-1.  */
+    { "NIST P-256", "prime256v1" },
+    { "NIST P-256", "secp256r1"  },
+    { "NIST P-256", "nistp256"   },          /* rfc5656.  */
+
+    { "NIST P-384", "secp384r1" },
+    { "NIST P-384", "1.3.132.0.34" },
+    { "NIST P-384", "nistp384"   },          /* rfc5656.  */
+
+    { "NIST P-521", "secp521r1" },
+    { "NIST P-521", "1.3.132.0.35" },
+    { "NIST P-521", "nistp521"   },          /* rfc5656.  */
+
+    { "brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1" },
+    { "brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3" },
+    { "brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5" },
+    { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7" },
+    { "brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9" },
+    { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11"},
+    { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13"},
+
+    { NULL, NULL}
+  };
+
+
+typedef struct
+{
+  const char *desc;           /* Description of the curve.  */
+  unsigned int nbits;         /* Number of bits.  */
+  unsigned int fips:1;        /* True if this is a FIPS140-2 approved curve. */
+
+  /* The model describing this curve.  This is mainly used to select
+     the group equation. */
+  enum gcry_mpi_ec_models model;
+
+  /* The actual ECC dialect used.  This is used for curve specific
+     optimizations and to select encodings etc. */
+  enum ecc_dialects dialect;
+
+  const char *p;              /* The prime defining the field.  */
+  const char *a, *b;          /* The coefficients.  For Twisted Edwards
+                                 Curves b is used for d.  */
+  const char *n;              /* The order of the base point.  */
+  const char *g_x, *g_y;      /* Base point.  */
+} ecc_domain_parms_t;
+
+
+/* This static table defines all available curves.  */
+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,
+      "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED",
+      "-0x01",
+      "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A",
+      "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED",
+      "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A",
+      "0x6666666666666666666666666666666666666666666666666666666666666658"
+    },
+    {
+      "NIST P-192", 192, 1,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0xfffffffffffffffffffffffffffffffeffffffffffffffff",
+      "0xfffffffffffffffffffffffffffffffefffffffffffffffc",
+      "0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
+      "0xffffffffffffffffffffffff99def836146bc9b1b4d22831",
+
+      "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
+      "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811"
+    },
+    {
+      "NIST P-224", 224, 1,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0xffffffffffffffffffffffffffffffff000000000000000000000001",
+      "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe",
+      "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
+      "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" ,
+
+      "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
+      "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34"
+    },
+    {
+      "NIST P-256", 256, 1,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
+      "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
+      "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
+      "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
+
+      "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
+      "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
+    },
+    {
+      "NIST P-384", 384, 1,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
+      "ffffffff0000000000000000ffffffff",
+      "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
+      "ffffffff0000000000000000fffffffc",
+      "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a"
+      "c656398d8a2ed19d2a85c8edd3ec2aef",
+      "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf"
+      "581a0db248b0a77aecec196accc52973",
+
+      "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38"
+      "5502f25dbf55296c3a545e3872760ab7",
+      "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0"
+      "0a60b1ce1d7e819d7a431d7c90ea0e5f"
+    },
+    {
+      "NIST P-521", 521, 1,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+      "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+      "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+      "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
+      "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10"
+      "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
+      "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+      "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
+
+      "0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d"
+      "3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
+      "0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e"
+      "662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650"
+    },
+
+    { "brainpoolP160r1", 160, 0,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0xe95e4a5f737059dc60dfc7ad95b3d8139515620f",
+      "0x340e7be2a280eb74e2be61bada745d97e8f7c300",
+      "0x1e589a8595423412134faa2dbdec95c8d8675e58",
+      "0xe95e4a5f737059dc60df5991d45029409e60fc09",
+      "0xbed5af16ea3f6a4f62938c4631eb5af7bdbcdbc3",
+      "0x1667cb477a1a8ec338f94741669c976316da6321"
+    },
+
+    { "brainpoolP192r1", 192, 0,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0xc302f41d932a36cda7a3463093d18db78fce476de1a86297",
+      "0x6a91174076b1e0e19c39c031fe8685c1cae040e5c69a28ef",
+      "0x469a28ef7c28cca3dc721d044f4496bcca7ef4146fbf25c9",
+      "0xc302f41d932a36cda7a3462f9e9e916b5be8f1029ac4acc1",
+      "0xc0a0647eaab6a48753b033c56cb0f0900a2f5c4853375fd6",
+      "0x14b690866abd5bb88b5f4828c1490002e6773fa2fa299b8f"
+    },
+
+    { "brainpoolP224r1", 224, 0,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0xd7c134aa264366862a18302575d1d787b09f075797da89f57ec8c0ff",
+      "0x68a5e62ca9ce6c1c299803a6c1530b514e182ad8b0042a59cad29f43",
+      "0x2580f63ccfe44138870713b1a92369e33e2135d266dbb372386c400b",
+      "0xd7c134aa264366862a18302575d0fb98d116bc4b6ddebca3a5a7939f",
+      "0x0d9029ad2c7e5cf4340823b2a87dc68c9e4ce3174c1e6efdee12c07d",
+      "0x58aa56f772c0726f24c6b89e4ecdac24354b9e99caa3f6d3761402cd"
+    },
+
+    { "brainpoolP256r1", 256, 0,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0xa9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377",
+      "0x7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9",
+      "0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6",
+      "0xa9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7",
+      "0x8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262",
+      "0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997"
+    },
+
+    { "brainpoolP320r1", 320, 0,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0xd35e472036bc4fb7e13c785ed201e065f98fcfa6f6f40def4f92b9ec7893ec28"
+      "fcd412b1f1b32e27",
+      "0x3ee30b568fbab0f883ccebd46d3f3bb8a2a73513f5eb79da66190eb085ffa9f4"
+      "92f375a97d860eb4",
+      "0x520883949dfdbc42d3ad198640688a6fe13f41349554b49acc31dccd88453981"
+      "6f5eb4ac8fb1f1a6",
+      "0xd35e472036bc4fb7e13c785ed201e065f98fcfa5b68f12a32d482ec7ee8658e9"
+      "8691555b44c59311",
+      "0x43bd7e9afb53d8b85289bcc48ee5bfe6f20137d10a087eb6e7871e2a10a599c7"
+      "10af8d0d39e20611",
+      "0x14fdd05545ec1cc8ab4093247f77275e0743ffed117182eaa9c77877aaac6ac7"
+      "d35245d1692e8ee1"
+    },
+
+    { "brainpoolP384r1", 384, 0,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123"
+      "acd3a729901d1a71874700133107ec53",
+      "0x7bc382c63d8c150c3c72080ace05afa0c2bea28e4fb22787139165efba91f90f"
+      "8aa5814a503ad4eb04a8c7dd22ce2826",
+      "0x04a8c7dd22ce28268b39b55416f0447c2fb77de107dcd2a62e880ea53eeb62d5"
+      "7cb4390295dbc9943ab78696fa504c11",
+      "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b31f166e6cac0425a7"
+      "cf3ab6af6b7fc3103b883202e9046565",
+      "0x1d1c64f068cf45ffa2a63a81b7c13f6b8847a3e77ef14fe3db7fcafe0cbd10e8"
+      "e826e03436d646aaef87b2e247d4af1e",
+      "0x8abe1d7520f9c2a45cb1eb8e95cfd55262b70b29feec5864e19c054ff9912928"
+      "0e4646217791811142820341263c5315"
+    },
+
+    { "brainpoolP512r1", 512, 0,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330871"
+      "7d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3",
+      "0x7830a3318b603b89e2327145ac234cc594cbdd8d3df91610a83441caea9863bc"
+      "2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94ca",
+      "0x3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a7"
+      "2bf2c7b9e7c1ac4d77fc94cadc083e67984050b75ebae5dd2809bd638016f723",
+      "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330870"
+      "553e5c414ca92619418661197fac10471db1d381085ddaddb58796829ca90069",
+      "0x81aee4bdd82ed9645a21322e9c4c6a9385ed9f70b5d916c1b43b62eef4d0098e"
+      "ff3b1f78e2d0d48d50d1687b93b97d5f7c6d5047406a5e688b352209bcb9f822",
+      "0x7dde385d566332ecc0eabfa9cf7822fdf209f70024a57b1aa000c55b881f8111"
+      "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892"
+    },
+    {
+      "GOST2001-test", 256, 0,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0x8000000000000000000000000000000000000000000000000000000000000431",
+      "0x0000000000000000000000000000000000000000000000000000000000000007",
+      "0x5fbff498aa938ce739b8e022fbafef40563f6e6a3472fc2a514c0ce9dae23b7e",
+      "0x8000000000000000000000000000000150fe8a1892976154c59cfc193accf5b3",
+
+      "0x0000000000000000000000000000000000000000000000000000000000000002",
+      "0x08e2a8a0e65147d4bd6316030e16d19c85c97f0a9ca267122b96abbcea7e8fc8",
+    },
+
+    {
+      "GOST2012-test", 511, 0,
+      MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD,
+      "0x4531acd1fe0023c7550d267b6b2fee80922b14b2ffb90f04d4eb7c09b5d2d15d"
+      "f1d852741af4704a0458047e80e4546d35b8336fac224dd81664bbf528be6373",
+      "0x0000000000000000000000000000000000000000000000000000000000000007",
+      "0x1cff0806a31116da29d8cfa54e57eb748bc5f377e49400fdd788b649eca1ac4"
+      "361834013b2ad7322480a89ca58e0cf74bc9e540c2add6897fad0a3084f302adc",
+      "0x4531acd1fe0023c7550d267b6b2fee80922b14b2ffb90f04d4eb7c09b5d2d15d"
+      "a82f2d7ecb1dbac719905c5eecc423f1d86e25edbe23c595d644aaf187e6e6df",
+
+      "0x24d19cc64572ee30f396bf6ebbfd7a6c5213b3b3d7057cc825f91093a68cd762"
+      "fd60611262cd838dc6b60aa7eee804e28bc849977fac33b4b530f1b120248a9a",
+      "0x2bb312a43bd2ce6e0d020613c857acddcfbf061e91e5f2c3f32447c259f39b2"
+      "c83ab156d77f1496bf7eb3351e1ee4e43dc1a18b91b24640b6dbb92cb1add371e",
+    },
+
+    { NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL }
+  };
+
+
+
+\f
+/* Return a copy of POINT.  */
+static gcry_mpi_point_t
+point_copy (gcry_mpi_point_t point)
+{
+  gcry_mpi_point_t newpoint;
+
+  if (point)
+    {
+      newpoint = mpi_point_new (0);
+      point_set (newpoint, point);
+    }
+  else
+    newpoint = NULL;
+  return newpoint;
+}
+
+
+/* Helper to scan a hex string. */
+static gcry_mpi_t
+scanval (const char *string)
+{
+  gpg_err_code_t rc;
+  gcry_mpi_t val;
+
+  rc = _gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
+  if (rc)
+    log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (rc));
+  return val;
+}
+
+
+/* Return the index of the domain_parms table for a curve with NAME.
+   Return -1 if not found.  */
+static int
+find_domain_parms_idx (const char *name)
+{
+  int idx, aliasno;
+
+  /* First check our native curves.  */
+  for (idx = 0; domain_parms[idx].desc; idx++)
+    if (!strcmp (name, domain_parms[idx].desc))
+      return idx;
+
+  /* If not found consult the alias table.  */
+  if (!domain_parms[idx].desc)
+    {
+      for (aliasno = 0; curve_aliases[aliasno].name; aliasno++)
+        if (!strcmp (name, curve_aliases[aliasno].other))
+          break;
+      if (curve_aliases[aliasno].name)
+        {
+          for (idx = 0; domain_parms[idx].desc; idx++)
+            if (!strcmp (curve_aliases[aliasno].name, domain_parms[idx].desc))
+              return idx;
+        }
+    }
+
+  return -1;
+}
+
+
+/* Generate the crypto system setup.  This function takes the NAME of
+   a curve or the desired number of bits and stores at R_CURVE the
+   parameters of the named curve or those of a suitable curve.  If
+   R_NBITS is not NULL, the chosen number of bits is stored there.
+   NULL may be given for R_CURVE, if the value is not required and for
+   example only a quick test for availability is desired.  Note that
+   the curve fields should be initialized to zero because fields which
+   are not NULL are skipped.  */
+gpg_err_code_t
+_gcry_ecc_fill_in_curve (unsigned int nbits, const char *name,
+                         elliptic_curve_t *curve, unsigned int *r_nbits)
+{
+  int idx;
+  const char *resname = NULL; /* Set to a found curve name.  */
+
+  if (name)
+    idx = find_domain_parms_idx (name);
+  else
+    {
+      for (idx = 0; domain_parms[idx].desc; idx++)
+        if (nbits == domain_parms[idx].nbits
+            && domain_parms[idx].model == MPI_EC_WEIERSTRASS)
+          break;
+      if (!domain_parms[idx].desc)
+        idx = -1;
+    }
+  if (idx < 0)
+    return GPG_ERR_UNKNOWN_CURVE;
+
+  resname = domain_parms[idx].desc;
+
+  /* In fips mode we only support NIST curves.  Note that it is
+     possible to bypass this check by specifying the curve parameters
+     directly.  */
+  if (fips_mode () && !domain_parms[idx].fips )
+    return GPG_ERR_NOT_SUPPORTED;
+
+  switch (domain_parms[idx].model)
+    {
+    case MPI_EC_WEIERSTRASS:
+    case MPI_EC_TWISTEDEDWARDS:
+      break;
+    case MPI_EC_MONTGOMERY:
+      return GPG_ERR_NOT_SUPPORTED;
+    default:
+      return GPG_ERR_BUG;
+    }
+
+
+  if (r_nbits)
+    *r_nbits = domain_parms[idx].nbits;
+
+  if (curve)
+    {
+      curve->model = domain_parms[idx].model;
+      curve->dialect = domain_parms[idx].dialect;
+      if (!curve->p)
+        curve->p = scanval (domain_parms[idx].p);
+      if (!curve->a)
+        curve->a = scanval (domain_parms[idx].a);
+      if (!curve->b)
+        curve->b = scanval (domain_parms[idx].b);
+      if (!curve->n)
+        curve->n = scanval (domain_parms[idx].n);
+      if (!curve->G.x)
+        curve->G.x = scanval (domain_parms[idx].g_x);
+      if (!curve->G.y)
+        curve->G.y = scanval (domain_parms[idx].g_y);
+      if (!curve->G.z)
+        curve->G.z = mpi_alloc_set_ui (1);
+      if (!curve->name)
+        curve->name = resname;
+    }
+
+  return 0;
+}
+
+
+/* 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
+   in standard uncompressed format.  Also update MODEL and DIALECT if
+   they are not NULL. */
+gpg_err_code_t
+_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)
+{
+  int idx;
+
+  idx = find_domain_parms_idx (name);
+  if (idx < 0)
+    return GPG_ERR_UNKNOWN_CURVE;
+
+  if (g)
+    {
+      char *buf;
+      size_t len;
+
+      len = 4;
+      len += strlen (domain_parms[idx].g_x+2);
+      len += strlen (domain_parms[idx].g_y+2);
+      len++;
+      buf = xtrymalloc (len);
+      if (!buf)
+        return gpg_err_code_from_syserror ();
+      strcpy (stpcpy (stpcpy (buf, "0x04"), domain_parms[idx].g_x+2),
+              domain_parms[idx].g_y+2);
+      _gcry_mpi_release (*g);
+      *g = scanval (buf);
+      xfree (buf);
+    }
+  if (model)
+    *model = domain_parms[idx].model;
+  if (dialect)
+    *dialect = domain_parms[idx].dialect;
+  if (p)
+    {
+      _gcry_mpi_release (*p);
+      *p = scanval (domain_parms[idx].p);
+    }
+  if (a)
+    {
+      _gcry_mpi_release (*a);
+      *a = scanval (domain_parms[idx].a);
+    }
+  if (b)
+    {
+      _gcry_mpi_release (*b);
+      *b = scanval (domain_parms[idx].b);
+    }
+  if (n)
+    {
+      _gcry_mpi_release (*n);
+      *n = scanval (domain_parms[idx].n);
+    }
+  return 0;
+}
+
+
+/* Return the name matching the parameters in PKEY.  This works only
+   with curves described by the Weierstrass equation. */
+const char *
+_gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits)
+{
+  gpg_err_code_t rc;
+  const char *result = NULL;
+  elliptic_curve_t E;
+  gcry_mpi_t mpi_g = NULL;
+  gcry_mpi_t tmp = NULL;
+  int idx;
+
+  memset (&E, 0, sizeof E);
+
+  if (r_nbits)
+    *r_nbits = 0;
+
+  if (!keyparms)
+    {
+      idx = iterator;
+      if (idx >= 0 && idx < DIM (domain_parms))
+        {
+          result = domain_parms[idx].desc;
+          if (r_nbits)
+            *r_nbits = domain_parms[idx].nbits;
+        }
+      return result;
+    }
+
+
+  /*
+   * Extract the curve parameters..
+   */
+  rc = gpg_err_code (sexp_extract_param (keyparms, NULL, "-pabgn",
+                                         &E.p, &E.a, &E.b, &mpi_g, &E.n,
+                                         NULL));
+  if (rc == GPG_ERR_NO_OBJ)
+    {
+      /* This might be the second use case of checking whether a
+         specific curve given by name is supported.  */
+      gcry_sexp_t l1;
+      char *name;
+
+      l1 = sexp_find_token (keyparms, "curve", 5);
+      if (!l1)
+        goto leave;  /* No curve name parameter.  */
+
+      name = sexp_nth_string (l1, 1);
+      sexp_release (l1);
+      if (!name)
+        goto leave;  /* Name missing or out of core. */
+
+      idx = find_domain_parms_idx (name);
+      xfree (name);
+      if (idx >= 0)  /* Curve found.  */
+        {
+          result = domain_parms[idx].desc;
+          if (r_nbits)
+            *r_nbits = domain_parms[idx].nbits;
+        }
+      return result;
+    }
+
+  if (rc)
+    goto leave;
+
+  if (mpi_g)
+    {
+      _gcry_mpi_point_init (&E.G);
+      if (_gcry_ecc_os2ec (&E.G, mpi_g))
+        goto leave;
+    }
+
+  for (idx = 0; domain_parms[idx].desc; idx++)
+    {
+      mpi_free (tmp);
+      tmp = scanval (domain_parms[idx].p);
+      if (!mpi_cmp (tmp, E.p))
+        {
+          mpi_free (tmp);
+          tmp = scanval (domain_parms[idx].a);
+          if (!mpi_cmp (tmp, E.a))
+            {
+              mpi_free (tmp);
+              tmp = scanval (domain_parms[idx].b);
+              if (!mpi_cmp (tmp, E.b))
+                {
+                  mpi_free (tmp);
+                  tmp = scanval (domain_parms[idx].n);
+                  if (!mpi_cmp (tmp, E.n))
+                    {
+                      mpi_free (tmp);
+                      tmp = scanval (domain_parms[idx].g_x);
+                      if (!mpi_cmp (tmp, E.G.x))
+                        {
+                          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;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+ leave:
+  _gcry_mpi_release (tmp);
+  _gcry_mpi_release (E.p);
+  _gcry_mpi_release (E.a);
+  _gcry_mpi_release (E.b);
+  _gcry_mpi_release (mpi_g);
+  _gcry_mpi_point_free_parts (&E.G);
+  _gcry_mpi_release (E.n);
+  return result;
+}
+
+
+/* Helper to extract an MPI from key parameters.  */
+static gpg_err_code_t
+mpi_from_keyparam (gcry_mpi_t *r_a, gcry_sexp_t keyparam, const char *name)
+{
+  gcry_err_code_t ec = 0;
+  gcry_sexp_t l1;
+
+  l1 = sexp_find_token (keyparam, name, 0);
+  if (l1)
+    {
+      *r_a = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+      sexp_release (l1);
+      if (!*r_a)
+        ec = GPG_ERR_INV_OBJ;
+    }
+  return ec;
+}
+
+/* Helper to extract a point from key parameters.  If no parameter
+   with NAME is found, the functions tries to find a non-encoded point
+   by appending ".x", ".y" and ".z" to NAME.  ".z" is in this case
+   optional and defaults to 1.  EC is the context which at this point
+   may not be fully initialized. */
+static gpg_err_code_t
+point_from_keyparam (gcry_mpi_point_t *r_a,
+                     gcry_sexp_t keyparam, const char *name, mpi_ec_t ec)
+{
+  gcry_err_code_t rc;
+  gcry_sexp_t l1;
+  gcry_mpi_point_t point;
+
+  l1 = sexp_find_token (keyparam, name, 0);
+  if (l1)
+    {
+      gcry_mpi_t a;
+
+      a = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_OPAQUE);
+      sexp_release (l1);
+      if (!a)
+        return GPG_ERR_INV_OBJ;
+
+      point = mpi_point_new (0);
+      if (ec && ec->dialect == ECC_DIALECT_ED25519)
+        rc = _gcry_ecc_eddsa_decodepoint (a, ec, point, NULL, NULL);
+      else
+        rc = _gcry_ecc_os2ec (point, a);
+      mpi_free (a);
+      if (rc)
+        {
+          mpi_point_release (point);
+          return rc;
+        }
+    }
+  else
+    {
+      char *tmpname;
+      gcry_mpi_t x = NULL;
+      gcry_mpi_t y = NULL;
+      gcry_mpi_t z = NULL;
+
+      tmpname = xtrymalloc (strlen (name) + 2 + 1);
+      if (!tmpname)
+        return gpg_err_code_from_syserror ();
+      strcpy (stpcpy (tmpname, name), ".x");
+      rc = mpi_from_keyparam (&x, keyparam, tmpname);
+      if (rc)
+        {
+          xfree (tmpname);
+          return rc;
+        }
+      strcpy (stpcpy (tmpname, name), ".y");
+      rc = mpi_from_keyparam (&y, keyparam, tmpname);
+      if (rc)
+        {
+          mpi_free (x);
+          xfree (tmpname);
+          return rc;
+        }
+      strcpy (stpcpy (tmpname, name), ".z");
+      rc = mpi_from_keyparam (&z, keyparam, tmpname);
+      if (rc)
+        {
+          mpi_free (y);
+          mpi_free (x);
+          xfree (tmpname);
+          return rc;
+        }
+      if (!z)
+        z = mpi_set_ui (NULL, 1);
+      if (x && y)
+        point = mpi_point_snatch_set (NULL, x, y, z);
+      else
+        {
+          mpi_free (x);
+          mpi_free (y);
+          mpi_free (z);
+          point = NULL;
+        }
+      xfree (tmpname);
+    }
+
+  if (point)
+    *r_a = point;
+  return 0;
+}
+
+
+/* This function creates a new context for elliptic curve operations.
+   Either KEYPARAM or CURVENAME must be given.  If both are given and
+   KEYPARAM has no curve parameter, CURVENAME is used to add missing
+   parameters.  On success 0 is returned and the new context stored at
+   R_CTX.  On error NULL is stored at R_CTX and an error code is
+   returned.  The context needs to be released using
+   gcry_ctx_release.  */
+gpg_err_code_t
+_gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
+                  gcry_sexp_t keyparam, const char *curvename)
+{
+  gpg_err_code_t errc;
+  gcry_ctx_t ctx = NULL;
+  enum gcry_mpi_ec_models model = MPI_EC_WEIERSTRASS;
+  enum ecc_dialects dialect = ECC_DIALECT_STANDARD;
+  gcry_mpi_t p = NULL;
+  gcry_mpi_t a = NULL;
+  gcry_mpi_t b = NULL;
+  gcry_mpi_point_t G = NULL;
+  gcry_mpi_t n = NULL;
+  gcry_mpi_point_t Q = NULL;
+  gcry_mpi_t d = NULL;
+  int flags = 0;
+  gcry_sexp_t l1;
+
+  *r_ctx = NULL;
+
+  if (keyparam)
+    {
+      /* Parse an optional flags list.  */
+      l1 = sexp_find_token (keyparam, "flags", 0);
+      if (l1)
+        {
+          errc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
+          sexp_release (l1);
+          l1 = NULL;
+          if (errc)
+            goto leave;
+        }
+
+      /* Check whether a curve name was given.  */
+      l1 = sexp_find_token (keyparam, "curve", 5);
+
+      /* If we don't have a curve name or if override parameters have
+         explicitly been requested, parse them.  */
+      if (!l1 || (flags & PUBKEY_FLAG_PARAM))
+        {
+          errc = mpi_from_keyparam (&p, keyparam, "p");
+          if (errc)
+            goto leave;
+          errc = mpi_from_keyparam (&a, keyparam, "a");
+          if (errc)
+            goto leave;
+          errc = mpi_from_keyparam (&b, keyparam, "b");
+          if (errc)
+            goto leave;
+          errc = point_from_keyparam (&G, keyparam, "g", NULL);
+          if (errc)
+            goto leave;
+          errc = mpi_from_keyparam (&n, keyparam, "n");
+          if (errc)
+            goto leave;
+        }
+    }
+  else
+    l1 = NULL; /* No curvename.  */
+
+  /* Check whether a curve parameter is available and use that to fill
+     in missing values.  If no curve parameter is available try an
+     optional provided curvename.  If only the curvename has been
+     given use that one. */
+  if (l1 || curvename)
+    {
+      char *name;
+      elliptic_curve_t *E;
+
+      if (l1)
+        {
+          name = sexp_nth_string (l1, 1);
+          sexp_release (l1);
+          if (!name)
+            {
+              errc = GPG_ERR_INV_OBJ; /* Name missing or out of core. */
+              goto leave;
+            }
+        }
+      else
+        name = NULL;
+
+      E = xtrycalloc (1, sizeof *E);
+      if (!E)
+        {
+          errc = gpg_err_code_from_syserror ();
+          xfree (name);
+          goto leave;
+        }
+
+      errc = _gcry_ecc_fill_in_curve (0, name? name : curvename, E, NULL);
+      xfree (name);
+      if (errc)
+        {
+          xfree (E);
+          goto leave;
+        }
+
+      model = E->model;
+      dialect = E->dialect;
+
+      if (!p)
+        {
+          p = E->p;
+          E->p = NULL;
+        }
+      if (!a)
+        {
+          a = E->a;
+          E->a = NULL;
+        }
+      if (!b)
+        {
+          b = E->b;
+          E->b = NULL;
+        }
+      if (!G)
+        {
+          G = mpi_point_snatch_set (NULL, E->G.x, E->G.y, E->G.z);
+          E->G.x = NULL;
+          E->G.y = NULL;
+          E->G.z = NULL;
+        }
+      if (!n)
+        {
+          n = E->n;
+          E->n = NULL;
+        }
+      _gcry_ecc_curve_free (E);
+      xfree (E);
+    }
+
+
+  errc = _gcry_mpi_ec_p_new (&ctx, model, dialect, flags, p, a, b);
+  if (!errc)
+    {
+      mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
+
+      if (b)
+        {
+          mpi_free (ec->b);
+          ec->b = b;
+          b = NULL;
+        }
+      if (G)
+        {
+          ec->G = G;
+          G = NULL;
+        }
+      if (n)
+        {
+          ec->n = n;
+          n = 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
+         that it is able to use the correct decompression.  Parsing
+         the private key D could have been done earlier but it is less
+         surprising if we do it here as well.  */
+      if (keyparam)
+        {
+          errc = point_from_keyparam (&Q, keyparam, "q", ec);
+          if (errc)
+            goto leave;
+          errc = mpi_from_keyparam (&d, keyparam, "d");
+          if (errc)
+            goto leave;
+        }
+
+      if (Q)
+        {
+          ec->Q = Q;
+          Q = NULL;
+        }
+      if (d)
+        {
+          ec->d = d;
+          d = NULL;
+        }
+
+      *r_ctx = ctx;
+      ctx = NULL;
+    }
+
+ leave:
+  _gcry_ctx_release (ctx);
+  mpi_free (p);
+  mpi_free (a);
+  mpi_free (b);
+  _gcry_mpi_point_release (G);
+  mpi_free (n);
+  _gcry_mpi_point_release (Q);
+  mpi_free (d);
+  return errc;
+}
+
+
+/* Return the parameters of the curve NAME as an S-expression.  */
+gcry_sexp_t
+_gcry_ecc_get_param_sexp (const char *name)
+{
+  unsigned int nbits;
+  elliptic_curve_t E;
+  mpi_ec_t ctx;
+  gcry_mpi_t g_x, g_y;
+  gcry_mpi_t pkey[6];
+  gcry_sexp_t result;
+  int i;
+
+  memset (&E, 0, sizeof E);
+  if (_gcry_ecc_fill_in_curve (0, name, &E, &nbits))
+    return NULL;
+
+  g_x = mpi_new (0);
+  g_y = mpi_new (0);
+  ctx = _gcry_mpi_ec_p_internal_new (MPI_EC_WEIERSTRASS,
+                                     ECC_DIALECT_STANDARD,
+                                     0,
+                                     E.p, E.a, NULL);
+  if (_gcry_mpi_ec_get_affine (g_x, g_y, &E.G, ctx))
+    log_fatal ("ecc get param: Failed to get affine coordinates\n");
+  _gcry_mpi_ec_free (ctx);
+  _gcry_mpi_point_free_parts (&E.G);
+
+  pkey[0] = E.p;
+  pkey[1] = E.a;
+  pkey[2] = E.b;
+  pkey[3] = _gcry_ecc_ec2os (g_x, g_y, E.p);
+  pkey[4] = E.n;
+  pkey[5] = 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]))
+    result = NULL;
+
+  for (i=0; pkey[i]; i++)
+    _gcry_mpi_release (pkey[i]);
+
+  return result;
+}
+
+
+/* Return an MPI (or opaque MPI) described by NAME and the context EC.
+   If COPY is true a copy is returned, if not a const MPI may be
+   returned.  In any case mpi_free must be used.  */
+gcry_mpi_t
+_gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy)
+{
+  if (!*name)
+    return NULL;
+
+  if (!strcmp (name, "p") && ec->p)
+    return mpi_is_const (ec->p) && !copy? ec->p : mpi_copy (ec->p);
+  if (!strcmp (name, "a") && ec->a)
+    return mpi_is_const (ec->a) && !copy? ec->a : mpi_copy (ec->a);
+  if (!strcmp (name, "b") && ec->b)
+    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, "d") && ec->d)
+    return mpi_is_const (ec->d) && !copy? ec->d : mpi_copy (ec->d);
+
+  /* Return a requested point coordinate.  */
+  if (!strcmp (name, "g.x") && ec->G && ec->G->x)
+    return mpi_is_const (ec->G->x) && !copy? ec->G->x : mpi_copy (ec->G->x);
+  if (!strcmp (name, "g.y") && ec->G && ec->G->y)
+    return mpi_is_const (ec->G->y) && !copy? ec->G->y : mpi_copy (ec->G->y);
+  if (!strcmp (name, "q.x") && ec->Q && ec->Q->x)
+    return mpi_is_const (ec->Q->x) && !copy? ec->Q->x : mpi_copy (ec->Q->x);
+  if (!strcmp (name, "q.y") && ec->Q && ec->Q->y)
+    return mpi_is_const (ec->G->y) && !copy? ec->Q->y : mpi_copy (ec->Q->y);
+
+  /* If the base point has been requested, return it in standard
+     encoding.  */
+  if (!strcmp (name, "g") && ec->G)
+    return _gcry_mpi_ec_ec2os (ec->G, ec);
+
+  /* If the public key has been requested, return it by default in
+     standard uncompressed encoding or if requested in other
+     encodings.  */
+  if (*name == 'q' && (!name[1] || name[1] == '@'))
+    {
+      /* If only the private key is given, compute the public key.  */
+      if (!ec->Q)
+        ec->Q = _gcry_ecc_compute_public (NULL, ec, NULL, NULL);
+
+      if (!ec->Q)
+        return NULL;
+
+      if (name[1] != '@')
+        return _gcry_mpi_ec_ec2os (ec->Q, ec);
+
+      if (!strcmp (name+2, "eddsa") && ec->model == MPI_EC_TWISTEDEDWARDS)
+        {
+          unsigned char *encpk;
+          unsigned int encpklen;
+
+          if (!_gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL,
+                                            &encpk, &encpklen))
+            return mpi_set_opaque (NULL, encpk, encpklen*8);
+        }
+    }
+
+  return NULL;
+}
+
+
+/* Return a point described by NAME and the context EC.  */
+gcry_mpi_point_t
+_gcry_ecc_get_point (const char *name, mpi_ec_t ec)
+{
+  if (!strcmp (name, "g") && ec->G)
+    return point_copy (ec->G);
+  if (!strcmp (name, "q"))
+    {
+      /* If only the private key is given, compute the public key.  */
+      if (!ec->Q)
+        ec->Q = _gcry_ecc_compute_public (NULL, ec, NULL, NULL);
+
+      if (ec->Q)
+        return point_copy (ec->Q);
+    }
+
+  return NULL;
+}
+
+
+/* Store the MPI NEWVALUE into the context EC under NAME. */
+gpg_err_code_t
+_gcry_ecc_set_mpi (const char *name, gcry_mpi_t newvalue, mpi_ec_t ec)
+{
+  gpg_err_code_t rc = 0;
+
+  if (!*name)
+    ;
+  else if (!strcmp (name, "p"))
+    {
+      mpi_free (ec->p);
+      ec->p = mpi_copy (newvalue);
+      _gcry_mpi_ec_get_reset (ec);
+    }
+  else if (!strcmp (name, "a"))
+    {
+      mpi_free (ec->a);
+      ec->a = mpi_copy (newvalue);
+      _gcry_mpi_ec_get_reset (ec);
+    }
+  else if (!strcmp (name, "b"))
+    {
+      mpi_free (ec->b);
+      ec->b = mpi_copy (newvalue);
+    }
+  else if (!strcmp (name, "n"))
+    {
+      mpi_free (ec->n);
+      ec->n = mpi_copy (newvalue);
+    }
+  else if (*name == 'q' && (!name[1] || name[1] == '@'))
+    {
+      if (newvalue)
+        {
+          if (!ec->Q)
+            ec->Q = mpi_point_new (0);
+          if (ec->dialect == ECC_DIALECT_ED25519)
+            rc = _gcry_ecc_eddsa_decodepoint (newvalue, ec, ec->Q, NULL, NULL);
+          else
+            rc = _gcry_ecc_os2ec (ec->Q, newvalue);
+        }
+      if (rc || !newvalue)
+        {
+          _gcry_mpi_point_release (ec->Q);
+          ec->Q = NULL;
+        }
+      /* Note: We assume that Q matches d and thus do not reset d.  */
+    }
+  else if (!strcmp (name, "d"))
+    {
+      mpi_free (ec->d);
+      ec->d = mpi_copy (newvalue);
+      if (ec->d)
+        {
+          /* We need to reset the public key because it may not
+             anymore match.  */
+          _gcry_mpi_point_release (ec->Q);
+          ec->Q = NULL;
+        }
+    }
+  else
+   rc = GPG_ERR_UNKNOWN_NAME;
+
+  return rc;
+}
+
+
+/* Store the point NEWVALUE into the context EC under NAME.  */
+gpg_err_code_t
+_gcry_ecc_set_point (const char *name, gcry_mpi_point_t newvalue, mpi_ec_t ec)
+{
+  if (!strcmp (name, "g"))
+    {
+      _gcry_mpi_point_release (ec->G);
+      ec->G = point_copy (newvalue);
+    }
+  else if (!strcmp (name, "q"))
+    {
+      _gcry_mpi_point_release (ec->Q);
+      ec->Q = point_copy (newvalue);
+    }
+  else
+    return GPG_ERR_UNKNOWN_NAME;
+
+  return 0;
+}
diff --git a/cipher/ecc-ecdsa.c b/cipher/ecc-ecdsa.c
new file mode 100644 (file)
index 0000000..1484830
--- /dev/null
@@ -0,0 +1,234 @@
+/* ecc-ecdsa.c  -  Elliptic Curve ECDSA signatures
+ * Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 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/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "context.h"
+#include "ec-context.h"
+#include "pubkey-internal.h"
+#include "ecc-common.h"
+
+
+/* Compute an ECDSA signature.
+ * Return the signature struct (r,s) from the message hash.  The caller
+ * must have allocated R and S.
+ */
+gpg_err_code_t
+_gcry_ecc_ecdsa_sign (gcry_mpi_t input, ECC_secret_key *skey,
+                      gcry_mpi_t r, gcry_mpi_t s,
+                      int flags, int hashalgo)
+{
+  gpg_err_code_t rc = 0;
+  int extraloops = 0;
+  gcry_mpi_t k, dr, sum, k_1, x;
+  mpi_point_struct I;
+  gcry_mpi_t hash;
+  const void *abuf;
+  unsigned int abits, qbits;
+  mpi_ec_t ctx;
+
+  if (DBG_CIPHER)
+    log_mpidump ("ecdsa sign hash  ", input );
+
+  qbits = mpi_get_nbits (skey->E.n);
+
+  /* Convert the INPUT into an MPI if needed.  */
+  rc = _gcry_dsa_normalize_hash (input, &hash, qbits);
+  if (rc)
+    return rc;
+
+  k = NULL;
+  dr = mpi_alloc (0);
+  sum = mpi_alloc (0);
+  k_1 = mpi_alloc (0);
+  x = mpi_alloc (0);
+  point_init (&I);
+
+  ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect, 0,
+                                     skey->E.p, skey->E.a, skey->E.b);
+
+  /* Two loops to avoid R or S are zero.  This is more of a joke than
+     a real demand because the probability of them being zero is less
+     than any hardware failure.  Some specs however require it.  */
+  do
+    {
+      do
+        {
+          mpi_free (k);
+          k = NULL;
+          if ((flags & PUBKEY_FLAG_RFC6979) && hashalgo)
+            {
+              /* Use Pornin's method for deterministic DSA.  If this
+                 flag is set, it is expected that HASH is an opaque
+                 MPI with the to be signed hash.  That hash is also
+                 used as h1 from 3.2.a.  */
+              if (!mpi_is_opaque (input))
+                {
+                  rc = GPG_ERR_CONFLICT;
+                  goto leave;
+                }
+
+              abuf = mpi_get_opaque (input, &abits);
+              rc = _gcry_dsa_gen_rfc6979_k (&k, skey->E.n, skey->d,
+                                            abuf, (abits+7)/8,
+                                            hashalgo, extraloops);
+              if (rc)
+                goto leave;
+              extraloops++;
+            }
+          else
+            k = _gcry_dsa_gen_k (skey->E.n, GCRY_STRONG_RANDOM);
+
+          _gcry_mpi_ec_mul_point (&I, k, &skey->E.G, ctx);
+          if (_gcry_mpi_ec_get_affine (x, NULL, &I, ctx))
+            {
+              if (DBG_CIPHER)
+                log_debug ("ecc sign: Failed to get affine coordinates\n");
+              rc = GPG_ERR_BAD_SIGNATURE;
+              goto leave;
+            }
+          mpi_mod (r, x, skey->E.n);  /* r = x mod n */
+        }
+      while (!mpi_cmp_ui (r, 0));
+
+      mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n  */
+      mpi_addm (sum, hash, dr, skey->E.n);  /* sum = hash + (d*r) mod n  */
+      mpi_invm (k_1, k, skey->E.n);         /* k_1 = k^(-1) mod n  */
+      mpi_mulm (s, k_1, sum, skey->E.n);    /* s = k^(-1)*(hash+(d*r)) mod n */
+    }
+  while (!mpi_cmp_ui (s, 0));
+
+  if (DBG_CIPHER)
+    {
+      log_mpidump ("ecdsa sign result r ", r);
+      log_mpidump ("ecdsa sign result s ", s);
+    }
+
+ leave:
+  _gcry_mpi_ec_free (ctx);
+  point_free (&I);
+  mpi_free (x);
+  mpi_free (k_1);
+  mpi_free (sum);
+  mpi_free (dr);
+  mpi_free (k);
+
+  if (hash != input)
+    mpi_free (hash);
+
+  return rc;
+}
+
+
+/* Verify an ECDSA signature.
+ * Check if R and S verifies INPUT.
+ */
+gpg_err_code_t
+_gcry_ecc_ecdsa_verify (gcry_mpi_t input, ECC_public_key *pkey,
+                        gcry_mpi_t r, gcry_mpi_t s)
+{
+  gpg_err_code_t err = 0;
+  gcry_mpi_t hash, h, h1, h2, x;
+  mpi_point_struct Q, Q1, Q2;
+  mpi_ec_t ctx;
+  unsigned int nbits;
+
+  if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, pkey->E.n) < 0) )
+    return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < r < n  failed.  */
+  if( !(mpi_cmp_ui (s, 0) > 0 && mpi_cmp (s, pkey->E.n) < 0) )
+    return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < s < n  failed.  */
+
+  nbits = mpi_get_nbits (pkey->E.n);
+  err = _gcry_dsa_normalize_hash (input, &hash, nbits);
+  if (err)
+    return err;
+
+  h  = mpi_alloc (0);
+  h1 = mpi_alloc (0);
+  h2 = mpi_alloc (0);
+  x = mpi_alloc (0);
+  point_init (&Q);
+  point_init (&Q1);
+  point_init (&Q2);
+
+  ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect, 0,
+                                     pkey->E.p, pkey->E.a, pkey->E.b);
+
+  /* h  = s^(-1) (mod n) */
+  mpi_invm (h, s, pkey->E.n);
+  /* h1 = hash * s^(-1) (mod n) */
+  mpi_mulm (h1, hash, h, pkey->E.n);
+  /* Q1 = [ hash * s^(-1) ]G  */
+  _gcry_mpi_ec_mul_point (&Q1, h1, &pkey->E.G, ctx);
+  /* h2 = r * s^(-1) (mod n) */
+  mpi_mulm (h2, r, h, pkey->E.n);
+  /* Q2 = [ r * s^(-1) ]Q */
+  _gcry_mpi_ec_mul_point (&Q2, h2, &pkey->Q, ctx);
+  /* Q  = ([hash * s^(-1)]G) + ([r * s^(-1)]Q) */
+  _gcry_mpi_ec_add_points (&Q, &Q1, &Q2, ctx);
+
+  if (!mpi_cmp_ui (Q.z, 0))
+    {
+      if (DBG_CIPHER)
+          log_debug ("ecc verify: Rejected\n");
+      err = GPG_ERR_BAD_SIGNATURE;
+      goto leave;
+    }
+  if (_gcry_mpi_ec_get_affine (x, NULL, &Q, ctx))
+    {
+      if (DBG_CIPHER)
+        log_debug ("ecc verify: Failed to get affine coordinates\n");
+      err = GPG_ERR_BAD_SIGNATURE;
+      goto leave;
+    }
+  mpi_mod (x, x, pkey->E.n); /* x = x mod E_n */
+  if (mpi_cmp (x, r))   /* x != r */
+    {
+      if (DBG_CIPHER)
+        {
+          log_mpidump ("     x", x);
+          log_mpidump ("     r", r);
+          log_mpidump ("     s", s);
+        }
+      err = GPG_ERR_BAD_SIGNATURE;
+      goto leave;
+    }
+
+ leave:
+  _gcry_mpi_ec_free (ctx);
+  point_free (&Q2);
+  point_free (&Q1);
+  point_free (&Q);
+  mpi_free (x);
+  mpi_free (h2);
+  mpi_free (h1);
+  mpi_free (h);
+  if (hash != input)
+    mpi_free (hash);
+
+  return err;
+}
diff --git a/cipher/ecc-eddsa.c b/cipher/ecc-eddsa.c
new file mode 100644 (file)
index 0000000..d08a84f
--- /dev/null
@@ -0,0 +1,808 @@
+/* ecc-eddsa.c  -  Elliptic Curve EdDSA signatures
+ * Copyright (C) 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/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "context.h"
+#include "ec-context.h"
+#include "ecc-common.h"
+
+
+\f
+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;
+    }
+}
+
+
+/* Helper to scan a hex string. */
+static gcry_mpi_t
+scanval (const char *string)
+{
+  gpg_err_code_t rc;
+  gcry_mpi_t val;
+
+  rc = _gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
+  if (rc)
+    log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (rc));
+  return val;
+}
+
+
+\f
+/* Encode MPI using the EdDSA scheme.  MINLEN specifies the required
+   length of the buffer in bytes.  On success 0 is returned an a
+   malloced buffer with the encoded point is stored at R_BUFFER; the
+   length of this buffer is stored at R_BUFLEN.  */
+static gpg_err_code_t
+eddsa_encodempi (gcry_mpi_t mpi, unsigned int minlen,
+                 unsigned char **r_buffer, unsigned int *r_buflen)
+{
+  unsigned char *rawmpi;
+  unsigned int rawmpilen;
+
+  rawmpi = _gcry_mpi_get_buffer (mpi, minlen, &rawmpilen, NULL);
+  if (!rawmpi)
+    return gpg_err_code_from_syserror ();
+
+  *r_buffer = rawmpi;
+  *r_buflen = rawmpilen;
+  return 0;
+}
+
+
+/* Encode (X,Y) using the EdDSA scheme.  MINLEN is the required length
+   in bytes for the result.  On success 0 is returned and a malloced
+   buffer with the encoded point is stored at R_BUFFER; the length of
+   this buffer is stored at R_BUFLEN.  */
+static gpg_err_code_t
+eddsa_encode_x_y (gcry_mpi_t x, gcry_mpi_t y, unsigned int minlen,
+                  unsigned char **r_buffer, unsigned int *r_buflen)
+{
+  unsigned char *rawmpi;
+  unsigned int rawmpilen;
+
+  rawmpi = _gcry_mpi_get_buffer (y, minlen, &rawmpilen, NULL);
+  if (!rawmpi)
+    return gpg_err_code_from_syserror ();
+  if (mpi_test_bit (x, 0) && rawmpilen)
+    rawmpi[rawmpilen - 1] |= 0x80;  /* Set sign bit.  */
+
+  *r_buffer = rawmpi;
+  *r_buflen = rawmpilen;
+  return 0;
+}
+
+/* Encode POINT using the EdDSA scheme.  X and Y are either scratch
+   variables supplied by the caller or NULL.  CTX is the usual
+   context.  On success 0 is returned and a malloced buffer with the
+   encoded point is stored at R_BUFFER; the length of this buffer is
+   stored at R_BUFLEN.  */
+gpg_err_code_t
+_gcry_ecc_eddsa_encodepoint (mpi_point_t point, mpi_ec_t ec,
+                             gcry_mpi_t x_in, gcry_mpi_t y_in,
+                             unsigned char **r_buffer, unsigned int *r_buflen)
+{
+  gpg_err_code_t rc;
+  gcry_mpi_t x, y;
+
+  x = x_in? x_in : mpi_new (0);
+  y = y_in? y_in : mpi_new (0);
+
+  if (_gcry_mpi_ec_get_affine (x, y, point, ec))
+    {
+      log_error ("eddsa_encodepoint: Failed to get affine coordinates\n");
+      rc = GPG_ERR_INTERNAL;
+    }
+  else
+    rc = eddsa_encode_x_y (x, y, ec->nbits/8, r_buffer, r_buflen);
+
+  if (!x_in)
+    mpi_free (x);
+  if (!y_in)
+    mpi_free (y);
+  return rc;
+}
+
+
+/* Make sure that the opaque MPI VALUE is in compact EdDSA format.
+   This function updates MPI if needed.  */
+gpg_err_code_t
+_gcry_ecc_eddsa_ensure_compact (gcry_mpi_t value, unsigned int nbits)
+{
+  gpg_err_code_t rc;
+  const unsigned char *buf;
+  unsigned int rawmpilen;
+  gcry_mpi_t x, y;
+  unsigned char *enc;
+  unsigned int enclen;
+
+  if (!mpi_is_opaque (value))
+    return GPG_ERR_INV_OBJ;
+  buf = mpi_get_opaque (value, &rawmpilen);
+  if (!buf)
+    return GPG_ERR_INV_OBJ;
+  rawmpilen = (rawmpilen + 7)/8;
+
+  /* Check whether the public key has been given in standard
+     uncompressed format.  In this case extract y and compress.  */
+  if (rawmpilen > 1 && buf[0] == 0x04 && (rawmpilen%2))
+    {
+      rc = _gcry_mpi_scan (&x, GCRYMPI_FMT_STD,
+                           buf+1, (rawmpilen-1)/2, NULL);
+      if (rc)
+        return rc;
+      rc = _gcry_mpi_scan (&y, GCRYMPI_FMT_STD,
+                           buf+1+(rawmpilen-1)/2, (rawmpilen-1)/2, NULL);
+      if (rc)
+        {
+          mpi_free (x);
+          return rc;
+        }
+
+      rc = eddsa_encode_x_y (x, y, nbits/8, &enc, &enclen);
+      mpi_free (x);
+      mpi_free (y);
+      if (rc)
+        return rc;
+
+      mpi_set_opaque (value, enc, 8*enclen);
+    }
+
+  return 0;
+}
+
+
+/* Recover X from Y and SIGN (which actually is a parity bit).  */
+gpg_err_code_t
+_gcry_ecc_eddsa_recover_x (gcry_mpi_t x, gcry_mpi_t y, int sign, mpi_ec_t ec)
+{
+  gpg_err_code_t rc = 0;
+  gcry_mpi_t u, v, v3, t;
+  static gcry_mpi_t p58, seven;
+
+  if (ec->dialect != ECC_DIALECT_ED25519)
+    return GPG_ERR_NOT_IMPLEMENTED;
+
+  if (!p58)
+    p58 = scanval ("0FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
+                   "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFD");
+  if (!seven)
+    seven = mpi_set_ui (NULL, 7);
+
+  u   = mpi_new (0);
+  v   = mpi_new (0);
+  v3  = mpi_new (0);
+  t   = mpi_new (0);
+
+  /* Compute u and v */
+  /* u = y^2    */
+  mpi_mulm (u, y, y, ec->p);
+  /* v = b*y^2   */
+  mpi_mulm (v, ec->b, u, ec->p);
+  /* u = y^2-1  */
+  mpi_sub_ui (u, u, 1);
+  /* v = b*y^2+1 */
+  mpi_add_ui (v, v, 1);
+
+  /* Compute sqrt(u/v) */
+  /* v3 = v^3 */
+  mpi_powm (v3, v, mpi_const (MPI_C_THREE), ec->p);
+  /* t = v3 * v3 * u * v = u * v^7 */
+  mpi_powm (t, v, seven, ec->p);
+  mpi_mulm (t, t, u, ec->p);
+  /* t = t^((p-5)/8) = (u * v^7)^((p-5)/8)  */
+  mpi_powm (t, t, p58, ec->p);
+  /* x = t * u * v^3 = (u * v^3) * (u * v^7)^((p-5)/8) */
+  mpi_mulm (t, t, u, ec->p);
+  mpi_mulm (x, t, v3, ec->p);
+
+  /* Adjust if needed.  */
+  /* t = v * x^2  */
+  mpi_mulm (t, x, x, ec->p);
+  mpi_mulm (t, t, v, ec->p);
+  /* -t == u ? x = x * sqrt(-1) */
+  mpi_neg (t, t);
+  if (!mpi_cmp (t, u))
+    {
+      static gcry_mpi_t m1;  /* Fixme: this is not thread-safe.  */
+      if (!m1)
+        m1 = scanval ("2B8324804FC1DF0B2B4D00993DFBD7A7"
+                      "2F431806AD2FE478C4EE1B274A0EA0B0");
+      mpi_mulm (x, x, m1, ec->p);
+      /* t = v * x^2  */
+      mpi_mulm (t, x, x, ec->p);
+      mpi_mulm (t, t, v, ec->p);
+      /* -t == u ? x = x * sqrt(-1) */
+      mpi_neg (t, t);
+      if (!mpi_cmp (t, u))
+        rc = GPG_ERR_INV_OBJ;
+    }
+
+  /* Choose the desired square root according to parity */
+  if (mpi_test_bit (x, 0) != !!sign)
+    mpi_sub (x, ec->p, x);
+
+  mpi_free (t);
+  mpi_free (v3);
+  mpi_free (v);
+  mpi_free (u);
+
+  return rc;
+}
+
+
+/* Decode the EdDSA style encoded PK and set it into RESULT.  CTX is
+   the usual curve context.  If R_ENCPK is not NULL, the encoded PK is
+   stored at that address; this is a new copy to be released by the
+   caller.  In contrast to the supplied PK, this is not an MPI and
+   thus guarnateed to be properly padded.  R_ENCPKLEN receives the
+   length of that encoded key.  */
+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 rc;
+  unsigned char *rawmpi;
+  unsigned int rawmpilen;
+  int sign;
+
+  if (mpi_is_opaque (pk))
+    {
+      const unsigned char *buf;
+
+      buf = mpi_get_opaque (pk, &rawmpilen);
+      if (!buf)
+        return GPG_ERR_INV_OBJ;
+      rawmpilen = (rawmpilen + 7)/8;
+
+      /* First check whether the public key has been given in standard
+         uncompressed format.  No need to recover x in this case.
+         Detection is easy: The size of the buffer will be odd and the
+         first byte be 0x04.  */
+      if (rawmpilen > 1 && buf[0] == 0x04 && (rawmpilen%2))
+        {
+          gcry_mpi_t x, y;
+
+          rc = _gcry_mpi_scan (&x, GCRYMPI_FMT_STD,
+                               buf+1, (rawmpilen-1)/2, NULL);
+          if (rc)
+            return rc;
+          rc = _gcry_mpi_scan (&y, GCRYMPI_FMT_STD,
+                               buf+1+(rawmpilen-1)/2, (rawmpilen-1)/2, NULL);
+          if (rc)
+            {
+              mpi_free (x);
+              return rc;
+            }
+
+          if (r_encpk)
+            {
+              rc = eddsa_encode_x_y (x, y, ctx->nbits/8, r_encpk, r_encpklen);
+              if (rc)
+                {
+                  mpi_free (x);
+                  mpi_free (y);
+                  return rc;
+                }
+            }
+          mpi_snatch (result->x, x);
+          mpi_snatch (result->y, y);
+          mpi_set_ui (result->z, 1);
+          return 0;
+        }
+
+      /* EdDSA compressed point.  */
+      rawmpi = xtrymalloc (rawmpilen? rawmpilen:1);
+      if (!rawmpi)
+        return gpg_err_code_from_syserror ();
+      memcpy (rawmpi, buf, rawmpilen);
+      reverse_buffer (rawmpi, rawmpilen);
+    }
+  else
+    {
+      /* Note: Without using an opaque MPI it is not reliable possible
+         to find out whether the public key has been given in
+         uncompressed format.  Thus we expect EdDSA format here.  */
+      rawmpi = _gcry_mpi_get_buffer (pk, ctx->nbits/8, &rawmpilen, NULL);
+      if (!rawmpi)
+        return gpg_err_code_from_syserror ();
+    }
+
+  if (rawmpilen)
+    {
+      sign = !!(rawmpi[0] & 0x80);
+      rawmpi[0] &= 0x7f;
+    }
+  else
+    sign = 0;
+  _gcry_mpi_set_buffer (result->y, rawmpi, rawmpilen, 0);
+  if (r_encpk)
+    {
+      /* Revert to little endian.  */
+      if (sign && rawmpilen)
+        rawmpi[0] |= 0x80;
+      reverse_buffer (rawmpi, rawmpilen);
+      *r_encpk = rawmpi;
+      if (r_encpklen)
+        *r_encpklen = rawmpilen;
+    }
+  else
+    xfree (rawmpi);
+
+  rc = _gcry_ecc_eddsa_recover_x (result->x, result->y, sign, ctx);
+  mpi_set_ui (result->z, 1);
+
+  return rc;
+}
+
+
+/* Compute the A value as used by EdDSA.  The caller needs to provide
+   the context EC and the actual secret D as an MPI.  The function
+   returns a newly allocated 64 byte buffer at r_digest; the first 32
+   bytes represent the A value.  NULL is returned on error and NULL
+   stored at R_DIGEST.  */
+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 rc;
+  unsigned char *rawmpi = NULL;
+  unsigned int rawmpilen;
+  unsigned char *digest;
+  gcry_buffer_t hvec[2];
+  int hashalgo, b;
+
+  *r_digest = NULL;
+
+  hashalgo = GCRY_MD_SHA512;
+  if (hashalgo != GCRY_MD_SHA512)
+    return GPG_ERR_DIGEST_ALGO;
+
+  b = (ec->nbits+7)/8;
+  if (b != 256/8)
+    return GPG_ERR_INTERNAL; /* We only support 256 bit. */
+
+  /* Note that we clear DIGEST so we can use it as input to left pad
+     the key with zeroes for hashing.  */
+  digest = xtrycalloc_secure (2, b);
+  if (!digest)
+    return gpg_err_code_from_syserror ();
+
+  memset (hvec, 0, sizeof hvec);
+
+  rawmpi = _gcry_mpi_get_buffer (d, 0, &rawmpilen, NULL);
+  if (!rawmpi)
+    {
+      xfree (digest);
+      return gpg_err_code_from_syserror ();
+    }
+
+  hvec[0].data = digest;
+  hvec[0].off = 0;
+  hvec[0].len = b > rawmpilen? b - rawmpilen : 0;
+  hvec[1].data = rawmpi;
+  hvec[1].off = 0;
+  hvec[1].len = rawmpilen;
+  rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 2);
+  xfree (rawmpi);
+  if (rc)
+    {
+      xfree (digest);
+      return rc;
+    }
+
+  /* Compute the A value.  */
+  reverse_buffer (digest, 32);  /* Only the first half of the hash.  */
+  digest[0]   = (digest[0] & 0x7f) | 0x40;
+  digest[31] &= 0xf8;
+
+  *r_digest = digest;
+  return 0;
+}
+
+
+/* Ed25519 version of the key generation.  */
+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)
+{
+  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;
+  char *dbuf;
+  size_t dlen;
+  gcry_buffer_t hvec[1];
+  unsigned char *hash_d = NULL;
+
+  point_init (&Q);
+  memset (hvec, 0, sizeof hvec);
+
+  a = mpi_snew (0);
+  x = mpi_new (0);
+  y = mpi_new (0);
+
+  /* Generate a secret.  */
+  hash_d = xtrymalloc_secure (2*b);
+  if (!hash_d)
+    {
+      rc = gpg_error_from_syserror ();
+      goto leave;
+    }
+  dlen = b;
+  dbuf = _gcry_random_bytes_secure (dlen, random_level);
+
+  /* Compute the A value.  */
+  hvec[0].data = dbuf;
+  hvec[0].len = dlen;
+  rc = _gcry_md_hash_buffers (GCRY_MD_SHA512, 0, hash_d, hvec, 1);
+  if (rc)
+    goto leave;
+  sk->d = _gcry_mpi_set_opaque (NULL, dbuf, dlen*8);
+  dbuf = NULL;
+  reverse_buffer (hash_d, 32);  /* Only the first half of the hash.  */
+  hash_d[0] = (hash_d[0] & 0x7f) | 0x40;
+  hash_d[31] &= 0xf8;
+  _gcry_mpi_set_buffer (a, hash_d, 32, 0);
+  xfree (hash_d); hash_d = NULL;
+  /* log_printmpi ("ecgen         a", a); */
+
+  /* Compute Q.  */
+  _gcry_mpi_ec_mul_point (&Q, a, &E->G, ctx);
+  if (DBG_CIPHER)
+    log_printpnt ("ecgen      pk", &Q, ctx);
+
+  /* Copy the stuff to the key structures. */
+  sk->E.model = E->model;
+  sk->E.dialect = E->dialect;
+  sk->E.p = mpi_copy (E->p);
+  sk->E.a = mpi_copy (E->a);
+  sk->E.b = mpi_copy (E->b);
+  point_init (&sk->E.G);
+  point_set (&sk->E.G, &E->G);
+  sk->E.n = mpi_copy (E->n);
+  point_init (&sk->Q);
+  point_set (&sk->Q, &Q);
+
+ leave:
+  point_free (&Q);
+  _gcry_mpi_release (a);
+  _gcry_mpi_release (x);
+  _gcry_mpi_release (y);
+  xfree (hash_d);
+  return rc;
+}
+
+
+/* Compute an EdDSA signature. See:
+ *   [ed25519] 23pp. (PDF) Daniel J. Bernstein, Niels Duif, Tanja
+ *   Lange, Peter Schwabe, Bo-Yin Yang. High-speed high-security
+ *   signatures.  Journal of Cryptographic Engineering 2 (2012), 77-89.
+ *   Document ID: a1a62a2f76d23f65d622484ddd09caf8.
+ *   URL: http://cr.yp.to/papers.html#ed25519. Date: 2011.09.26.
+ *
+ * Despite that this function requires the specification of a hash
+ * algorithm, we only support what has been specified by the paper.
+ * This may change in the future.  Note that we don't check the used
+ * curve; the user is responsible to use Ed25519.
+ *
+ * Return the signature struct (r,s) from the message hash.  The caller
+ * must have allocated R_R and S.
+ */
+gpg_err_code_t
+_gcry_ecc_eddsa_sign (gcry_mpi_t input, ECC_secret_key *skey,
+                      gcry_mpi_t r_r, gcry_mpi_t s, int hashalgo, gcry_mpi_t pk)
+{
+  int rc;
+  mpi_ec_t ctx = NULL;
+  int b;
+  unsigned int tmp;
+  unsigned char *digest;
+  gcry_buffer_t hvec[3];
+  const void *mbuf;
+  size_t mlen;
+  unsigned char *rawmpi = NULL;
+  unsigned int rawmpilen;
+  unsigned char *encpk = NULL; /* Encoded public key.  */
+  unsigned int encpklen;
+  mpi_point_struct I;          /* Intermediate value.  */
+  mpi_point_struct Q;          /* Public key.  */
+  gcry_mpi_t a, x, y, r;
+
+  memset (hvec, 0, sizeof hvec);
+
+  if (!mpi_is_opaque (input))
+    return GPG_ERR_INV_DATA;
+
+  /* Initialize some helpers.  */
+  point_init (&I);
+  point_init (&Q);
+  a = mpi_snew (0);
+  x = mpi_new (0);
+  y = mpi_new (0);
+  r = mpi_new (0);
+  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. */
+
+  rc = _gcry_ecc_eddsa_compute_h_d (&digest, skey->d, ctx);
+  if (rc)
+    goto leave;
+  _gcry_mpi_set_buffer (a, digest, 32, 0);
+
+  /* Compute the public key if it has not been supplied as optional
+     parameter.  */
+  if (pk)
+    {
+      rc = _gcry_ecc_eddsa_decodepoint (pk, ctx, &Q,  &encpk, &encpklen);
+      if (rc)
+        goto leave;
+      if (DBG_CIPHER)
+        log_printhex ("* e_pk", encpk, encpklen);
+      if (!_gcry_mpi_ec_curve_point (&Q, ctx))
+        {
+          rc = GPG_ERR_BROKEN_PUBKEY;
+          goto leave;
+        }
+    }
+  else
+    {
+      _gcry_mpi_ec_mul_point (&Q, a, &skey->E.G, ctx);
+      rc = _gcry_ecc_eddsa_encodepoint (&Q, ctx, x, y, &encpk, &encpklen);
+      if (rc)
+        goto leave;
+      if (DBG_CIPHER)
+        log_printhex ("  e_pk", encpk, encpklen);
+    }
+
+  /* Compute R.  */
+  mbuf = mpi_get_opaque (input, &tmp);
+  mlen = (tmp +7)/8;
+  if (DBG_CIPHER)
+    log_printhex ("     m", mbuf, mlen);
+
+  hvec[0].data = digest;
+  hvec[0].off  = 32;
+  hvec[0].len  = 32;
+  hvec[1].data = (char*)mbuf;
+  hvec[1].len  = mlen;
+  rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 2);
+  if (rc)
+    goto leave;
+  reverse_buffer (digest, 64);
+  if (DBG_CIPHER)
+    log_printhex ("     r", digest, 64);
+  _gcry_mpi_set_buffer (r, digest, 64, 0);
+  _gcry_mpi_ec_mul_point (&I, r, &skey->E.G, ctx);
+  if (DBG_CIPHER)
+    log_printpnt ("   r", &I, ctx);
+
+  /* Convert R into affine coordinates and apply encoding.  */
+  rc = _gcry_ecc_eddsa_encodepoint (&I, ctx, x, y, &rawmpi, &rawmpilen);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    log_printhex ("   e_r", rawmpi, rawmpilen);
+
+  /* S = r + a * H(encodepoint(R) + encodepoint(pk) + m) mod n  */
+  hvec[0].data = rawmpi;  /* (this is R) */
+  hvec[0].off  = 0;
+  hvec[0].len  = rawmpilen;
+  hvec[1].data = encpk;
+  hvec[1].off  = 0;
+  hvec[1].len  = encpklen;
+  hvec[2].data = (char*)mbuf;
+  hvec[2].off  = 0;
+  hvec[2].len  = mlen;
+  rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 3);
+  if (rc)
+    goto leave;
+
+  /* No more need for RAWMPI thus we now transfer it to R_R.  */
+  mpi_set_opaque (r_r, rawmpi, rawmpilen*8);
+  rawmpi = NULL;
+
+  reverse_buffer (digest, 64);
+  if (DBG_CIPHER)
+    log_printhex (" H(R+)", digest, 64);
+  _gcry_mpi_set_buffer (s, digest, 64, 0);
+  mpi_mulm (s, s, a, skey->E.n);
+  mpi_addm (s, s, r, skey->E.n);
+  rc = eddsa_encodempi (s, b, &rawmpi, &rawmpilen);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    log_printhex ("   e_s", rawmpi, rawmpilen);
+  mpi_set_opaque (s, rawmpi, rawmpilen*8);
+  rawmpi = NULL;
+
+  rc = 0;
+
+ leave:
+  _gcry_mpi_release (a);
+  _gcry_mpi_release (x);
+  _gcry_mpi_release (y);
+  _gcry_mpi_release (r);
+  xfree (digest);
+  _gcry_mpi_ec_free (ctx);
+  point_free (&I);
+  point_free (&Q);
+  xfree (encpk);
+  xfree (rawmpi);
+  return rc;
+}
+
+
+/* Verify an EdDSA signature.  See sign_eddsa for the reference.
+ * Check if R_IN and S_IN verifies INPUT.  PKEY has the curve
+ * parameters and PK is the EdDSA style encoded public key.
+ */
+gpg_err_code_t
+_gcry_ecc_eddsa_verify (gcry_mpi_t input, ECC_public_key *pkey,
+                        gcry_mpi_t r_in, gcry_mpi_t s_in, int hashalgo,
+                        gcry_mpi_t pk)
+{
+  int rc;
+  mpi_ec_t ctx = NULL;
+  int b;
+  unsigned int tmp;
+  mpi_point_struct Q;          /* Public key.  */
+  unsigned char *encpk = NULL; /* Encoded public key.  */
+  unsigned int encpklen;
+  const void *mbuf, *rbuf;
+  unsigned char *tbuf = NULL;
+  size_t mlen, rlen;
+  unsigned int tlen;
+  unsigned char digest[64];
+  gcry_buffer_t hvec[3];
+  gcry_mpi_t h, s;
+  mpi_point_struct Ia, Ib;
+
+  if (!mpi_is_opaque (input) || !mpi_is_opaque (r_in) || !mpi_is_opaque (s_in))
+    return GPG_ERR_INV_DATA;
+  if (hashalgo != GCRY_MD_SHA512)
+    return GPG_ERR_DIGEST_ALGO;
+
+  point_init (&Q);
+  point_init (&Ia);
+  point_init (&Ib);
+  h = mpi_new (0);
+  s = mpi_new (0);
+
+  ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect, 0,
+                                     pkey->E.p, pkey->E.a, pkey->E.b);
+  b = ctx->nbits/8;
+  if (b != 256/8)
+    return GPG_ERR_INTERNAL; /* We only support 256 bit. */
+
+  /* Decode and check the public key.  */
+  rc = _gcry_ecc_eddsa_decodepoint (pk, ctx, &Q, &encpk, &encpklen);
+  if (rc)
+    goto leave;
+  if (!_gcry_mpi_ec_curve_point (&Q, ctx))
+    {
+      rc = GPG_ERR_BROKEN_PUBKEY;
+      goto leave;
+    }
+  if (DBG_CIPHER)
+    log_printhex ("  e_pk", encpk, encpklen);
+  if (encpklen != b)
+    {
+      rc = GPG_ERR_INV_LENGTH;
+      goto leave;
+    }
+
+  /* Convert the other input parameters.  */
+  mbuf = mpi_get_opaque (input, &tmp);
+  mlen = (tmp +7)/8;
+  if (DBG_CIPHER)
+    log_printhex ("     m", mbuf, mlen);
+  rbuf = mpi_get_opaque (r_in, &tmp);
+  rlen = (tmp +7)/8;
+  if (DBG_CIPHER)
+    log_printhex ("     r", rbuf, rlen);
+  if (rlen != b)
+    {
+      rc = GPG_ERR_INV_LENGTH;
+      goto leave;
+    }
+
+  /* h = H(encodepoint(R) + encodepoint(pk) + m)  */
+  hvec[0].data = (char*)rbuf;
+  hvec[0].off  = 0;
+  hvec[0].len  = rlen;
+  hvec[1].data = encpk;
+  hvec[1].off  = 0;
+  hvec[1].len  = encpklen;
+  hvec[2].data = (char*)mbuf;
+  hvec[2].off  = 0;
+  hvec[2].len  = mlen;
+  rc = _gcry_md_hash_buffers (hashalgo, 0, digest, hvec, 3);
+  if (rc)
+    goto leave;
+  reverse_buffer (digest, 64);
+  if (DBG_CIPHER)
+    log_printhex (" H(R+)", digest, 64);
+  _gcry_mpi_set_buffer (h, digest, 64, 0);
+
+  /* According to the paper the best way for verification is:
+         encodepoint(sG - h·Q) = encodepoint(r)
+     because we don't need to decode R. */
+  {
+    void *sbuf;
+    unsigned int slen;
+
+    sbuf = _gcry_mpi_get_opaque_copy (s_in, &tmp);
+    slen = (tmp +7)/8;
+    reverse_buffer (sbuf, slen);
+    if (DBG_CIPHER)
+      log_printhex ("     s", sbuf, slen);
+    _gcry_mpi_set_buffer (s, sbuf, slen, 0);
+    xfree (sbuf);
+    if (slen != b)
+      {
+        rc = GPG_ERR_INV_LENGTH;
+        goto leave;
+      }
+  }
+
+  _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_ec_add_points (&Ia, &Ia, &Ib, ctx);
+  rc = _gcry_ecc_eddsa_encodepoint (&Ia, ctx, s, h, &tbuf, &tlen);
+  if (rc)
+    goto leave;
+  if (tlen != rlen || memcmp (tbuf, rbuf, tlen))
+    {
+      rc = GPG_ERR_BAD_SIGNATURE;
+      goto leave;
+    }
+
+  rc = 0;
+
+ leave:
+  xfree (encpk);
+  xfree (tbuf);
+  _gcry_mpi_ec_free (ctx);
+  _gcry_mpi_release (s);
+  _gcry_mpi_release (h);
+  point_free (&Ia);
+  point_free (&Ib);
+  point_free (&Q);
+  return rc;
+}
diff --git a/cipher/ecc-gost.c b/cipher/ecc-gost.c
new file mode 100644 (file)
index 0000000..a34fa08
--- /dev/null
@@ -0,0 +1,233 @@
+/* ecc-gots.c  -  Elliptic Curve GOST signatures
+ * Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
+ * 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 <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "context.h"
+#include "ec-context.h"
+#include "ecc-common.h"
+#include "pubkey-internal.h"
+
+
+/* Compute an GOST R 34.10-01/-12 signature.
+ * Return the signature struct (r,s) from the message hash.  The caller
+ * must have allocated R and S.
+ */
+gpg_err_code_t
+_gcry_ecc_gost_sign (gcry_mpi_t input, ECC_secret_key *skey,
+                     gcry_mpi_t r, gcry_mpi_t s)
+{
+  gpg_err_code_t rc = 0;
+  gcry_mpi_t k, dr, sum, ke, x, e;
+  mpi_point_struct I;
+  gcry_mpi_t hash;
+  const void *abuf;
+  unsigned int abits, qbits;
+  mpi_ec_t ctx;
+
+  if (DBG_CIPHER)
+    log_mpidump ("gost sign hash  ", input );
+
+  qbits = mpi_get_nbits (skey->E.n);
+
+  /* Convert the INPUT into an MPI if needed.  */
+  if (mpi_is_opaque (input))
+    {
+      abuf = mpi_get_opaque (input, &abits);
+      rc = _gcry_mpi_scan (&hash, GCRYMPI_FMT_USG, abuf, (abits+7)/8, NULL);
+      if (rc)
+        return rc;
+      if (abits > qbits)
+        mpi_rshift (hash, hash, abits - qbits);
+    }
+  else
+    hash = input;
+
+
+  k = NULL;
+  dr = mpi_alloc (0);
+  sum = mpi_alloc (0);
+  ke = mpi_alloc (0);
+  e = mpi_alloc (0);
+  x = mpi_alloc (0);
+  point_init (&I);
+
+  ctx = _gcry_mpi_ec_p_internal_new (skey->E.model, skey->E.dialect, 0,
+                                     skey->E.p, skey->E.a, skey->E.b);
+
+  mpi_mod (e, input, skey->E.n); /* e = hash mod n */
+
+  if (!mpi_cmp_ui (e, 0))
+    mpi_set_ui (e, 1);
+
+  /* Two loops to avoid R or S are zero.  This is more of a joke than
+     a real demand because the probability of them being zero is less
+     than any hardware failure.  Some specs however require it.  */
+  do
+    {
+      do
+        {
+          mpi_free (k);
+          k = _gcry_dsa_gen_k (skey->E.n, GCRY_STRONG_RANDOM);
+
+          _gcry_mpi_ec_mul_point (&I, k, &skey->E.G, ctx);
+          if (_gcry_mpi_ec_get_affine (x, NULL, &I, ctx))
+            {
+              if (DBG_CIPHER)
+                log_debug ("ecc sign: Failed to get affine coordinates\n");
+              rc = GPG_ERR_BAD_SIGNATURE;
+              goto leave;
+            }
+          mpi_mod (r, x, skey->E.n);  /* r = x mod n */
+        }
+      while (!mpi_cmp_ui (r, 0));
+      mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n  */
+      mpi_mulm (ke, k, e, skey->E.n); /* ke = k*e mod n */
+      mpi_addm (s, ke, dr, skey->E.n); /* sum = (k*e+ d*r) mod n  */
+    }
+  while (!mpi_cmp_ui (s, 0));
+
+  if (DBG_CIPHER)
+    {
+      log_mpidump ("gost sign result r ", r);
+      log_mpidump ("gost sign result s ", s);
+    }
+
+ leave:
+  _gcry_mpi_ec_free (ctx);
+  point_free (&I);
+  mpi_free (x);
+  mpi_free (e);
+  mpi_free (ke);
+  mpi_free (sum);
+  mpi_free (dr);
+  mpi_free (k);
+
+  if (hash != input)
+    mpi_free (hash);
+
+  return rc;
+}
+
+
+/* Verify a GOST R 34.10-01/-12 signature.
+ * Check if R and S verifies INPUT.
+ */
+gpg_err_code_t
+_gcry_ecc_gost_verify (gcry_mpi_t input, ECC_public_key *pkey,
+                       gcry_mpi_t r, gcry_mpi_t s)
+{
+  gpg_err_code_t err = 0;
+  gcry_mpi_t e, x, z1, z2, v, rv, zero;
+  mpi_point_struct Q, Q1, Q2;
+  mpi_ec_t ctx;
+
+  if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, pkey->E.n) < 0) )
+    return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < r < n  failed.  */
+  if( !(mpi_cmp_ui (s, 0) > 0 && mpi_cmp (s, pkey->E.n) < 0) )
+    return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < s < n  failed.  */
+
+  x = mpi_alloc (0);
+  e = mpi_alloc (0);
+  z1 = mpi_alloc (0);
+  z2 = mpi_alloc (0);
+  v = mpi_alloc (0);
+  rv = mpi_alloc (0);
+  zero = mpi_alloc (0);
+
+  point_init (&Q);
+  point_init (&Q1);
+  point_init (&Q2);
+
+  ctx = _gcry_mpi_ec_p_internal_new (pkey->E.model, pkey->E.dialect, 0,
+                                     pkey->E.p, pkey->E.a, pkey->E.b);
+
+  mpi_mod (e, input, pkey->E.n); /* e = hash mod n */
+  if (!mpi_cmp_ui (e, 0))
+    mpi_set_ui (e, 1);
+  mpi_invm (v, e, pkey->E.n); /* v = e^(-1) (mod n) */
+  mpi_mulm (z1, s, v, pkey->E.n); /* z1 = s*v (mod n) */
+  mpi_mulm (rv, r, v, pkey->E.n); /* rv = s*v (mod n) */
+  mpi_subm (z2, zero, rv, pkey->E.n); /* z2 = -r*v (mod n) */
+
+  _gcry_mpi_ec_mul_point (&Q1, z1, &pkey->E.G, ctx);
+/*   log_mpidump ("Q1.x", Q1.x); */
+/*   log_mpidump ("Q1.y", Q1.y); */
+/*   log_mpidump ("Q1.z", Q1.z); */
+  _gcry_mpi_ec_mul_point (&Q2, z2, &pkey->Q, ctx);
+/*   log_mpidump ("Q2.x", Q2.x); */
+/*   log_mpidump ("Q2.y", Q2.y); */
+/*   log_mpidump ("Q2.z", Q2.z); */
+  _gcry_mpi_ec_add_points (&Q, &Q1, &Q2, ctx);
+/*   log_mpidump (" Q.x", Q.x); */
+/*   log_mpidump (" Q.y", Q.y); */
+/*   log_mpidump (" Q.z", Q.z); */
+
+  if (!mpi_cmp_ui (Q.z, 0))
+    {
+      if (DBG_CIPHER)
+          log_debug ("ecc verify: Rejected\n");
+      err = GPG_ERR_BAD_SIGNATURE;
+      goto leave;
+    }
+  if (_gcry_mpi_ec_get_affine (x, NULL, &Q, ctx))
+    {
+      if (DBG_CIPHER)
+        log_debug ("ecc verify: Failed to get affine coordinates\n");
+      err = GPG_ERR_BAD_SIGNATURE;
+      goto leave;
+    }
+  mpi_mod (x, x, pkey->E.n); /* x = x mod E_n */
+  if (mpi_cmp (x, r))   /* x != r */
+    {
+      if (DBG_CIPHER)
+        {
+          log_mpidump ("     x", x);
+          log_mpidump ("     r", r);
+          log_mpidump ("     s", s);
+          log_debug ("ecc verify: Not verified\n");
+        }
+      err = GPG_ERR_BAD_SIGNATURE;
+      goto leave;
+    }
+  if (DBG_CIPHER)
+    log_debug ("ecc verify: Accepted\n");
+
+ leave:
+  _gcry_mpi_ec_free (ctx);
+  point_free (&Q2);
+  point_free (&Q1);
+  point_free (&Q);
+  mpi_free (zero);
+  mpi_free (rv);
+  mpi_free (v);
+  mpi_free (z2);
+  mpi_free (z1);
+  mpi_free (x);
+  mpi_free (e);
+  return err;
+}
diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c
new file mode 100644 (file)
index 0000000..7b750c0
--- /dev/null
@@ -0,0 +1,287 @@
+/* ecc-misc.c  -  Elliptic Curve miscellaneous functions
+ * Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 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/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "context.h"
+#include "ec-context.h"
+#include "ecc-common.h"
+
+
+/*
+ * Release a curve object.
+ */
+void
+_gcry_ecc_curve_free (elliptic_curve_t *E)
+{
+  mpi_free (E->p); E->p = NULL;
+  mpi_free (E->a); E->a = NULL;
+  mpi_free (E->b);  E->b = NULL;
+  _gcry_mpi_point_free_parts (&E->G);
+  mpi_free (E->n);  E->n = NULL;
+}
+
+
+/*
+ * Return a copy of a curve object.
+ */
+elliptic_curve_t
+_gcry_ecc_curve_copy (elliptic_curve_t E)
+{
+  elliptic_curve_t R;
+
+  R.model = E.model;
+  R.dialect = E.dialect;
+  R.name = E.name;
+  R.p = mpi_copy (E.p);
+  R.a = mpi_copy (E.a);
+  R.b = mpi_copy (E.b);
+  _gcry_mpi_point_init (&R.G);
+  point_set (&R.G, &E.G);
+  R.n = mpi_copy (E.n);
+
+  return R;
+}
+
+
+/*
+ * Return a description of the curve model.
+ */
+const char *
+_gcry_ecc_model2str (enum gcry_mpi_ec_models model)
+{
+  const char *str = "?";
+  switch (model)
+    {
+    case MPI_EC_WEIERSTRASS:    str = "Weierstrass"; break;
+    case MPI_EC_MONTGOMERY:     str = "Montgomery";  break;
+    case MPI_EC_TWISTEDEDWARDS: str = "Twisted Edwards"; break;
+    }
+  return str;
+}
+
+
+/*
+ * Return a description of the curve dialect.
+ */
+const char *
+_gcry_ecc_dialect2str (enum ecc_dialects dialect)
+{
+  const char *str = "?";
+  switch (dialect)
+    {
+    case ECC_DIALECT_STANDARD:  str = "Standard"; break;
+    case ECC_DIALECT_ED25519:   str = "Ed25519"; break;
+    }
+  return str;
+}
+
+
+gcry_mpi_t
+_gcry_ecc_ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p)
+{
+  gpg_err_code_t rc;
+  int pbytes = (mpi_get_nbits (p)+7)/8;
+  size_t n;
+  unsigned char *buf, *ptr;
+  gcry_mpi_t result;
+
+  buf = xmalloc ( 1 + 2*pbytes );
+  *buf = 04; /* Uncompressed point.  */
+  ptr = buf+1;
+  rc = _gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, x);
+  if (rc)
+    log_fatal ("mpi_print failed: %s\n", gpg_strerror (rc));
+  if (n < pbytes)
+    {
+      memmove (ptr+(pbytes-n), ptr, n);
+      memset (ptr, 0, (pbytes-n));
+    }
+  ptr += pbytes;
+  rc = _gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, y);
+  if (rc)
+    log_fatal ("mpi_print failed: %s\n", gpg_strerror (rc));
+  if (n < pbytes)
+    {
+      memmove (ptr+(pbytes-n), ptr, n);
+      memset (ptr, 0, (pbytes-n));
+    }
+
+  rc = _gcry_mpi_scan (&result, GCRYMPI_FMT_USG, buf, 1+2*pbytes, NULL);
+  if (rc)
+    log_fatal ("mpi_scan failed: %s\n", gpg_strerror (rc));
+  xfree (buf);
+
+  return result;
+}
+
+
+/* Convert POINT into affine coordinates using the context CTX and
+   return a newly allocated MPI.  If the conversion is not possible
+   NULL is returned.  This function won't print an error message.  */
+gcry_mpi_t
+_gcry_mpi_ec_ec2os (gcry_mpi_point_t point, mpi_ec_t ectx)
+{
+  gcry_mpi_t g_x, g_y, result;
+
+  g_x = mpi_new (0);
+  g_y = mpi_new (0);
+  if (_gcry_mpi_ec_get_affine (g_x, g_y, point, ectx))
+    result = NULL;
+  else
+    result = _gcry_ecc_ec2os (g_x, g_y, ectx->p);
+  mpi_free (g_x);
+  mpi_free (g_y);
+
+  return result;
+}
+
+
+/* RESULT must have been initialized and is set on success to the
+   point given by VALUE.  */
+gcry_err_code_t
+_gcry_ecc_os2ec (mpi_point_t result, gcry_mpi_t value)
+{
+  gcry_err_code_t rc;
+  size_t n;
+  const unsigned char *buf;
+  unsigned char *buf_memory;
+  gcry_mpi_t x, y;
+
+  if (mpi_is_opaque (value))
+    {
+      unsigned int nbits;
+
+      buf = mpi_get_opaque (value, &nbits);
+      if (!buf)
+        return GPG_ERR_INV_OBJ;
+      n = (nbits + 7)/8;
+      buf_memory = NULL;
+    }
+  else
+    {
+      n = (mpi_get_nbits (value)+7)/8;
+      buf_memory = xmalloc (n);
+      rc = _gcry_mpi_print (GCRYMPI_FMT_USG, buf_memory, n, &n, value);
+      if (rc)
+        {
+          xfree (buf_memory);
+          return rc;
+        }
+      buf = buf_memory;
+    }
+
+  if (n < 1)
+    {
+      xfree (buf_memory);
+      return GPG_ERR_INV_OBJ;
+    }
+  if (*buf != 4)
+    {
+      xfree (buf_memory);
+      return GPG_ERR_NOT_IMPLEMENTED; /* No support for point compression.  */
+    }
+  if ( ((n-1)%2) )
+    {
+      xfree (buf_memory);
+      return GPG_ERR_INV_OBJ;
+    }
+  n = (n-1)/2;
+  rc = _gcry_mpi_scan (&x, GCRYMPI_FMT_USG, buf+1, n, NULL);
+  if (rc)
+    {
+      xfree (buf_memory);
+      return rc;
+    }
+  rc = _gcry_mpi_scan (&y, GCRYMPI_FMT_USG, buf+1+n, n, NULL);
+  xfree (buf_memory);
+  if (rc)
+    {
+      mpi_free (x);
+      return rc;
+    }
+
+  mpi_set (result->x, x);
+  mpi_set (result->y, y);
+  mpi_set_ui (result->z, 1);
+
+  mpi_free (x);
+  mpi_free (y);
+
+  return 0;
+}
+
+
+/* Compute the public key from the the context EC.  Obviously a
+   requirement is that the secret key is available in EC.  On success
+   Q is returned; on error NULL.  If Q is NULL a newly allocated point
+   is returned.  If G or D are given they override the values taken
+   from EC. */
+mpi_point_t
+_gcry_ecc_compute_public (mpi_point_t Q, mpi_ec_t ec,
+                          mpi_point_t G, gcry_mpi_t d)
+{
+  if (!G)
+    G = ec->G;
+  if (!d)
+    d = ec->d;
+
+  if (!d || !G || !ec->p || !ec->a)
+    return NULL;
+  if (ec->model == MPI_EC_TWISTEDEDWARDS && !ec->b)
+    return NULL;
+
+  if (ec->dialect == ECC_DIALECT_ED25519
+      && (ec->flags & PUBKEY_FLAG_EDDSA))
+    {
+      gcry_mpi_t a;
+      unsigned char *digest;
+
+      if (_gcry_ecc_eddsa_compute_h_d (&digest, d, ec))
+        return NULL;
+
+      a = mpi_snew (0);
+      _gcry_mpi_set_buffer (a, digest, 32, 0);
+      xfree (digest);
+
+      /* And finally the public key.  */
+      if (!Q)
+        Q = mpi_point_new (0);
+      if (Q)
+        _gcry_mpi_ec_mul_point (Q, a, G, ec);
+      mpi_free (a);
+    }
+  else
+    {
+      if (!Q)
+        Q = mpi_point_new (0);
+      if (Q)
+        _gcry_mpi_ec_mul_point (Q, d, G, ec);
+    }
+
+  return Q;
+}
index bbff7ee..debb71b 100644 (file)
@@ -1,22 +1,22 @@
 /* ecc.c  -  Elliptic Curve Cryptography
  Copyright (C) 2007, 2008, 2010, 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, write to the Free Software
-   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
  USA.  */
* Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 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/>.
+ */
 
 /* This code is originally based on the Patch 0.1.6 for the gnupg
    1.4.x branch as retrieved on 2007-03-21 from
@@ -47,7 +47,6 @@
   - In mpi/ec.c we use mpi_powm for x^2 mod p: Either implement a
     special case in mpi_powm or check whether mpi_mulm is faster.
 
-  - Decide whether we should hide the mpi_point_t definition.
 */
 
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
 
 #include "g10lib.h"
 #include "mpi.h"
 #include "cipher.h"
-
-/* Definition of a curve.  */
-typedef struct
-{
-  gcry_mpi_t p;   /* Prime specifying the field GF(p).  */
-  gcry_mpi_t a;   /* First coefficient of the Weierstrass equation.  */
-  gcry_mpi_t b;   /* Second coefficient of the Weierstrass equation.  */
-  mpi_point_t G;  /* Base point (generator).  */
-  gcry_mpi_t n;   /* Order of G.  */
-  const char *name;  /* Name of curve or NULL.  */
-} elliptic_curve_t;
+#include "context.h"
+#include "ec-context.h"
+#include "pubkey-internal.h"
+#include "ecc-common.h"
 
 
-typedef struct
-{
-  elliptic_curve_t E;
-  mpi_point_t Q;  /* Q = [d]G  */
-} ECC_public_key;
-
-typedef struct
-{
-  elliptic_curve_t E;
-  mpi_point_t Q;
-  gcry_mpi_t d;
-} ECC_secret_key;
-
-
-/* This tables defines aliases for curve names.  */
-static const struct
-{
-  const char *name;  /* Our name.  */
-  const char *other; /* Other name. */
-} curve_aliases[] =
+static const char *ecc_names[] =
   {
-    { "NIST P-192", "1.2.840.10045.3.1.1" }, /* X9.62 OID  */
-    { "NIST P-192", "prime192v1" },          /* X9.62 name.  */
-    { "NIST P-192", "secp192r1"  },          /* SECP name.  */
-
-    { "NIST P-224", "secp224r1" },
-    { "NIST P-224", "1.3.132.0.33" },        /* SECP OID.  */
-
-    { "NIST P-256", "1.2.840.10045.3.1.7" }, /* From NIST SP 800-78-1.  */
-    { "NIST P-256", "prime256v1" },
-    { "NIST P-256", "secp256r1"  },
-
-    { "NIST P-384", "secp384r1" },
-    { "NIST P-384", "1.3.132.0.34" },
-
-    { "NIST P-521", "secp521r1" },
-    { "NIST P-521", "1.3.132.0.35" },
-
-    { "brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1" },
-    { "brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3" },
-    { "brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5" },
-    { "brainpoolP256r1", "1.3.36.3.3.2.8.1.1.7" },
-    { "brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9" },
-    { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11"},
-    { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13"},
-
-    { NULL, NULL}
-  };
-
-typedef struct   {
-  const char *desc;           /* Description of the curve.  */
-  unsigned int nbits;         /* Number of bits.  */
-  unsigned int fips:1;        /* True if this is a FIPS140-2 approved curve. */
-  const char  *p;             /* Order of the prime field.  */
-  const char *a, *b;          /* The coefficients. */
-  const char *n;              /* The order of the base point.  */
-  const char *g_x, *g_y;      /* Base point.  */
-} ecc_domain_parms_t;
-
-/* This static table defines all available curves.  */
-static const ecc_domain_parms_t domain_parms[] =
-  {
-    {
-      "NIST P-192", 192, 1,
-      "0xfffffffffffffffffffffffffffffffeffffffffffffffff",
-      "0xfffffffffffffffffffffffffffffffefffffffffffffffc",
-      "0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
-      "0xffffffffffffffffffffffff99def836146bc9b1b4d22831",
-
-      "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
-      "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811"
-    },
-    {
-      "NIST P-224", 224, 1,
-      "0xffffffffffffffffffffffffffffffff000000000000000000000001",
-      "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe",
-      "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
-      "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" ,
-
-      "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
-      "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34"
-    },
-    {
-      "NIST P-256", 256, 1,
-      "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
-      "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
-      "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
-      "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
-
-      "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
-      "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
-    },
-    {
-      "NIST P-384", 384, 1,
-      "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
-      "ffffffff0000000000000000ffffffff",
-      "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
-      "ffffffff0000000000000000fffffffc",
-      "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a"
-      "c656398d8a2ed19d2a85c8edd3ec2aef",
-      "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf"
-      "581a0db248b0a77aecec196accc52973",
-
-      "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38"
-      "5502f25dbf55296c3a545e3872760ab7",
-      "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0"
-      "0a60b1ce1d7e819d7a431d7c90ea0e5f"
-    },
-    {
-      "NIST P-521", 521, 1,
-      "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-      "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
-      "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-      "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
-      "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10"
-      "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
-      "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
-      "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
-
-      "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d"
-      "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
-      "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6"
-      "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650"
-    },
-
-    { "brainpoolP160r1", 160, 0,
-      "0xe95e4a5f737059dc60dfc7ad95b3d8139515620f",
-      "0x340e7be2a280eb74e2be61bada745d97e8f7c300",
-      "0x1e589a8595423412134faa2dbdec95c8d8675e58",
-      "0xe95e4a5f737059dc60df5991d45029409e60fc09",
-      "0xbed5af16ea3f6a4f62938c4631eb5af7bdbcdbc3",
-      "0x1667cb477a1a8ec338f94741669c976316da6321"
-    },
-
-    { "brainpoolP192r1", 192, 0,
-      "0xc302f41d932a36cda7a3463093d18db78fce476de1a86297",
-      "0x6a91174076b1e0e19c39c031fe8685c1cae040e5c69a28ef",
-      "0x469a28ef7c28cca3dc721d044f4496bcca7ef4146fbf25c9",
-      "0xc302f41d932a36cda7a3462f9e9e916b5be8f1029ac4acc1",
-      "0xc0a0647eaab6a48753b033c56cb0f0900a2f5c4853375fd6",
-      "0x14b690866abd5bb88b5f4828c1490002e6773fa2fa299b8f"
-    },
-
-    { "brainpoolP224r1", 224, 0,
-      "0xd7c134aa264366862a18302575d1d787b09f075797da89f57ec8c0ff",
-      "0x68a5e62ca9ce6c1c299803a6c1530b514e182ad8b0042a59cad29f43",
-      "0x2580f63ccfe44138870713b1a92369e33e2135d266dbb372386c400b",
-      "0xd7c134aa264366862a18302575d0fb98d116bc4b6ddebca3a5a7939f",
-      "0x0d9029ad2c7e5cf4340823b2a87dc68c9e4ce3174c1e6efdee12c07d",
-      "0x58aa56f772c0726f24c6b89e4ecdac24354b9e99caa3f6d3761402cd"
-    },
-
-    { "brainpoolP256r1", 256, 0,
-      "0xa9fb57dba1eea9bc3e660a909d838d726e3bf623d52620282013481d1f6e5377",
-      "0x7d5a0975fc2c3057eef67530417affe7fb8055c126dc5c6ce94a4b44f330b5d9",
-      "0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6",
-      "0xa9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7",
-      "0x8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262",
-      "0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997"
-    },
-
-    { "brainpoolP320r1", 320, 0,
-      "0xd35e472036bc4fb7e13c785ed201e065f98fcfa6f6f40def4f92b9ec7893ec28"
-      "fcd412b1f1b32e27",
-      "0x3ee30b568fbab0f883ccebd46d3f3bb8a2a73513f5eb79da66190eb085ffa9f4"
-      "92f375a97d860eb4",
-      "0x520883949dfdbc42d3ad198640688a6fe13f41349554b49acc31dccd88453981"
-      "6f5eb4ac8fb1f1a6",
-      "0xd35e472036bc4fb7e13c785ed201e065f98fcfa5b68f12a32d482ec7ee8658e9"
-      "8691555b44c59311",
-      "0x43bd7e9afb53d8b85289bcc48ee5bfe6f20137d10a087eb6e7871e2a10a599c7"
-      "10af8d0d39e20611",
-      "0x14fdd05545ec1cc8ab4093247f77275e0743ffed117182eaa9c77877aaac6ac7"
-      "d35245d1692e8ee1"
-    },
-
-    { "brainpoolP384r1", 384, 0,
-      "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b412b1da197fb71123"
-      "acd3a729901d1a71874700133107ec53",
-      "0x7bc382c63d8c150c3c72080ace05afa0c2bea28e4fb22787139165efba91f90f"
-      "8aa5814a503ad4eb04a8c7dd22ce2826",
-      "0x04a8c7dd22ce28268b39b55416f0447c2fb77de107dcd2a62e880ea53eeb62d5"
-      "7cb4390295dbc9943ab78696fa504c11",
-      "0x8cb91e82a3386d280f5d6f7e50e641df152f7109ed5456b31f166e6cac0425a7"
-      "cf3ab6af6b7fc3103b883202e9046565",
-      "0x1d1c64f068cf45ffa2a63a81b7c13f6b8847a3e77ef14fe3db7fcafe0cbd10e8"
-      "e826e03436d646aaef87b2e247d4af1e",
-      "0x8abe1d7520f9c2a45cb1eb8e95cfd55262b70b29feec5864e19c054ff9912928"
-      "0e4646217791811142820341263c5315"
-    },
-
-    { "brainpoolP512r1", 512, 0,
-      "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330871"
-      "7d4d9b009bc66842aecda12ae6a380e62881ff2f2d82c68528aa6056583a48f3",
-      "0x7830a3318b603b89e2327145ac234cc594cbdd8d3df91610a83441caea9863bc"
-      "2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a72bf2c7b9e7c1ac4d77fc94ca",
-      "0x3df91610a83441caea9863bc2ded5d5aa8253aa10a2ef1c98b9ac8b57f1117a7"
-      "2bf2c7b9e7c1ac4d77fc94cadc083e67984050b75ebae5dd2809bd638016f723",
-      "0xaadd9db8dbe9c48b3fd4e6ae33c9fc07cb308db3b3c9d20ed6639cca70330870"
-      "553e5c414ca92619418661197fac10471db1d381085ddaddb58796829ca90069",
-      "0x81aee4bdd82ed9645a21322e9c4c6a9385ed9f70b5d916c1b43b62eef4d0098e"
-      "ff3b1f78e2d0d48d50d1687b93b97d5f7c6d5047406a5e688b352209bcb9f822",
-      "0x7dde385d566332ecc0eabfa9cf7822fdf209f70024a57b1aa000c55b881f8111"
-      "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892"
-    },
-
-    { NULL, 0, 0, NULL, NULL, NULL, NULL }
+    "ecc",
+    "ecdsa",
+    "ecdh",
+    "eddsa",
+    "gost",
+    NULL,
   };
 
 
@@ -287,22 +81,10 @@ static void (*progress_cb) (void *, const char*, int, int, int);
 static void *progress_cb_data;
 
 
-#define point_init(a)  _gcry_mpi_ec_point_init ((a))
-#define point_free(a)  _gcry_mpi_ec_point_free ((a))
-
-
 \f
 /* Local prototypes. */
-static gcry_mpi_t gen_k (gcry_mpi_t p, int security_level);
 static void test_keys (ECC_secret_key * sk, unsigned int nbits);
-static int check_secret_key (ECC_secret_key * sk);
-static gpg_err_code_t sign (gcry_mpi_t input, ECC_secret_key *skey,
-                            gcry_mpi_t r, gcry_mpi_t s);
-static gpg_err_code_t verify (gcry_mpi_t input, ECC_public_key *pkey,
-                              gcry_mpi_t r, gcry_mpi_t s);
-
-
-static gcry_mpi_t gen_y_2 (gcry_mpi_t x, elliptic_curve_t * base);
+static unsigned int ecc_get_nbits (gcry_sexp_t parms);
 
 
 
@@ -325,258 +107,109 @@ _gcry_register_pk_ecc_progress (void (*cb) (void *, const char *,
 
 
 \f
-
-/* Set the value from S into D.  */
-static void
-point_set (mpi_point_t *d, mpi_point_t *s)
-{
-  mpi_set (d->x, s->x);
-  mpi_set (d->y, s->y);
-  mpi_set (d->z, s->z);
-}
-
-
-/*
- * Release a curve object.
- */
-static void
-curve_free (elliptic_curve_t *E)
-{
-  mpi_free (E->p); E->p = NULL;
-  mpi_free (E->a); E->a = NULL;
-  mpi_free (E->b);  E->b = NULL;
-  point_free (&E->G);
-  mpi_free (E->n);  E->n = NULL;
-}
-
-
-/*
- * Return a copy of a curve object.
- */
-static elliptic_curve_t
-curve_copy (elliptic_curve_t E)
-{
-  elliptic_curve_t R;
-
-  R.p = mpi_copy (E.p);
-  R.a = mpi_copy (E.a);
-  R.b = mpi_copy (E.b);
-  point_init (&R.G);
-  point_set (&R.G, &E.G);
-  R.n = mpi_copy (E.n);
-
-  return R;
-}
-
-
-/* Helper to scan a hex string. */
-static gcry_mpi_t
-scanval (const char *string)
-{
-  gpg_error_t err;
-  gcry_mpi_t val;
-
-  err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
-  if (err)
-    log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (err));
-  return val;
-}
-
-
-
-\f
-
-/****************
- * Solve the right side of the equation that defines a curve.
- */
-static gcry_mpi_t
-gen_y_2 (gcry_mpi_t x, elliptic_curve_t *base)
-{
-  gcry_mpi_t three, x_3, axb, y;
-
-  three = mpi_alloc_set_ui (3);
-  x_3 = mpi_new (0);
-  axb = mpi_new (0);
-  y   = mpi_new (0);
-
-  mpi_powm (x_3, x, three, base->p);
-  mpi_mulm (axb, base->a, x, base->p);
-  mpi_addm (axb, axb, base->b, base->p);
-  mpi_addm (y, x_3, axb, base->p);
-
-  mpi_free (x_3);
-  mpi_free (axb);
-  mpi_free (three);
-  return y; /* The quadratic value of the coordinate if it exist. */
-}
-
-
-/* Generate a random secret scalar k with an order of p
-
-   At the beginning this was identical to the code is in elgamal.c.
-   Later imporved by mmr.   Further simplified by wk.  */
-static gcry_mpi_t
-gen_k (gcry_mpi_t p, int security_level)
+/* Standard version of the key generation.  */
+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)
 {
-  gcry_mpi_t k;
-  unsigned int nbits;
+  mpi_point_struct Q;
 
-  nbits = mpi_get_nbits (p);
-  k = mpi_snew (nbits);
-  if (DBG_CIPHER)
-    log_debug ("choosing a random k of %u bits at seclevel %d\n",
-               nbits, security_level);
+  point_init (&Q);
 
-  gcry_mpi_randomize (k, nbits, security_level);
+  /* Generate a secret.  */
+  if (ctx->dialect == ECC_DIALECT_ED25519)
+    {
+      char *rndbuf;
+
+      sk->d = mpi_snew (256);
+      rndbuf = _gcry_random_bytes_secure (32, random_level);
+      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 (sk->d, rndbuf, 32, 0);
+      xfree (rndbuf);
+    }
+  else
+    sk->d = _gcry_dsa_gen_k (E->n, random_level);
 
-  mpi_mod (k, k, p);  /*  k = k mod p  */
 
-  return k;
-}
+  /* Compute Q.  */
+  _gcry_mpi_ec_mul_point (&Q, sk->d, &E->G, ctx);
 
+  /* Copy the stuff to the key structures. */
+  sk->E.model = E->model;
+  sk->E.dialect = E->dialect;
+  sk->E.p = mpi_copy (E->p);
+  sk->E.a = mpi_copy (E->a);
+  sk->E.b = mpi_copy (E->b);
+  point_init (&sk->E.G);
+  point_set (&sk->E.G, &E->G);
+  sk->E.n = mpi_copy (E->n);
+  point_init (&sk->Q);
 
-/* Generate the crypto system setup.  This function takes the NAME of
-   a curve or the desired number of bits and stores at R_CURVE the
-   parameters of the named curve or those of a suitable curve.  The
-   chosen number of bits is stored on R_NBITS.  */
-static gpg_err_code_t
-fill_in_curve (unsigned int nbits, const char *name,
-               elliptic_curve_t *curve, unsigned int *r_nbits)
-{
-  int idx, aliasno;
-  const char *resname = NULL; /* Set to a found curve name.  */
-
-  if (name)
-    {
-      /* First check our native curves.  */
-      for (idx = 0; domain_parms[idx].desc; idx++)
-        if (!strcmp (name, domain_parms[idx].desc))
-          {
-            resname = domain_parms[idx].desc;
-            break;
-          }
-      /* If not found consult the alias table.  */
-      if (!domain_parms[idx].desc)
-        {
-          for (aliasno = 0; curve_aliases[aliasno].name; aliasno++)
-            if (!strcmp (name, curve_aliases[aliasno].other))
-              break;
-          if (curve_aliases[aliasno].name)
-            {
-              for (idx = 0; domain_parms[idx].desc; idx++)
-                if (!strcmp (curve_aliases[aliasno].name,
-                             domain_parms[idx].desc))
-                  {
-                    resname = domain_parms[idx].desc;
-                    break;
-                  }
-            }
-        }
-    }
+  /* 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
+   * end up with the min(y,p-y) as the y coordinate.  Such a public
+   * key allows the most efficient compression: y can simply be
+   * dropped because we know that it's a minimum of the two
+   * 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)
+    point_set (&sk->Q, &Q);
   else
     {
-      for (idx = 0; domain_parms[idx].desc; idx++)
-        if (nbits == domain_parms[idx].nbits)
-          break;
-    }
-  if (!domain_parms[idx].desc)
-    return GPG_ERR_INV_VALUE;
-
-  /* In fips mode we only support NIST curves.  Note that it is
-     possible to bypass this check by specifying the curve parameters
-     directly.  */
-  if (fips_mode () && !domain_parms[idx].fips )
-    return GPG_ERR_NOT_SUPPORTED;
-
-  *r_nbits = domain_parms[idx].nbits;
-  curve->p = scanval (domain_parms[idx].p);
-  curve->a = scanval (domain_parms[idx].a);
-  curve->b = scanval (domain_parms[idx].b);
-  curve->n = scanval (domain_parms[idx].n);
-  curve->G.x = scanval (domain_parms[idx].g_x);
-  curve->G.y = scanval (domain_parms[idx].g_y);
-  curve->G.z = mpi_alloc_set_ui (1);
-  curve->name = resname;
+      gcry_mpi_t x, y, negative;
+      const unsigned int pbits = mpi_get_nbits (E->p);
 
-  return 0;
-}
+      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");
 
-/*
- * First obtain the setup.  Over the finite field randomize an scalar
- * secret value, and calculate the public point.
- */
-static gpg_err_code_t
-generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
-              int transient_key,
-              gcry_mpi_t g_x, gcry_mpi_t g_y,
-              gcry_mpi_t q_x, gcry_mpi_t q_y,
-              const char **r_usedcurve)
-{
-  gpg_err_code_t err;
-  elliptic_curve_t E;
-  gcry_mpi_t d;
-  mpi_point_t Q;
-  mpi_ec_t ctx;
-  gcry_random_level_t random_level;
-
-  *r_usedcurve = NULL;
-
-  err = fill_in_curve (nbits, name, &E, &nbits);
-  if (err)
-    return err;
+      if (E->model == MPI_EC_WEIERSTRASS)
+        mpi_sub (negative, E->p, y);      /* negative = p - y */
+      else
+        mpi_sub (negative, E->p, x);      /* negative = p - x */
 
-  if (DBG_CIPHER)
-    {
-      log_mpidump ("ecgen curve  p", E.p);
-      log_mpidump ("ecgen curve  a", E.a);
-      log_mpidump ("ecgen curve  b", E.b);
-      log_mpidump ("ecgen curve  n", E.n);
-      log_mpidump ("ecgen curve Gx", E.G.x);
-      log_mpidump ("ecgen curve Gy", E.G.y);
-      log_mpidump ("ecgen curve Gz", E.G.z);
-      if (E.name)
-        log_debug   ("ecgen curve used: %s\n", E.name);
-    }
-
-  random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
-  d = gen_k (E.n, random_level);
+      if (mpi_cmp (negative, y) < 0)   /* p - y < p */
+        {
+          /* 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));
+          else
+            mpi_point_snatch_set (&sk->Q, negative, y, mpi_alloc_set_ui (1));
 
-  /* Compute Q.  */
-  point_init (&Q);
-  ctx = _gcry_mpi_ec_init (E.p, E.a);
-  _gcry_mpi_ec_mul_point (&Q, d, &E.G, ctx);
+          if (DBG_CIPHER)
+            log_debug ("ecgen converted Q to a compliant point\n");
+        }
+      else /* p - y >= p */
+        {
+          /* No change is needed exactly 50% of the time: just copy. */
+          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);
+        }
 
-  /* Copy the stuff to the key structures. */
-  sk->E.p = mpi_copy (E.p);
-  sk->E.a = mpi_copy (E.a);
-  sk->E.b = mpi_copy (E.b);
-  point_init (&sk->E.G);
-  point_set (&sk->E.G, &E.G);
-  sk->E.n = mpi_copy (E.n);
-  point_init (&sk->Q);
-  point_set (&sk->Q, &Q);
-  sk->d    = mpi_copy (d);
-  /* We also return copies of G and Q in affine coordinates if
-     requested.  */
-  if (g_x && g_y)
-    {
-      if (_gcry_mpi_ec_get_affine (g_x, g_y, &sk->E.G, ctx))
-        log_fatal ("ecgen: Failed to get affine coordinates\n");
+      if (E->model == MPI_EC_WEIERSTRASS)
+        mpi_free (y);
+      else
+        mpi_free (x);
     }
-  if (q_x && q_y)
-    {
-      if (_gcry_mpi_ec_get_affine (q_x, q_y, &sk->Q, ctx))
-        log_fatal ("ecgen: Failed to get affine coordinates\n");
-    }
-  _gcry_mpi_ec_free (ctx);
 
   point_free (&Q);
-  mpi_free (d);
-
-  *r_usedcurve = E.name;
-  curve_free (&E);
-
   /* Now we can test our keys (this should never fail!).  */
   test_keys (sk, nbits - 64);
 
@@ -595,7 +228,7 @@ test_keys (ECC_secret_key *sk, unsigned int nbits)
 {
   ECC_public_key pk;
   gcry_mpi_t test = mpi_new (nbits);
-  mpi_point_t R_;
+  mpi_point_struct R_;
   gcry_mpi_t c = mpi_new (nbits);
   gcry_mpi_t out = mpi_new (nbits);
   gcry_mpi_t r = mpi_new (nbits);
@@ -606,16 +239,16 @@ test_keys (ECC_secret_key *sk, unsigned int nbits)
 
   point_init (&R_);
 
-  pk.E = curve_copy (sk->E);
+  pk.E = _gcry_ecc_curve_copy (sk->E);
   point_init (&pk.Q);
   point_set (&pk.Q, &sk->Q);
 
-  gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
+  _gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM);
 
-  if (sign (test, sk, r, s) )
+  if (_gcry_ecc_ecdsa_sign (test, sk, r, s, 0, 0) )
     log_fatal ("ECDSA operation: sign failed\n");
 
-  if (verify (test, &pk, r, s))
+  if (_gcry_ecc_ecdsa_verify (test, &pk, r, s))
     {
       log_fatal ("ECDSA operation: sign, verify failed\n");
     }
@@ -624,7 +257,7 @@ test_keys (ECC_secret_key *sk, unsigned int nbits)
     log_debug ("ECDSA operation: sign, verify ok.\n");
 
   point_free (&pk.Q);
-  curve_free (&pk.E);
+  _gcry_ecc_curve_free (&pk.E);
 
   point_free (&R_);
   mpi_free (s);
@@ -640,232 +273,109 @@ test_keys (ECC_secret_key *sk, unsigned int nbits)
  * between the public value and the secret one.
  */
 static int
-check_secret_key (ECC_secret_key * sk)
+check_secret_key (ECC_secret_key *sk, mpi_ec_t ec, int flags)
 {
-  mpi_point_t Q;
-  gcry_mpi_t y_2, y2 = mpi_alloc (0);
-  mpi_ec_t ctx;
+  int rc = 1;
+  mpi_point_struct Q;
+  gcry_mpi_t x1, y1;
+  gcry_mpi_t x2 = NULL;
+  gcry_mpi_t y2 = NULL;
+
+  point_init (&Q);
+  x1 = mpi_new (0);
+  y1 = mpi_new (0);
 
-  /* ?primarity test of 'p' */
-  /*  (...) //!! */
   /* G in E(F_p) */
-  y_2 = gen_y_2 (sk->E.G.x, &sk->E);   /*  y^2=x^3+a*x+b */
-  mpi_mulm (y2, sk->E.G.y, sk->E.G.y, sk->E.p);      /*  y^2=y*y */
-  if (mpi_cmp (y_2, y2))
+  if (!_gcry_mpi_ec_curve_point (&sk->E.G, ec))
     {
       if (DBG_CIPHER)
         log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n");
-      return (1);
+      goto leave;
     }
+
   /* G != PaI */
   if (!mpi_cmp_ui (sk->E.G.z, 0))
     {
       if (DBG_CIPHER)
         log_debug ("Bad check: 'G' cannot be Point at Infinity!\n");
-      return (1);
+      goto leave;
     }
 
-  point_init (&Q);
-  ctx = _gcry_mpi_ec_init (sk->E.p, sk->E.a);
-  _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx);
-  if (mpi_cmp_ui (Q.z, 0))
+  /* Check order of curve.  */
+  if (sk->E.dialect != ECC_DIALECT_ED25519)
     {
-      if (DBG_CIPHER)
-        log_debug ("check_secret_key: E is not a curve of order n\n");
-      point_free (&Q);
-      _gcry_mpi_ec_free (ctx);
-      return 1;
+      _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ec);
+      if (mpi_cmp_ui (Q.z, 0))
+        {
+          if (DBG_CIPHER)
+            log_debug ("check_secret_key: E is not a curve of order n\n");
+          goto leave;
+        }
     }
-  /* pubkey cannot be PaI */
+
+  /* Pubkey cannot be PaI */
   if (!mpi_cmp_ui (sk->Q.z, 0))
     {
       if (DBG_CIPHER)
         log_debug ("Bad check: Q can not be a Point at Infinity!\n");
-      _gcry_mpi_ec_free (ctx);
-      return (1);
+      goto leave;
     }
+
   /* pubkey = [d]G over E */
-  _gcry_mpi_ec_mul_point (&Q, sk->d, &sk->E.G, ctx);
-  if ((Q.x == sk->Q.x) && (Q.y == sk->Q.y) && (Q.z == sk->Q.z))
+  if (!_gcry_ecc_compute_public (&Q, ec, &sk->E.G, sk->d))
     {
       if (DBG_CIPHER)
-        log_debug
-          ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
-      _gcry_mpi_ec_free (ctx);
-      return (1);
-    }
-  _gcry_mpi_ec_free (ctx);
-  point_free (&Q);
-  return 0;
-}
-
-
-/*
- * Return the signature struct (r,s) from the message hash.  The caller
- * must have allocated R and S.
- */
-static gpg_err_code_t
-sign (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s)
-{
-  gpg_err_code_t err = 0;
-  gcry_mpi_t k, dr, sum, k_1, x;
-  mpi_point_t I;
-  mpi_ec_t ctx;
-
-  if (DBG_CIPHER)
-    log_mpidump ("ecdsa sign hash  ", input );
-
-  k = NULL;
-  dr = mpi_alloc (0);
-  sum = mpi_alloc (0);
-  k_1 = mpi_alloc (0);
-  x = mpi_alloc (0);
-  point_init (&I);
-
-  mpi_set_ui (s, 0);
-  mpi_set_ui (r, 0);
-
-  ctx = _gcry_mpi_ec_init (skey->E.p, skey->E.a);
-
-  while (!mpi_cmp_ui (s, 0)) /* s == 0 */
-    {
-      while (!mpi_cmp_ui (r, 0)) /* r == 0 */
-        {
-          /* Note, that we are guaranteed to enter this loop at least
-             once because r has been intialized to 0.  We can't use a
-             do_while because we want to keep the value of R even if S
-             has to be recomputed.  */
-          mpi_free (k);
-          k = gen_k (skey->E.n, GCRY_STRONG_RANDOM);
-          _gcry_mpi_ec_mul_point (&I, k, &skey->E.G, ctx);
-          if (_gcry_mpi_ec_get_affine (x, NULL, &I, ctx))
-            {
-              if (DBG_CIPHER)
-                log_debug ("ecc sign: Failed to get affine coordinates\n");
-              err = GPG_ERR_BAD_SIGNATURE;
-              goto leave;
-            }
-          mpi_mod (r, x, skey->E.n);  /* r = x mod n */
-        }
-      mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n  */
-      mpi_addm (sum, input, dr, skey->E.n); /* sum = hash + (d*r) mod n  */
-      mpi_invm (k_1, k, skey->E.n);         /* k_1 = k^(-1) mod n  */
-      mpi_mulm (s, k_1, sum, skey->E.n);    /* s = k^(-1)*(hash+(d*r)) mod n */
-    }
-
-  if (DBG_CIPHER)
-    {
-      log_mpidump ("ecdsa sign result r ", r);
-      log_mpidump ("ecdsa sign result s ", s);
+        log_debug ("Bad check: computation of dG failed\n");
+      goto leave;
     }
-
- leave:
-  _gcry_mpi_ec_free (ctx);
-  point_free (&I);
-  mpi_free (x);
-  mpi_free (k_1);
-  mpi_free (sum);
-  mpi_free (dr);
-  mpi_free (k);
-
-  return err;
-}
-
-
-/*
- * Check if R and S verifies INPUT.
- */
-static gpg_err_code_t
-verify (gcry_mpi_t input, ECC_public_key *pkey, gcry_mpi_t r, gcry_mpi_t s)
-{
-  gpg_err_code_t err = 0;
-  gcry_mpi_t h, h1, h2, x, y;
-  mpi_point_t Q, Q1, Q2;
-  mpi_ec_t ctx;
-
-  if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, pkey->E.n) < 0) )
-    return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < r < n  failed.  */
-  if( !(mpi_cmp_ui (s, 0) > 0 && mpi_cmp (s, pkey->E.n) < 0) )
-    return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < s < n  failed.  */
-
-  h  = mpi_alloc (0);
-  h1 = mpi_alloc (0);
-  h2 = mpi_alloc (0);
-  x = mpi_alloc (0);
-  y = mpi_alloc (0);
-  point_init (&Q);
-  point_init (&Q1);
-  point_init (&Q2);
-
-  ctx = _gcry_mpi_ec_init (pkey->E.p, pkey->E.a);
-
-  /* h  = s^(-1) (mod n) */
-  mpi_invm (h, s, pkey->E.n);
-/*   log_mpidump ("   h", h); */
-  /* h1 = hash * s^(-1) (mod n) */
-  mpi_mulm (h1, input, h, pkey->E.n);
-/*   log_mpidump ("  h1", h1); */
-  /* Q1 = [ hash * s^(-1) ]G  */
-  _gcry_mpi_ec_mul_point (&Q1, h1, &pkey->E.G, ctx);
-/*   log_mpidump ("Q1.x", Q1.x); */
-/*   log_mpidump ("Q1.y", Q1.y); */
-/*   log_mpidump ("Q1.z", Q1.z); */
-  /* h2 = r * s^(-1) (mod n) */
-  mpi_mulm (h2, r, h, pkey->E.n);
-/*   log_mpidump ("  h2", h2); */
-  /* Q2 = [ r * s^(-1) ]Q */
-  _gcry_mpi_ec_mul_point (&Q2, h2, &pkey->Q, ctx);
-/*   log_mpidump ("Q2.x", Q2.x); */
-/*   log_mpidump ("Q2.y", Q2.y); */
-/*   log_mpidump ("Q2.z", Q2.z); */
-  /* Q  = ([hash * s^(-1)]G) + ([r * s^(-1)]Q) */
-  _gcry_mpi_ec_add_points (&Q, &Q1, &Q2, ctx);
-/*   log_mpidump (" Q.x", Q.x); */
-/*   log_mpidump (" Q.y", Q.y); */
-/*   log_mpidump (" Q.z", Q.z); */
-
-  if (!mpi_cmp_ui (Q.z, 0))
+  if (_gcry_mpi_ec_get_affine (x1, y1, &Q, ec))
     {
       if (DBG_CIPHER)
-          log_debug ("ecc verify: Rejected\n");
-      err = GPG_ERR_BAD_SIGNATURE;
+        log_debug ("Bad check: Q can not be a Point at Infinity!\n");
       goto leave;
     }
-  if (_gcry_mpi_ec_get_affine (x, y, &Q, ctx))
+
+  if ((flags & PUBKEY_FLAG_EDDSA))
+    ; /* Fixme: EdDSA is special.  */
+  else if (!mpi_cmp_ui (sk->Q.z, 1))
     {
-      if (DBG_CIPHER)
-        log_debug ("ecc verify: Failed to get affine coordinates\n");
-      err = GPG_ERR_BAD_SIGNATURE;
-      goto leave;
+      /* Fast path if Q is already in affine coordinates.  */
+      if (mpi_cmp (x1, sk->Q.x) || mpi_cmp (y1, sk->Q.y))
+        {
+          if (DBG_CIPHER)
+            log_debug
+              ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
+          goto leave;
+        }
     }
-  mpi_mod (x, x, pkey->E.n); /* x = x mod E_n */
-  if (mpi_cmp (x, r))   /* x != r */
+  else
     {
-      if (DBG_CIPHER)
+      x2 = mpi_new (0);
+      y2 = mpi_new (0);
+      if (_gcry_mpi_ec_get_affine (x2, y2, &sk->Q, ec))
         {
-          log_mpidump ("     x", x);
-          log_mpidump ("     y", y);
-          log_mpidump ("     r", r);
-          log_mpidump ("     s", s);
-          log_debug ("ecc verify: Not verified\n");
+          if (DBG_CIPHER)
+            log_debug ("Bad check: Q can not be a Point at Infinity!\n");
+          goto leave;
+        }
+
+      if (mpi_cmp (x1, x2) || mpi_cmp (y1, y2))
+        {
+          if (DBG_CIPHER)
+            log_debug
+              ("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
+          goto leave;
         }
-      err = GPG_ERR_BAD_SIGNATURE;
-      goto leave;
     }
-  if (DBG_CIPHER)
-    log_debug ("ecc verify: Accepted\n");
+  rc = 0; /* Okay.  */
 
  leave:
-  _gcry_mpi_ec_free (ctx);
-  point_free (&Q2);
-  point_free (&Q1);
+  mpi_free (x2);
+  mpi_free (x1);
+  mpi_free (y1);
+  mpi_free (y2);
   point_free (&Q);
-  mpi_free (y);
-  mpi_free (x);
-  mpi_free (h2);
-  mpi_free (h1);
-  mpi_free (h);
-  return err;
+  return rc;
 }
 
 
@@ -873,482 +383,671 @@ verify (gcry_mpi_t input, ECC_public_key *pkey, gcry_mpi_t r, gcry_mpi_t s)
 /*********************************************
  **************  interface  ******************
  *********************************************/
-static gcry_mpi_t
-ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p)
-{
-  gpg_error_t err;
-  int pbytes = (mpi_get_nbits (p)+7)/8;
-  size_t n;
-  unsigned char *buf, *ptr;
-  gcry_mpi_t result;
-
-  buf = gcry_xmalloc ( 1 + 2*pbytes );
-  *buf = 04; /* Uncompressed point.  */
-  ptr = buf+1;
-  err = gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, x);
-  if (err)
-    log_fatal ("mpi_print failed: %s\n", gpg_strerror (err));
-  if (n < pbytes)
-    {
-      memmove (ptr+(pbytes-n), ptr, n);
-      memset (ptr, 0, (pbytes-n));
-    }
-  ptr += pbytes;
-  err = gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, y);
-  if (err)
-    log_fatal ("mpi_print failed: %s\n", gpg_strerror (err));
-  if (n < pbytes)
-    {
-      memmove (ptr+(pbytes-n), ptr, n);
-      memset (ptr, 0, (pbytes-n));
-    }
-
-  err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, buf, 1+2*pbytes, NULL);
-  if (err)
-    log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err));
-  gcry_free (buf);
-
-  return result;
-}
 
-
-/* RESULT must have been initialized and is set on success to the
-   point given by VALUE.  */
-static gcry_error_t
-os2ec (mpi_point_t *result, gcry_mpi_t value)
+static gcry_err_code_t
+ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
 {
-  gcry_error_t err;
-  size_t n;
-  unsigned char *buf;
-  gcry_mpi_t x, y;
+  gpg_err_code_t rc;
+  unsigned int nbits;
+  elliptic_curve_t E;
+  ECC_secret_key sk;
+  gcry_mpi_t x = NULL;
+  gcry_mpi_t y = 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;
+  gcry_mpi_t base = NULL;
+  gcry_mpi_t public = NULL;
+  gcry_mpi_t secret = NULL;
+  int flags = 0;
+
+  memset (&E, 0, sizeof E);
+  memset (&sk, 0, sizeof sk);
+
+  rc = _gcry_pk_util_get_nbits (genparms, &nbits);
+  if (rc)
+    return rc;
+
+  /* Parse the optional "curve" parameter. */
+  l1 = sexp_find_token (genparms, "curve", 0);
+  if (l1)
+    {
+      curve_name = _gcry_sexp_nth_string (l1, 1);
+      sexp_release (l1);
+      if (!curve_name)
+        return GPG_ERR_INV_OBJ; /* No curve name or value too large. */
+    }
 
-  n = (mpi_get_nbits (value)+7)/8;
-  buf = gcry_xmalloc (n);
-  err = gcry_mpi_print (GCRYMPI_FMT_USG, buf, n, &n, value);
-  if (err)
+  /* Parse the optional flags list.  */
+  l1 = sexp_find_token (genparms, "flags", 0);
+  if (l1)
     {
-      gcry_free (buf);
-      return err;
+      rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
+      sexp_release (l1);
+      if (rc)
+        goto leave;
     }
-  if (n < 1)
+
+  /* Parse the deprecated optional transient-key flag.  */
+  l1 = sexp_find_token (genparms, "transient-key", 0);
+  if (l1)
     {
-      gcry_free (buf);
-      return GPG_ERR_INV_OBJ;
+      flags |= PUBKEY_FLAG_TRANSIENT_KEY;
+      sexp_release (l1);
     }
-  if (*buf != 4)
+
+  /* NBITS is required if no curve name has been given.  */
+  if (!nbits && !curve_name)
+    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;
+
+  if (DBG_CIPHER)
     {
-      gcry_free (buf);
-      return GPG_ERR_NOT_IMPLEMENTED; /* No support for point compression.  */
+      log_debug ("ecgen curve info: %s/%s\n",
+                 _gcry_ecc_model2str (E.model),
+                 _gcry_ecc_dialect2str (E.dialect));
+      if (E.name)
+        log_debug ("ecgen curve used: %s\n", E.name);
+      log_printmpi ("ecgen curve   p", E.p);
+      log_printmpi ("ecgen curve   a", E.a);
+      log_printmpi ("ecgen curve   b", E.b);
+      log_printmpi ("ecgen curve   n", E.n);
+      log_printpnt ("ecgen curve G", &E.G, NULL);
     }
-  if ( ((n-1)%2) )
+
+  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, 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);
+  else
+    rc = nist_generate_key (&sk, &E, ctx, random_level, nbits);
+  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))
     {
-      gcry_free (buf);
-      return GPG_ERR_INV_OBJ;
+      unsigned char *encpk;
+      unsigned int encpklen;
+
+      rc = _gcry_ecc_eddsa_encodepoint (&sk.Q, ctx, x, y, &encpk, &encpklen);
+      if (rc)
+        return rc;
+      public = mpi_new (0);
+      mpi_set_opaque (public, encpk, encpklen*8);
+      encpk = NULL;
     }
-  n = (n-1)/2;
-  err = gcry_mpi_scan (&x, GCRYMPI_FMT_USG, buf+1, n, NULL);
-  if (err)
+  else
     {
-      gcry_free (buf);
-      return err;
+      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);
     }
-  err = gcry_mpi_scan (&y, GCRYMPI_FMT_USG, buf+1+n, n, NULL);
-  gcry_free (buf);
-  if (err)
+  secret = sk.d; sk.d = NULL;
+  if (E.name)
+    {
+      rc = sexp_build (&curve_info, NULL, "(curve %s)", E.name);
+      if (rc)
+        goto leave;
+    }
+
+  if ((flags & PUBKEY_FLAG_PARAM) || (flags & PUBKEY_FLAG_EDDSA))
     {
-      mpi_free (x);
-      return err;
+      rc = sexp_build
+        (&curve_flags, NULL,
+         ((flags & PUBKEY_FLAG_PARAM) && (flags & PUBKEY_FLAG_EDDSA))?
+         "(flags param eddsa)" :
+         ((flags & PUBKEY_FLAG_PARAM))?
+         "(flags param)" :
+         "(flags eddsa)");
+      if (rc)
+        goto leave;
     }
 
-  mpi_set (result->x, x);
-  mpi_set (result->y, y);
-  mpi_set_ui (result->z, 1);
+  if ((flags & PUBKEY_FLAG_PARAM) && E.name)
+    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)))"
+                     " (private-key"
+                     "  (ecc%S%S(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)(d%m)))"
+                     " )",
+                     curve_info, curve_flags,
+                     sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, public,
+                     curve_info, curve_flags,
+                     sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, public, secret);
+  else
+    rc = sexp_build (r_skey, NULL,
+                     "(key-data"
+                     " (public-key"
+                     "  (ecc%S%S(q%m)))"
+                     " (private-key"
+                     "  (ecc%S%S(q%m)(d%m)))"
+                     " )",
+                     curve_info, curve_flags,
+                     public,
+                     curve_info, curve_flags,
+                     public, secret);
+  if (rc)
+    goto leave;
+
+  if (DBG_CIPHER)
+    {
+      log_printmpi ("ecgen result  p", sk.E.p);
+      log_printmpi ("ecgen result  a", sk.E.a);
+      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  Q", public);
+      log_printmpi ("ecgen result  d", secret);
+      if ((flags & PUBKEY_FLAG_EDDSA))
+        log_debug ("ecgen result  using Ed25519+EdDSA\n");
+    }
 
+ leave:
+  mpi_free (secret);
+  mpi_free (public);
+  mpi_free (base);
+  {
+    _gcry_ecc_curve_free (&sk.E);
+    point_free (&sk.Q);
+    mpi_free (sk.d);
+  }
+  _gcry_ecc_curve_free (&E);
   mpi_free (x);
   mpi_free (y);
-
-  return 0;
+  _gcry_mpi_ec_free (ctx);
+  sexp_release (curve_flags);
+  sexp_release (curve_info);
+  return rc;
 }
 
 
-/* Extended version of ecc_generate.  */
 static gcry_err_code_t
-ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
-                  const gcry_sexp_t genparms,
-                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
-                  gcry_sexp_t *r_extrainfo)
+ecc_check_secret_key (gcry_sexp_t keyparms)
 {
-  gpg_err_code_t ec;
+  gcry_err_code_t rc;
+  gcry_sexp_t l1 = NULL;
+  int flags = 0;
+  char *curvename = NULL;
+  gcry_mpi_t mpi_g = NULL;
+  gcry_mpi_t mpi_q = NULL;
   ECC_secret_key sk;
-  gcry_mpi_t g_x, g_y, q_x, q_y;
-  char *curve_name = NULL;
-  gcry_sexp_t l1;
-  int transient_key = 0;
-  const char *usedcurve = NULL;
+  mpi_ec_t ec = NULL;
 
-  (void)algo;
-  (void)evalue;
+  memset (&sk, 0, sizeof sk);
 
-  if (genparms)
+  /* Look for flags. */
+  l1 = sexp_find_token (keyparms, "flags", 0);
+  if (l1)
     {
-      /* Parse the optional "curve" parameter. */
-      l1 = gcry_sexp_find_token (genparms, "curve", 0);
-      if (l1)
-        {
-          curve_name = _gcry_sexp_nth_string (l1, 1);
-          gcry_sexp_release (l1);
-          if (!curve_name)
-            return GPG_ERR_INV_OBJ; /* No curve name or value too large. */
-        }
+      rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
+      if (rc)
+        goto leave;
+    }
 
-      /* Parse the optional transient-key flag.  */
-      l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
-      if (l1)
+  /* Extract the parameters.  */
+  if ((flags & PUBKEY_FLAG_PARAM))
+    rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?/q?+d",
+                             &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n,
+                             &mpi_q, &sk.d, NULL);
+  else
+    rc = sexp_extract_param (keyparms, NULL, "/q?+d",
+                             &mpi_q, &sk.d, NULL);
+  if (rc)
+    goto leave;
+
+  /* Add missing parameters using the optional curve parameter.  */
+  sexp_release (l1);
+  l1 = sexp_find_token (keyparms, "curve", 5);
+  if (l1)
+    {
+      curvename = sexp_nth_string (l1, 1);
+      if (curvename)
         {
-          transient_key = 1;
-          gcry_sexp_release (l1);
+          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);
+          if (rc)
+            return rc;
         }
     }
+  if (mpi_g)
+    {
+      point_init (&sk.E.G);
+      rc = _gcry_ecc_os2ec (&sk.E.G, mpi_g);
+      if (rc)
+        goto leave;
+    }
 
-  /* NBITS is required if no curve name has been given.  */
-  if (!nbits && !curve_name)
-    return GPG_ERR_NO_OBJ; /* No NBITS parameter. */
-
-  g_x = mpi_new (0);
-  g_y = mpi_new (0);
-  q_x = mpi_new (0);
-  q_y = mpi_new (0);
-  ec = generate_key (&sk, nbits, curve_name, transient_key, g_x, g_y, q_x, q_y,
-                     &usedcurve);
-  gcry_free (curve_name);
-  if (ec)
-    return ec;
-  if (usedcurve)  /* Fixme: No error return checking.  */
-    gcry_sexp_build (r_extrainfo, NULL, "(curve %s)", usedcurve);
-
-  skey[0] = sk.E.p;
-  skey[1] = sk.E.a;
-  skey[2] = sk.E.b;
-  skey[3] = ec2os (g_x, g_y, sk.E.p);
-  skey[4] = sk.E.n;
-  skey[5] = ec2os (q_x, q_y, sk.E.p);
-  skey[6] = sk.d;
-
-  mpi_free (g_x);
-  mpi_free (g_y);
-  mpi_free (q_x);
-  mpi_free (q_y);
-
-  point_free (&sk.E.G);
-  point_free (&sk.Q);
-
-  /* Make an empty list of factors.  */
-  *retfactors = gcry_calloc ( 1, sizeof **retfactors );
-  if (!*retfactors)
-    return gpg_err_code_from_syserror ();  /* Fixme: relase mem?  */
-
+  /* Guess required fields if a curve parameter has not been given.
+     FIXME: This is a crude hacks.  We need to fix that.  */
+  if (!curvename)
+    {
+      sk.E.model = ((flags & PUBKEY_FLAG_EDDSA)
+               ? MPI_EC_TWISTEDEDWARDS
+               : MPI_EC_WEIERSTRASS);
+      sk.E.dialect = ((flags & PUBKEY_FLAG_EDDSA)
+                      ? ECC_DIALECT_ED25519
+                      : ECC_DIALECT_STANDARD);
+    }
   if (DBG_CIPHER)
     {
-      log_mpidump ("ecgen result p", skey[0]);
-      log_mpidump ("ecgen result a", skey[1]);
-      log_mpidump ("ecgen result b", skey[2]);
-      log_mpidump ("ecgen result G", skey[3]);
-      log_mpidump ("ecgen result n", skey[4]);
-      log_mpidump ("ecgen result Q", skey[5]);
-      log_mpidump ("ecgen result d", skey[6]);
+      log_debug ("ecc_testkey inf: %s/%s\n",
+                 _gcry_ecc_model2str (sk.E.model),
+                 _gcry_ecc_dialect2str (sk.E.dialect));
+      if (sk.E.name)
+        log_debug  ("ecc_testkey nam: %s\n", sk.E.name);
+      log_printmpi ("ecc_testkey   p", sk.E.p);
+      log_printmpi ("ecc_testkey   a", sk.E.a);
+      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   q", mpi_q);
+      if (!fips_mode ())
+        log_printmpi ("ecc_testkey   d", sk.d);
     }
-
-  return 0;
-}
-
-
-static gcry_err_code_t
-ecc_generate (int algo, unsigned int nbits, unsigned long evalue,
-              gcry_mpi_t *skey, gcry_mpi_t **retfactors)
-{
-  (void)evalue;
-  return ecc_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL);
-}
-
-
-/* Return the parameters of the curve NAME in an MPI array.  */
-static gcry_err_code_t
-ecc_get_param (const char *name, gcry_mpi_t *pkey)
-{
-  gpg_err_code_t err;
-  unsigned int nbits;
-  elliptic_curve_t E;
-  mpi_ec_t ctx;
-  gcry_mpi_t g_x, g_y;
-
-  err = fill_in_curve (0, name, &E, &nbits);
-  if (err)
-    return err;
-
-  g_x = mpi_new (0);
-  g_y = mpi_new (0);
-  ctx = _gcry_mpi_ec_init (E.p, E.a);
-  if (_gcry_mpi_ec_get_affine (g_x, g_y, &E.G, ctx))
-    log_fatal ("ecc get param: Failed to get affine coordinates\n");
-  _gcry_mpi_ec_free (ctx);
-  point_free (&E.G);
-
-  pkey[0] = E.p;
-  pkey[1] = E.a;
-  pkey[2] = E.b;
-  pkey[3] = ec2os (g_x, g_y, E.p);
-  pkey[4] = E.n;
-  pkey[5] = NULL;
-
-  mpi_free (g_x);
-  mpi_free (g_y);
-
-  return 0;
-}
-
-
-/* Return the parameters of the curve NAME as an S-expression.  */
-static gcry_sexp_t
-ecc_get_param_sexp (const char *name)
-{
-  gcry_mpi_t pkey[6];
-  gcry_sexp_t result;
-  int i;
-
-  if (ecc_get_param (name, pkey))
-    return NULL;
-
-  if (gcry_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]))
-    result = NULL;
-
-  for (i=0; pkey[i]; i++)
-    gcry_mpi_release (pkey[i]);
-
-  return result;
-}
-
-
-/* Return the name matching the parameters in PKEY.  */
-static const char *
-ecc_get_curve (gcry_mpi_t *pkey, int iterator, unsigned int *r_nbits)
-{
-  gpg_err_code_t err;
-  elliptic_curve_t E;
-  int idx;
-  gcry_mpi_t tmp;
-  const char *result = NULL;
-
-  if (r_nbits)
-    *r_nbits = 0;
-
-  if (!pkey)
+  if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.d)
     {
-      idx = iterator;
-      if (idx >= 0 && idx < DIM (domain_parms))
-        {
-          result = domain_parms[idx].desc;
-          if (r_nbits)
-            *r_nbits = domain_parms[idx].nbits;
-        }
-      return result;
+      rc = GPG_ERR_NO_OBJ;
+      goto leave;
     }
 
-  if (!pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4])
-    return NULL;
+  ec = _gcry_mpi_ec_p_internal_new (sk.E.model, sk.E.dialect, 0,
+                                    sk.E.p, sk.E.a, sk.E.b);
 
-  E.p = pkey[0];
-  E.a = pkey[1];
-  E.b = pkey[2];
-  point_init (&E.G);
-  err = os2ec (&E.G, pkey[3]);
-  if (err)
+  if (mpi_q)
     {
-      point_free (&E.G);
-      return NULL;
+      point_init (&sk.Q);
+      if (ec->dialect == ECC_DIALECT_ED25519)
+        rc = _gcry_ecc_eddsa_decodepoint (mpi_q, ec, &sk.Q, NULL, NULL);
+      else
+        rc = _gcry_ecc_os2ec (&sk.Q, mpi_q);
+      if (rc)
+        goto leave;
     }
-  E.n = pkey[4];
-
-  for (idx = 0; domain_parms[idx].desc; idx++)
+  else
     {
-      tmp = scanval (domain_parms[idx].p);
-      if (!mpi_cmp (tmp, E.p))
-        {
-          mpi_free (tmp);
-          tmp = scanval (domain_parms[idx].a);
-          if (!mpi_cmp (tmp, E.a))
-            {
-              mpi_free (tmp);
-              tmp = scanval (domain_parms[idx].b);
-              if (!mpi_cmp (tmp, E.b))
-                {
-                  mpi_free (tmp);
-                  tmp = scanval (domain_parms[idx].n);
-                  if (!mpi_cmp (tmp, E.n))
-                    {
-                      mpi_free (tmp);
-                      tmp = scanval (domain_parms[idx].g_x);
-                      if (!mpi_cmp (tmp, E.G.x))
-                        {
-                          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;
-                              break;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-      mpi_free (tmp);
+      /* The secret key test requires Q.  */
+      rc = GPG_ERR_NO_OBJ;
+      goto leave;
     }
 
-  point_free (&E.G);
+  if (check_secret_key (&sk, ec, flags))
+    rc = GPG_ERR_BAD_SECKEY;
 
-  return result;
+ leave:
+  _gcry_mpi_ec_free (ec);
+  _gcry_mpi_release (sk.E.p);
+  _gcry_mpi_release (sk.E.a);
+  _gcry_mpi_release (sk.E.b);
+  _gcry_mpi_release (mpi_g);
+  point_free (&sk.E.G);
+  _gcry_mpi_release (sk.E.n);
+  _gcry_mpi_release (mpi_q);
+  point_free (&sk.Q);
+  _gcry_mpi_release (sk.d);
+  xfree (curvename);
+  sexp_release (l1);
+  if (DBG_CIPHER)
+    log_debug ("ecc_testkey   => %s\n", gpg_strerror (rc));
+  return rc;
 }
 
 
 static gcry_err_code_t
-ecc_check_secret_key (int algo, gcry_mpi_t *skey)
+ecc_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
 {
-  gpg_err_code_t err;
+  gcry_err_code_t rc;
+  struct pk_encoding_ctx ctx;
+  gcry_mpi_t data = NULL;
+  gcry_sexp_t l1 = NULL;
+  char *curvename = NULL;
+  gcry_mpi_t mpi_g = NULL;
+  gcry_mpi_t mpi_q = NULL;
   ECC_secret_key sk;
+  gcry_mpi_t sig_r = NULL;
+  gcry_mpi_t sig_s = NULL;
 
-  (void)algo;
+  memset (&sk, 0, sizeof sk);
 
-  /* FIXME:  This check looks a bit fishy:  Now long is the array?  */
-  if (!skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] || !skey[5]
-      || !skey[6])
-    return GPG_ERR_BAD_MPI;
+  _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN, 0);
 
-  sk.E.p = skey[0];
-  sk.E.a = skey[1];
-  sk.E.b = skey[2];
-  point_init (&sk.E.G);
-  err = os2ec (&sk.E.G, skey[3]);
-  if (err)
+  /* Extract the data.  */
+  rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    log_mpidump ("ecc_sign   data", data);
+
+  /*
+   * Extract the key.
+   */
+  if ((ctx.flags & PUBKEY_FLAG_PARAM))
+    rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?/q?+d",
+                             &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n,
+                             &mpi_q, &sk.d, NULL);
+  else
+    rc = sexp_extract_param (keyparms, NULL, "/q?+d",
+                             &mpi_q, &sk.d, NULL);
+  if (rc)
+    goto leave;
+  if (mpi_g)
+    {
+      point_init (&sk.E.G);
+      rc = _gcry_ecc_os2ec (&sk.E.G, mpi_g);
+      if (rc)
+        goto leave;
+    }
+  /* Add missing parameters using the optional curve parameter.  */
+  sexp_release (l1);
+  l1 = sexp_find_token (keyparms, "curve", 5);
+  if (l1)
+    {
+      curvename = sexp_nth_string (l1, 1);
+      if (curvename)
+        {
+          rc = _gcry_ecc_fill_in_curve (0, curvename, &sk.E, NULL);
+          if (rc)
+            return rc;
+        }
+    }
+  /* Guess required fields if a curve parameter has not been given.
+     FIXME: This is a crude hacks.  We need to fix that.  */
+  if (!curvename)
+    {
+      sk.E.model = ((ctx.flags & PUBKEY_FLAG_EDDSA)
+                    ? MPI_EC_TWISTEDEDWARDS
+                    : MPI_EC_WEIERSTRASS);
+      sk.E.dialect = ((ctx.flags & PUBKEY_FLAG_EDDSA)
+                      ? ECC_DIALECT_ED25519
+                      : ECC_DIALECT_STANDARD);
+    }
+  if (DBG_CIPHER)
     {
-      point_free (&sk.E.G);
-      return err;
+      log_debug ("ecc_sign   info: %s/%s%s\n",
+                 _gcry_ecc_model2str (sk.E.model),
+                 _gcry_ecc_dialect2str (sk.E.dialect),
+                 (ctx.flags & PUBKEY_FLAG_EDDSA)? "+EdDSA":"");
+      if (sk.E.name)
+        log_debug  ("ecc_sign   name: %s\n", sk.E.name);
+      log_printmpi ("ecc_sign      p", sk.E.p);
+      log_printmpi ("ecc_sign      a", sk.E.a);
+      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      q", mpi_q);
+      if (!fips_mode ())
+        log_printmpi ("ecc_sign      d", sk.d);
     }
-  sk.E.n = skey[4];
-  point_init (&sk.Q);
-  err = os2ec (&sk.Q, skey[5]);
-  if (err)
+  if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.d)
     {
-      point_free (&sk.E.G);
-      point_free (&sk.Q);
-      return err;
+      rc = GPG_ERR_NO_OBJ;
+      goto leave;
     }
 
-  sk.d = skey[6];
 
-  if (check_secret_key (&sk))
+  sig_r = mpi_new (0);
+  sig_s = mpi_new (0);
+  if ((ctx.flags & PUBKEY_FLAG_EDDSA))
+    {
+      /* EdDSA requires the public key.  */
+      rc = _gcry_ecc_eddsa_sign (data, &sk, sig_r, sig_s, ctx.hash_algo, mpi_q);
+      if (!rc)
+        rc = sexp_build (r_sig, NULL,
+                         "(sig-val(eddsa(r%M)(s%M)))", sig_r, sig_s);
+    }
+  else if ((ctx.flags & PUBKEY_FLAG_GOST))
+    {
+      rc = _gcry_ecc_gost_sign (data, &sk, sig_r, sig_s);
+      if (!rc)
+        rc = sexp_build (r_sig, NULL,
+                         "(sig-val(gost(r%M)(s%M)))", sig_r, sig_s);
+    }
+  else
     {
-      point_free (&sk.E.G);
-      point_free (&sk.Q);
-      return GPG_ERR_BAD_SECKEY;
+      rc = _gcry_ecc_ecdsa_sign (data, &sk, sig_r, sig_s,
+                                 ctx.flags, ctx.hash_algo);
+      if (!rc)
+        rc = sexp_build (r_sig, NULL,
+                         "(sig-val(ecdsa(r%M)(s%M)))", sig_r, sig_s);
     }
+
+
+ leave:
+  _gcry_mpi_release (sk.E.p);
+  _gcry_mpi_release (sk.E.a);
+  _gcry_mpi_release (sk.E.b);
+  _gcry_mpi_release (mpi_g);
   point_free (&sk.E.G);
+  _gcry_mpi_release (sk.E.n);
+  _gcry_mpi_release (mpi_q);
   point_free (&sk.Q);
-  return 0;
+  _gcry_mpi_release (sk.d);
+  _gcry_mpi_release (sig_r);
+  _gcry_mpi_release (sig_s);
+  xfree (curvename);
+  _gcry_mpi_release (data);
+  sexp_release (l1);
+  _gcry_pk_util_free_encoding_ctx (&ctx);
+  if (DBG_CIPHER)
+    log_debug ("ecc_sign      => %s\n", gpg_strerror (rc));
+  return rc;
 }
 
 
 static gcry_err_code_t
-ecc_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
+ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
 {
-  gpg_err_code_t err;
-  ECC_secret_key sk;
-
-  (void)algo;
+  gcry_err_code_t rc;
+  struct pk_encoding_ctx ctx;
+  gcry_sexp_t l1 = NULL;
+  char *curvename = NULL;
+  gcry_mpi_t mpi_g = NULL;
+  gcry_mpi_t mpi_q = NULL;
+  gcry_mpi_t sig_r = NULL;
+  gcry_mpi_t sig_s = NULL;
+  gcry_mpi_t data = NULL;
+  ECC_public_key pk;
+  int sigflags;
 
-  if (!data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
-      || !skey[5] || !skey[6] )
-    return GPG_ERR_BAD_MPI;
+  memset (&pk, 0, sizeof pk);
+  _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY,
+                                   ecc_get_nbits (s_keyparms));
 
-  sk.E.p = skey[0];
-  sk.E.a = skey[1];
-  sk.E.b = skey[2];
-  point_init (&sk.E.G);
-  err = os2ec (&sk.E.G, skey[3]);
-  if (err)
+  /* Extract the data.  */
+  rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    log_mpidump ("ecc_verify data", data);
+
+  /*
+   * Extract the signature value.
+   */
+  rc = _gcry_pk_util_preparse_sigval (s_sig, ecc_names, &l1, &sigflags);
+  if (rc)
+    goto leave;
+  rc = sexp_extract_param (l1, NULL, (sigflags & PUBKEY_FLAG_EDDSA)? "/rs":"rs",
+                           &sig_r, &sig_s, NULL);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
     {
-      point_free (&sk.E.G);
-      return err;
+      log_mpidump ("ecc_verify  s_r", sig_r);
+      log_mpidump ("ecc_verify  s_s", sig_s);
     }
-  sk.E.n = skey[4];
-  point_init (&sk.Q);
-  err = os2ec (&sk.Q, skey[5]);
-  if (err)
+  if ((ctx.flags & PUBKEY_FLAG_EDDSA) ^ (sigflags & PUBKEY_FLAG_EDDSA))
     {
-      point_free (&sk.E.G);
-      point_free (&sk.Q);
-      return err;
+      rc = GPG_ERR_CONFLICT; /* Inconsistent use of flag/algoname.  */
+      goto leave;
     }
-  sk.d = skey[6];
 
-  resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.E.p));
-  resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.E.p));
-  err = sign (data, &sk, resarr[0], resarr[1]);
-  if (err)
+
+  /*
+   * Extract the key.
+   */
+  if ((ctx.flags & PUBKEY_FLAG_PARAM))
+    rc = sexp_extract_param (s_keyparms, NULL, "-p?a?b?g?n?/q",
+                             &pk.E.p, &pk.E.a, &pk.E.b, &mpi_g, &pk.E.n,
+                             &mpi_q, NULL);
+  else
+    rc = sexp_extract_param (s_keyparms, NULL, "/q",
+                             &mpi_q, NULL);
+  if (rc)
+    goto leave;
+  if (mpi_g)
     {
-      mpi_free (resarr[0]);
-      mpi_free (resarr[1]);
-      resarr[0] = NULL; /* Mark array as released.  */
+      point_init (&pk.E.G);
+      rc = _gcry_ecc_os2ec (&pk.E.G, mpi_g);
+      if (rc)
+        goto leave;
+    }
+  /* Add missing parameters using the optional curve parameter.  */
+  sexp_release (l1);
+  l1 = sexp_find_token (s_keyparms, "curve", 5);
+  if (l1)
+    {
+      curvename = sexp_nth_string (l1, 1);
+      if (curvename)
+        {
+          rc = _gcry_ecc_fill_in_curve (0, curvename, &pk.E, NULL);
+          if (rc)
+            return rc;
+        }
+    }
+  /* Guess required fields if a curve parameter has not been given.
+     FIXME: This is a crude hacks.  We need to fix that.  */
+  if (!curvename)
+    {
+      pk.E.model = ((sigflags & PUBKEY_FLAG_EDDSA)
+                    ? MPI_EC_TWISTEDEDWARDS
+                    : MPI_EC_WEIERSTRASS);
+      pk.E.dialect = ((sigflags & PUBKEY_FLAG_EDDSA)
+                      ? ECC_DIALECT_ED25519
+                      : ECC_DIALECT_STANDARD);
     }
-  point_free (&sk.E.G);
-  point_free (&sk.Q);
-  return err;
-}
-
-
-static gcry_err_code_t
-ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
-            int (*cmp)(void *, gcry_mpi_t), void *opaquev)
-{
-  gpg_err_code_t err;
-  ECC_public_key pk;
 
-  (void)algo;
-  (void)cmp;
-  (void)opaquev;
+  if (DBG_CIPHER)
+    {
+      log_debug ("ecc_verify info: %s/%s%s\n",
+                 _gcry_ecc_model2str (pk.E.model),
+                 _gcry_ecc_dialect2str (pk.E.dialect),
+                 (sigflags & PUBKEY_FLAG_EDDSA)? "+EdDSA":"");
+      if (pk.E.name)
+        log_debug  ("ecc_verify name: %s\n", pk.E.name);
+      log_printmpi ("ecc_verify    p", pk.E.p);
+      log_printmpi ("ecc_verify    a", pk.E.a);
+      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    q", mpi_q);
+    }
+  if (!pk.E.p || !pk.E.a || !pk.E.b || !pk.E.G.x || !pk.E.n || !mpi_q)
+    {
+      rc = GPG_ERR_NO_OBJ;
+      goto leave;
+    }
 
-  if (!data[0] || !data[1] || !hash || !pkey[0] || !pkey[1] || !pkey[2]
-      || !pkey[3] || !pkey[4] || !pkey[5] )
-    return GPG_ERR_BAD_MPI;
 
-  pk.E.p = pkey[0];
-  pk.E.a = pkey[1];
-  pk.E.b = pkey[2];
-  point_init (&pk.E.G);
-  err = os2ec (&pk.E.G, pkey[3]);
-  if (err)
+  /*
+   * Verify the signature.
+   */
+  if ((sigflags & PUBKEY_FLAG_EDDSA))
     {
-      point_free (&pk.E.G);
-      return err;
+      rc = _gcry_ecc_eddsa_verify (data, &pk, sig_r, sig_s,
+                                   ctx.hash_algo, mpi_q);
     }
-  pk.E.n = pkey[4];
-  point_init (&pk.Q);
-  err = os2ec (&pk.Q, pkey[5]);
-  if (err)
+  else if ((sigflags & PUBKEY_FLAG_GOST))
     {
-      point_free (&pk.E.G);
-      point_free (&pk.Q);
-      return err;
+      point_init (&pk.Q);
+      rc = _gcry_ecc_os2ec (&pk.Q, mpi_q);
+      if (rc)
+        goto leave;
+
+      rc = _gcry_ecc_gost_verify (data, &pk, sig_r, sig_s);
     }
+  else
+    {
+      point_init (&pk.Q);
+      if (pk.E.dialect == ECC_DIALECT_ED25519)
+        {
+          mpi_ec_t ec;
+
+          /* Fixme: Factor the curve context setup out of eddsa_verify
+             and ecdsa_verify. So that we don't do it twice.  */
+          ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect, 0,
+                                            pk.E.p, pk.E.a, pk.E.b);
+
+          rc = _gcry_ecc_eddsa_decodepoint (mpi_q, ec, &pk.Q, NULL, NULL);
+          _gcry_mpi_ec_free (ec);
+        }
+      else
+        {
+          rc = _gcry_ecc_os2ec (&pk.Q, mpi_q);
+        }
+      if (rc)
+        goto leave;
+
+      if (mpi_is_opaque (data))
+        {
+          const void *abuf;
+          unsigned int abits, qbits;
+          gcry_mpi_t a;
+
+          qbits = mpi_get_nbits (pk.E.n);
+
+          abuf = mpi_get_opaque (data, &abits);
+          rc = _gcry_mpi_scan (&a, GCRYMPI_FMT_USG, abuf, (abits+7)/8, NULL);
+          if (!rc)
+            {
+              if (abits > qbits)
+                mpi_rshift (a, a, abits - qbits);
 
-  err = verify (hash, &pk, data[0], data[1]);
+              rc = _gcry_ecc_ecdsa_verify (a, &pk, sig_r, sig_s);
+              _gcry_mpi_release (a);
+            }
+        }
+      else
+        rc = _gcry_ecc_ecdsa_verify (data, &pk, sig_r, sig_s);
+    }
 
+ leave:
+  _gcry_mpi_release (pk.E.p);
+  _gcry_mpi_release (pk.E.a);
+  _gcry_mpi_release (pk.E.b);
+  _gcry_mpi_release (mpi_g);
   point_free (&pk.E.G);
+  _gcry_mpi_release (pk.E.n);
+  _gcry_mpi_release (mpi_q);
   point_free (&pk.Q);
-  return err;
+  _gcry_mpi_release (data);
+  _gcry_mpi_release (sig_r);
+  _gcry_mpi_release (sig_s);
+  xfree (curvename);
+  sexp_release (l1);
+  _gcry_pk_util_free_encoding_ctx (&ctx);
+  if (DBG_CIPHER)
+    log_debug ("ecc_verify    => %s\n", rc?gpg_strerror (rc):"Good");
+  return rc;
 }
 
 
@@ -1370,9 +1069,9 @@ ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
  * ecc_encrypt_raw description:
  *   input:
  *     data[0] : private scalar (k)
- *   output:
- *     result[0] : shared point (kdG)
- *     result[1] : generated ephemeral public key (kG)
+ *   output: A new S-expression with the parameters:
+ *     s : shared point (kdG)
+ *     e : generated ephemeral public key (kG)
  *
  * ecc_decrypt_raw description:
  *   input:
@@ -1381,46 +1080,110 @@ ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
  *     result[0] : shared point (kdG)
  */
 static gcry_err_code_t
-ecc_encrypt_raw (int algo, gcry_mpi_t *resarr, gcry_mpi_t k,
-                 gcry_mpi_t *pkey, int flags)
+ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
 {
+  gcry_err_code_t rc;
+  struct pk_encoding_ctx ctx;
+  gcry_sexp_t l1 = NULL;
+  char *curvename = NULL;
+  gcry_mpi_t mpi_g = NULL;
+  gcry_mpi_t mpi_q = NULL;
+  gcry_mpi_t mpi_s = NULL;
+  gcry_mpi_t mpi_e = NULL;
+  gcry_mpi_t data = NULL;
   ECC_public_key pk;
-  mpi_ec_t ctx;
-  gcry_mpi_t result[2];
-  int err;
+  mpi_ec_t ec = NULL;
+
+  memset (&pk, 0, sizeof pk);
+  _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT,
+                                   ecc_get_nbits (keyparms));
+
+  /*
+   * Extract the data.
+   */
+  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;
+    }
 
-  (void)algo;
-  (void)flags;
 
-  if (!k
-      || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4] || !pkey[5])
-    return GPG_ERR_BAD_MPI;
+  /*
+   * 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,
+                           &mpi_q, NULL);
+  if (rc)
+    goto leave;
+  if (mpi_g)
+    {
+      point_init (&pk.E.G);
+      rc = _gcry_ecc_os2ec (&pk.E.G, mpi_g);
+      if (rc)
+        goto leave;
+    }
+  /* Add missing parameters using the optional curve parameter.  */
+  sexp_release (l1);
+  l1 = sexp_find_token (keyparms, "curve", 5);
+  if (l1)
+    {
+      curvename = sexp_nth_string (l1, 1);
+      if (curvename)
+        {
+          rc = _gcry_ecc_fill_in_curve (0, curvename, &pk.E, NULL);
+          if (rc)
+            return rc;
+        }
+    }
+  /* Guess required fields if a curve parameter has not been given.  */
+  if (!curvename)
+    {
+      pk.E.model = MPI_EC_WEIERSTRASS;
+      pk.E.dialect = ECC_DIALECT_STANDARD;
+    }
 
-  pk.E.p = pkey[0];
-  pk.E.a = pkey[1];
-  pk.E.b = pkey[2];
-  point_init (&pk.E.G);
-  err = os2ec (&pk.E.G, pkey[3]);
-  if (err)
+  if (DBG_CIPHER)
     {
-      point_free (&pk.E.G);
-      return err;
+      log_debug ("ecc_encrypt info: %s/%s\n",
+                 _gcry_ecc_model2str (pk.E.model),
+                 _gcry_ecc_dialect2str (pk.E.dialect));
+      if (pk.E.name)
+        log_debug  ("ecc_encrypt name: %s\n", pk.E.name);
+      log_printmpi ("ecc_encrypt    p", pk.E.p);
+      log_printmpi ("ecc_encrypt    a", pk.E.a);
+      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    q", mpi_q);
     }
-  pk.E.n = pkey[4];
-  point_init (&pk.Q);
-  err = os2ec (&pk.Q, pkey[5]);
-  if (err)
+  if (!pk.E.p || !pk.E.a || !pk.E.b || !pk.E.G.x || !pk.E.n || !mpi_q)
+    {
+      rc = GPG_ERR_NO_OBJ;
+      goto leave;
+    }
+
+  /* Convert the public key.  */
+  if (mpi_q)
     {
-      point_free (&pk.E.G);
-      point_free (&pk.Q);
-      return err;
+      point_init (&pk.Q);
+      rc = _gcry_ecc_os2ec (&pk.Q, mpi_q);
+      if (rc)
+        goto leave;
     }
 
-  ctx = _gcry_mpi_ec_init (pk.E.p, pk.E.a);
+  /* 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_t R;     /* Result that we return.  */
+    mpi_point_struct R;  /* Result that we return.  */
     gcry_mpi_t x, y;
 
     x = mpi_new (0);
@@ -1429,20 +1192,18 @@ ecc_encrypt_raw (int algo, gcry_mpi_t *resarr, gcry_mpi_t k,
     point_init (&R);
 
     /* R = kQ  <=>  R = kdG  */
-    _gcry_mpi_ec_mul_point (&R, k, &pk.Q, ctx);
+    _gcry_mpi_ec_mul_point (&R, data, &pk.Q, ec);
 
-    if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
+    if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
       log_fatal ("ecdh: Failed to get affine coordinates for kdG\n");
-
-    result[0] = ec2os (x, y, pk.E.p);
+    mpi_s = _gcry_ecc_ec2os (x, y, pk.E.p);
 
     /* R = kG */
-    _gcry_mpi_ec_mul_point (&R, k, &pk.E.G, ctx);
+    _gcry_mpi_ec_mul_point (&R, data, &pk.E.G, ec);
 
-    if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
+    if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
       log_fatal ("ecdh: Failed to get affine coordinates for kG\n");
-
-    result[1] = ec2os (x, y, pk.E.p);
+    mpi_e = _gcry_ecc_ec2os (x, y, pk.E.p);
 
     mpi_free (x);
     mpi_free (y);
@@ -1450,24 +1211,29 @@ ecc_encrypt_raw (int algo, gcry_mpi_t *resarr, gcry_mpi_t k,
     point_free (&R);
   }
 
-  _gcry_mpi_ec_free (ctx);
+  rc = sexp_build (r_ciph, NULL, "(enc-val(ecdh(s%m)(e%m)))", mpi_s, mpi_e);
+
+ leave:
+  _gcry_mpi_release (pk.E.p);
+  _gcry_mpi_release (pk.E.a);
+  _gcry_mpi_release (pk.E.b);
+  _gcry_mpi_release (mpi_g);
   point_free (&pk.E.G);
+  _gcry_mpi_release (pk.E.n);
+  _gcry_mpi_release (mpi_q);
   point_free (&pk.Q);
-
-  if (!result[0] || !result[1])
-    {
-      mpi_free (result[0]);
-      mpi_free (result[1]);
-      return GPG_ERR_ENOMEM;
-    }
-
-  /* Success.  */
-  resarr[0] = result[0];
-  resarr[1] = result[1];
-
-  return 0;
+  _gcry_mpi_release (data);
+  _gcry_mpi_release (mpi_s);
+  _gcry_mpi_release (mpi_e);
+  xfree (curvename);
+  _gcry_mpi_ec_free (ec);
+  _gcry_pk_util_free_encoding_ctx (&ctx);
+  if (DBG_CIPHER)
+    log_debug ("ecc_encrypt    => %s\n", gpg_strerror (rc));
+  return rc;
 }
 
+
 /*  input:
  *     data[0] : a point kG (ephemeral public key)
  *   output:
@@ -1476,65 +1242,115 @@ ecc_encrypt_raw (int algo, gcry_mpi_t *resarr, gcry_mpi_t k,
  *  see ecc_encrypt_raw for details.
  */
 static gcry_err_code_t
-ecc_decrypt_raw (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
-                 gcry_mpi_t *skey, int flags)
+ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
 {
+  gpg_err_code_t rc;
+  struct pk_encoding_ctx ctx;
+  gcry_sexp_t l1 = NULL;
+  gcry_mpi_t data_e = NULL;
   ECC_secret_key sk;
-  mpi_point_t R;       /* Result that we return.  */
-  mpi_point_t kG;
-  mpi_ec_t ctx;
-  gcry_mpi_t r;
-  int err;
-
-  (void)algo;
-  (void)flags;
-
-  *result = NULL;
-
-  if (!data || !data[0]
-      || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
-      || !skey[5] || !skey[6] )
-    return GPG_ERR_BAD_MPI;
-
+  gcry_mpi_t mpi_g = NULL;
+  char *curvename = NULL;
+  mpi_ec_t ec = NULL;
+  mpi_point_struct kG;
+  mpi_point_struct R;
+  gcry_mpi_t r = NULL;
+
+  memset (&sk, 0, sizeof sk);
   point_init (&kG);
-  err = os2ec (&kG, data[0]);
-  if (err)
+  point_init (&R);
+
+  _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT,
+                                   ecc_get_nbits (keyparms));
+
+  /*
+   * Extract the data.
+   */
+  rc = _gcry_pk_util_preparse_encval (s_data, ecc_names, &l1, &ctx);
+  if (rc)
+    goto leave;
+  rc = sexp_extract_param (l1, NULL, "e", &data_e, NULL);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    log_printmpi ("ecc_decrypt  d_e", data_e);
+  if (mpi_is_opaque (data_e))
     {
-      point_free (&kG);
-      return err;
+      rc = GPG_ERR_INV_DATA;
+      goto leave;
     }
 
-
-  sk.E.p = skey[0];
-  sk.E.a = skey[1];
-  sk.E.b = skey[2];
-  point_init (&sk.E.G);
-  err = os2ec (&sk.E.G, skey[3]);
-  if (err)
+  /*
+   * Extract the key.
+   */
+  rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?+d",
+                           &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n,
+                           &sk.d, NULL);
+  if (rc)
+    goto leave;
+  if (mpi_g)
     {
-      point_free (&kG);
-      point_free (&sk.E.G);
-      return err;
+      point_init (&sk.E.G);
+      rc = _gcry_ecc_os2ec (&sk.E.G, mpi_g);
+      if (rc)
+        goto leave;
+    }
+  /* Add missing parameters using the optional curve parameter.  */
+  sexp_release (l1);
+  l1 = sexp_find_token (keyparms, "curve", 5);
+  if (l1)
+    {
+      curvename = sexp_nth_string (l1, 1);
+      if (curvename)
+        {
+          rc = _gcry_ecc_fill_in_curve (0, curvename, &sk.E, NULL);
+          if (rc)
+            return rc;
+        }
+    }
+  /* Guess required fields if a curve parameter has not been given.  */
+  if (!curvename)
+    {
+      sk.E.model = MPI_EC_WEIERSTRASS;
+      sk.E.dialect = ECC_DIALECT_STANDARD;
     }
-  sk.E.n = skey[4];
-  point_init (&sk.Q);
-  err = os2ec (&sk.Q, skey[5]);
-  if (err)
+  if (DBG_CIPHER)
+    {
+      log_debug ("ecc_decrypt info: %s/%s\n",
+                 _gcry_ecc_model2str (sk.E.model),
+                 _gcry_ecc_dialect2str (sk.E.dialect));
+      if (sk.E.name)
+        log_debug  ("ecc_decrypt name: %s\n", sk.E.name);
+      log_printmpi ("ecc_decrypt    p", sk.E.p);
+      log_printmpi ("ecc_decrypt    a", sk.E.a);
+      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);
+      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)
+    {
+      rc = GPG_ERR_NO_OBJ;
+      goto leave;
+    }
+
+
+  /*
+   * Compute the plaintext.
+   */
+  rc = _gcry_ecc_os2ec (&kG, data_e);
+  if (rc)
     {
       point_free (&kG);
-      point_free (&sk.E.G);
-      point_free (&sk.Q);
-      return err;
+      return rc;
     }
-  sk.d = skey[6];
 
-  ctx = _gcry_mpi_ec_init (sk.E.p, sk.E.a);
+  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 */
-  point_init (&R);
-  _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ctx);
-
-  point_free (&kG);
+  _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ec);
 
   /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so:  */
   {
@@ -1543,101 +1359,181 @@ ecc_decrypt_raw (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
     x = mpi_new (0);
     y = mpi_new (0);
 
-    if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
+    if (_gcry_mpi_ec_get_affine (x, y, &R, ec))
       log_fatal ("ecdh: Failed to get affine coordinates\n");
 
-    r = ec2os (x, y, sk.E.p);
+    r = _gcry_ecc_ec2os (x, y, sk.E.p);
+    if (!r)
+      rc = gpg_err_code_from_syserror ();
+    else
+      rc = 0;
     mpi_free (x);
     mpi_free (y);
   }
+  if (DBG_CIPHER)
+    log_printmpi ("ecc_decrypt  res", r);
+
+  if (!rc)
+    rc = sexp_build (r_plain, NULL, "(value %m)", r);
 
+ leave:
   point_free (&R);
-  _gcry_mpi_ec_free (ctx);
   point_free (&kG);
+  _gcry_mpi_release (r);
+  _gcry_mpi_release (sk.E.p);
+  _gcry_mpi_release (sk.E.a);
+  _gcry_mpi_release (sk.E.b);
+  _gcry_mpi_release (mpi_g);
   point_free (&sk.E.G);
-  point_free (&sk.Q);
-
-  if (!r)
-    return GPG_ERR_ENOMEM;
-
-  /* Success.  */
-
-  *result = r;
-
-  return 0;
+  _gcry_mpi_release (sk.E.n);
+  _gcry_mpi_release (sk.d);
+  _gcry_mpi_release (data_e);
+  xfree (curvename);
+  sexp_release (l1);
+  _gcry_mpi_ec_free (ec);
+  _gcry_pk_util_free_encoding_ctx (&ctx);
+  if (DBG_CIPHER)
+    log_debug ("ecc_decrypt    => %s\n", gpg_strerror (rc));
+  return rc;
 }
 
 
+/* Return the number of bits for the key described by PARMS.  On error
+ * 0 is returned.  The format of PARMS starts with the algorithm name;
+ * for example:
+ *
+ *   (ecc
+ *     (p <mpi>)
+ *     (a <mpi>)
+ *     (b <mpi>)
+ *     (g <mpi>)
+ *     (n <mpi>)
+ *     (q <mpi>))
+ *
+ * More parameters may be given currently P is needed.  FIXME: We
+ * need allow for a "curve" parameter.
+ */
 static unsigned int
-ecc_get_nbits (int algo, gcry_mpi_t *pkey)
+ecc_get_nbits (gcry_sexp_t parms)
 {
-  (void)algo;
+  gcry_sexp_t l1;
+  gcry_mpi_t p;
+  unsigned int nbits = 0;
+  char *curve;
+
+  l1 = sexp_find_token (parms, "p", 1);
+  if (!l1)
+    { /* Parameter P not found - check whether we have "curve".  */
+      l1 = sexp_find_token (parms, "curve", 5);
+      if (!l1)
+        return 0; /* Neither P nor CURVE found.  */
+
+      curve = sexp_nth_string (l1, 1);
+      sexp_release (l1);
+      if (!curve)
+        return 0;  /* No curve name given (or out of core). */
 
-  return mpi_get_nbits (pkey[0]);
+      if (_gcry_ecc_fill_in_curve (0, curve, NULL, &nbits))
+        nbits = 0;
+      xfree (curve);
+    }
+  else
+    {
+      p = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+      sexp_release (l1);
+      if (p)
+        {
+          nbits = mpi_get_nbits (p);
+          _gcry_mpi_release (p);
+        }
+    }
+  return nbits;
 }
 
 
 /* See rsa.c for a description of this function.  */
 static gpg_err_code_t
-compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
+compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms)
 {
 #define N_COMPONENTS 6
   static const char names[N_COMPONENTS+1] = "pabgnq";
-  gpg_err_code_t ec = 0;
+  gpg_err_code_t rc;
   gcry_sexp_t l1;
   gcry_mpi_t values[N_COMPONENTS];
   int idx;
+  char *curvename = NULL;
+  int flags = 0;
+  enum gcry_mpi_ec_models model = 0;
+  enum ecc_dialects dialect = 0;
 
-  /* Clear the values for easier error cleanup.  */
+  /* Clear the values first.  */
   for (idx=0; idx < N_COMPONENTS; idx++)
     values[idx] = NULL;
 
-  /* Fill values with all provided parameters.  */
-  for (idx=0; idx < N_COMPONENTS; idx++)
+
+  /* Look for flags. */
+  l1 = sexp_find_token (keyparms, "flags", 0);
+  if (l1)
     {
-      l1 = gcry_sexp_find_token (keyparam, names+idx, 1);
-      if (l1)
-        {
-          values[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
-         gcry_sexp_release (l1);
-         if (!values[idx])
-            {
-              ec = GPG_ERR_INV_OBJ;
-              goto leave;
-            }
-       }
+      rc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
+      if (rc)
+        goto leave;
+    }
+
+  /* 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",
+                                 &values[0], &values[1], &values[2],
+                                 &values[3], &values[4], &values[5],
+                                 NULL);
+      else
+        rc = sexp_extract_param (keyparms, NULL, "p?a?b?g?n?q",
+                                 &values[0], &values[1], &values[2],
+                                 &values[3], &values[4], &values[5],
+                                 NULL);
+    }
+  else
+    {
+      if ((flags & PUBKEY_FLAG_EDDSA))
+        rc = sexp_extract_param (keyparms, NULL, "/q",
+                                 &values[5], NULL);
+      else
+        rc = sexp_extract_param (keyparms, NULL, "q",
+                                 &values[5], NULL);
     }
+  if (rc)
+    goto leave;
 
   /* Check whether a curve parameter is available and use that to fill
      in missing values.  */
-  l1 = gcry_sexp_find_token (keyparam, "curve", 5);
+  sexp_release (l1);
+  l1 = sexp_find_token (keyparms, "curve", 5);
   if (l1)
     {
-      char *curve;
-      gcry_mpi_t tmpvalues[N_COMPONENTS];
-
-      for (idx = 0; idx < N_COMPONENTS; idx++)
-        tmpvalues[idx] = NULL;
-
-      curve = _gcry_sexp_nth_string (l1, 1);
-      gcry_sexp_release (l1);
-      if (!curve)
+      curvename = sexp_nth_string (l1, 1);
+      if (curvename)
         {
-          ec = GPG_ERR_INV_OBJ; /* Name missing or out of core. */
-          goto leave;
+          rc = _gcry_ecc_update_curve_param (curvename,
+                                             &model, &dialect,
+                                             &values[0], &values[1], &values[2],
+                                             &values[3], &values[4]);
+          if (rc)
+            goto leave;
         }
-      ec = ecc_get_param (curve, tmpvalues);
-      gcry_free (curve);
-      if (ec)
-        goto leave;
+    }
 
-      for (idx = 0; idx < N_COMPONENTS; idx++)
-        {
-          if (!values[idx])
-            values[idx] = tmpvalues[idx];
-          else
-            mpi_free (tmpvalues[idx]);
-        }
+  /* Guess required fields if a curve parameter has not been given.
+     FIXME: This is a crude hacks.  We need to fix that.  */
+  if (!curvename)
+    {
+      model = ((flags & PUBKEY_FLAG_EDDSA)
+               ? MPI_EC_TWISTEDEDWARDS
+               : MPI_EC_WEIERSTRASS);
+      dialect = ((flags & PUBKEY_FLAG_EDDSA)
+                 ? ECC_DIALECT_ED25519
+                 : ECC_DIALECT_STANDARD);
     }
 
   /* Check that all parameters are known and normalize all MPIs (that
@@ -1646,41 +1542,159 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
   for (idx = 0; idx < N_COMPONENTS; idx++)
     if (!values[idx])
       {
-        ec = GPG_ERR_NO_OBJ;
+        rc = GPG_ERR_NO_OBJ;
         goto leave;
       }
     else
       _gcry_mpi_normalize (values[idx]);
 
+  /* Uncompress the public key with the exception of EdDSA where
+     compression is the default and we thus compute the keygrip using
+     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 (dialect == ECC_DIALECT_ED25519)
+        rc = _gcry_ecc_eddsa_ensure_compact (values[5], 256);
+      else
+        rc = GPG_ERR_NOT_IMPLEMENTED;
+      if (rc)
+        goto leave;
+    }
+
   /* Hash them all.  */
   for (idx = 0; idx < N_COMPONENTS; idx++)
     {
       char buf[30];
-      unsigned char *rawmpi;
-      unsigned int rawmpilen;
 
-      rawmpi = _gcry_mpi_get_buffer (values[idx], &rawmpilen, NULL);
-      if (!rawmpi)
+      if (mpi_is_opaque (values[idx]))
         {
-          ec = gpg_err_code_from_syserror ();
-          goto leave;
+          const unsigned char *raw;
+          unsigned int n;
+
+          raw = mpi_get_opaque (values[idx], &n);
+          n = (n + 7)/8;
+          snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], n);
+          _gcry_md_write (md, buf, strlen (buf));
+          _gcry_md_write (md, raw, n);
+          _gcry_md_write (md, ")", 1);
+        }
+      else
+        {
+          unsigned char *rawmpi;
+          unsigned int rawmpilen;
+
+          rawmpi = _gcry_mpi_get_buffer (values[idx], 0, &rawmpilen, NULL);
+          if (!rawmpi)
+            {
+              rc = gpg_err_code_from_syserror ();
+              goto leave;
+            }
+          snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], rawmpilen);
+          _gcry_md_write (md, buf, strlen (buf));
+          _gcry_md_write (md, rawmpi, rawmpilen);
+          _gcry_md_write (md, ")", 1);
+          xfree (rawmpi);
         }
-      snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], rawmpilen);
-      gcry_md_write (md, buf, strlen (buf));
-      gcry_md_write (md, rawmpi, rawmpilen);
-      gcry_md_write (md, ")", 1);
-      gcry_free (rawmpi);
     }
 
  leave:
+  xfree (curvename);
+  sexp_release (l1);
   for (idx = 0; idx < N_COMPONENTS; idx++)
     _gcry_mpi_release (values[idx]);
 
-  return ec;
+  return rc;
 #undef N_COMPONENTS
 }
 
 
+\f
+/*
+   Low-level API helper functions.
+ */
+
+/* This is the worker function for gcry_pubkey_get_sexp for ECC
+   algorithms.  Note that the caller has already stored NULL at
+   R_SEXP.  */
+gpg_err_code_t
+_gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec)
+{
+  gpg_err_code_t rc;
+  gcry_mpi_t mpi_G = NULL;
+  gcry_mpi_t mpi_Q = NULL;
+
+  if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n)
+    return GPG_ERR_BAD_CRYPT_CTX;
+
+  if (mode == GCRY_PK_GET_SECKEY && !ec->d)
+    return GPG_ERR_NO_SECKEY;
+
+  /* Compute the public point if it is missing.  */
+  if (!ec->Q && ec->d)
+    ec->Q = _gcry_ecc_compute_public (NULL, ec, NULL, NULL);
+
+  /* Encode G and Q.  */
+  mpi_G = _gcry_mpi_ec_ec2os (ec->G, ec);
+  if (!mpi_G)
+    {
+      rc = GPG_ERR_BROKEN_PUBKEY;
+      goto leave;
+    }
+  if (!ec->Q)
+    {
+      rc = GPG_ERR_BAD_CRYPT_CTX;
+      goto leave;
+    }
+
+  if (ec->dialect == ECC_DIALECT_ED25519)
+    {
+      unsigned char *encpk;
+      unsigned int encpklen;
+
+      rc = _gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL,
+                                        &encpk, &encpklen);
+      if (rc)
+        goto leave;
+      mpi_Q = mpi_set_opaque (NULL, encpk, encpklen*8);
+      encpk = NULL;
+    }
+  else
+    {
+      mpi_Q = _gcry_mpi_ec_ec2os (ec->Q, ec);
+    }
+  if (!mpi_Q)
+    {
+      rc = GPG_ERR_BROKEN_PUBKEY;
+      goto leave;
+    }
+
+  /* Fixme: We should return a curve name instead of the parameters if
+     if know that they match a curve.  */
+
+  if (ec->d && (!mode || mode == GCRY_PK_GET_SECKEY))
+    {
+      /* 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);
+    }
+  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);
+    }
+  else
+    rc = GPG_ERR_BAD_CRYPT_CTX;
+
+ leave:
+  mpi_free (mpi_Q);
+  mpi_free (mpi_G);
+  return rc;
+}
 
 
 \f
@@ -1706,7 +1720,7 @@ selftests_ecdsa (selftest_report_func_t report)
 
  failed:
   if (report)
-    report ("pubkey", GCRY_PK_ECDSA, what, errtxt);
+    report ("pubkey", GCRY_PK_ECC, what, errtxt);
   return GPG_ERR_SELFTEST_FAILED;
 }
 
@@ -1715,74 +1729,32 @@ selftests_ecdsa (selftest_report_func_t report)
 static gpg_err_code_t
 run_selftests (int algo, int extended, selftest_report_func_t report)
 {
-  gpg_err_code_t ec;
-
   (void)extended;
 
-  switch (algo)
-    {
-    case GCRY_PK_ECDSA:
-      ec = selftests_ecdsa (report);
-      break;
-    default:
-      ec = GPG_ERR_PUBKEY_ALGO;
-      break;
+  if (algo != GCRY_PK_ECC)
+    return GPG_ERR_PUBKEY_ALGO;
 
-    }
-  return ec;
+  return selftests_ecdsa (report);
 }
 
 
 
 \f
-static const char *ecdsa_names[] =
-  {
-    "ecdsa",
-    "ecc",
-    NULL,
-  };
-static const char *ecdh_names[] =
-  {
-    "ecdh",
-    "ecc",
-    NULL,
-  };
-
-gcry_pk_spec_t _gcry_pubkey_spec_ecdsa =
-  {
-    "ECDSA", ecdsa_names,
-    "pabgnq", "pabgnqd", "", "rs", "pabgnq",
-    GCRY_PK_USAGE_SIGN,
-    ecc_generate,
-    ecc_check_secret_key,
-    NULL,
-    NULL,
-    ecc_sign,
-    ecc_verify,
-    ecc_get_nbits
-  };
-
-gcry_pk_spec_t _gcry_pubkey_spec_ecdh =
+gcry_pk_spec_t _gcry_pubkey_spec_ecc =
   {
-    "ECDH", ecdh_names,
-    "pabgnq", "pabgnqd", "se", "", "pabgnq",
-    GCRY_PK_USAGE_ENCR,
+    GCRY_PK_ECC, { 0, 0 },
+    (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR),
+    "ECC", ecc_names,
+    "pabgnq", "pabgnqd", "sw", "rs", "pabgnq",
     ecc_generate,
     ecc_check_secret_key,
     ecc_encrypt_raw,
     ecc_decrypt_raw,
-    NULL,
-    NULL,
-    ecc_get_nbits
-  };
-
-
-pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa =
-  {
+    ecc_sign,
+    ecc_verify,
+    ecc_get_nbits,
     run_selftests,
-    ecc_generate_ext,
     compute_keygrip,
-    ecc_get_param,
-    ecc_get_curve,
-    ecc_get_param_sexp
+    _gcry_ecc_get_curve,
+    _gcry_ecc_get_param_sexp
   };
index ce4be85..a71a9bc 100644 (file)
@@ -1,6 +1,7 @@
 /* Elgamal.c  -  Elgamal Public Key encryption
  * Copyright (C) 1998, 2000, 2001, 2002, 2003,
  *               2008  Free Software Foundation, Inc.
+ * Copyright (C) 2013 g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
@@ -29,6 +30,8 @@
 #include "g10lib.h"
 #include "mpi.h"
 #include "cipher.h"
+#include "pubkey-internal.h"
+
 
 typedef struct
 {
@@ -47,6 +50,15 @@ typedef struct
 } ELG_secret_key;
 
 
+static const char *elg_names[] =
+  {
+    "elg",
+    "openpgp-elg",
+    "openpgp-elg-sig",
+    NULL,
+  };
+
+
 static int test_keys (ELG_secret_key *sk, unsigned int nbits, int nodie);
 static gcry_mpi_t gen_k (gcry_mpi_t p, int small_k);
 static void generate (ELG_secret_key *sk, unsigned nbits, gcry_mpi_t **factors);
@@ -59,6 +71,7 @@ static void sign (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
                   ELG_secret_key *skey);
 static int  verify (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input,
                     ELG_public_key *pkey);
+static unsigned int elg_get_nbits (gcry_sexp_t parms);
 
 
 static void (*progress_cb) (void *, const char *, int, int, int);
@@ -128,17 +141,17 @@ static int
 test_keys ( ELG_secret_key *sk, unsigned int nbits, int nodie )
 {
   ELG_public_key pk;
-  gcry_mpi_t test = gcry_mpi_new ( 0 );
-  gcry_mpi_t out1_a = gcry_mpi_new ( nbits );
-  gcry_mpi_t out1_b = gcry_mpi_new ( nbits );
-  gcry_mpi_t out2 = gcry_mpi_new ( nbits );
+  gcry_mpi_t test   = mpi_new ( 0 );
+  gcry_mpi_t out1_a = mpi_new ( nbits );
+  gcry_mpi_t out1_b = mpi_new ( nbits );
+  gcry_mpi_t out2   = mpi_new ( nbits );
   int failed = 0;
 
   pk.p = sk->p;
   pk.g = sk->g;
   pk.y = sk->y;
 
-  gcry_mpi_randomize ( test, nbits, GCRY_WEAK_RANDOM );
+  _gcry_mpi_randomize ( test, nbits, GCRY_WEAK_RANDOM );
 
   do_encrypt ( out1_a, out1_b, test, &pk );
   decrypt ( out2, out1_a, out1_b, sk );
@@ -149,10 +162,10 @@ test_keys ( ELG_secret_key *sk, unsigned int nbits, int nodie )
   if ( !verify( out1_a, out1_b, test, &pk ) )
     failed |= 2;
 
-  gcry_mpi_release ( test );
-  gcry_mpi_release ( out1_a );
-  gcry_mpi_release ( out1_b );
-  gcry_mpi_release ( out2 );
+  _gcry_mpi_release ( test );
+  _gcry_mpi_release ( out1_a );
+  _gcry_mpi_release ( out1_b );
+  _gcry_mpi_release ( out2 );
 
   if (failed && !nodie)
     log_fatal ("Elgamal test key for %s %s failed\n",
@@ -197,14 +210,14 @@ gen_k( gcry_mpi_t p, int small_k )
 
   nbytes = (nbits+7)/8;
   if( DBG_CIPHER )
-    log_debug("choosing a random k ");
+    log_debug("choosing a random k\n");
   mpi_sub_ui( p_1, p, 1);
   for(;;)
     {
       if( !rndbuf || nbits < 32 )
         {
-          gcry_free(rndbuf);
-          rndbuf = gcry_random_bytes_secure( nbytes, GCRY_STRONG_RANDOM );
+          xfree(rndbuf);
+          rndbuf = _gcry_random_bytes_secure( nbytes, GCRY_STRONG_RANDOM );
         }
       else
         {
@@ -213,9 +226,9 @@ gen_k( gcry_mpi_t p, int small_k )
              to get_random_bytes() and use this the here maybe it is
              easier to do this directly in random.c Anyway, it is
              highly inlikely that we will ever reach this code. */
-          char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
+          char *pp = _gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
           memcpy( rndbuf, pp, 4 );
-          gcry_free(pp);
+          xfree(pp);
        }
       _gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
 
@@ -233,7 +246,7 @@ gen_k( gcry_mpi_t p, int small_k )
                 progress('-');
               break; /* no */
             }
-          if (gcry_mpi_gcd( temp, k, p_1 ))
+          if (mpi_gcd( temp, k, p_1 ))
             goto found;  /* okay, k is relative prime to (p-1) */
           mpi_add_ui( k, k, 1 );
           if( DBG_CIPHER )
@@ -241,7 +254,7 @@ gen_k( gcry_mpi_t p, int small_k )
        }
     }
  found:
-  gcry_free(rndbuf);
+  xfree (rndbuf);
   if( DBG_CIPHER )
     progress('\n');
   mpi_free(p_1);
@@ -267,7 +280,7 @@ generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors )
   unsigned int xbits;
   byte *rndbuf;
 
-  p_min1 = gcry_mpi_new ( nbits );
+  p_min1 = mpi_new ( nbits );
   qbits = wiener_map( nbits );
   if( qbits & 1 ) /* better have a even one */
     qbits++;
@@ -290,9 +303,9 @@ generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors )
   xbits = qbits * 3 / 2;
   if( xbits >= nbits )
     BUG();
-  x = gcry_mpi_snew ( xbits );
+  x = mpi_snew ( xbits );
   if( DBG_CIPHER )
-    log_debug("choosing a random x of size %u", xbits );
+    log_debug("choosing a random x of size %u\n", xbits );
   rndbuf = NULL;
   do
     {
@@ -302,39 +315,38 @@ generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors )
         { /* Change only some of the higher bits */
           if( xbits < 16 ) /* should never happen ... */
             {
-              gcry_free(rndbuf);
-              rndbuf = gcry_random_bytes_secure( (xbits+7)/8,
-                                                 GCRY_VERY_STRONG_RANDOM );
+              xfree(rndbuf);
+              rndbuf = _gcry_random_bytes_secure ((xbits+7)/8,
+                                                  GCRY_VERY_STRONG_RANDOM);
             }
           else
             {
-              char *r = gcry_random_bytes_secure( 2,
-                                                  GCRY_VERY_STRONG_RANDOM );
+              char *r = _gcry_random_bytes_secure (2, GCRY_VERY_STRONG_RANDOM);
               memcpy(rndbuf, r, 2 );
-              gcry_free(r);
+              xfree (r);
             }
        }
       else
         {
-          rndbuf = gcry_random_bytes_secure( (xbits+7)/8,
-                                             GCRY_VERY_STRONG_RANDOM );
+          rndbuf = _gcry_random_bytes_secure ((xbits+7)/8,
+                                              GCRY_VERY_STRONG_RANDOM );
        }
       _gcry_mpi_set_buffer( x, rndbuf, (xbits+7)/8, 0 );
       mpi_clear_highbit( x, xbits+1 );
     }
   while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) );
-  gcry_free(rndbuf);
+  xfree(rndbuf);
 
-  y = gcry_mpi_new (nbits);
-  gcry_mpi_powm( y, g, x, p );
+  y = mpi_new (nbits);
+  mpi_powm( y, g, x, p );
 
   if( DBG_CIPHER )
     {
-      progress('\n');
-      log_mpidump("elg  p= ", p );
-      log_mpidump("elg  g= ", g );
-      log_mpidump("elg  y= ", y );
-      log_mpidump("elg  x= ", x );
+      progress ('\n');
+      log_mpidump ("elg  p", p );
+      log_mpidump ("elg  g", g );
+      log_mpidump ("elg  y", y );
+      log_mpidump ("elg  x", x );
     }
 
   /* Copy the stuff to the key structures */
@@ -343,7 +355,7 @@ generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors )
   sk->y = y;
   sk->x = x;
 
-  gcry_mpi_release ( p_min1 );
+  _gcry_mpi_release ( p_min1 );
 
   /* Now we can test our keys (this should never fail!) */
   test_keys ( sk, nbits - 64, 0 );
@@ -378,7 +390,7 @@ generate_using_x (ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t x,
   if ( xbits < 64 || xbits >= nbits )
     return GPG_ERR_INV_VALUE;
 
-  p_min1 = gcry_mpi_new ( nbits );
+  p_min1 = mpi_new ( nbits );
   qbits  = wiener_map ( nbits );
   if ( (qbits & 1) ) /* Better have an even one.  */
     qbits++;
@@ -390,39 +402,39 @@ generate_using_x (ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t x,
     log_debug ("using a supplied x of size %u", xbits );
   if ( !(mpi_cmp_ui ( x, 0 ) > 0 && mpi_cmp ( x, p_min1 ) <0 ) )
     {
-      gcry_mpi_release ( p_min1 );
-      gcry_mpi_release ( p );
-      gcry_mpi_release ( g );
+      _gcry_mpi_release ( p_min1 );
+      _gcry_mpi_release ( p );
+      _gcry_mpi_release ( g );
       return GPG_ERR_INV_VALUE;
     }
 
-  y = gcry_mpi_new (nbits);
-  gcry_mpi_powm ( y, g, x, p );
+  y = mpi_new (nbits);
+  mpi_powm ( y, g, x, p );
 
   if ( DBG_CIPHER )
     {
       progress ('\n');
-      log_mpidump ("elg  p", p );
-      log_mpidump ("elg  g", g );
-      log_mpidump ("elg  y", y );
-      log_mpidump ("elg  x", x );
+      log_mpidump ("elg  p", p );
+      log_mpidump ("elg  g", g );
+      log_mpidump ("elg  y", y );
+      log_mpidump ("elg  x", x );
     }
 
   /* Copy the stuff to the key structures */
   sk->p = p;
   sk->g = g;
   sk->y = y;
-  sk->x = gcry_mpi_copy (x);
+  sk->x = mpi_copy (x);
 
-  gcry_mpi_release ( p_min1 );
+  _gcry_mpi_release ( p_min1 );
 
   /* Now we can test our keys. */
   if ( test_keys ( sk, nbits - 64, 1 ) )
     {
-      gcry_mpi_release ( sk->p ); sk->p = NULL;
-      gcry_mpi_release ( sk->g ); sk->g = NULL;
-      gcry_mpi_release ( sk->y ); sk->y = NULL;
-      gcry_mpi_release ( sk->x ); sk->x = NULL;
+      _gcry_mpi_release ( sk->p ); sk->p = NULL;
+      _gcry_mpi_release ( sk->g ); sk->g = NULL;
+      _gcry_mpi_release ( sk->y ); sk->y = NULL;
+      _gcry_mpi_release ( sk->x ); sk->x = NULL;
       return GPG_ERR_BAD_SECKEY;
     }
 
@@ -440,7 +452,7 @@ check_secret_key( ELG_secret_key *sk )
   int rc;
   gcry_mpi_t y = mpi_alloc( mpi_get_nlimbs(sk->y) );
 
-  gcry_mpi_powm( y, sk->g, sk->x, sk->p );
+  mpi_powm (y, sk->g, sk->x, sk->p);
   rc = !mpi_cmp( y, sk->y );
   mpi_free( y );
   return rc;
@@ -458,23 +470,24 @@ do_encrypt(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
    */
 
   k = gen_k( pkey->p, 1 );
-  gcry_mpi_powm( a, pkey->g, k, pkey->p );
+  mpi_powm (a, pkey->g, k, pkey->p);
+
   /* b = (y^k * input) mod p
    *    = ((y^k mod p) * (input mod p)) mod p
    * and because input is < p
    *    = ((y^k mod p) * input) mod p
    */
-  gcry_mpi_powm( b, pkey->y, k, pkey->p );
-  gcry_mpi_mulm( b, b, input, pkey->p );
+  mpi_powm (b, pkey->y, k, pkey->p);
+  mpi_mulm (b, b, input, pkey->p);
 #if 0
   if( DBG_CIPHER )
     {
-      log_mpidump("elg encrypted y", pkey->y);
-      log_mpidump("elg encrypted p", pkey->p);
-      log_mpidump("elg encrypted k", k);
-      log_mpidump("elg encrypted M", input);
-      log_mpidump("elg encrypted a", a);
-      log_mpidump("elg encrypted b", b);
+      log_mpidump("elg encrypted y", pkey->y);
+      log_mpidump("elg encrypted p", pkey->p);
+      log_mpidump("elg encrypted k", k);
+      log_mpidump("elg encrypted M", input);
+      log_mpidump("elg encrypted a", a);
+      log_mpidump("elg encrypted b", b);
     }
 #endif
   mpi_free(k);
@@ -484,22 +497,25 @@ 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 )
+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 ) );
 
+  mpi_normalize (a);
+  mpi_normalize (b);
+
   /* output = b/(a^x) mod p */
-  gcry_mpi_powm( t1, a, skey->x, skey->p );
+  mpi_powm( t1, a, skey->x, skey->p );
   mpi_invm( t1, t1, skey->p );
   mpi_mulm( output, b, t1, skey->p );
 #if 0
   if( DBG_CIPHER )
     {
-      log_mpidump("elg decrypted x= ", skey->x);
-      log_mpidump("elg decrypted p= ", skey->p);
-      log_mpidump("elg decrypted a= ", a);
-      log_mpidump("elg decrypted b= ", b);
-      log_mpidump("elg decrypted M= ", output);
+      log_mpidump ("elg decrypted x", skey->x);
+      log_mpidump ("elg decrypted p", skey->p);
+      log_mpidump ("elg decrypted a", a);
+      log_mpidump ("elg decrypted b", b);
+      log_mpidump ("elg decrypted M", output);
     }
 #endif
   mpi_free(t1);
@@ -526,7 +542,7 @@ sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey )
     */
     mpi_sub_ui(p_1, p_1, 1);
     k = gen_k( skey->p, 0 /* no small K ! */ );
-    gcry_mpi_powm( a, skey->g, k, skey->p );
+    mpi_powm( a, skey->g, k, skey->p );
     mpi_mul(t, skey->x, a );
     mpi_subm(t, input, t, p_1 );
     mpi_invm(inv, k, p_1 );
@@ -535,14 +551,14 @@ sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey )
 #if 0
     if( DBG_CIPHER )
       {
-       log_mpidump("elg sign p= ", skey->p);
-       log_mpidump("elg sign g= ", skey->g);
-       log_mpidump("elg sign y= ", skey->y);
-       log_mpidump("elg sign x= ", skey->x);
-       log_mpidump("elg sign k= ", k);
-       log_mpidump("elg sign M= ", input);
-       log_mpidump("elg sign a= ", a);
-       log_mpidump("elg sign b= ", b);
+       log_mpidump ("elg sign p", skey->p);
+       log_mpidump ("elg sign g", skey->g);
+       log_mpidump ("elg sign y", skey->y);
+       log_mpidump ("elg sign x", skey->x);
+       log_mpidump ("elg sign k", k);
+       log_mpidump ("elg sign M", input);
+       log_mpidump ("elg sign a", a);
+       log_mpidump ("elg sign b", b);
       }
 #endif
     mpi_free(k);
@@ -613,233 +629,469 @@ verify(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey )
  *********************************************/
 
 static gpg_err_code_t
-elg_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
-                  const gcry_sexp_t genparms,
-                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
-                  gcry_sexp_t *r_extrainfo)
+elg_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
 {
-  gpg_err_code_t ec;
+  gpg_err_code_t rc;
+  unsigned int nbits;
   ELG_secret_key sk;
   gcry_mpi_t xvalue = NULL;
   gcry_sexp_t l1;
+  gcry_mpi_t *factors = NULL;
+  gcry_sexp_t misc_info = NULL;
+
+  memset (&sk, 0, sizeof sk);
 
-  (void)algo;
-  (void)evalue;
-  (void)r_extrainfo;
+  rc = _gcry_pk_util_get_nbits (genparms, &nbits);
+  if (rc)
+    return rc;
 
-  if (genparms)
+  /* Parse the optional xvalue element. */
+  l1 = sexp_find_token (genparms, "xvalue", 0);
+  if (l1)
     {
-      /* Parse the optional xvalue element. */
-      l1 = gcry_sexp_find_token (genparms, "xvalue", 0);
-      if (l1)
-        {
-          xvalue = gcry_sexp_nth_mpi (l1, 1, 0);
-          gcry_sexp_release (l1);
-          if (!xvalue)
-            return GPG_ERR_BAD_MPI;
-        }
+      xvalue = sexp_nth_mpi (l1, 1, 0);
+      sexp_release (l1);
+      if (!xvalue)
+        return GPG_ERR_BAD_MPI;
     }
 
   if (xvalue)
-    ec = generate_using_x (&sk, nbits, xvalue, retfactors);
+    {
+      rc = generate_using_x (&sk, nbits, xvalue, &factors);
+      mpi_free (xvalue);
+    }
   else
     {
-      generate (&sk, nbits, retfactors);
-      ec = 0;
+      generate (&sk, nbits, &factors);
+      rc = 0;
+    }
+  if (rc)
+    goto leave;
+
+  if (factors && factors[0])
+    {
+      int nfac;
+      void **arg_list;
+      char *buffer, *p;
+
+      for (nfac = 0; factors[nfac]; nfac++)
+        ;
+      arg_list = xtrycalloc (nfac+1, sizeof *arg_list);
+      if (!arg_list)
+        {
+          rc = gpg_err_code_from_syserror ();
+          goto leave;
+        }
+      buffer = xtrymalloc (30 + nfac*2 + 2 + 1);
+      if (!buffer)
+        {
+          rc = gpg_err_code_from_syserror ();
+          xfree (arg_list);
+          goto leave;
+        }
+      p = stpcpy (buffer, "(misc-key-info(pm1-factors");
+      for(nfac = 0; factors[nfac]; nfac++)
+        {
+          p = stpcpy (p, "%m");
+          arg_list[nfac] = factors + nfac;
+        }
+      p = stpcpy (p, "))");
+      rc = sexp_build_array (&misc_info, NULL, buffer, arg_list);
+      xfree (arg_list);
+      xfree (buffer);
+      if (rc)
+        goto leave;
     }
 
-  skey[0] = sk.p;
-  skey[1] = sk.g;
-  skey[2] = sk.y;
-  skey[3] = sk.x;
+  rc = sexp_build (r_skey, NULL,
+                   "(key-data"
+                   " (public-key"
+                   "  (elg(p%m)(g%m)(y%m)))"
+                   " (private-key"
+                   "  (elg(p%m)(g%m)(y%m)(x%m)))"
+                   " %S)",
+                   sk.p, sk.g, sk.y,
+                   sk.p, sk.g, sk.y, sk.x,
+                   misc_info);
+
+ leave:
+  mpi_free (sk.p);
+  mpi_free (sk.g);
+  mpi_free (sk.y);
+  mpi_free (sk.x);
+  sexp_release (misc_info);
+  if (factors)
+    {
+      gcry_mpi_t *mp;
+      for (mp = factors; *mp; mp++)
+        mpi_free (*mp);
+      xfree (factors);
+    }
 
-  return ec;
+  return rc;
 }
 
 
 static gcry_err_code_t
-elg_generate (int algo, unsigned int nbits, unsigned long evalue,
-              gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+elg_check_secret_key (gcry_sexp_t keyparms)
 {
-  ELG_secret_key sk;
-
-  (void)algo;
-  (void)evalue;
-
-  generate (&sk, nbits, retfactors);
-  skey[0] = sk.p;
-  skey[1] = sk.g;
-  skey[2] = sk.y;
-  skey[3] = sk.x;
-
-  return GPG_ERR_NO_ERROR;
+  gcry_err_code_t rc;
+  ELG_secret_key sk = {NULL, NULL, NULL, NULL};
+
+  rc = sexp_extract_param (keyparms, NULL, "pgyx",
+                           &sk.p, &sk.g, &sk.y, &sk.x,
+                           NULL);
+  if (rc)
+    goto leave;
+
+  if (!check_secret_key (&sk))
+    rc = GPG_ERR_BAD_SECKEY;
+
+ leave:
+  _gcry_mpi_release (sk.p);
+  _gcry_mpi_release (sk.g);
+  _gcry_mpi_release (sk.y);
+  _gcry_mpi_release (sk.x);
+  if (DBG_CIPHER)
+    log_debug ("elg_testkey    => %s\n", gpg_strerror (rc));
+  return rc;
 }
 
 
 static gcry_err_code_t
-elg_check_secret_key (int algo, gcry_mpi_t *skey)
+elg_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  ELG_secret_key sk;
-
-  (void)algo;
-
-  if ((! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]))
-    err = GPG_ERR_BAD_MPI;
-  else
+  gcry_err_code_t rc;
+  struct pk_encoding_ctx ctx;
+  gcry_mpi_t mpi_a = NULL;
+  gcry_mpi_t mpi_b = NULL;
+  gcry_mpi_t data = NULL;
+  ELG_public_key pk = { NULL, NULL, NULL };
+
+  _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT,
+                                   elg_get_nbits (keyparms));
+
+  /* Extract the data.  */
+  rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    log_mpidump ("elg_encrypt data", data);
+  if (mpi_is_opaque (data))
     {
-      sk.p = skey[0];
-      sk.g = skey[1];
-      sk.y = skey[2];
-      sk.x = skey[3];
+      rc = GPG_ERR_INV_DATA;
+      goto leave;
+    }
 
-      if (! check_secret_key (&sk))
-       err = GPG_ERR_BAD_SECKEY;
+  /* Extract the key.  */
+  rc = sexp_extract_param (keyparms, NULL, "pgy",
+                           &pk.p, &pk.g, &pk.y, NULL);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    {
+      log_mpidump ("elg_encrypt  p", pk.p);
+      log_mpidump ("elg_encrypt  g", pk.g);
+      log_mpidump ("elg_encrypt  y", pk.y);
     }
 
-  return err;
+  /* Do Elgamal computation and build result.  */
+  mpi_a = mpi_new (0);
+  mpi_b = mpi_new (0);
+  do_encrypt (mpi_a, mpi_b, data, &pk);
+  rc = sexp_build (r_ciph, NULL, "(enc-val(elg(a%m)(b%m)))", mpi_a, mpi_b);
+
+ leave:
+  _gcry_mpi_release (mpi_a);
+  _gcry_mpi_release (mpi_b);
+  _gcry_mpi_release (pk.p);
+  _gcry_mpi_release (pk.g);
+  _gcry_mpi_release (pk.y);
+  _gcry_mpi_release (data);
+  _gcry_pk_util_free_encoding_ctx (&ctx);
+  if (DBG_CIPHER)
+    log_debug ("elg_encrypt   => %s\n", gpg_strerror (rc));
+  return rc;
 }
 
 
 static gcry_err_code_t
-elg_encrypt (int algo, gcry_mpi_t *resarr,
-             gcry_mpi_t data, gcry_mpi_t *pkey, int flags)
+elg_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  ELG_public_key pk;
-
-  (void)algo;
-  (void)flags;
-
-  if ((! data) || (! pkey[0]) || (! pkey[1]) || (! pkey[2]))
-    err = GPG_ERR_BAD_MPI;
-  else
+  gpg_err_code_t rc;
+  struct pk_encoding_ctx ctx;
+  gcry_sexp_t l1 = NULL;
+  gcry_mpi_t data_a = NULL;
+  gcry_mpi_t data_b = NULL;
+  ELG_secret_key sk = {NULL, NULL, NULL, NULL};
+  gcry_mpi_t plain = NULL;
+  unsigned char *unpad = NULL;
+  size_t unpadlen = 0;
+
+  _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT,
+                                   elg_get_nbits (keyparms));
+
+  /* Extract the data.  */
+  rc = _gcry_pk_util_preparse_encval (s_data, elg_names, &l1, &ctx);
+  if (rc)
+    goto leave;
+  rc = sexp_extract_param (l1, NULL, "ab", &data_a, &data_b, NULL);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
     {
-      pk.p = pkey[0];
-      pk.g = pkey[1];
-      pk.y = pkey[2];
-      resarr[0] = mpi_alloc (mpi_get_nlimbs (pk.p));
-      resarr[1] = mpi_alloc (mpi_get_nlimbs (pk.p));
-      do_encrypt (resarr[0], resarr[1], data, &pk);
+      log_printmpi ("elg_decrypt  d_a", data_a);
+      log_printmpi ("elg_decrypt  d_b", data_b);
+    }
+  if (mpi_is_opaque (data_a) || mpi_is_opaque (data_b))
+    {
+      rc = GPG_ERR_INV_DATA;
+      goto leave;
     }
-  return err;
-}
-
 
-static gcry_err_code_t
-elg_decrypt (int algo, gcry_mpi_t *result,
-             gcry_mpi_t *data, gcry_mpi_t *skey, int flags)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  ELG_secret_key sk;
+  /* Extract the key.  */
+  rc = sexp_extract_param (keyparms, NULL, "pgyx",
+                           &sk.p, &sk.g, &sk.y, &sk.x,
+                           NULL);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    {
+      log_printmpi ("elg_decrypt    p", sk.p);
+      log_printmpi ("elg_decrypt    g", sk.g);
+      log_printmpi ("elg_decrypt    y", sk.y);
+      if (!fips_mode ())
+        log_printmpi ("elg_decrypt    x", sk.x);
+    }
 
-  (void)algo;
-  (void)flags;
+  plain = mpi_snew (ctx.nbits);
+  decrypt (plain, data_a, data_b, &sk);
+  if (DBG_CIPHER)
+    log_printmpi ("elg_decrypt  res", plain);
 
-  if ((! data[0]) || (! data[1])
-      || (! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]))
-    err = GPG_ERR_BAD_MPI;
-  else
+  /* Reverse the encoding and build the s-expression.  */
+  switch (ctx.encoding)
     {
-      sk.p = skey[0];
-      sk.g = skey[1];
-      sk.y = skey[2];
-      sk.x = skey[3];
-      *result = mpi_alloc_secure (mpi_get_nlimbs (sk.p));
-      decrypt (*result, data[0], data[1], &sk);
+    case PUBKEY_ENC_PKCS1:
+      rc = _gcry_rsa_pkcs1_decode_for_enc (&unpad, &unpadlen, ctx.nbits, plain);
+      mpi_free (plain); plain = NULL;
+      if (!rc)
+        rc = sexp_build (r_plain, NULL, "(value %b)", (int)unpadlen, unpad);
+      break;
+
+    case PUBKEY_ENC_OAEP:
+      rc = _gcry_rsa_oaep_decode (&unpad, &unpadlen,
+                                  ctx.nbits, ctx.hash_algo, plain,
+                                  ctx.label, ctx.labellen);
+      mpi_free (plain); plain = NULL;
+      if (!rc)
+        rc = sexp_build (r_plain, NULL, "(value %b)", (int)unpadlen, unpad);
+      break;
+
+    default:
+      /* Raw format.  For backward compatibility we need to assume a
+         signed mpi by using the sexp format string "%m".  */
+      rc = sexp_build (r_plain, NULL,
+                       (ctx.flags & PUBKEY_FLAG_LEGACYRESULT)
+                       ? "%m" : "(value %m)",
+                       plain);
+      break;
     }
-  return err;
+
+
+ leave:
+  xfree (unpad);
+  _gcry_mpi_release (plain);
+  _gcry_mpi_release (sk.p);
+  _gcry_mpi_release (sk.g);
+  _gcry_mpi_release (sk.y);
+  _gcry_mpi_release (sk.x);
+  _gcry_mpi_release (data_a);
+  _gcry_mpi_release (data_b);
+  sexp_release (l1);
+  _gcry_pk_util_free_encoding_ctx (&ctx);
+  if (DBG_CIPHER)
+    log_debug ("elg_decrypt    => %s\n", gpg_strerror (rc));
+  return rc;
 }
 
 
 static gcry_err_code_t
-elg_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
+elg_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  ELG_secret_key sk;
-
-  (void)algo;
+  gcry_err_code_t rc;
+  struct pk_encoding_ctx ctx;
+  gcry_mpi_t data = NULL;
+  ELG_secret_key sk = {NULL, NULL, NULL, NULL};
+  gcry_mpi_t sig_r = NULL;
+  gcry_mpi_t sig_s = NULL;
+
+  _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN,
+                                   elg_get_nbits (keyparms));
+
+  /* Extract the data.  */
+  rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    log_mpidump ("elg_sign   data", data);
+  if (mpi_is_opaque (data))
+    {
+      rc = GPG_ERR_INV_DATA;
+      goto leave;
+    }
 
-  if ((! data)
-      || (! skey[0]) || (! skey[1]) || (! skey[2]) || (! skey[3]))
-    err = GPG_ERR_BAD_MPI;
-  else
+  /* Extract the key.  */
+  rc = sexp_extract_param (keyparms, NULL, "pgyx",
+                           &sk.p, &sk.g, &sk.y, &sk.x, NULL);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
     {
-      sk.p = skey[0];
-      sk.g = skey[1];
-      sk.y = skey[2];
-      sk.x = skey[3];
-      resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.p));
-      resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.p));
-      sign (resarr[0], resarr[1], data, &sk);
+      log_mpidump ("elg_sign      p", sk.p);
+      log_mpidump ("elg_sign      g", sk.g);
+      log_mpidump ("elg_sign      y", sk.y);
+      if (!fips_mode ())
+        log_mpidump ("elg_sign      x", sk.x);
     }
 
-  return err;
+  sig_r = mpi_new (0);
+  sig_s = mpi_new (0);
+  sign (sig_r, sig_s, data, &sk);
+  if (DBG_CIPHER)
+    {
+      log_mpidump ("elg_sign  sig_r", sig_r);
+      log_mpidump ("elg_sign  sig_s", sig_s);
+    }
+  rc = sexp_build (r_sig, NULL, "(sig-val(elg(r%M)(s%M)))", sig_r, sig_s);
+
+ leave:
+  _gcry_mpi_release (sig_r);
+  _gcry_mpi_release (sig_s);
+  _gcry_mpi_release (sk.p);
+  _gcry_mpi_release (sk.g);
+  _gcry_mpi_release (sk.y);
+  _gcry_mpi_release (sk.x);
+  _gcry_mpi_release (data);
+  _gcry_pk_util_free_encoding_ctx (&ctx);
+  if (DBG_CIPHER)
+    log_debug ("elg_sign      => %s\n", gpg_strerror (rc));
+  return rc;
 }
 
 
 static gcry_err_code_t
-elg_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
-            int (*cmp) (void *, gcry_mpi_t), void *opaquev)
+elg_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  ELG_public_key pk;
+  gcry_err_code_t rc;
+  struct pk_encoding_ctx ctx;
+  gcry_sexp_t l1 = NULL;
+  gcry_mpi_t sig_r = NULL;
+  gcry_mpi_t sig_s = NULL;
+  gcry_mpi_t data = NULL;
+  ELG_public_key pk = { NULL, NULL, NULL };
+
+  _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY,
+                                   elg_get_nbits (s_keyparms));
+
+  /* Extract the data.  */
+  rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    log_mpidump ("elg_verify data", data);
+  if (mpi_is_opaque (data))
+    {
+      rc = GPG_ERR_INV_DATA;
+      goto leave;
+    }
 
-  (void)algo;
-  (void)cmp;
-  (void)opaquev;
+  /* Extract the signature value.  */
+  rc = _gcry_pk_util_preparse_sigval (s_sig, elg_names, &l1, NULL);
+  if (rc)
+    goto leave;
+  rc = sexp_extract_param (l1, NULL, "rs", &sig_r, &sig_s, NULL);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    {
+      log_mpidump ("elg_verify  s_r", sig_r);
+      log_mpidump ("elg_verify  s_s", sig_s);
+    }
 
-  if ((! data[0]) || (! data[1]) || (! hash)
-      || (! pkey[0]) || (! pkey[1]) || (! pkey[2]))
-    err = GPG_ERR_BAD_MPI;
-  else
+  /* Extract the key.  */
+  rc = sexp_extract_param (s_keyparms, NULL, "pgy",
+                                 &pk.p, &pk.g, &pk.y, NULL);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
     {
-      pk.p = pkey[0];
-      pk.g = pkey[1];
-      pk.y = pkey[2];
-      if (! verify (data[0], data[1], hash, &pk))
-       err = GPG_ERR_BAD_SIGNATURE;
+      log_mpidump ("elg_verify    p", pk.p);
+      log_mpidump ("elg_verify    g", pk.g);
+      log_mpidump ("elg_verify    y", pk.y);
     }
 
-  return err;
+  /* Verify the signature.  */
+  if (!verify (sig_r, sig_s, data, &pk))
+    rc = GPG_ERR_BAD_SIGNATURE;
+
+ leave:
+  _gcry_mpi_release (pk.p);
+  _gcry_mpi_release (pk.g);
+  _gcry_mpi_release (pk.y);
+  _gcry_mpi_release (data);
+  _gcry_mpi_release (sig_r);
+  _gcry_mpi_release (sig_s);
+  sexp_release (l1);
+  _gcry_pk_util_free_encoding_ctx (&ctx);
+  if (DBG_CIPHER)
+    log_debug ("elg_verify    => %s\n", rc?gpg_strerror (rc):"Good");
+  return rc;
 }
 
 
+/* Return the number of bits for the key described by PARMS.  On error
+ * 0 is returned.  The format of PARMS starts with the algorithm name;
+ * for example:
+ *
+ *   (dsa
+ *     (p <mpi>)
+ *     (g <mpi>)
+ *     (y <mpi>))
+ *
+ * More parameters may be given but we only need P here.
+ */
 static unsigned int
-elg_get_nbits (int algo, gcry_mpi_t *pkey)
+elg_get_nbits (gcry_sexp_t parms)
 {
-  (void)algo;
-
-  return mpi_get_nbits (pkey[0]);
+  gcry_sexp_t l1;
+  gcry_mpi_t p;
+  unsigned int nbits;
+
+  l1 = sexp_find_token (parms, "p", 1);
+  if (!l1)
+    return 0; /* Parameter P not found.  */
+
+  p= sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+  sexp_release (l1);
+  nbits = p? mpi_get_nbits (p) : 0;
+  _gcry_mpi_release (p);
+  return nbits;
 }
 
 
-static const char *elg_names[] =
-  {
-    "elg",
-    "openpgp-elg",
-    "openpgp-elg-sig",
-    NULL,
-  };
-
-
+\f
 gcry_pk_spec_t _gcry_pubkey_spec_elg =
   {
+    GCRY_PK_ELG, { 0, 0 },
+    (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR),
     "ELG", elg_names,
     "pgy", "pgyx", "ab", "rs", "pgy",
-    GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR,
     elg_generate,
     elg_check_secret_key,
     elg_encrypt,
     elg_decrypt,
     elg_sign,
     elg_verify,
-    elg_get_nbits
-  };
-
-pk_extra_spec_t _gcry_pubkey_extraspec_elg =
-  {
-    NULL,
-    elg_generate_ext,
-    NULL
+    elg_get_nbits,
   };
diff --git a/cipher/gost.h b/cipher/gost.h
new file mode 100644 (file)
index 0000000..d058eb2
--- /dev/null
@@ -0,0 +1,31 @@
+/* gost.h - GOST 28147-89 implementation
+ * Copyright (C) 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 _GCRY_GOST_H
+#define _GCRY_GOST_H
+
+typedef struct {
+  u32 key[8];
+} 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);
+
+#endif
diff --git a/cipher/gost28147.c b/cipher/gost28147.c
new file mode 100644 (file)
index 0000000..c094209
--- /dev/null
@@ -0,0 +1,452 @@
+/* gost28147.c - GOST 28147-89 implementation for Libgcrypt
+ * Copyright (C) 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/>.
+ */
+
+/* GOST 28147-89 defines several modes of encryption:
+ * - ECB which should be used only for key transfer
+ * - CFB mode
+ * - OFB-like mode with additional transformation on keystream
+ *   RFC 5830 names this 'counter encryption' mode
+ *   Original GOST text uses the term 'gammirovanie'
+ * - MAC mode
+ *
+ * This implementation handles ECB and CFB modes via usual libgcrypt handling.
+ * OFB-like and MAC modes are unsupported.
+ */
+
+#include <config.h>
+#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 "gost.h"
+
+static gcry_err_code_t
+gost_setkey (void *c, const byte *key, unsigned keylen)
+{
+  int i;
+  GOST28147_context *ctx = c;
+
+  if (keylen != 256 / 8)
+    return GPG_ERR_INV_KEYLEN;
+
+  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);
+    }
+  return GPG_ERR_NO_ERROR;
+}
+
+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];
+  return cm1;
+}
+
+static unsigned int
+gost_encrypt_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);
+
+  n2 ^= gost_val (ctx, n1, 0); n1 ^= gost_val (ctx, n2, 1);
+  n2 ^= gost_val (ctx, n1, 2); n1 ^= gost_val (ctx, n2, 3);
+  n2 ^= gost_val (ctx, n1, 4); n1 ^= gost_val (ctx, n2, 5);
+  n2 ^= gost_val (ctx, n1, 6); n1 ^= gost_val (ctx, n2, 7);
+
+  n2 ^= gost_val (ctx, n1, 0); n1 ^= gost_val (ctx, n2, 1);
+  n2 ^= gost_val (ctx, n1, 2); n1 ^= gost_val (ctx, n2, 3);
+  n2 ^= gost_val (ctx, n1, 4); n1 ^= gost_val (ctx, n2, 5);
+  n2 ^= gost_val (ctx, n1, 6); n1 ^= gost_val (ctx, n2, 7);
+
+  n2 ^= gost_val (ctx, n1, 0); n1 ^= gost_val (ctx, n2, 1);
+  n2 ^= gost_val (ctx, n1, 2); n1 ^= gost_val (ctx, n2, 3);
+  n2 ^= gost_val (ctx, n1, 4); n1 ^= gost_val (ctx, n2, 5);
+  n2 ^= gost_val (ctx, n1, 6); n1 ^= gost_val (ctx, n2, 7);
+
+  n2 ^= gost_val (ctx, n1, 7); n1 ^= gost_val (ctx, n2, 6);
+  n2 ^= gost_val (ctx, n1, 5); n1 ^= gost_val (ctx, n2, 4);
+  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;
+
+  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)
+{
+  gost_setkey (c, key, 32);
+  return gost_encrypt_block (c, out, in) + 5 * sizeof(void *);
+}
+
+static unsigned int
+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);
+
+  n2 ^= gost_val (ctx, n1, 0); n1 ^= gost_val (ctx, n2, 1);
+  n2 ^= gost_val (ctx, n1, 2); n1 ^= gost_val (ctx, n2, 3);
+  n2 ^= gost_val (ctx, n1, 4); n1 ^= gost_val (ctx, n2, 5);
+  n2 ^= gost_val (ctx, n1, 6); n1 ^= gost_val (ctx, n2, 7);
+
+  n2 ^= gost_val (ctx, n1, 7); n1 ^= gost_val (ctx, n2, 6);
+  n2 ^= gost_val (ctx, n1, 5); n1 ^= gost_val (ctx, n2, 4);
+  n2 ^= gost_val (ctx, n1, 3); n1 ^= gost_val (ctx, n2, 2);
+  n2 ^= gost_val (ctx, n1, 1); n1 ^= gost_val (ctx, n2, 0);
+
+  n2 ^= gost_val (ctx, n1, 7); n1 ^= gost_val (ctx, n2, 6);
+  n2 ^= gost_val (ctx, n1, 5); n1 ^= gost_val (ctx, n2, 4);
+  n2 ^= gost_val (ctx, n1, 3); n1 ^= gost_val (ctx, n2, 2);
+  n2 ^= gost_val (ctx, n1, 1); n1 ^= gost_val (ctx, n2, 0);
+
+  n2 ^= gost_val (ctx, n1, 7); n1 ^= gost_val (ctx, n2, 6);
+  n2 ^= gost_val (ctx, n1, 5); n1 ^= gost_val (ctx, n2, 4);
+  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;
+
+  return /* burn_stack */ 4*sizeof(void*) /* func call */ +
+                          3*sizeof(void*) /* stack */ +
+                          4*sizeof(void*) /* gost_val call */;
+}
+
+gcry_cipher_spec_t _gcry_cipher_spec_gost28147 =
+  {
+    GCRY_CIPHER_GOST28147, {0, 0},
+    "GOST28147", NULL, NULL, 8, 256,
+    sizeof (GOST28147_context),
+    gost_setkey,
+    gost_encrypt_block,
+    gost_decrypt_block,
+  };
diff --git a/cipher/gostr3411-94.c b/cipher/gostr3411-94.c
new file mode 100644 (file)
index 0000000..5486964
--- /dev/null
@@ -0,0 +1,286 @@
+/* gostr3411-94.c - GOST R 34.11-94 hash function
+ * Copyright (C) 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>
+
+#include "g10lib.h"
+#include "bithelp.h"
+#include "cipher.h"
+#include "hash-common.h"
+
+#include "gost.h"
+
+#define max(a, b) (((a) > (b)) ? (a) : (b))
+
+typedef struct {
+  gcry_md_block_ctx_t bctx;
+  GOST28147_context hd;
+  byte h[32];
+  byte sigma[32];
+  u32 len;
+} GOSTR3411_CONTEXT;
+
+static unsigned int
+transform (void *c, const unsigned char *data);
+
+static void
+gost3411_init (void *context, unsigned int flags)
+{
+  GOSTR3411_CONTEXT *hd = context;
+
+  (void)flags;
+
+  memset (&hd->hd, 0, sizeof(hd->hd));
+  memset (hd->h, 0, 32);
+  memset (hd->sigma, 0, 32);
+
+  hd->bctx.nblocks = 0;
+  hd->bctx.count = 0;
+  hd->bctx.blocksize = 32;
+  hd->bctx.bwrite = transform;
+}
+
+static void
+do_p (unsigned char *p, unsigned char *u, unsigned char *v)
+{
+  int i, k;
+  for (k = 0; k < 8; k++)
+    {
+      for (i = 0; i < 4; i++)
+        {
+          p[i + 4 * k] = u[8 * i + k] ^ v[8 * i + k];
+        }
+    }
+}
+
+static void
+do_a (unsigned char *u)
+{
+  unsigned char temp[8];
+  int i;
+  memcpy (temp, u, 8);
+  memmove (u, u+8, 24);
+  for (i = 0; i < 8; i++)
+    {
+      u[24 + i] = u[i] ^ temp[i];
+    }
+}
+/* apply do_a twice: 1 2 3 4 -> 3 4 1^2 2^3 */
+static void
+do_a2 (unsigned char *u)
+{
+  unsigned char temp[16];
+  int i;
+  memcpy (temp, u, 16);
+  memcpy (u, u + 16, 16);
+  for (i = 0; i < 8; i++)
+    {
+      u[16 + i] = temp[i] ^ temp[8 + i];
+      u[24 + i] =    u[i] ^ temp[8 + i];
+    }
+}
+
+static void
+do_apply_c2 (unsigned char *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;
+}
+
+#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];
+
+static void
+do_phi_submix (unsigned char *e, unsigned char *x, int round)
+{
+  int i;
+  round *= 2;
+  for (i = 0; i < 32; i++)
+    {
+      e[(i + round) % 32] ^= x[i];
+    }
+}
+
+static void
+do_add (unsigned char *s, unsigned char *a)
+{
+  unsigned temp = 0;
+  int i;
+
+  for (i = 0; i < 32; i++)
+    {
+      temp = s[i] + a[i] + (temp >> 8);
+      s[i] = temp & 0xff;
+    }
+}
+
+static unsigned int
+do_hash_step (GOST28147_context *hd, unsigned char *h, unsigned char *m)
+{
+  unsigned char u[32], v[32], s[32];
+  unsigned char k[32];
+  unsigned int burn;
+  int i;
+
+  memcpy (u, h, 32);
+  memcpy (v, m, 32);
+
+  for (i = 0; i < 4; i++) {
+    do_p (k, u, v);
+
+    burn = _gcry_gost_enc_one (hd, k, s + i*8, h + i*8);
+
+    do_a (u);
+    if (i == 1)
+      do_apply_c2 (u);
+    do_a2 (v);
+  }
+
+  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);
+      /* 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);
+      if (i == 0)
+        do_phi_submix(s, m, 12);
+      do_phi_step (s, 12);
+      if (i == 0)
+        do_phi_submix(s, h, 13);
+      do_phi_step (s, 13);
+      do_phi_step (s, 14);
+      do_phi_step (s, 15);
+    }
+
+  memcpy (h, s+20, 12);
+  memcpy (h+12, s, 20);
+
+  return /* burn_stack */ 4 * sizeof(void*) /* func call (ret addr + args) */ +
+                          4 * 32 + 2 * sizeof(int) /* stack */ +
+                          max(burn /* _gcry_gost_enc_one */,
+                              sizeof(void*) * 2 /* do_a2 call */ +
+                              16 + sizeof(int) /* do_a2 stack */ );
+}
+
+
+static unsigned int
+transform (void *ctx, const unsigned char *data)
+{
+  GOSTR3411_CONTEXT *hd = ctx;
+  byte m[32];
+  unsigned int burn;
+
+  memcpy (m, data, 32);
+  burn = do_hash_step (&hd->hd, hd->h, m);
+  do_add (hd->sigma, m);
+
+  return /* burn_stack */ burn + 3 * sizeof(void*) + 32 + 2 * sizeof(void*);
+}
+
+/*
+   The routine finally 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: 32
+   bytes with the message the digest.  */
+static void
+gost3411_final (void *context)
+{
+  GOSTR3411_CONTEXT *hd = context;
+  size_t padlen = 0;
+  byte l[32];
+  int i;
+  u32 nblocks;
+
+  if (hd->bctx.count > 0)
+    {
+      padlen = 32 - hd->bctx.count;
+      memset (hd->bctx.buf + hd->bctx.count, 0, padlen);
+      hd->bctx.count += padlen;
+      _gcry_md_block_write (hd, NULL, 0); /* flush */;
+    }
+
+  if (hd->bctx.count != 0)
+    return; /* Something went wrong */
+
+  memset (l, 0, 32);
+
+  nblocks = hd->bctx.nblocks;
+  if (padlen)
+    {
+      nblocks --;
+      l[0] = 256 - padlen * 8;
+    }
+
+  for (i = 1; i < 32 && nblocks != 0; i++)
+    {
+      l[i] = nblocks % 256;
+      nblocks /= 256;
+    }
+
+  do_hash_step (&hd->hd, hd->h, l);
+  do_hash_step (&hd->hd, hd->h, hd->sigma);
+}
+
+static byte *
+gost3411_read (void *context)
+{
+  GOSTR3411_CONTEXT *hd = context;
+
+  return hd->h;
+}
+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,
+    sizeof (GOSTR3411_CONTEXT)
+  };
index 8c413bc..ffbc39e 100644 (file)
@@ -91,3 +91,55 @@ _gcry_hash_selftest_check_one (int algo,
 
   return result;
 }
+
+
+/* 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.  */
+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;
+
+  if (sizeof(hd->buf) < hd->blocksize)
+    BUG();
+
+  if (hd->buf == NULL || hd->bwrite == NULL)
+    return;
+
+  if (hd->count == hd->blocksize)  /* Flush the buffer. */
+    {
+      stack_burn = hd->bwrite (hd, hd->buf);
+      _gcry_burn_stack (stack_burn);
+      stack_burn = 0;
+      hd->count = 0;
+      if (!++hd->nblocks)
+        hd->nblocks_high++;
+    }
+  if (!inbuf)
+    return;
+
+  if (hd->count)
+    {
+      for (; inlen && hd->count < hd->blocksize; inlen--)
+        hd->buf[hd->count++] = *inbuf++;
+      _gcry_md_block_write (hd, NULL, 0);
+      if (!inlen)
+        return;
+    }
+
+  while (inlen >= hd->blocksize)
+    {
+      stack_burn = hd->bwrite (hd, inbuf);
+      hd->count = 0;
+      if (!++hd->nblocks)
+        hd->nblocks_high++;
+      inlen -= hd->blocksize;
+      inbuf += hd->blocksize;
+    }
+  _gcry_burn_stack (stack_burn);
+  for (; inlen && hd->count < hd->blocksize; inlen--)
+    hd->buf[hd->count++] = *inbuf++;
+}
index fdebef4..aa95365 100644 (file)
 #ifndef GCRY_HASH_COMMON_H
 #define GCRY_HASH_COMMON_H
 
+#include "types.h"
+
 
 const char * _gcry_hash_selftest_check_one
 /**/         (int algo,
               int datamode, const void *data, size_t datalen,
               const void *expect, size_t expectlen);
 
-
-
-
+/* Type for the md_write helper function.  */
+typedef unsigned int (*_gcry_md_block_write_t) (void *c,
+                                               const unsigned char *buf);
+
+#if defined(HAVE_U64_TYPEDEF) && (defined(USE_SHA512) || defined(USE_WHIRLPOOL))
+/* SHA-512 needs u64 and larger buffer. Whirlpool needs u64. */
+# define MD_BLOCK_MAX_BLOCKSIZE 128
+# define MD_NBLOCKS_TYPE u64
+#else
+# define MD_BLOCK_MAX_BLOCKSIZE 64
+# define MD_NBLOCKS_TYPE u32
+#endif
+
+typedef struct gcry_md_block_ctx
+{
+    byte buf[MD_BLOCK_MAX_BLOCKSIZE];
+    MD_NBLOCKS_TYPE nblocks;
+    MD_NBLOCKS_TYPE nblocks_high;
+    int count;
+    size_t blocksize;
+    _gcry_md_block_write_t bwrite;
+} gcry_md_block_ctx_t;
+
+
+void
+_gcry_md_block_write( void *context, const void *inbuf_arg, size_t inlen);
 
 #endif /*GCRY_HASH_COMMON_H*/
index a32ece7..7c27342 100644 (file)
@@ -718,7 +718,7 @@ _gcry_hmac_selftest (int algo, int extended, selftest_report_func_t report)
 {
   gcry_err_code_t ec = 0;
 
-  if (!gcry_md_test_algo (algo))
+  if (!_gcry_md_test_algo (algo))
     {
       ec = run_selftests (algo, extended, report);
     }
diff --git a/cipher/idea.c b/cipher/idea.c
new file mode 100644 (file)
index 0000000..14234cf
--- /dev/null
@@ -0,0 +1,379 @@
+/* idea.c  -  IDEA function
+ * Copyright 1997, 1998, 1999, 2001 Werner Koch (dd9jn)
+ * Copyright 2013 g10 Code GmbH
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * WERNER KOCH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Werner Koch shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Werner Koch.
+ *
+ * Patents on IDEA have expired:
+ *   Europe: EP0482154 on 2011-05-16,
+ *   Japan:  JP3225440 on 2011-05-16,
+ *   U.S.:   5,214,703 on 2012-01-07.
+ */
+
+/*
+ * Please see http://www.noepatents.org/ to learn why software patents
+ * are bad for society and what you can do to fight them.
+ *
+ * The code herein is based on the one from:
+ *   Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
+ *   ISBN 0-471-11709-9.
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "types.h"  /* for byte and u32 typedefs */
+#include "g10lib.h"
+#include "cipher.h"
+
+
+#define IDEA_KEYSIZE 16
+#define IDEA_BLOCKSIZE 8
+#define IDEA_ROUNDS 8
+#define IDEA_KEYLEN (6*IDEA_ROUNDS+4)
+
+typedef struct {
+    u16 ek[IDEA_KEYLEN];
+    u16 dk[IDEA_KEYLEN];
+    int have_dk;
+} IDEA_context;
+
+static const char *selftest(void);
+
+
+static u16
+mul_inv( u16 x )
+{
+    u16 t0, t1;
+    u16 q, y;
+
+    if( x < 2 )
+       return x;
+    t1 = 0x10001UL / x;
+    y =  0x10001UL % x;
+    if( y == 1 )
+       return (1-t1) & 0xffff;
+
+    t0 = 1;
+    do {
+       q = x / y;
+       x = x % y;
+       t0 += q * t1;
+       if( x == 1 )
+           return t0;
+       q = y / x;
+       y = y % x;
+       t1 += q * t0;
+    } while( y != 1 );
+    return (1-t1) & 0xffff;
+}
+
+
+
+static void
+expand_key( const byte *userkey, u16 *ek )
+{
+    int i,j;
+
+    for(j=0; j < 8; j++ ) {
+       ek[j] = (*userkey << 8) + userkey[1];
+       userkey += 2;
+    }
+    for(i=0; j < IDEA_KEYLEN; j++ ) {
+       i++;
+       ek[i+7] = ek[i&7] << 9 | ek[(i+1)&7] >> 7;
+       ek += i & 8;
+       i &= 7;
+    }
+}
+
+
+static void
+invert_key( u16 *ek, u16 dk[IDEA_KEYLEN] )
+{
+    int i;
+    u16 t1, t2, t3;
+    u16 temp[IDEA_KEYLEN];
+    u16 *p = temp + IDEA_KEYLEN;
+
+    t1 = mul_inv( *ek++ );
+    t2 = -*ek++;
+    t3 = -*ek++;
+    *--p = mul_inv( *ek++ );
+    *--p = t3;
+    *--p = t2;
+    *--p = t1;
+
+    for(i=0; i < IDEA_ROUNDS-1; i++ ) {
+       t1 = *ek++;
+       *--p = *ek++;
+       *--p = t1;
+
+       t1 = mul_inv( *ek++ );
+       t2 = -*ek++;
+       t3 = -*ek++;
+       *--p = mul_inv( *ek++ );
+       *--p = t2;
+       *--p = t3;
+       *--p = t1;
+    }
+    t1 = *ek++;
+    *--p = *ek++;
+    *--p = t1;
+
+    t1 = mul_inv( *ek++ );
+    t2 = -*ek++;
+    t3 = -*ek++;
+    *--p = mul_inv( *ek++ );
+    *--p = t3;
+    *--p = t2;
+    *--p = t1;
+    memcpy(dk, temp, sizeof(temp) );
+    memset(temp, 0, sizeof(temp) );  /* burn temp */
+}
+
+
+static void
+cipher( byte *outbuf, const byte *inbuf, u16 *key )
+{
+    u16 s2, s3;
+    u16 in[4];
+    int r = IDEA_ROUNDS;
+#define x1 (in[0])
+#define x2 (in[1])
+#define x3 (in[2])
+#define x4 (in[3])
+#define MUL(x,y) \
+       do {u16 _t16; u32 _t32;                     \
+           if( (_t16 = (y)) ) {                    \
+               if( (x = (x)&0xffff) ) {            \
+                   _t32 = (u32)x * _t16;           \
+                   x = _t32 & 0xffff;              \
+                   _t16 = _t32 >> 16;              \
+                   x = ((x)-_t16) + (x<_t16?1:0);  \
+               }                                   \
+               else {                              \
+                   x = 1 - _t16;                   \
+               }                                   \
+           }                                       \
+           else {                                  \
+               x = 1 - x;                          \
+           }                                       \
+       } while(0)
+
+    memcpy (in, inbuf, sizeof in);
+#ifndef WORDS_BIGENDIAN
+    x1 = (x1>>8) | (x1<<8);
+    x2 = (x2>>8) | (x2<<8);
+    x3 = (x3>>8) | (x3<<8);
+    x4 = (x4>>8) | (x4<<8);
+#endif
+    do {
+       MUL(x1, *key++);
+       x2 += *key++;
+       x3 += *key++;
+       MUL(x4, *key++ );
+
+       s3 = x3;
+       x3 ^= x1;
+       MUL(x3, *key++);
+       s2 = x2;
+       x2 ^=x4;
+       x2 += x3;
+       MUL(x2, *key++);
+       x3 += x2;
+
+       x1 ^= x2;
+       x4 ^= x3;
+
+       x2 ^= s3;
+       x3 ^= s2;
+    } while( --r );
+    MUL(x1, *key++);
+    x3 += *key++;
+    x2 += *key++;
+    MUL(x4, *key);
+
+#ifndef WORDS_BIGENDIAN
+    x1 = (x1>>8) | (x1<<8);
+    x2 = (x2>>8) | (x2<<8);
+    x3 = (x3>>8) | (x3<<8);
+    x4 = (x4>>8) | (x4<<8);
+#endif
+    memcpy (outbuf+0, &x1, 2);
+    memcpy (outbuf+2, &x3, 2);
+    memcpy (outbuf+4, &x2, 2);
+    memcpy (outbuf+6, &x4, 2);
+#undef MUL
+#undef x1
+#undef x2
+#undef x3
+#undef x4
+}
+
+
+static int
+do_setkey( IDEA_context *c, const byte *key, unsigned int keylen )
+{
+    static int initialized = 0;
+    static const char *selftest_failed = 0;
+
+    if( !initialized ) {
+       initialized = 1;
+       selftest_failed = selftest();
+       if( selftest_failed )
+           log_error( "%s\n", selftest_failed );
+    }
+    if( selftest_failed )
+       return GPG_ERR_SELFTEST_FAILED;
+
+    assert(keylen == 16);
+    c->have_dk = 0;
+    expand_key( key, c->ek );
+    invert_key( c->ek, c->dk );
+    return 0;
+}
+
+static gcry_err_code_t
+idea_setkey (void *context, const byte *key, unsigned int keylen)
+{
+    IDEA_context *ctx = context;
+    int rc = do_setkey (ctx, key, keylen);
+    _gcry_burn_stack (23+6*sizeof(void*));
+    return rc;
+}
+
+static void
+encrypt_block( IDEA_context *c, byte *outbuf, const byte *inbuf )
+{
+    cipher( outbuf, inbuf, c->ek );
+}
+
+static unsigned int
+idea_encrypt (void *context, byte *out, const byte *in)
+{
+    IDEA_context *ctx = context;
+    encrypt_block (ctx, out, in);
+    return /*burn_stack*/ (24+3*sizeof (void*));
+}
+
+static void
+decrypt_block( IDEA_context *c, byte *outbuf, const byte *inbuf )
+{
+    if( !c->have_dk ) {
+       c->have_dk = 1;
+       invert_key( c->ek, c->dk );
+    }
+    cipher( outbuf, inbuf, c->dk );
+}
+
+static unsigned int
+idea_decrypt (void *context, byte *out, const byte *in)
+{
+    IDEA_context *ctx = context;
+    decrypt_block (ctx, out, in);
+    return /*burn_stack*/ (24+3*sizeof (void*));
+}
+
+
+static const char *
+selftest( void )
+{
+static struct {
+    byte key[16];
+    byte plain[8];
+    byte cipher[8];
+} test_vectors[] = {
+    { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+       0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+      { 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03 },
+      { 0x11, 0xFB, 0xED, 0x2B, 0x01, 0x98, 0x6D, 0xE5 } },
+    { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+       0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+      { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
+      { 0x54, 0x0E, 0x5F, 0xEA, 0x18, 0xC2, 0xF8, 0xB1 } },
+    { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+       0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+      { 0x00, 0x19, 0x32, 0x4B, 0x64, 0x7D, 0x96, 0xAF },
+      { 0x9F, 0x0A, 0x0A, 0xB6, 0xE1, 0x0C, 0xED, 0x78 } },
+    { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+       0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+      { 0xF5, 0x20, 0x2D, 0x5B, 0x9C, 0x67, 0x1B, 0x08 },
+      { 0xCF, 0x18, 0xFD, 0x73, 0x55, 0xE2, 0xC5, 0xC5 } },
+    { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+       0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+      { 0xFA, 0xE6, 0xD2, 0xBE, 0xAA, 0x96, 0x82, 0x6E },
+      { 0x85, 0xDF, 0x52, 0x00, 0x56, 0x08, 0x19, 0x3D } },
+    { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+       0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+      { 0x0A, 0x14, 0x1E, 0x28, 0x32, 0x3C, 0x46, 0x50 },
+      { 0x2F, 0x7D, 0xE7, 0x50, 0x21, 0x2F, 0xB7, 0x34 } },
+    { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+       0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+      { 0x05, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x23, 0x28 },
+      { 0x7B, 0x73, 0x14, 0x92, 0x5D, 0xE5, 0x9C, 0x09 } },
+    { { 0x00, 0x05, 0x00, 0x0A, 0x00, 0x0F, 0x00, 0x14,
+       0x00, 0x19, 0x00, 0x1E, 0x00, 0x23, 0x00, 0x28 },
+      { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
+      { 0x3E, 0xC0, 0x47, 0x80, 0xBE, 0xFF, 0x6E, 0x20 } },
+    { { 0x3A, 0x98, 0x4E, 0x20, 0x00, 0x19, 0x5D, 0xB3,
+       0x2E, 0xE5, 0x01, 0xC8, 0xC4, 0x7C, 0xEA, 0x60 },
+      { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
+      { 0x97, 0xBC, 0xD8, 0x20, 0x07, 0x80, 0xDA, 0x86 } },
+    { { 0x00, 0x64, 0x00, 0xC8, 0x01, 0x2C, 0x01, 0x90,
+       0x01, 0xF4, 0x02, 0x58, 0x02, 0xBC, 0x03, 0x20 },
+      { 0x05, 0x32, 0x0A, 0x64, 0x14, 0xC8, 0x19, 0xFA },
+      { 0x65, 0xBE, 0x87, 0xE7, 0xA2, 0x53, 0x8A, 0xED } },
+    { { 0x9D, 0x40, 0x75, 0xC1, 0x03, 0xBC, 0x32, 0x2A,
+       0xFB, 0x03, 0xE7, 0xBE, 0x6A, 0xB3, 0x00, 0x06 },
+      { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 },
+      { 0xF5, 0xDB, 0x1A, 0xC4, 0x5E, 0x5E, 0xF9, 0xF9 } }
+};
+    IDEA_context c;
+    byte buffer[8];
+    int i;
+
+    for(i=0; i < DIM(test_vectors); i++ ) {
+       do_setkey( &c, test_vectors[i].key, 16 );
+       encrypt_block( &c, buffer, test_vectors[i].plain );
+       if( memcmp( buffer, test_vectors[i].cipher, 8 ) )
+           return "IDEA test encryption failed.";
+       decrypt_block( &c, buffer, test_vectors[i].cipher );
+       if( memcmp( buffer, test_vectors[i].plain, 8 ) )
+           return "IDEA test decryption failed.";
+    }
+
+    return NULL;
+}
+
+
+gcry_cipher_spec_t _gcry_cipher_spec_idea =
+  {
+    GCRY_CIPHER_IDEA, {0, 0},
+    "IDEA", NULL, NULL, IDEA_BLOCKSIZE, 128,
+    sizeof (IDEA_context),
+    idea_setkey, idea_encrypt, idea_decrypt
+  };
diff --git a/cipher/kdf-internal.h b/cipher/kdf-internal.h
new file mode 100644 (file)
index 0000000..7079860
--- /dev/null
@@ -0,0 +1,40 @@
+/* kdf-internal.h  - Internal defs for kdf.c
+ * Copyright (C) 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/>.
+ */
+
+#ifndef GCRY_KDF_INTERNAL_H
+#define GCRY_KDF_INTERNAL_H
+
+/*-- kdf.c --*/
+gpg_err_code_t
+_gcry_kdf_pkdf2 (const void *passphrase, size_t passphraselen,
+                 int hashalgo,
+                 const void *salt, size_t saltlen,
+                 unsigned long iterations,
+                 size_t keysize, void *keybuffer);
+
+/*-- scrypt.c --*/
+gcry_err_code_t
+_gcry_kdf_scrypt (const unsigned char *passwd, size_t passwdlen,
+                  int algo, int subalgo,
+                  const unsigned char *salt, size_t saltlen,
+                  unsigned long iterations,
+                  size_t dklen, unsigned char *dk);
+
+
+#endif /*GCRY_KDF_INTERNAL_H*/
index d981022..af0dc48 100644 (file)
@@ -1,5 +1,6 @@
 /* kdf.c  - Key Derivation Functions
  * Copyright (C) 1998, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2013 g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
@@ -26,6 +27,7 @@
 #include "g10lib.h"
 #include "cipher.h"
 #include "ath.h"
+#include "kdf-internal.h"
 
 
 /* Transform a passphrase into a suitable key of length KEYSIZE and
@@ -33,7 +35,7 @@
    must provide an HASHALGO, a valid ALGO and depending on that algo a
    SALT of 8 bytes and the number of ITERATIONS.  Code taken from
    gnupg/agent/protect.c:hash_passphrase.  */
-gpg_err_code_t
+static gpg_err_code_t
 openpgp_s2k (const void *passphrase, size_t passphraselen,
              int algo, int hashalgo,
              const void *salt, size_t saltlen,
@@ -51,10 +53,9 @@ openpgp_s2k (const void *passphrase, size_t passphraselen,
       && (!salt || saltlen != 8))
     return GPG_ERR_INV_VALUE;
 
-  secmode = gcry_is_secure (passphrase) || gcry_is_secure (keybuffer);
+  secmode = _gcry_is_secure (passphrase) || _gcry_is_secure (keybuffer);
 
-  ec = gpg_err_code (gcry_md_open (&md, hashalgo,
-                                   secmode? GCRY_MD_FLAG_SECURE : 0));
+  ec = _gcry_md_open (&md, hashalgo, secmode? GCRY_MD_FLAG_SECURE : 0);
   if (ec)
     return ec;
 
@@ -62,9 +63,9 @@ openpgp_s2k (const void *passphrase, size_t passphraselen,
     {
       if (pass)
         {
-          gcry_md_reset (md);
+          _gcry_md_reset (md);
           for (i=0; i < pass; i++) /* Preset the hash context.  */
-            gcry_md_putc (md, 0);
+            _gcry_md_putc (md, 0);
        }
 
       if (algo == GCRY_KDF_SALTED_S2K || algo == GCRY_KDF_ITERSALTED_S2K)
@@ -81,30 +82,30 @@ openpgp_s2k (const void *passphrase, size_t passphraselen,
 
           while (count > len2)
             {
-              gcry_md_write (md, salt, saltlen);
-              gcry_md_write (md, passphrase, passphraselen);
+              _gcry_md_write (md, salt, saltlen);
+              _gcry_md_write (md, passphrase, passphraselen);
               count -= len2;
             }
           if (count < saltlen)
-            gcry_md_write (md, salt, count);
+            _gcry_md_write (md, salt, count);
           else
             {
-              gcry_md_write (md, salt, saltlen);
+              _gcry_md_write (md, salt, saltlen);
               count -= saltlen;
-              gcry_md_write (md, passphrase, count);
+              _gcry_md_write (md, passphrase, count);
             }
         }
       else
-        gcry_md_write (md, passphrase, passphraselen);
+        _gcry_md_write (md, passphrase, passphraselen);
 
-      gcry_md_final (md);
-      i = gcry_md_get_algo_dlen (hashalgo);
+      _gcry_md_final (md);
+      i = _gcry_md_get_algo_dlen (hashalgo);
       if (i > keysize - used)
         i = keysize - used;
-      memcpy (key+used, gcry_md_read (md, hashalgo), i);
+      memcpy (key+used, _gcry_md_read (md, hashalgo), i);
       used += i;
     }
-  gcry_md_close (md);
+  _gcry_md_close (md);
   return 0;
 }
 
@@ -116,11 +117,11 @@ openpgp_s2k (const void *passphrase, size_t passphraselen,
    used in HMAC mode.  SALT is a salt of length SALTLEN and ITERATIONS
    gives the number of iterations.  */
 gpg_err_code_t
-pkdf2 (const void *passphrase, size_t passphraselen,
-       int hashalgo,
-       const void *salt, size_t saltlen,
-       unsigned long iterations,
-       size_t keysize, void *keybuffer)
+_gcry_kdf_pkdf2 (const void *passphrase, size_t passphraselen,
+                 int hashalgo,
+                 const void *salt, size_t saltlen,
+                 unsigned long iterations,
+                 size_t keysize, void *keybuffer)
 {
   gpg_err_code_t ec;
   gcry_md_hd_t md;
@@ -138,14 +139,17 @@ pkdf2 (const void *passphrase, size_t passphraselen,
   unsigned long iter;  /* Current iteration number.  */
   unsigned int i;
 
-  if (!salt || !saltlen || !iterations || !dklen)
+  /* NWe 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)
     return GPG_ERR_INV_VALUE;
 
-  hlen = gcry_md_get_algo_dlen (hashalgo);
+  hlen = _gcry_md_get_algo_dlen (hashalgo);
   if (!hlen)
     return GPG_ERR_DIGEST_ALGO;
 
-  secmode = gcry_is_secure (passphrase) || gcry_is_secure (keybuffer);
+  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.  */
@@ -156,19 +160,26 @@ pkdf2 (const void *passphrase, size_t passphraselen,
 
   /* Setup buffers and prepare a hash context.  */
   sbuf = (secmode
-          ? gcry_malloc_secure (saltlen + 4 + hlen + hlen)
-          : gcry_malloc (saltlen + 4 + hlen + hlen));
+          ? xtrymalloc_secure (saltlen + 4 + hlen + hlen)
+          : xtrymalloc (saltlen + 4 + hlen + hlen));
   if (!sbuf)
     return gpg_err_code_from_syserror ();
   tbuf = sbuf + saltlen + 4;
   ubuf = tbuf + hlen;
 
-  ec = gpg_err_code (gcry_md_open (&md, hashalgo,
-                                   (GCRY_MD_FLAG_HMAC
-                                    | (secmode?GCRY_MD_FLAG_SECURE:0))));
+  ec = _gcry_md_open (&md, hashalgo, (GCRY_MD_FLAG_HMAC
+                                      | (secmode?GCRY_MD_FLAG_SECURE:0)));
   if (ec)
     {
-      gcry_free (sbuf);
+      xfree (sbuf);
+      return ec;
+    }
+
+  ec = _gcry_md_setkey (md, passphrase, passphraselen);
+  if (ec)
+    {
+      _gcry_md_close (md);
+      xfree (sbuf);
       return ec;
     }
 
@@ -178,27 +189,21 @@ pkdf2 (const void *passphrase, size_t passphraselen,
     {
       for (iter = 0; iter < iterations; iter++)
         {
-          ec = gpg_err_code (gcry_md_setkey (md, passphrase, passphraselen));
-          if (ec)
-            {
-              gcry_md_close (md);
-              gcry_free (sbuf);
-              return ec;
-            }
+          _gcry_md_reset (md);
           if (!iter) /* Compute U_1:  */
             {
               sbuf[saltlen]     = (lidx >> 24);
               sbuf[saltlen + 1] = (lidx >> 16);
               sbuf[saltlen + 2] = (lidx >> 8);
               sbuf[saltlen + 3] = lidx;
-              gcry_md_write (md, sbuf, saltlen + 4);
-              memcpy (ubuf, gcry_md_read (md, 0), hlen);
+              _gcry_md_write (md, sbuf, saltlen + 4);
+              memcpy (ubuf, _gcry_md_read (md, 0), hlen);
               memcpy (tbuf, ubuf, hlen);
             }
           else /* Compute U_(2..c):  */
             {
-              gcry_md_write (md, ubuf, hlen);
-              memcpy (ubuf, gcry_md_read (md, 0), hlen);
+              _gcry_md_write (md, ubuf, hlen);
+              memcpy (ubuf, _gcry_md_read (md, 0), hlen);
               for (i=0; i < hlen; i++)
                 tbuf[i] ^= ubuf[i];
             }
@@ -212,8 +217,8 @@ pkdf2 (const void *passphrase, size_t passphraselen,
         }
     }
 
-  gcry_md_close (md);
-  gcry_free (sbuf);
+  _gcry_md_close (md);
+  xfree (sbuf);
   return 0;
 }
 
@@ -229,20 +234,21 @@ pkdf2 (const void *passphrase, size_t passphraselen,
    is a salt as needed by most KDF algorithms.  ITERATIONS is a
    positive integer parameter to most KDFs.  0 is returned on success,
    or an error code on failure.  */
-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)
+gpg_err_code_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)
 {
   gpg_err_code_t ec;
 
-  if (!passphrase || !passphraselen)
+  if (!passphrase)
     {
       ec = GPG_ERR_INV_DATA;
       goto leave;
     }
+
   if (!keybuffer || !keysize)
     {
       ec = GPG_ERR_INV_VALUE;
@@ -255,8 +261,11 @@ gcry_kdf_derive (const void *passphrase, size_t passphraselen,
     case GCRY_KDF_SIMPLE_S2K:
     case GCRY_KDF_SALTED_S2K:
     case GCRY_KDF_ITERSALTED_S2K:
-      ec = openpgp_s2k (passphrase, passphraselen, algo, subalgo,
-                        salt, saltlen, iterations, keysize, keybuffer);
+      if (!passphraselen)
+        ec = GPG_ERR_INV_DATA;
+      else
+        ec = openpgp_s2k (passphrase, passphraselen, algo, subalgo,
+                          salt, saltlen, iterations, keysize, keybuffer);
       break;
 
     case GCRY_KDF_PBKDF1:
@@ -264,8 +273,21 @@ gcry_kdf_derive (const void *passphrase, size_t passphraselen,
       break;
 
     case GCRY_KDF_PBKDF2:
-      ec = pkdf2 (passphrase, passphraselen, subalgo,
-                  salt, saltlen, iterations, keysize, keybuffer);
+      if (!saltlen)
+        ec = GPG_ERR_INV_VALUE;
+      else
+        ec = _gcry_kdf_pkdf2 (passphrase, passphraselen, subalgo,
+                              salt, saltlen, iterations, keysize, keybuffer);
+      break;
+
+    case 41:
+    case GCRY_KDF_SCRYPT:
+#if USE_SCRYPT
+      ec = _gcry_kdf_scrypt (passphrase, passphraselen, algo, subalgo,
+                             salt, saltlen, iterations, keysize, keybuffer);
+#else
+      ec = GPG_ERR_UNSUPPORTED_ALGORITHM;
+#endif /*USE_SCRYPT*/
       break;
 
     default:
@@ -274,5 +296,5 @@ gcry_kdf_derive (const void *passphrase, size_t passphraselen,
     }
 
  leave:
-  return gpg_error (ec);
+  return ec;
 }
diff --git a/cipher/mac-cmac.c b/cipher/mac-cmac.c
new file mode 100644 (file)
index 0000000..69a2f17
--- /dev/null
@@ -0,0 +1,226 @@
+/* mac-cmac.c  -  CMAC glue for MAC API
+ * Copyright © 2013 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 "./mac-internal.h"
+
+
+static int
+map_mac_algo_to_cipher (int mac_algo)
+{
+  switch (mac_algo)
+    {
+    default:
+      return GCRY_CIPHER_NONE;
+    case GCRY_MAC_CMAC_AES:
+      return GCRY_CIPHER_AES;
+    case GCRY_MAC_CMAC_3DES:
+      return GCRY_CIPHER_3DES;
+    case GCRY_MAC_CMAC_CAMELLIA:
+      return GCRY_CIPHER_CAMELLIA128;
+    case GCRY_MAC_CMAC_IDEA:
+      return GCRY_CIPHER_IDEA;
+    case GCRY_MAC_CMAC_CAST5:
+      return GCRY_CIPHER_CAST5;
+    case GCRY_MAC_CMAC_BLOWFISH:
+      return GCRY_CIPHER_BLOWFISH;
+    case GCRY_MAC_CMAC_TWOFISH:
+      return GCRY_CIPHER_TWOFISH;
+    case GCRY_MAC_CMAC_SERPENT:
+      return GCRY_CIPHER_SERPENT128;
+    case GCRY_MAC_CMAC_SEED:
+      return GCRY_CIPHER_SEED;
+    case GCRY_MAC_CMAC_RFC2268:
+      return GCRY_CIPHER_RFC2268_128;
+    case GCRY_MAC_CMAC_GOST28147:
+      return GCRY_CIPHER_GOST28147;
+    }
+}
+
+
+static gcry_err_code_t
+cmac_open (gcry_mac_hd_t h)
+{
+  gcry_err_code_t err;
+  gcry_cipher_hd_t hd;
+  int secure = (h->magic == CTX_MAGIC_SECURE);
+  int cipher_algo;
+  unsigned int flags;
+
+  cipher_algo = map_mac_algo_to_cipher (h->spec->algo);
+  flags = (secure ? GCRY_CIPHER_SECURE : 0);
+
+  err = _gcry_cipher_open_internal (&hd, cipher_algo, GCRY_CIPHER_MODE_CMAC,
+                                    flags);
+  if (err)
+    return err;
+
+  h->u.cmac.cipher_algo = cipher_algo;
+  h->u.cmac.ctx = hd;
+  h->u.cmac.blklen = _gcry_cipher_get_algo_blklen (cipher_algo);
+  return 0;
+}
+
+
+static void
+cmac_close (gcry_mac_hd_t h)
+{
+  _gcry_cipher_close (h->u.cmac.ctx);
+  h->u.cmac.ctx = NULL;
+}
+
+
+static gcry_err_code_t
+cmac_setkey (gcry_mac_hd_t h, const unsigned char *key, size_t keylen)
+{
+  return _gcry_cipher_setkey (h->u.cmac.ctx, key, keylen);
+}
+
+
+static gcry_err_code_t
+cmac_reset (gcry_mac_hd_t h)
+{
+  return _gcry_cipher_reset (h->u.cmac.ctx);
+}
+
+
+static gcry_err_code_t
+cmac_write (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
+{
+  return _gcry_cipher_cmac_authenticate (h->u.cmac.ctx, buf, buflen);
+}
+
+
+static gcry_err_code_t
+cmac_read (gcry_mac_hd_t h, unsigned char *outbuf, size_t * outlen)
+{
+  if (*outlen > h->u.cmac.blklen)
+    *outlen = h->u.cmac.blklen;
+  return _gcry_cipher_cmac_get_tag (h->u.cmac.ctx, outbuf, *outlen);
+}
+
+
+static gcry_err_code_t
+cmac_verify (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
+{
+  return _gcry_cipher_cmac_check_tag (h->u.cmac.ctx, buf, buflen);
+}
+
+
+static unsigned int
+cmac_get_maclen (int algo)
+{
+  return _gcry_cipher_get_algo_blklen (map_mac_algo_to_cipher (algo));
+}
+
+
+static unsigned int
+cmac_get_keylen (int algo)
+{
+  return _gcry_cipher_get_algo_keylen (map_mac_algo_to_cipher (algo));
+}
+
+
+static gcry_mac_spec_ops_t cmac_ops = {
+  cmac_open,
+  cmac_close,
+  cmac_setkey,
+  NULL,
+  cmac_reset,
+  cmac_write,
+  cmac_read,
+  cmac_verify,
+  cmac_get_maclen,
+  cmac_get_keylen
+};
+
+
+#if USE_BLOWFISH
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_blowfish = {
+  GCRY_MAC_CMAC_BLOWFISH, {0, 0}, "CMAC_BLOWFISH",
+  &cmac_ops
+};
+#endif
+#if USE_DES
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_tripledes = {
+  GCRY_MAC_CMAC_3DES, {0, 1}, "CMAC_3DES",
+  &cmac_ops
+};
+#endif
+#if USE_CAST5
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_cast5 = {
+  GCRY_MAC_CMAC_CAST5, {0, 0}, "CMAC_CAST5",
+  &cmac_ops
+};
+#endif
+#if USE_AES
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_aes = {
+  GCRY_MAC_CMAC_AES, {0, 1}, "CMAC_AES",
+  &cmac_ops
+};
+#endif
+#if USE_TWOFISH
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_twofish = {
+  GCRY_MAC_CMAC_TWOFISH, {0, 0}, "CMAC_TWOFISH",
+  &cmac_ops
+};
+#endif
+#if USE_SERPENT
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_serpent = {
+  GCRY_MAC_CMAC_SERPENT, {0, 0}, "CMAC_SERPENT",
+  &cmac_ops
+};
+#endif
+#if USE_RFC2268
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_rfc2268 = {
+  GCRY_MAC_CMAC_RFC2268, {0, 0}, "CMAC_RFC2268",
+  &cmac_ops
+};
+#endif
+#if USE_SEED
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_seed = {
+  GCRY_MAC_CMAC_SEED, {0, 0}, "CMAC_SEED",
+  &cmac_ops
+};
+#endif
+#if USE_CAMELLIA
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_camellia = {
+  GCRY_MAC_CMAC_CAMELLIA, {0, 0}, "CMAC_CAMELLIA",
+  &cmac_ops
+};
+#endif
+#ifdef USE_IDEA
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_idea = {
+  GCRY_MAC_CMAC_IDEA, {0, 0}, "CMAC_IDEA",
+  &cmac_ops
+};
+#endif
+#if USE_GOST28147
+gcry_mac_spec_t _gcry_mac_type_spec_cmac_gost28147 = {
+  GCRY_MAC_CMAC_GOST28147, {0, 0}, "CMAC_GOST28147",
+  &cmac_ops
+};
+#endif
diff --git a/cipher/mac-gmac.c b/cipher/mac-gmac.c
new file mode 100644 (file)
index 0000000..18d56b5
--- /dev/null
@@ -0,0 +1,185 @@
+/* mac-gmac.c  -  GMAC glue for MAC API
+ * Copyright © 2013 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 "./mac-internal.h"
+
+
+static int
+map_mac_algo_to_cipher (int mac_algo)
+{
+  switch (mac_algo)
+    {
+    default:
+      return GCRY_CIPHER_NONE;
+    case GCRY_MAC_GMAC_AES:
+      return GCRY_CIPHER_AES;
+    case GCRY_MAC_GMAC_CAMELLIA:
+      return GCRY_CIPHER_CAMELLIA128;
+    case GCRY_MAC_GMAC_TWOFISH:
+      return GCRY_CIPHER_TWOFISH;
+    case GCRY_MAC_GMAC_SERPENT:
+      return GCRY_CIPHER_SERPENT128;
+    case GCRY_MAC_GMAC_SEED:
+      return GCRY_CIPHER_SEED;
+    }
+}
+
+
+static gcry_err_code_t
+gmac_open (gcry_mac_hd_t h)
+{
+  gcry_err_code_t err;
+  gcry_cipher_hd_t hd;
+  int secure = (h->magic == CTX_MAGIC_SECURE);
+  int cipher_algo;
+  unsigned int flags;
+
+  cipher_algo = map_mac_algo_to_cipher (h->spec->algo);
+  flags = (secure ? GCRY_CIPHER_SECURE : 0);
+
+  err = _gcry_cipher_open_internal (&hd, cipher_algo, GCRY_CIPHER_MODE_GCM,
+                                    flags);
+  if (err)
+    return err;
+
+  h->u.gmac.cipher_algo = cipher_algo;
+  h->u.gmac.ctx = hd;
+  return 0;
+}
+
+
+static void
+gmac_close (gcry_mac_hd_t h)
+{
+  _gcry_cipher_close (h->u.gmac.ctx);
+  h->u.gmac.ctx = NULL;
+}
+
+
+static gcry_err_code_t
+gmac_setkey (gcry_mac_hd_t h, const unsigned char *key, size_t keylen)
+{
+  return _gcry_cipher_setkey (h->u.gmac.ctx, key, keylen);
+}
+
+
+static gcry_err_code_t
+gmac_setiv (gcry_mac_hd_t h, const unsigned char *iv, size_t ivlen)
+{
+  return _gcry_cipher_setiv (h->u.gmac.ctx, iv, ivlen);
+}
+
+
+static gcry_err_code_t
+gmac_reset (gcry_mac_hd_t h)
+{
+  return _gcry_cipher_reset (h->u.gmac.ctx);
+}
+
+
+static gcry_err_code_t
+gmac_write (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
+{
+  return _gcry_cipher_authenticate (h->u.gmac.ctx, buf, buflen);
+}
+
+
+static gcry_err_code_t
+gmac_read (gcry_mac_hd_t h, unsigned char *outbuf, size_t * outlen)
+{
+  if (*outlen > GCRY_GCM_BLOCK_LEN)
+    *outlen = GCRY_GCM_BLOCK_LEN;
+  return _gcry_cipher_gettag (h->u.gmac.ctx, outbuf, *outlen);
+}
+
+
+static gcry_err_code_t
+gmac_verify (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
+{
+  return _gcry_cipher_checktag (h->u.gmac.ctx, buf, buflen);
+}
+
+
+static unsigned int
+gmac_get_maclen (int algo)
+{
+  (void)algo;
+  return GCRY_GCM_BLOCK_LEN;
+}
+
+
+static unsigned int
+gmac_get_keylen (int algo)
+{
+  return _gcry_cipher_get_algo_keylen (map_mac_algo_to_cipher (algo));
+}
+
+
+static gcry_mac_spec_ops_t gmac_ops = {
+  gmac_open,
+  gmac_close,
+  gmac_setkey,
+  gmac_setiv,
+  gmac_reset,
+  gmac_write,
+  gmac_read,
+  gmac_verify,
+  gmac_get_maclen,
+  gmac_get_keylen
+};
+
+
+#if USE_AES
+gcry_mac_spec_t _gcry_mac_type_spec_gmac_aes = {
+  GCRY_MAC_GMAC_AES, {0, 1}, "GMAC_AES",
+  &gmac_ops
+};
+#endif
+#if USE_TWOFISH
+gcry_mac_spec_t _gcry_mac_type_spec_gmac_twofish = {
+  GCRY_MAC_GMAC_TWOFISH, {0, 0}, "GMAC_TWOFISH",
+  &gmac_ops
+};
+#endif
+#if USE_SERPENT
+gcry_mac_spec_t _gcry_mac_type_spec_gmac_serpent = {
+  GCRY_MAC_GMAC_SERPENT, {0, 0}, "GMAC_SERPENT",
+  &gmac_ops
+};
+#endif
+#if USE_SEED
+gcry_mac_spec_t _gcry_mac_type_spec_gmac_seed = {
+  GCRY_MAC_GMAC_SEED, {0, 0}, "GMAC_SEED",
+  &gmac_ops
+};
+#endif
+#if USE_CAMELLIA
+gcry_mac_spec_t _gcry_mac_type_spec_gmac_camellia = {
+  GCRY_MAC_GMAC_CAMELLIA, {0, 0}, "GMAC_CAMELLIA",
+  &gmac_ops
+};
+#endif
diff --git a/cipher/mac-hmac.c b/cipher/mac-hmac.c
new file mode 100644 (file)
index 0000000..15c613d
--- /dev/null
@@ -0,0 +1,272 @@
+/* mac-hmac.c  -  HMAC glue for MAC API
+ * Copyright © 2013 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 "bufhelp.h"
+
+
+static int
+map_mac_algo_to_md (int mac_algo)
+{
+  switch (mac_algo)
+    {
+    default:
+      return GCRY_MD_NONE;
+    case GCRY_MAC_HMAC_MD4:
+      return GCRY_MD_MD4;
+    case GCRY_MAC_HMAC_MD5:
+      return GCRY_MD_MD5;
+    case GCRY_MAC_HMAC_SHA1:
+      return GCRY_MD_SHA1;
+    case GCRY_MAC_HMAC_SHA224:
+      return GCRY_MD_SHA224;
+    case GCRY_MAC_HMAC_SHA256:
+      return GCRY_MD_SHA256;
+    case GCRY_MAC_HMAC_SHA384:
+      return GCRY_MD_SHA384;
+    case GCRY_MAC_HMAC_SHA512:
+      return GCRY_MD_SHA512;
+    case GCRY_MAC_HMAC_RMD160:
+      return GCRY_MD_RMD160;
+    case GCRY_MAC_HMAC_TIGER1:
+      return GCRY_MD_TIGER1;
+    case GCRY_MAC_HMAC_WHIRLPOOL:
+      return GCRY_MD_WHIRLPOOL;
+    case GCRY_MAC_HMAC_GOSTR3411_94:
+      return GCRY_MD_GOSTR3411_94;
+    case GCRY_MAC_HMAC_STRIBOG256:
+      return GCRY_MD_STRIBOG256;
+    case GCRY_MAC_HMAC_STRIBOG512:
+      return GCRY_MD_STRIBOG512;
+    }
+}
+
+
+static gcry_err_code_t
+hmac_open (gcry_mac_hd_t h)
+{
+  gcry_err_code_t err;
+  gcry_md_hd_t hd;
+  int secure = (h->magic == CTX_MAGIC_SECURE);
+  unsigned int flags;
+  int md_algo;
+
+  md_algo = map_mac_algo_to_md (h->spec->algo);
+
+  flags = GCRY_MD_FLAG_HMAC;
+  flags |= (secure ? GCRY_MD_FLAG_SECURE : 0);
+
+  err = _gcry_md_open (&hd, md_algo, flags);
+  if (err)
+    return err;
+
+  h->u.hmac.md_algo = md_algo;
+  h->u.hmac.md_ctx = hd;
+  return 0;
+}
+
+
+static void
+hmac_close (gcry_mac_hd_t h)
+{
+  _gcry_md_close (h->u.hmac.md_ctx);
+  h->u.hmac.md_ctx = NULL;
+}
+
+
+static gcry_err_code_t
+hmac_setkey (gcry_mac_hd_t h, const unsigned char *key, size_t keylen)
+{
+  return _gcry_md_setkey (h->u.hmac.md_ctx, key, keylen);
+}
+
+
+static gcry_err_code_t
+hmac_reset (gcry_mac_hd_t h)
+{
+  _gcry_md_reset (h->u.hmac.md_ctx);
+  return 0;
+}
+
+
+static gcry_err_code_t
+hmac_write (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
+{
+  _gcry_md_write (h->u.hmac.md_ctx, buf, buflen);
+  return 0;
+}
+
+
+static gcry_err_code_t
+hmac_read (gcry_mac_hd_t h, unsigned char *outbuf, size_t * outlen)
+{
+  unsigned int dlen;
+  const unsigned char *digest;
+
+  dlen = _gcry_md_get_algo_dlen (h->u.hmac.md_algo);
+  digest = _gcry_md_read (h->u.hmac.md_ctx, h->u.hmac.md_algo);
+
+  if (*outlen <= dlen)
+    buf_cpy (outbuf, digest, *outlen);
+  else
+    {
+      buf_cpy (outbuf, digest, dlen);
+      *outlen = dlen;
+    }
+
+  return 0;
+}
+
+
+static gcry_err_code_t
+hmac_verify (gcry_mac_hd_t h, const unsigned char *buf, size_t buflen)
+{
+  unsigned int dlen;
+  const unsigned char *digest;
+
+  dlen = _gcry_md_get_algo_dlen (h->u.hmac.md_algo);
+  digest = _gcry_md_read (h->u.hmac.md_ctx, h->u.hmac.md_algo);
+
+  if (buflen > dlen)
+    return GPG_ERR_INV_LENGTH;
+
+  return buf_eq_const (buf, digest, buflen) ? 0 : GPG_ERR_CHECKSUM;
+}
+
+
+static unsigned int
+hmac_get_maclen (int algo)
+{
+  return _gcry_md_get_algo_dlen (map_mac_algo_to_md (algo));
+}
+
+
+static unsigned int
+hmac_get_keylen (int algo)
+{
+  /* Return blocksize for default key length. */
+  switch (algo)
+    {
+    case GCRY_MAC_HMAC_SHA384:
+    case GCRY_MAC_HMAC_SHA512:
+      return 128;
+    case GCRY_MAC_HMAC_GOSTR3411_94:
+      return 32;
+    default:
+      return 64;
+    }
+}
+
+
+static const gcry_mac_spec_ops_t hmac_ops = {
+  hmac_open,
+  hmac_close,
+  hmac_setkey,
+  NULL,
+  hmac_reset,
+  hmac_write,
+  hmac_read,
+  hmac_verify,
+  hmac_get_maclen,
+  hmac_get_keylen
+};
+
+
+#if USE_SHA1
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha1 = {
+  GCRY_MAC_HMAC_SHA1, {0, 1}, "HMAC_SHA1",
+  &hmac_ops
+};
+#endif
+#if USE_SHA256
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha256 = {
+  GCRY_MAC_HMAC_SHA256, {0, 1}, "HMAC_SHA256",
+  &hmac_ops
+};
+
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha224 = {
+  GCRY_MAC_HMAC_SHA224, {0, 1}, "HMAC_SHA224",
+  &hmac_ops
+};
+#endif
+#if USE_SHA512
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha512 = {
+  GCRY_MAC_HMAC_SHA512, {0, 1}, "HMAC_SHA512",
+  &hmac_ops
+};
+
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha384 = {
+  GCRY_MAC_HMAC_SHA384, {0, 1}, "HMAC_SHA384",
+  &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",
+  &hmac_ops
+};
+#endif
+#ifdef USE_GOST_R_3411_12
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_stribog256 = {
+  GCRY_MAC_HMAC_STRIBOG256, {0, 0}, "HMAC_STRIBOG256",
+  &hmac_ops
+};
+
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_stribog512 = {
+  GCRY_MAC_HMAC_STRIBOG512, {0, 0}, "HMAC_STRIBOG512",
+  &hmac_ops
+};
+#endif
+#if USE_WHIRLPOOL
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_whirlpool = {
+  GCRY_MAC_HMAC_WHIRLPOOL, {0, 0}, "HMAC_WHIRLPOOL",
+  &hmac_ops
+};
+#endif
+#if USE_RMD160
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_rmd160 = {
+  GCRY_MAC_HMAC_RMD160, {0, 0}, "HMAC_RIPEMD160",
+  &hmac_ops
+};
+#endif
+#if USE_TIGER
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_tiger1 = {
+  GCRY_MAC_HMAC_TIGER1, {0, 0}, "HMAC_TIGER",
+  &hmac_ops
+};
+#endif
+#if USE_MD5
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_md5 = {
+  GCRY_MAC_HMAC_MD5, {0, 0}, "HMAC_MD5",
+  &hmac_ops
+};
+#endif
+#if USE_MD4
+gcry_mac_spec_t _gcry_mac_type_spec_hmac_md4 = {
+  GCRY_MAC_HMAC_MD4, {0, 0}, "HMAC_MD4",
+  &hmac_ops
+};
+#endif
diff --git a/cipher/mac-internal.h b/cipher/mac-internal.h
new file mode 100644 (file)
index 0000000..6fc304b
--- /dev/null
@@ -0,0 +1,204 @@
+/* mac-internal.h  -  Internal defs for mac.c
+ * Copyright © 2013 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 data object used to hold a handle to an encryption object.  */
+struct gcry_mac_handle;
+
+\f
+/*
+ *
+ * Message authentication code related definitions.
+ *
+ */
+
+
+/* Magic values for the context structure.  */
+#define CTX_MAGIC_NORMAL 0x59d9b8af
+#define CTX_MAGIC_SECURE 0x12c27cd0
+
+
+/* MAC module functions. */
+typedef gcry_err_code_t (*gcry_mac_open_func_t)(gcry_mac_hd_t h);
+typedef void (*gcry_mac_close_func_t)(gcry_mac_hd_t h);
+typedef gcry_err_code_t (*gcry_mac_setkey_func_t)(gcry_mac_hd_t h,
+                                                 const unsigned char *key,
+                                                 size_t keylen);
+typedef gcry_err_code_t (*gcry_mac_setiv_func_t)(gcry_mac_hd_t h,
+                                                const unsigned char *iv,
+                                                size_t ivlen);
+typedef gcry_err_code_t (*gcry_mac_reset_func_t)(gcry_mac_hd_t h);
+typedef gcry_err_code_t (*gcry_mac_write_func_t)(gcry_mac_hd_t h,
+                                                const unsigned char *inbuf,
+                                                size_t inlen);
+typedef gcry_err_code_t (*gcry_mac_read_func_t)(gcry_mac_hd_t h,
+                                               unsigned char *outbuf,
+                                               size_t *outlen);
+typedef gcry_err_code_t (*gcry_mac_verify_func_t)(gcry_mac_hd_t h,
+                                                 const unsigned char *inbuf,
+                                                 size_t inlen);
+typedef unsigned int (*gcry_mac_get_maclen_func_t)(int algo);
+typedef unsigned int (*gcry_mac_get_keylen_func_t)(int algo);
+
+
+typedef struct gcry_mac_spec_ops
+{
+  gcry_mac_open_func_t open;
+  gcry_mac_close_func_t close;
+  gcry_mac_setkey_func_t setkey;
+  gcry_mac_setiv_func_t setiv;
+  gcry_mac_reset_func_t reset;
+  gcry_mac_write_func_t write;
+  gcry_mac_read_func_t read;
+  gcry_mac_verify_func_t verify;
+  gcry_mac_get_maclen_func_t get_maclen;
+  gcry_mac_get_keylen_func_t get_keylen;
+} gcry_mac_spec_ops_t;
+
+
+/* Module specification structure for message authentication codes.  */
+typedef struct gcry_mac_spec
+{
+  int algo;
+  struct {
+    unsigned int disabled:1;
+    unsigned int fips:1;
+  } flags;
+  const char *name;
+  const gcry_mac_spec_ops_t *ops;
+} gcry_mac_spec_t;
+
+
+
+/* The handle structure.  */
+struct gcry_mac_handle
+{
+  int magic;
+  int algo;
+  const gcry_mac_spec_t *spec;
+  gcry_ctx_t gcry_ctx;
+  union {
+    struct {
+      gcry_md_hd_t md_ctx;
+      int md_algo;
+    } hmac;
+    struct {
+      gcry_cipher_hd_t ctx;
+      int cipher_algo;
+      unsigned int blklen;
+    } cmac;
+    struct {
+      gcry_cipher_hd_t ctx;
+      int cipher_algo;
+    } gmac;
+  } u;
+};
+
+
+/*
+ * The HMAC algorithm specifications (mac-hmac.c).
+ */
+#if USE_SHA1
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha1;
+#endif
+#if USE_SHA256
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha256;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha224;
+#endif
+#if USE_SHA512
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha512;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_sha384;
+#endif
+#ifdef USE_GOST_R_3411_94
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_gost3411_94;
+#endif
+#ifdef USE_GOST_R_3411_12
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_stribog256;
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_stribog512;
+#endif
+#if USE_WHIRLPOOL
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_whirlpool;
+#endif
+#if USE_RMD160
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_rmd160;
+#endif
+#if USE_TIGER
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_tiger1;
+#endif
+#if USE_MD5
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_md5;
+#endif
+#if USE_MD4
+extern gcry_mac_spec_t _gcry_mac_type_spec_hmac_md4;
+#endif
+
+/*
+ * The CMAC algorithm specifications (mac-cmac.c).
+ */
+#if USE_BLOWFISH
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_blowfish;
+#endif
+#if USE_DES
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_tripledes;
+#endif
+#if USE_CAST5
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_cast5;
+#endif
+#if USE_AES
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_aes;
+#endif
+#if USE_TWOFISH
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_twofish;
+#endif
+#if USE_SERPENT
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_serpent;
+#endif
+#if USE_RFC2268
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_rfc2268;
+#endif
+#if USE_SEED
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_seed;
+#endif
+#if USE_CAMELLIA
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_camellia;
+#endif
+#ifdef USE_IDEA
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_idea;
+#endif
+#if USE_GOST28147
+extern gcry_mac_spec_t _gcry_mac_type_spec_cmac_gost28147;
+#endif
+
+/*
+ * The GMAC algorithm specifications (mac-gmac.c).
+ */
+#if USE_AES
+extern gcry_mac_spec_t _gcry_mac_type_spec_gmac_aes;
+#endif
+#if USE_TWOFISH
+extern gcry_mac_spec_t _gcry_mac_type_spec_gmac_twofish;
+#endif
+#if USE_SERPENT
+extern gcry_mac_spec_t _gcry_mac_type_spec_gmac_serpent;
+#endif
+#if USE_SEED
+extern gcry_mac_spec_t _gcry_mac_type_spec_gmac_seed;
+#endif
+#if USE_CAMELLIA
+extern gcry_mac_spec_t _gcry_mac_type_spec_gmac_camellia;
+#endif
diff --git a/cipher/mac.c b/cipher/mac.c
new file mode 100644 (file)
index 0000000..fa36c7d
--- /dev/null
@@ -0,0 +1,465 @@
+/* mac.c  -  message authentication code dispatcher
+ * Copyright © 2013 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"
+
+
+/* This is the list of the digest implementations included in
+   libgcrypt.  */
+static gcry_mac_spec_t *mac_list[] = {
+#if USE_SHA1
+  &_gcry_mac_type_spec_hmac_sha1,
+#endif
+#if USE_SHA256
+  &_gcry_mac_type_spec_hmac_sha256,
+  &_gcry_mac_type_spec_hmac_sha224,
+#endif
+#if USE_SHA512
+  &_gcry_mac_type_spec_hmac_sha512,
+  &_gcry_mac_type_spec_hmac_sha384,
+#endif
+#ifdef USE_GOST_R_3411_94
+  &_gcry_mac_type_spec_hmac_gost3411_94,
+#endif
+#ifdef USE_GOST_R_3411_12
+  &_gcry_mac_type_spec_hmac_stribog256,
+  &_gcry_mac_type_spec_hmac_stribog512,
+#endif
+#if USE_WHIRLPOOL
+  &_gcry_mac_type_spec_hmac_whirlpool,
+#endif
+#if USE_RMD160
+  &_gcry_mac_type_spec_hmac_rmd160,
+#endif
+#if USE_TIGER
+  &_gcry_mac_type_spec_hmac_tiger1,
+#endif
+#if USE_MD5
+  &_gcry_mac_type_spec_hmac_md5,
+#endif
+#if USE_MD4
+  &_gcry_mac_type_spec_hmac_md4,
+#endif
+#if USE_BLOWFISH
+  &_gcry_mac_type_spec_cmac_blowfish,
+#endif
+#if USE_DES
+  &_gcry_mac_type_spec_cmac_tripledes,
+#endif
+#if USE_CAST5
+  &_gcry_mac_type_spec_cmac_cast5,
+#endif
+#if USE_AES
+  &_gcry_mac_type_spec_cmac_aes,
+  &_gcry_mac_type_spec_gmac_aes,
+#endif
+#if USE_TWOFISH
+  &_gcry_mac_type_spec_cmac_twofish,
+  &_gcry_mac_type_spec_gmac_twofish,
+#endif
+#if USE_SERPENT
+  &_gcry_mac_type_spec_cmac_serpent,
+  &_gcry_mac_type_spec_gmac_serpent,
+#endif
+#if USE_RFC2268
+  &_gcry_mac_type_spec_cmac_rfc2268,
+#endif
+#if USE_SEED
+  &_gcry_mac_type_spec_cmac_seed,
+  &_gcry_mac_type_spec_gmac_seed,
+#endif
+#if USE_CAMELLIA
+  &_gcry_mac_type_spec_cmac_camellia,
+  &_gcry_mac_type_spec_gmac_camellia,
+#endif
+#ifdef USE_IDEA
+  &_gcry_mac_type_spec_cmac_idea,
+#endif
+#if USE_GOST28147
+  &_gcry_mac_type_spec_cmac_gost28147,
+#endif
+  NULL,
+};
+
+
+\f
+/* Return the spec structure for the MAC algorithm ALGO.  For an
+   unknown algorithm NULL is returned.  */
+static gcry_mac_spec_t *
+spec_from_algo (int algo)
+{
+  gcry_mac_spec_t *spec;
+  int idx;
+
+  for (idx = 0; (spec = mac_list[idx]); idx++)
+    if (algo == spec->algo)
+      return spec;
+  return NULL;
+}
+
+
+/* Lookup a mac's spec by its name.  */
+static gcry_mac_spec_t *
+spec_from_name (const char *name)
+{
+  gcry_mac_spec_t *spec;
+  int idx;
+
+  for (idx = 0; (spec = mac_list[idx]); idx++)
+    if (!stricmp (name, spec->name))
+      return spec;
+
+  return NULL;
+}
+
+
+/****************
+ * Map a string to the mac algo
+ */
+int
+_gcry_mac_map_name (const char *string)
+{
+  gcry_mac_spec_t *spec;
+
+  if (!string)
+    return 0;
+
+  /* Not found, search a matching mac name.  */
+  spec = spec_from_name (string);
+  if (spec)
+    return spec->algo;
+
+  return 0;
+}
+
+
+/****************
+ * This function simply returns the name of the algorithm or some constant
+ * string when there is no algo.  It will never return NULL.
+ * Use the macro gcry_mac_test_algo() to check whether the algorithm
+ * is valid.
+ */
+const char *
+_gcry_mac_algo_name (int algorithm)
+{
+  gcry_mac_spec_t *spec;
+
+  spec = spec_from_algo (algorithm);
+  return spec ? spec->name : "?";
+}
+
+
+static gcry_err_code_t
+check_mac_algo (int algorithm)
+{
+  gcry_mac_spec_t *spec;
+
+  spec = spec_from_algo (algorithm);
+  if (spec && !spec->flags.disabled)
+    return 0;
+
+  return GPG_ERR_MAC_ALGO;
+}
+
+
+/****************
+ * Open a message digest handle for use with algorithm ALGO.
+ */
+static gcry_err_code_t
+mac_open (gcry_mac_hd_t * hd, int algo, int secure, gcry_ctx_t ctx)
+{
+  gcry_mac_spec_t *spec;
+  gcry_err_code_t err;
+  gcry_mac_hd_t h;
+
+  spec = spec_from_algo (algo);
+  if (!spec)
+    return GPG_ERR_MAC_ALGO;
+  else if (spec->flags.disabled)
+    return GPG_ERR_MAC_ALGO;
+  else if (!spec->ops)
+    return GPG_ERR_MAC_ALGO;
+  else if (!spec->ops->open || !spec->ops->write || !spec->ops->setkey ||
+           !spec->ops->read || !spec->ops->verify || !spec->ops->reset)
+    return GPG_ERR_MAC_ALGO;
+
+  if (secure)
+    h = xtrycalloc_secure (1, sizeof (*h));
+  else
+    h = xtrycalloc (1, sizeof (*h));
+
+  if (!h)
+    return gpg_err_code_from_syserror ();
+
+  h->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
+  h->spec = spec;
+  h->algo = algo;
+  h->gcry_ctx = ctx;
+
+  err = h->spec->ops->open (h);
+  if (err)
+    xfree (h);
+  else
+    *hd = h;
+
+  return err;
+}
+
+
+static gcry_error_t
+mac_reset (gcry_mac_hd_t hd)
+{
+  if (hd->spec->ops->reset)
+    return hd->spec->ops->reset (hd);
+
+  return 0;
+}
+
+
+static void
+mac_close (gcry_mac_hd_t hd)
+{
+  if (hd->spec->ops->close)
+    hd->spec->ops->close (hd);
+
+  wipememory (hd, sizeof (*hd));
+
+  xfree (hd);
+}
+
+
+static gcry_error_t
+mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
+{
+  if (!hd->spec->ops->setkey)
+    return GPG_ERR_INV_ARG;
+  if (keylen > 0 && !key)
+    return GPG_ERR_INV_ARG;
+
+  return hd->spec->ops->setkey (hd, key, keylen);
+}
+
+
+static gcry_error_t
+mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
+{
+  if (!hd->spec->ops->setiv)
+    return GPG_ERR_INV_ARG;
+  if (ivlen > 0 && !iv)
+    return GPG_ERR_INV_ARG;
+
+  return hd->spec->ops->setiv (hd, iv, ivlen);
+}
+
+
+static gcry_error_t
+mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen)
+{
+  if (!hd->spec->ops->write)
+    return GPG_ERR_INV_ARG;
+  if (inlen > 0 && !inbuf)
+    return GPG_ERR_INV_ARG;
+
+  return hd->spec->ops->write (hd, inbuf, inlen);
+}
+
+
+static gcry_error_t
+mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen)
+{
+  if (!outbuf || !outlen || *outlen == 0 || !hd->spec->ops->read)
+    return GPG_ERR_INV_ARG;
+
+  return hd->spec->ops->read (hd, outbuf, outlen);
+}
+
+
+static gcry_error_t
+mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
+{
+  if (!buf || buflen == 0 || !hd->spec->ops->verify)
+    return GPG_ERR_INV_ARG;
+
+  return hd->spec->ops->verify (hd, buf, buflen);
+}
+
+
+/* Create a MAC object for algorithm ALGO.  FLAGS may be
+   given as an bitwise OR of the gcry_mac_flags values.
+   H is guaranteed to be a valid handle or NULL on error.  */
+gpg_err_code_t
+_gcry_mac_open (gcry_mac_hd_t * h, int algo, unsigned int flags,
+                gcry_ctx_t ctx)
+{
+  gcry_err_code_t rc;
+  gcry_mac_hd_t hd = NULL;
+
+  if ((flags & ~GCRY_MAC_FLAG_SECURE))
+    rc = GPG_ERR_INV_ARG;
+  else
+    rc = mac_open (&hd, algo, !!(flags & GCRY_MAC_FLAG_SECURE), ctx);
+
+  *h = rc ? NULL : hd;
+  return rc;
+}
+
+
+void
+_gcry_mac_close (gcry_mac_hd_t hd)
+{
+  mac_close (hd);
+}
+
+
+gcry_err_code_t
+_gcry_mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
+{
+  return mac_setkey (hd, key, keylen);
+}
+
+
+gcry_err_code_t
+_gcry_mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
+{
+  return mac_setiv (hd, iv, ivlen);
+}
+
+
+gcry_err_code_t
+_gcry_mac_write (gcry_mac_hd_t hd, const void *inbuf, size_t inlen)
+{
+  return mac_write (hd, inbuf, inlen);
+}
+
+
+gcry_err_code_t
+_gcry_mac_read (gcry_mac_hd_t hd, void *outbuf, size_t * outlen)
+{
+  return mac_read (hd, outbuf, outlen);
+}
+
+
+gcry_err_code_t
+_gcry_mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
+{
+  return mac_verify (hd, buf, buflen);
+}
+
+
+unsigned int
+_gcry_mac_get_algo_maclen (int algo)
+{
+  gcry_mac_spec_t *spec;
+
+  spec = spec_from_algo (algo);
+  if (!spec || !spec->ops || !spec->ops->get_maclen)
+    return 0;
+
+  return spec->ops->get_maclen (algo);
+}
+
+
+unsigned int
+_gcry_mac_get_algo_keylen (int algo)
+{
+  gcry_mac_spec_t *spec;
+
+  spec = spec_from_algo (algo);
+  if (!spec || !spec->ops || !spec->ops->get_keylen)
+    return 0;
+
+  return spec->ops->get_keylen (algo);
+}
+
+
+gcry_err_code_t
+_gcry_mac_ctl (gcry_mac_hd_t hd, int cmd, void *buffer, size_t buflen)
+{
+  gcry_err_code_t rc;
+
+  /* Currently not used.  */
+  (void) hd;
+  (void) buffer;
+  (void) buflen;
+
+  switch (cmd)
+    {
+    case GCRYCTL_RESET:
+      rc = mac_reset (hd);
+      break;
+    default:
+      rc = GPG_ERR_INV_OP;
+    }
+  return rc;
+}
+
+
+/* Return information about the given MAC algorithm ALGO.
+
+    GCRYCTL_TEST_ALGO:
+        Returns 0 if the specified algorithm ALGO is available for use.
+        BUFFER and NBYTES must be zero.
+
+   Note: Because this function is in most cases used to return an
+   integer value, we can make it easier for the caller to just look at
+   the return value.  The caller will in all cases consult the value
+   and thereby detecting whether a error occurred or not (i.e. while
+   checking the block size)
+ */
+gcry_err_code_t
+_gcry_mac_algo_info (int algo, int what, void *buffer, size_t * nbytes)
+{
+  gcry_err_code_t rc = 0;
+  unsigned int ui;
+
+  switch (what)
+    {
+    case GCRYCTL_GET_KEYLEN:
+      if (buffer || (!nbytes))
+        rc = GPG_ERR_INV_ARG;
+      else
+        {
+          ui = _gcry_mac_get_algo_keylen (algo);
+          if (ui > 0)
+            *nbytes = (size_t) ui;
+          else
+            /* The only reason for an error is an invalid algo.  */
+            rc = GPG_ERR_MAC_ALGO;
+        }
+      break;
+    case GCRYCTL_TEST_ALGO:
+      if (buffer || nbytes)
+        rc = GPG_ERR_INV_ARG;
+      else
+        rc = check_mac_algo (algo);
+      break;
+
+    default:
+      rc = GPG_ERR_INV_OP;
+    }
+
+  return rc;
+}
index c3b3a4f..22da30a 100644 (file)
@@ -1,6 +1,7 @@
 /* md.c  -  message digest dispatcher
  * Copyright (C) 1998, 1999, 2002, 2003, 2006,
  *               2008 Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2014 g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
 
 #include "rmd.h"
 
-/* A dummy extraspec so that we do not need to tests the extraspec
-   field from the module specification against NULL and instead
-   directly test the respective fields of extraspecs.  */
-static md_extra_spec_t dummy_extra_spec;
-
 
 /* This is the list of the digest implementations included in
    libgcrypt.  */
-static struct digest_table_entry
-{
-  gcry_md_spec_t *digest;
-  md_extra_spec_t *extraspec;
-  unsigned int algorithm;
-  int fips_allowed;
-} digest_table[] =
+static gcry_md_spec_t *digest_list[] =
   {
 #if USE_CRC
-    /* We allow the CRC algorithms even in FIPS mode because they are
-       actually no cryptographic primitives.  */
-    { &_gcry_digest_spec_crc32,
-      &dummy_extra_spec,                 GCRY_MD_CRC32, 1 },
-    { &_gcry_digest_spec_crc32_rfc1510,
-      &dummy_extra_spec,                 GCRY_MD_CRC32_RFC1510, 1 },
-    { &_gcry_digest_spec_crc24_rfc2440,
-      &dummy_extra_spec,                 GCRY_MD_CRC24_RFC2440, 1 },
-#endif
-#if USE_MD4
-    { &_gcry_digest_spec_md4,
-      &dummy_extra_spec,                 GCRY_MD_MD4 },
-#endif
-#if USE_MD5
-    { &_gcry_digest_spec_md5,
-      &dummy_extra_spec,                 GCRY_MD_MD5, 1 },
-#endif
-#if USE_RMD160
-    { &_gcry_digest_spec_rmd160,
-      &dummy_extra_spec,                 GCRY_MD_RMD160 },
+     &_gcry_digest_spec_crc32,
+     &_gcry_digest_spec_crc32_rfc1510,
+     &_gcry_digest_spec_crc24_rfc2440,
 #endif
 #if USE_SHA1
-    { &_gcry_digest_spec_sha1,
-      &_gcry_digest_extraspec_sha1,      GCRY_MD_SHA1, 1 },
+     &_gcry_digest_spec_sha1,
 #endif
 #if USE_SHA256
-    { &_gcry_digest_spec_sha256,
-      &_gcry_digest_extraspec_sha256,    GCRY_MD_SHA256, 1 },
-    { &_gcry_digest_spec_sha224,
-      &_gcry_digest_extraspec_sha224,    GCRY_MD_SHA224, 1 },
+     &_gcry_digest_spec_sha256,
+     &_gcry_digest_spec_sha224,
 #endif
 #if USE_SHA512
-    { &_gcry_digest_spec_sha512,
-      &_gcry_digest_extraspec_sha512,    GCRY_MD_SHA512, 1 },
-    { &_gcry_digest_spec_sha384,
-      &_gcry_digest_extraspec_sha384,    GCRY_MD_SHA384, 1 },
+     &_gcry_digest_spec_sha512,
+     &_gcry_digest_spec_sha384,
 #endif
-#if USE_TIGER
-    { &_gcry_digest_spec_tiger,
-      &dummy_extra_spec,                 GCRY_MD_TIGER },
-    { &_gcry_digest_spec_tiger1,
-      &dummy_extra_spec,                 GCRY_MD_TIGER1 },
-    { &_gcry_digest_spec_tiger2,
-      &dummy_extra_spec,                 GCRY_MD_TIGER2 },
+#ifdef USE_GOST_R_3411_94
+     &_gcry_digest_spec_gost3411_94,
+#endif
+#ifdef USE_GOST_R_3411_12
+     &_gcry_digest_spec_stribog_256,
+     &_gcry_digest_spec_stribog_512,
 #endif
 #if USE_WHIRLPOOL
-    { &_gcry_digest_spec_whirlpool,
-      &dummy_extra_spec,                 GCRY_MD_WHIRLPOOL },
+     &_gcry_digest_spec_whirlpool,
 #endif
-    { NULL },
+#if USE_RMD160
+     &_gcry_digest_spec_rmd160,
+#endif
+#if USE_TIGER
+     &_gcry_digest_spec_tiger,
+     &_gcry_digest_spec_tiger1,
+     &_gcry_digest_spec_tiger2,
+#endif
+#if USE_MD5
+     &_gcry_digest_spec_md5,
+#endif
+#if USE_MD4
+     &_gcry_digest_spec_md4,
+#endif
+    NULL
   };
 
-/* List of registered digests.  */
-static gcry_module_t digests_registered;
-
-/* This is the lock protecting DIGESTS_REGISTERED.  */
-static ath_mutex_t digests_registered_lock = ATH_MUTEX_INITIALIZER;
-
-/* Flag to check whether the default ciphers have already been
-   registered.  */
-static int default_digests_registered;
 
 typedef struct gcry_md_list
 {
-  gcry_md_spec_t *digest;
-  gcry_module_t module;
+  gcry_md_spec_t *spec;
   struct gcry_md_list *next;
   size_t actual_struct_size;     /* Allocated size of this structure. */
   PROPERLY_ALIGNED_TYPE context;
 } GcryDigestEntry;
 
-/* this structure is put right after the gcry_md_hd_t buffer, so that
+/* This structure is put right after the gcry_md_hd_t buffer, so that
  * only one memory block is needed. */
 struct gcry_md_context
 {
   int  magic;
   size_t actual_handle_size;     /* Allocated size of this handle. */
-  int  secure;
   FILE  *debug;
-  int finalized;
+  struct {
+    unsigned int secure: 1;
+    unsigned int finalized:1;
+    unsigned int bugemu1:1;
+  } flags;
   GcryDigestEntry *list;
   byte *macpads;
   int macpads_Bsize;             /* Blocksize as used for the HMAC pads. */
@@ -136,301 +109,175 @@ struct gcry_md_context
 #define CTX_MAGIC_NORMAL 0x11071961
 #define CTX_MAGIC_SECURE 0x16917011
 
-/* Convenient macro for registering the default digests.  */
-#define REGISTER_DEFAULT_DIGESTS                   \
-  do                                               \
-    {                                              \
-      ath_mutex_lock (&digests_registered_lock);   \
-      if (! default_digests_registered)            \
-        {                                          \
-          md_register_default ();                  \
-          default_digests_registered = 1;          \
-        }                                          \
-      ath_mutex_unlock (&digests_registered_lock); \
-    }                                              \
-  while (0)
-
-
-static const char * digest_algo_to_string( int algo );
-static gcry_err_code_t check_digest_algo (int algo);
-static gcry_err_code_t md_open (gcry_md_hd_t *h, int algo,
-                                int secure, int hmac);
 static gcry_err_code_t md_enable (gcry_md_hd_t hd, int algo);
-static gcry_err_code_t md_copy (gcry_md_hd_t a, gcry_md_hd_t *b);
 static void md_close (gcry_md_hd_t a);
 static void md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen);
-static void md_final(gcry_md_hd_t a);
 static byte *md_read( gcry_md_hd_t a, int algo );
 static int md_get_algo( gcry_md_hd_t a );
 static int md_digest_length( int algo );
-static const byte *md_asn_oid( int algo, size_t *asnlen, size_t *mdlen );
 static void md_start_debug ( gcry_md_hd_t a, const char *suffix );
 static void md_stop_debug ( gcry_md_hd_t a );
 
 
+\f
+static int
+map_algo (int algo)
+{
+  return algo;
+}
 
 
-/* Internal function.  Register all the ciphers included in
-   CIPHER_TABLE.  Returns zero on success or an error code.  */
-static void
-md_register_default (void)
+/* Return the spec structure for the hash algorithm ALGO.  For an
+   unknown algorithm NULL is returned.  */
+static gcry_md_spec_t *
+spec_from_algo (int algo)
 {
-  gcry_err_code_t err = 0;
-  int i;
+  int idx;
+  gcry_md_spec_t *spec;
 
-  for (i = 0; !err && digest_table[i].digest; i++)
-    {
-      if ( fips_mode ())
-        {
-          if (!digest_table[i].fips_allowed)
-            continue;
-          if (digest_table[i].algorithm == GCRY_MD_MD5
-              && _gcry_enforced_fips_mode () )
-            continue;  /* Do not register in enforced fips mode.  */
-        }
+  algo = map_algo (algo);
 
-      err = _gcry_module_add (&digests_registered,
-                              digest_table[i].algorithm,
-                              (void *) digest_table[i].digest,
-                              (void *) digest_table[i].extraspec,
-                              NULL);
-    }
-
-  if (err)
-    BUG ();
+  for (idx = 0; (spec = digest_list[idx]); idx++)
+    if (algo == spec->algo)
+      return spec;
+  return NULL;
 }
 
-/* Internal callback function.  */
-static int
-gcry_md_lookup_func_name (void *spec, void *data)
-{
-  gcry_md_spec_t *digest = (gcry_md_spec_t *) spec;
-  char *name = (char *) data;
-
-  return (! stricmp (digest->name, name));
-}
 
-/* Internal callback function.  Used via _gcry_module_lookup.  */
-static int
-gcry_md_lookup_func_oid (void *spec, void *data)
+/* Lookup a hash's spec by its name.  */
+static gcry_md_spec_t *
+spec_from_name (const char *name)
 {
-  gcry_md_spec_t *digest = (gcry_md_spec_t *) spec;
-  char *oid = (char *) data;
-  gcry_md_oid_spec_t *oid_specs = digest->oids;
-  int ret = 0, i;
+  gcry_md_spec_t *spec;
+  int idx;
 
-  if (oid_specs)
+  for (idx=0; (spec = digest_list[idx]); idx++)
     {
-      for (i = 0; oid_specs[i].oidstring && (! ret); i++)
-        if (! stricmp (oid, oid_specs[i].oidstring))
-          ret = 1;
+      if (!stricmp (name, spec->name))
+        return spec;
     }
 
-  return ret;
-}
-
-/* Internal function.  Lookup a digest entry by it's name.  */
-static gcry_module_t
-gcry_md_lookup_name (const char *name)
-{
-  gcry_module_t digest;
-
-  digest = _gcry_module_lookup (digests_registered, (void *) name,
-                               gcry_md_lookup_func_name);
-
-  return digest;
+  return NULL;
 }
 
-/* Internal function.  Lookup a cipher entry by it's oid.  */
-static gcry_module_t
-gcry_md_lookup_oid (const char *oid)
-{
-  gcry_module_t digest;
-
-  digest = _gcry_module_lookup (digests_registered, (void *) oid,
-                               gcry_md_lookup_func_oid);
-
-  return digest;
-}
 
-/* Register a new digest module whose specification can be found in
-   DIGEST.  On success, a new algorithm ID is stored in ALGORITHM_ID
-   and a pointer representhing this module is stored in MODULE.  */
-gcry_error_t
-_gcry_md_register (gcry_md_spec_t *digest,
-                   md_extra_spec_t *extraspec,
-                   unsigned int *algorithm_id,
-                   gcry_module_t *module)
+/* Lookup a hash's spec by its OID.  */
+static gcry_md_spec_t *
+spec_from_oid (const char *oid)
 {
-  gcry_err_code_t err = 0;
-  gcry_module_t mod;
-
-  /* We do not support module loading in fips mode.  */
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+  gcry_md_spec_t *spec;
+  gcry_md_oid_spec_t *oid_specs;
+  int idx, j;
 
-  ath_mutex_lock (&digests_registered_lock);
-  err = _gcry_module_add (&digests_registered, 0,
-                         (void *) digest,
-                         (void *)(extraspec? extraspec : &dummy_extra_spec),
-                          &mod);
-  ath_mutex_unlock (&digests_registered_lock);
-
-  if (! err)
+  for (idx=0; (spec = digest_list[idx]); idx++)
     {
-      *module = mod;
-      *algorithm_id = mod->mod_id;
+      oid_specs = spec->oids;
+      if (oid_specs)
+        {
+          for (j = 0; oid_specs[j].oidstring; j++)
+            if (!stricmp (oid, oid_specs[j].oidstring))
+              return spec;
+        }
     }
 
-  return gcry_error (err);
-}
-
-/* Unregister the digest identified by ID, which must have been
-   registered with gcry_digest_register.  */
-void
-gcry_md_unregister (gcry_module_t module)
-{
-  ath_mutex_lock (&digests_registered_lock);
-  _gcry_module_release (module);
-  ath_mutex_unlock (&digests_registered_lock);
+  return NULL;
 }
 
 
-static int
-search_oid (const char *oid, int *algorithm, gcry_md_oid_spec_t *oid_spec)
+static gcry_md_spec_t *
+search_oid (const char *oid, gcry_md_oid_spec_t *oid_spec)
 {
-  gcry_module_t module;
-  int ret = 0;
+  gcry_md_spec_t *spec;
+  int i;
 
   if (oid && ((! strncmp (oid, "oid.", 4))
              || (! strncmp (oid, "OID.", 4))))
     oid += 4;
 
-  module = gcry_md_lookup_oid (oid);
-  if (module)
+  spec = spec_from_oid (oid);
+  if (spec && spec->oids)
     {
-      gcry_md_spec_t *digest = module->spec;
-      int i;
-
-      for (i = 0; digest->oids[i].oidstring && !ret; i++)
-       if (! stricmp (oid, digest->oids[i].oidstring))
+      for (i = 0; spec->oids[i].oidstring; i++)
+       if (!stricmp (oid, spec->oids[i].oidstring))
          {
-           if (algorithm)
-             *algorithm = module->mod_id;
            if (oid_spec)
-             *oid_spec = digest->oids[i];
-           ret = 1;
+             *oid_spec = spec->oids[i];
+           return spec;
          }
-      _gcry_module_release (module);
     }
 
-  return ret;
+  return NULL;
 }
 
+
 /****************
  * Map a string to the digest algo
  */
 int
-gcry_md_map_name (const char *string)
+_gcry_md_map_name (const char *string)
 {
-  gcry_module_t digest;
-  int ret, algorithm = 0;
+  gcry_md_spec_t *spec;
 
-  if (! string)
+  if (!string)
     return 0;
 
-  REGISTER_DEFAULT_DIGESTS;
-
   /* If the string starts with a digit (optionally prefixed with
      either "OID." or "oid."), we first look into our table of ASN.1
      object identifiers to figure out the algorithm */
+  spec = search_oid (string, NULL);
+  if (spec)
+    return spec->algo;
 
-  ath_mutex_lock (&digests_registered_lock);
-
-  ret = search_oid (string, &algorithm, NULL);
-  if (! ret)
-    {
-      /* Not found, search a matching digest name.  */
-      digest = gcry_md_lookup_name (string);
-      if (digest)
-       {
-         algorithm = digest->mod_id;
-         _gcry_module_release (digest);
-       }
-    }
-  ath_mutex_unlock (&digests_registered_lock);
+  /* Not found, search a matching digest name.  */
+  spec = spec_from_name (string);
+  if (spec)
+    return spec->algo;
 
-  return algorithm;
+  return 0;
 }
 
 
 /****************
- * Map a digest algo to a string
- */
-static const char *
-digest_algo_to_string (int algorithm)
-{
-  const char *name = NULL;
-  gcry_module_t digest;
-
-  REGISTER_DEFAULT_DIGESTS;
-
-  ath_mutex_lock (&digests_registered_lock);
-  digest = _gcry_module_lookup_id (digests_registered, algorithm);
-  if (digest)
-    {
-      name = ((gcry_md_spec_t *) digest->spec)->name;
-      _gcry_module_release (digest);
-    }
-  ath_mutex_unlock (&digests_registered_lock);
-
-  return name;
-}
-
-/****************
  * This function simply returns the name of the algorithm or some constant
  * string when there is no algo.  It will never return NULL.
  * Use the macro gcry_md_test_algo() to check whether the algorithm
  * is valid.
  */
 const char *
-gcry_md_algo_name (int algorithm)
+_gcry_md_algo_name (int algorithm)
 {
-  const char *s = digest_algo_to_string (algorithm);
-  return s ? s : "?";
+  gcry_md_spec_t *spec;
+
+  spec = spec_from_algo (algorithm);
+  return spec ? spec->name : "?";
 }
 
 
 static gcry_err_code_t
 check_digest_algo (int algorithm)
 {
-  gcry_err_code_t rc = 0;
-  gcry_module_t digest;
+  gcry_md_spec_t *spec;
 
-  REGISTER_DEFAULT_DIGESTS;
+  spec = spec_from_algo (algorithm);
+  if (spec && !spec->flags.disabled)
+    return 0;
 
-  ath_mutex_lock (&digests_registered_lock);
-  digest = _gcry_module_lookup_id (digests_registered, algorithm);
-  if (digest)
-    _gcry_module_release (digest);
-  else
-    rc = GPG_ERR_DIGEST_ALGO;
-  ath_mutex_unlock (&digests_registered_lock);
+  return GPG_ERR_DIGEST_ALGO;
 
-  return rc;
 }
 
 
-
 /****************
  * Open a message digest handle for use with algorithm ALGO.
  * More algorithms may be added by md_enable(). The initial algorithm
  * may be 0.
  */
 static gcry_err_code_t
-md_open (gcry_md_hd_t *h, int algo, int secure, int hmac)
+md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_err_code_t err = 0;
+  int secure = !!(flags & GCRY_MD_FLAG_SECURE);
+  int hmac =   !!(flags & GCRY_MD_FLAG_HMAC);
   int bufsize = secure ? 512 : 1024;
   struct gcry_md_context *ctx;
   gcry_md_hd_t hd;
@@ -456,9 +303,9 @@ md_open (gcry_md_hd_t *h, int algo, int secure, int hmac)
 
   /* Allocate and set the Context pointer to the private data */
   if (secure)
-    hd = gcry_malloc_secure (n + sizeof (struct gcry_md_context));
+    hd = xtrymalloc_secure (n + sizeof (struct gcry_md_context));
   else
-    hd = gcry_malloc (n + sizeof (struct gcry_md_context));
+    hd = xtrymalloc (n + sizeof (struct gcry_md_context));
 
   if (! hd)
     err = gpg_err_code_from_errno (errno);
@@ -474,7 +321,8 @@ md_open (gcry_md_hd_t *h, int algo, int secure, int hmac)
       memset (hd->ctx, 0, sizeof *hd->ctx);
       ctx->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL;
       ctx->actual_handle_size = n + sizeof (struct gcry_md_context);
-      ctx->secure = secure;
+      ctx->flags.secure = secure;
+      ctx->flags.bugemu1 = !!(flags & GCRY_MD_FLAG_BUGEMU1);
 
       if (hmac)
        {
@@ -484,11 +332,14 @@ md_open (gcry_md_hd_t *h, int algo, int secure, int hmac)
               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 = gcry_malloc_secure (2*(ctx->macpads_Bsize));
+          ctx->macpads = xtrymalloc_secure (2*(ctx->macpads_Bsize));
          if (!ctx->macpads)
            {
              err = gpg_err_code_from_errno (errno);
@@ -521,22 +372,21 @@ md_open (gcry_md_hd_t *h, int algo, int secure, int hmac)
    given as 0 if the algorithms to be used are later set using
    gcry_md_enable. H is guaranteed to be a valid handle or NULL on
    error.  */
-gcry_error_t
-gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
+gcry_err_code_t
+_gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_err_code_t rc;
   gcry_md_hd_t hd;
 
-  if ((flags & ~(GCRY_MD_FLAG_SECURE | GCRY_MD_FLAG_HMAC)))
-    err = GPG_ERR_INV_ARG;
+  if ((flags & ~(GCRY_MD_FLAG_SECURE
+                 | GCRY_MD_FLAG_HMAC
+                 | GCRY_MD_FLAG_BUGEMU1)))
+    rc = GPG_ERR_INV_ARG;
   else
-    {
-      err = md_open (&hd, algo, (flags & GCRY_MD_FLAG_SECURE),
-                    (flags & GCRY_MD_FLAG_HMAC));
-    }
+    rc = md_open (&hd, algo, flags);
 
-  *h = err? NULL : hd;
-  return gcry_error (err);
+  *h = rc? NULL : hd;
+  return rc;
 }
 
 
@@ -545,27 +395,20 @@ static gcry_err_code_t
 md_enable (gcry_md_hd_t hd, int algorithm)
 {
   struct gcry_md_context *h = hd->ctx;
-  gcry_md_spec_t *digest = NULL;
+  gcry_md_spec_t *spec;
   GcryDigestEntry *entry;
-  gcry_module_t module;
   gcry_err_code_t err = 0;
 
   for (entry = h->list; entry; entry = entry->next)
-    if (entry->module->mod_id == algorithm)
-      return err; /* already enabled */
-
-  REGISTER_DEFAULT_DIGESTS;
+    if (entry->spec->algo == algorithm)
+      return 0; /* Already enabled */
 
-  ath_mutex_lock (&digests_registered_lock);
-  module = _gcry_module_lookup_id (digests_registered, algorithm);
-  ath_mutex_unlock (&digests_registered_lock);
-  if (! module)
+  spec = spec_from_algo (algorithm);
+  if (!spec)
     {
       log_debug ("md_enable: algorithm %d not available\n", algorithm);
       err = GPG_ERR_DIGEST_ALGO;
     }
- else
-    digest = (gcry_md_spec_t *) module->spec;
 
 
   if (!err && algorithm == GCRY_MD_MD5 && fips_mode ())
@@ -582,37 +425,27 @@ md_enable (gcry_md_hd_t hd, int algorithm)
   if (!err)
     {
       size_t size = (sizeof (*entry)
-                     + digest->contextsize
+                     + spec->contextsize
                      - sizeof (entry->context));
 
       /* And allocate a new list entry. */
-      if (h->secure)
-       entry = gcry_malloc_secure (size);
+      if (h->flags.secure)
+       entry = xtrymalloc_secure (size);
       else
-       entry = gcry_malloc (size);
+       entry = xtrymalloc (size);
 
       if (! entry)
        err = gpg_err_code_from_errno (errno);
       else
        {
-         entry->digest = digest;
-         entry->module = module;
+         entry->spec = spec;
          entry->next = h->list;
           entry->actual_struct_size = size;
          h->list = entry;
 
          /* And init this instance. */
-         entry->digest->init (&entry->context.c);
-       }
-    }
-
-  if (err)
-    {
-      if (module)
-       {
-          ath_mutex_lock (&digests_registered_lock);
-          _gcry_module_release (module);
-          ath_mutex_unlock (&digests_registered_lock);
+         entry->spec->init (&entry->context.c,
+                             h->flags.bugemu1? GCRY_MD_FLAG_BUGEMU1:0);
        }
     }
 
@@ -620,16 +453,17 @@ md_enable (gcry_md_hd_t hd, int algorithm)
 }
 
 
-gcry_error_t
-gcry_md_enable (gcry_md_hd_t hd, int algorithm)
+gcry_err_code_t
+_gcry_md_enable (gcry_md_hd_t hd, int algorithm)
 {
-  return gcry_error (md_enable (hd, algorithm));
+  return md_enable (hd, algorithm);
 }
 
+
 static gcry_err_code_t
 md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_err_code_t err = 0;
   struct gcry_md_context *a = ahd->ctx;
   struct gcry_md_context *b;
   GcryDigestEntry *ar, *br;
@@ -640,10 +474,10 @@ md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
     md_write (ahd, NULL, 0);
 
   n = (char *) ahd->ctx - (char *) ahd;
-  if (a->secure)
-    bhd = gcry_malloc_secure (n + sizeof (struct gcry_md_context));
+  if (a->flags.secure)
+    bhd = xtrymalloc_secure (n + sizeof (struct gcry_md_context));
   else
-    bhd = gcry_malloc (n + sizeof (struct gcry_md_context));
+    bhd = xtrymalloc (n + sizeof (struct gcry_md_context));
 
   if (! bhd)
     err = gpg_err_code_from_errno (errno);
@@ -661,7 +495,7 @@ md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
       b->debug = NULL;
       if (a->macpads)
        {
-         b->macpads = gcry_malloc_secure (2*(a->macpads_Bsize));
+         b->macpads = xtrymalloc_secure (2*(a->macpads_Bsize));
          if (! b->macpads)
            {
              err = gpg_err_code_from_errno (errno);
@@ -678,14 +512,14 @@ md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
     {
       for (ar = a->list; ar; ar = ar->next)
         {
-          if (a->secure)
-            br = gcry_malloc_secure (sizeof *br
-                                     + ar->digest->contextsize
-                                     - sizeof(ar->context));
+          if (a->flags.secure)
+            br = xtrymalloc_secure (sizeof *br
+                                    + ar->spec->contextsize
+                                    - sizeof(ar->context));
           else
-            br = gcry_malloc (sizeof *br
-                              + ar->digest->contextsize
-                              - sizeof (ar->context));
+            br = xtrymalloc (sizeof *br
+                             + ar->spec->contextsize
+                             - sizeof (ar->context));
           if (!br)
             {
              err = gpg_err_code_from_errno (errno);
@@ -693,15 +527,10 @@ md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
               break;
             }
 
-          memcpy (br, ar, (sizeof (*br) + ar->digest->contextsize
+          memcpy (br, ar, (sizeof (*br) + ar->spec->contextsize
                            - sizeof (ar->context)));
           br->next = b->list;
           b->list = br;
-
-          /* Add a reference to the module.  */
-          ath_mutex_lock (&digests_registered_lock);
-          _gcry_module_use (br->module);
-          ath_mutex_unlock (&digests_registered_lock);
         }
     }
 
@@ -714,39 +543,43 @@ md_copy (gcry_md_hd_t ahd, gcry_md_hd_t *b_hd)
   return err;
 }
 
-gcry_error_t
-gcry_md_copy (gcry_md_hd_t *handle, gcry_md_hd_t hd)
+
+gcry_err_code_t
+_gcry_md_copy (gcry_md_hd_t *handle, gcry_md_hd_t hd)
 {
-  gcry_err_code_t err;
+  gcry_err_code_t rc;
 
-  err = md_copy (hd, handle);
-  if (err)
+  rc = md_copy (hd, handle);
+  if (rc)
     *handle = NULL;
-  return gcry_error (err);
+  return rc;
 }
 
+
 /*
  * Reset all contexts and discard any buffered stuff.  This may be used
  * instead of a md_close(); md_open().
  */
 void
-gcry_md_reset (gcry_md_hd_t a)
+_gcry_md_reset (gcry_md_hd_t a)
 {
   GcryDigestEntry *r;
 
   /* Note: We allow this even in fips non operational mode.  */
 
-  a->bufpos = a->ctx->finalized = 0;
+  a->bufpos = a->ctx->flags.finalized = 0;
 
   for (r = a->ctx->list; r; r = r->next)
     {
-      memset (r->context.c, 0, r->digest->contextsize);
-      (*r->digest->init) (&r->context.c);
+      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 */
 }
 
+
 static void
 md_close (gcry_md_hd_t a)
 {
@@ -759,30 +592,29 @@ md_close (gcry_md_hd_t a)
   for (r = a->ctx->list; r; r = r2)
     {
       r2 = r->next;
-      ath_mutex_lock (&digests_registered_lock);
-      _gcry_module_release (r->module);
-      ath_mutex_unlock (&digests_registered_lock);
       wipememory (r, r->actual_struct_size);
-      gcry_free (r);
+      xfree (r);
     }
 
   if (a->ctx->macpads)
     {
       wipememory (a->ctx->macpads, 2*(a->ctx->macpads_Bsize));
-      gcry_free(a->ctx->macpads);
+      xfree(a->ctx->macpads);
     }
 
   wipememory (a, a->ctx->actual_handle_size);
-  gcry_free(a);
+  xfree(a);
 }
 
+
 void
-gcry_md_close (gcry_md_hd_t hd)
+_gcry_md_close (gcry_md_hd_t hd)
 {
   /* Note: We allow this even in fips non operational mode.  */
   md_close (hd);
 }
 
+
 static void
 md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen)
 {
@@ -799,33 +631,35 @@ md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen)
   for (r = a->ctx->list; r; r = r->next)
     {
       if (a->bufpos)
-       (*r->digest->write) (&r->context.c, a->buf, a->bufpos);
-      (*r->digest->write) (&r->context.c, inbuf, inlen);
+       (*r->spec->write) (&r->context.c, a->buf, a->bufpos);
+      (*r->spec->write) (&r->context.c, inbuf, inlen);
     }
   a->bufpos = 0;
 }
 
+
 void
-gcry_md_write (gcry_md_hd_t hd, const void *inbuf, size_t inlen)
+_gcry_md_write (gcry_md_hd_t hd, const void *inbuf, size_t inlen)
 {
   md_write (hd, inbuf, inlen);
 }
 
+
 static void
 md_final (gcry_md_hd_t a)
 {
   GcryDigestEntry *r;
 
-  if (a->ctx->finalized)
+  if (a->ctx->flags.finalized)
     return;
 
   if (a->bufpos)
     md_write (a, NULL, 0);
 
   for (r = a->ctx->list; r; r = r->next)
-    (*r->digest->final) (&r->context.c);
+    (*r->spec->final) (&r->context.c);
 
-  a->ctx->finalized = 1;
+  a->ctx->flags.finalized = 1;
 
   if (a->ctx->macpads)
     {
@@ -834,8 +668,11 @@ md_final (gcry_md_hd_t a)
       byte *p = md_read (a, algo);
       size_t dlen = md_digest_length (algo);
       gcry_md_hd_t om;
-      gcry_err_code_t err = md_open (&om, algo, a->ctx->secure, 0);
+      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,
@@ -849,6 +686,7 @@ md_final (gcry_md_hd_t a)
     }
 }
 
+
 static gcry_err_code_t
 prepare_macpads (gcry_md_hd_t hd, const unsigned char *key, size_t keylen)
 {
@@ -862,10 +700,10 @@ prepare_macpads (gcry_md_hd_t hd, const unsigned char *key, size_t keylen)
 
   if ( keylen > hd->ctx->macpads_Bsize )
     {
-      helpkey = gcry_malloc_secure (md_digest_length (algo));
+      helpkey = xtrymalloc_secure (md_digest_length (algo));
       if (!helpkey)
         return gpg_err_code_from_errno (errno);
-      gcry_md_hash_buffer (algo, helpkey, key, keylen);
+      _gcry_md_hash_buffer (algo, helpkey, key, keylen);
       key = helpkey;
       keylen = md_digest_length (algo);
       gcry_assert ( keylen <= hd->ctx->macpads_Bsize );
@@ -881,24 +719,24 @@ prepare_macpads (gcry_md_hd_t hd, const unsigned char *key, size_t keylen)
       ipad[i] ^= 0x36;
       opad[i] ^= 0x5c;
     }
-  gcry_free (helpkey);
+  xfree (helpkey);
 
-  return GPG_ERR_NO_ERROR;
+  return 0;
 }
 
-gcry_error_t
-gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
+
+gcry_err_code_t
+_gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
 {
   gcry_err_code_t rc = 0;
 
+  (void)buflen; /* Currently not used.  */
+
   switch (cmd)
     {
     case GCRYCTL_FINALIZE:
       md_final (hd);
       break;
-    case GCRYCTL_SET_KEY:
-      rc = gcry_err_code (gcry_md_setkey (hd, buffer, buflen));
-      break;
     case GCRYCTL_START_DUMP:
       md_start_debug (hd, buffer);
       break;
@@ -908,31 +746,33 @@ gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
     default:
       rc = GPG_ERR_INV_OP;
     }
-  return gcry_error (rc);
+  return rc;
 }
 
-gcry_error_t
-gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen)
+
+gcry_err_code_t
+_gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen)
 {
-  gcry_err_code_t rc = GPG_ERR_NO_ERROR;
+  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);
+      if (!rc)
+       _gcry_md_reset (hd);
     }
 
-  return gcry_error (rc);
+  return rc;
 }
 
+
 /* The new debug interface.  If SUFFIX is a string it creates an debug
    file for the context HD.  IF suffix is NULL, the file is closed and
    debugging is stopped.  */
 void
-gcry_md_debug (gcry_md_hd_t hd, const char *suffix)
+_gcry_md_debug (gcry_md_hd_t hd, const char *suffix)
 {
   if (suffix)
     md_start_debug (hd, suffix);
@@ -941,9 +781,9 @@ gcry_md_debug (gcry_md_hd_t hd, const char *suffix)
 }
 
 
-
 /****************
- * if ALGO is null get the digest for the used algo (which should be only one)
+ * If ALGO is null get the digest for the used algo (which should be
+ * only one)
  */
 static byte *
 md_read( gcry_md_hd_t a, int algo )
@@ -957,30 +797,31 @@ md_read( gcry_md_hd_t a, int algo )
         {
           if (r->next)
             log_debug ("more than one algorithm in md_read(0)\n");
-          return r->digest->read (&r->context.c);
+          return r->spec->read (&r->context.c);
         }
     }
   else
     {
       for (r = a->ctx->list; r; r = r->next)
-       if (r->module->mod_id == algo)
-         return r->digest->read (&r->context.c);
+       if (r->spec->algo == algo)
+         return r->spec->read (&r->context.c);
     }
   BUG();
   return NULL;
 }
 
+
 /*
  * Read out the complete digest, this function implictly finalizes
  * the hash.
  */
 byte *
-gcry_md_read (gcry_md_hd_t hd, int algo)
+_gcry_md_read (gcry_md_hd_t hd, int algo)
 {
   /* This function is expected to always return a digest, thus we
      can't return an error which we actually should do in
      non-operational state.  */
-  gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
+  _gcry_md_ctl (hd, GCRYCTL_FINALIZE, NULL, 0);
   return md_read (hd, algo);
 }
 
@@ -989,7 +830,7 @@ gcry_md_read (gcry_md_hd_t hd, int algo)
  * Read out an intermediate digest.  Not yet functional.
  */
 gcry_err_code_t
-gcry_md_get (gcry_md_hd_t hd, int algo, byte *buffer, int buflen)
+_gcry_md_get (gcry_md_hd_t hd, int algo, byte *buffer, int buflen)
 {
   (void)hd;
   (void)algo;
@@ -1009,8 +850,8 @@ gcry_md_get (gcry_md_hd_t hd, int algo, byte *buffer, int buflen)
  * hash.  No error is returned, the function will abort on an invalid
  * algo.  DISABLED_ALGOS are ignored here.  */
 void
-gcry_md_hash_buffer (int algo, void *digest,
-                     const void *buffer, size_t length)
+_gcry_md_hash_buffer (int algo, void *digest,
+                      const void *buffer, size_t length)
 {
   if (algo == GCRY_MD_SHA1)
     _gcry_sha1_hash_buffer (digest, buffer, length);
@@ -1034,7 +875,7 @@ gcry_md_hash_buffer (int algo, void *digest,
             }
         }
 
-      err = md_open (&h, algo, 0, 0);
+      err = md_open (&h, algo, 0);
       if (err)
        log_bug ("gcry_md_open failed for algo %d: %s",
                  algo, gpg_strerror (gcry_error(err)));
@@ -1045,6 +886,83 @@ gcry_md_hash_buffer (int algo, void *digest,
     }
 }
 
+
+/* Shortcut function to hash multiple buffers with a given algo.  In
+   contrast to gcry_md_hash_buffer, this function returns an error on
+   invalid arguments or on other problems; disabled algorithms are
+   _not_ ignored but flagged as an error.
+
+   The data to sign is taken from the array IOV which has IOVCNT items.
+
+   The only supported flag in 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 0 is returned and resulting hash or HMAC is stored at
+   DIGEST which must have been provided by the caller with an
+   appropriate length.  */
+gpg_err_code_t
+_gcry_md_hash_buffers (int algo, unsigned int flags, void *digest,
+                       const gcry_buffer_t *iov, int iovcnt)
+{
+  int hmac;
+
+  if (!iov || iovcnt < 0)
+    return GPG_ERR_INV_ARG;
+  if (flags & ~(GCRY_MD_FLAG_HMAC))
+    return GPG_ERR_INV_ARG;
+
+  hmac = !!(flags & GCRY_MD_FLAG_HMAC);
+  if (hmac && iovcnt < 1)
+    return GPG_ERR_INV_ARG;
+
+  if (algo == GCRY_MD_SHA1 && !hmac)
+    _gcry_sha1_hash_buffers (digest, iov, iovcnt);
+  else
+    {
+      /* For the others we do not have a fast function, so we use the
+        normal functions. */
+      gcry_md_hd_t h;
+      gpg_err_code_t rc;
+
+      if (algo == GCRY_MD_MD5 && fips_mode ())
+        {
+          _gcry_inactivate_fips_mode ("MD5 used");
+          if (_gcry_enforced_fips_mode () )
+            {
+              /* We should never get to here because we do not register
+                 MD5 in enforced fips mode.  */
+              _gcry_fips_noreturn ();
+            }
+        }
+
+      rc = md_open (&h, algo, (hmac? GCRY_MD_FLAG_HMAC:0));
+      if (rc)
+        return rc;
+
+      if (hmac)
+        {
+          rc = _gcry_md_setkey (h,
+                                (const char*)iov[0].data + iov[0].off,
+                                iov[0].len);
+          if (rc)
+            {
+              md_close (h);
+              return rc;
+            }
+          iov++; iovcnt--;
+        }
+      for (;iovcnt; iov++, iovcnt--)
+        md_write (h, (const char*)iov[0].data + iov[0].off, iov[0].len);
+      md_final (h);
+      memcpy (digest, md_read (h, algo), md_digest_length (algo));
+      md_close (h);
+    }
+
+  return 0;
+}
+
+
 static int
 md_get_algo (gcry_md_hd_t a)
 {
@@ -1055,11 +973,12 @@ md_get_algo (gcry_md_hd_t a)
       fips_signal_error ("possible usage error");
       log_error ("WARNING: more than one algorithm in md_get_algo()\n");
     }
-  return r ? r->module->mod_id : 0;
+  return r ? r->spec->algo : 0;
 }
 
+
 int
-gcry_md_get_algo (gcry_md_hd_t hd)
+_gcry_md_get_algo (gcry_md_hd_t hd)
 {
   return md_get_algo (hd);
 }
@@ -1071,29 +990,19 @@ gcry_md_get_algo (gcry_md_hd_t hd)
 static int
 md_digest_length (int algorithm)
 {
-  gcry_module_t digest;
-  int mdlen = 0;
-
-  REGISTER_DEFAULT_DIGESTS;
-
-  ath_mutex_lock (&digests_registered_lock);
-  digest = _gcry_module_lookup_id (digests_registered, algorithm);
-  if (digest)
-    {
-      mdlen = ((gcry_md_spec_t *) digest->spec)->mdlen;
-      _gcry_module_release (digest);
-    }
-  ath_mutex_unlock (&digests_registered_lock);
+  gcry_md_spec_t *spec;
 
-  return mdlen;
+  spec = spec_from_algo (algorithm);
+  return spec? spec->mdlen : 0;
 }
 
+
 /****************
  * Return the length of the digest in bytes.
  * This function will return 0 in case of errors.
  */
 unsigned int
-gcry_md_get_algo_dlen (int algorithm)
+_gcry_md_get_algo_dlen (int algorithm)
 {
   return md_digest_length (algorithm);
 }
@@ -1104,31 +1013,25 @@ gcry_md_get_algo_dlen (int algorithm)
 static const byte *
 md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen)
 {
+  gcry_md_spec_t *spec;
   const byte *asnoid = NULL;
-  gcry_module_t digest;
 
-  REGISTER_DEFAULT_DIGESTS;
-
-  ath_mutex_lock (&digests_registered_lock);
-  digest = _gcry_module_lookup_id (digests_registered, algorithm);
-  if (digest)
+  spec = spec_from_algo (algorithm);
+  if (spec)
     {
       if (asnlen)
-       *asnlen = ((gcry_md_spec_t *) digest->spec)->asnlen;
+       *asnlen = spec->asnlen;
       if (mdlen)
-       *mdlen = ((gcry_md_spec_t *) digest->spec)->mdlen;
-      asnoid = ((gcry_md_spec_t *) digest->spec)->asnoid;
-      _gcry_module_release (digest);
+       *mdlen = spec->mdlen;
+      asnoid = spec->asnoid;
     }
   else
     log_bug ("no ASN.1 OID for md algo %d\n", algorithm);
-  ath_mutex_unlock (&digests_registered_lock);
 
   return asnoid;
 }
 
 
-
 /****************
  * Return information about the given cipher algorithm
  * WHAT select the kind of information returned:
@@ -1138,6 +1041,8 @@ md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen)
  *  GCRYCTL_GET_ASNOID:
  *     Return the ASNOID of the algorithm in buffer. if buffer is NULL, only
  *     the required length is returned.
+ *  GCRYCTL_SELFTEST
+ *      Helper for the regression tests - shall not be used by applications.
  *
  * Note:  Because this function is in most cases used to return an
  * integer value, we can make it easier for the caller to just look at
@@ -1145,52 +1050,59 @@ md_asn_oid (int algorithm, size_t *asnlen, size_t *mdlen)
  * and thereby detecting whether a error occurred or not (i.e. while checking
  * the block size)
  */
-gcry_error_t
-gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes)
+gcry_err_code_t
+_gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_err_code_t rc;
 
   switch (what)
     {
     case GCRYCTL_TEST_ALGO:
       if (buffer || nbytes)
-       err = GPG_ERR_INV_ARG;
+       rc = GPG_ERR_INV_ARG;
       else
-       err = check_digest_algo (algo);
+       rc = check_digest_algo (algo);
       break;
 
     case GCRYCTL_GET_ASNOID:
       /* We need to check that the algo is available because
          md_asn_oid would otherwise raise an assertion. */
-      err = check_digest_algo (algo);
-      if (!err)
+      rc = check_digest_algo (algo);
+      if (!rc)
         {
           const char unsigned *asn;
           size_t asnlen;
 
           asn = md_asn_oid (algo, &asnlen, NULL);
           if (buffer && (*nbytes >= asnlen))
-         {
-           memcpy (buffer, asn, asnlen);
-           *nbytes = asnlen;
-         }
+            {
+              memcpy (buffer, asn, asnlen);
+              *nbytes = asnlen;
+            }
           else if (!buffer && nbytes)
             *nbytes = asnlen;
           else
             {
               if (buffer)
-                err = GPG_ERR_TOO_SHORT;
+                rc = GPG_ERR_TOO_SHORT;
               else
-                err = GPG_ERR_INV_ARG;
+                rc = GPG_ERR_INV_ARG;
             }
         }
       break;
 
-  default:
-    err = GPG_ERR_INV_OP;
+    case GCRYCTL_SELFTEST:
+      /* Helper function for the regression tests.  */
+      rc = gpg_err_code (_gcry_md_selftest (algo, nbytes? (int)*nbytes : 0,
+                                             NULL));
+      break;
+
+    default:
+      rc = GPG_ERR_INV_OP;
+      break;
   }
 
-  return gcry_error (err);
+  return rc;
 }
 
 
@@ -1215,6 +1127,7 @@ md_start_debug ( gcry_md_hd_t md, const char *suffix )
     log_debug("md debug: can't open %s\n", buf );
 }
 
+
 static void
 md_stop_debug( gcry_md_hd_t md )
 {
@@ -1248,15 +1161,15 @@ md_stop_debug( gcry_md_hd_t md )
  *     Returns 1 if the algo is enabled for that handle.
  *     The algo must be passed as the address of an int.
  */
-gcry_error_t
-gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
+gcry_err_code_t
+_gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_err_code_t rc = 0;
 
   switch (cmd)
     {
     case GCRYCTL_IS_SECURE:
-      *nbytes = h->ctx->secure;
+      *nbytes = h->ctx->flags.secure;
       break;
 
     case GCRYCTL_IS_ALGO_ENABLED:
@@ -1265,14 +1178,14 @@ gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
        int algo;
 
        if ( !buffer || (nbytes && (*nbytes != sizeof (int))))
-         err = GPG_ERR_INV_ARG;
+         rc = GPG_ERR_INV_ARG;
        else
          {
            algo = *(int*)buffer;
 
            *nbytes = 0;
            for(r=h->ctx->list; r; r = r->next ) {
-             if (r->module->mod_id == algo)
+             if (r->spec->algo == algo)
                {
                  *nbytes = 1;
                  break;
@@ -1283,10 +1196,10 @@ gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
       }
 
   default:
-    err = GPG_ERR_INV_OP;
+    rc = GPG_ERR_INV_OP;
   }
 
-  return gcry_error (err);
+  return rc;
 }
 
 
@@ -1294,20 +1207,16 @@ gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes)
 gcry_err_code_t
 _gcry_md_init (void)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
-  REGISTER_DEFAULT_DIGESTS;
-
-  return err;
+  return 0;
 }
 
 
 int
-gcry_md_is_secure (gcry_md_hd_t a)
+_gcry_md_is_secure (gcry_md_hd_t a)
 {
   size_t value;
 
-  if (gcry_md_info (a, GCRYCTL_IS_SECURE, NULL, &value))
+  if (_gcry_md_info (a, GCRYCTL_IS_SECURE, NULL, &value))
     value = 1; /* It seems to be better to assume secure memory on
                   error. */
   return value;
@@ -1315,69 +1224,37 @@ gcry_md_is_secure (gcry_md_hd_t a)
 
 
 int
-gcry_md_is_enabled (gcry_md_hd_t a, int algo)
+_gcry_md_is_enabled (gcry_md_hd_t a, int algo)
 {
   size_t value;
 
   value = sizeof algo;
-  if (gcry_md_info (a, GCRYCTL_IS_ALGO_ENABLED, &algo, &value))
+  if (_gcry_md_info (a, GCRYCTL_IS_ALGO_ENABLED, &algo, &value))
     value = 0;
   return value;
 }
 
-/* Get a list consisting of the IDs of the loaded message digest
-   modules.  If LIST is zero, write the number of loaded message
-   digest modules to LIST_LENGTH and return.  If LIST is non-zero, the
-   first *LIST_LENGTH algorithm IDs are stored in LIST, which must be
-   of according size.  In case there are less message digest modules
-   than *LIST_LENGTH, *LIST_LENGTH is updated to the correct
-   number.  */
-gcry_error_t
-gcry_md_list (int *list, int *list_length)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
-  ath_mutex_lock (&digests_registered_lock);
-  err = _gcry_module_list (digests_registered, list, list_length);
-  ath_mutex_unlock (&digests_registered_lock);
-
-  return err;
-}
-
 
 /* Run the selftests for digest algorithm ALGO with optional reporting
    function REPORT.  */
 gpg_error_t
 _gcry_md_selftest (int algo, int extended, selftest_report_func_t report)
 {
-  gcry_module_t module = NULL;
-  cipher_extra_spec_t *extraspec = NULL;
   gcry_err_code_t ec = 0;
+  gcry_md_spec_t *spec;
 
-  REGISTER_DEFAULT_DIGESTS;
-
-  ath_mutex_lock (&digests_registered_lock);
-  module = _gcry_module_lookup_id (digests_registered, algo);
-  if (module && !(module->flags & FLAG_MODULE_DISABLED))
-    extraspec = module->extraspec;
-  ath_mutex_unlock (&digests_registered_lock);
-  if (extraspec && extraspec->selftest)
-    ec = extraspec->selftest (algo, extended, report);
+  spec = spec_from_algo (algo);
+  if (spec && !spec->flags.disabled && spec->selftest)
+    ec = spec->selftest (algo, extended, report);
   else
     {
-      ec = GPG_ERR_DIGEST_ALGO;
+      ec = spec->selftest? GPG_ERR_DIGEST_ALGO : GPG_ERR_NOT_IMPLEMENTED;
       if (report)
         report ("digest", algo, "module",
-                module && !(module->flags & FLAG_MODULE_DISABLED)?
+                (spec && !spec->flags.disabled)?
                 "no selftest available" :
-                module? "algorithm disabled" : "algorithm not found");
+                spec? "algorithm disabled" : "algorithm not found");
     }
 
-  if (module)
-    {
-      ath_mutex_lock (&digests_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&digests_registered_lock);
-    }
   return gpg_error (ec);
 }
index 8909ec4..624ae99 100644 (file)
 #include "cipher.h"
 
 #include "bithelp.h"
+#include "bufhelp.h"
+#include "hash-common.h"
 
 
 typedef struct {
+    gcry_md_block_ctx_t bctx;
     u32 A,B,C,D;         /* chaining variables */
-    u32  nblocks;
-    byte buf[64];
-    int  count;
 } MD4_CONTEXT;
 
+static unsigned int
+transform ( void *c, const unsigned char *data );
 
 static void
-md4_init( void *context )
+md4_init (void *context, unsigned int flags)
 {
   MD4_CONTEXT *ctx = context;
 
+  (void)flags;
+
   ctx->A = 0x67452301;
   ctx->B = 0xefcdab89;
   ctx->C = 0x98badcfe;
   ctx->D = 0x10325476;
 
-  ctx->nblocks = 0;
-  ctx->count = 0;
+  ctx->bctx.nblocks = 0;
+  ctx->bctx.nblocks_high = 0;
+  ctx->bctx.count = 0;
+  ctx->bctx.blocksize = 64;
+  ctx->bctx.bwrite = transform;
 }
 
 #define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
@@ -88,30 +95,19 @@ md4_init( void *context )
 /****************
  * transform 64 bytes
  */
-static void
-transform ( MD4_CONTEXT *ctx, const unsigned char *data )
+static unsigned int
+transform ( void *c, const unsigned char *data )
 {
+  MD4_CONTEXT *ctx = c;
   u32 in[16];
   register u32 A = ctx->A;
   register u32 B = ctx->B;
   register u32 C = ctx->C;
   register u32 D = ctx->D;
+  int i;
 
-#ifdef WORDS_BIGENDIAN
-  {
-    int i;
-    byte *p2, *p1;
-    for(i=0, p1=data, p2=(byte*)in; i < 16; i++, p2 += 4 )
-      {
-       p2[3] = *p1++;
-       p2[2] = *p1++;
-       p2[1] = *p1++;
-       p2[0] = *p1++;
-      }
-  }
-#else
-  memcpy (in, data, 64);
-#endif
+  for ( i = 0; i < 16; i++ )
+    in[i] = buf_get_le32(data + i * 4);
 
   /* Round 1.  */
 #define function(a,b,c,d,k,s) a=rol(a+F(b,c,d)+in[k],s);
@@ -182,50 +178,8 @@ transform ( MD4_CONTEXT *ctx, const unsigned char *data )
   ctx->B += B;
   ctx->C += C;
   ctx->D += D;
-}
-
-
-
-/* The routine updates the message-digest context to
- * account for the presence of each of the characters inBuf[0..inLen-1]
- * in the message whose digest is being computed.
- */
-static void
-md4_write ( void *context, const void *inbuf_arg, size_t inlen)
-{
-  const unsigned char *inbuf = inbuf_arg;
-  MD4_CONTEXT *hd = context;
 
-  if( hd->count == 64 ) /* flush the buffer */
-    {
-      transform( hd, hd->buf );
-      _gcry_burn_stack (80+6*sizeof(void*));
-      hd->count = 0;
-      hd->nblocks++;
-    }
-  if( !inbuf )
-    return;
-
-  if( hd->count )
-    {
-      for( ; inlen && hd->count < 64; inlen-- )
-        hd->buf[hd->count++] = *inbuf++;
-      md4_write( hd, NULL, 0 );
-      if( !inlen )
-        return;
-    }
-  _gcry_burn_stack (80+6*sizeof(void*));
-
-  while( inlen >= 64 )
-    {
-      transform( hd, inbuf );
-      hd->count = 0;
-      hd->nblocks++;
-      inlen -= 64;
-      inbuf += 64;
-    }
-  for( ; inlen && hd->count < 64; inlen-- )
-    hd->buf[hd->count++] = *inbuf++;
+  return /*burn_stack*/ 80+6*sizeof(void*);
 }
 
 
@@ -240,18 +194,24 @@ static void
 md4_final( void *context )
 {
   MD4_CONTEXT *hd = context;
-  u32 t, msb, lsb;
+  u32 t, th, msb, lsb;
   byte *p;
+  unsigned int burn;
 
-  md4_write(hd, NULL, 0); /* flush */;
+  _gcry_md_block_write(hd, NULL, 0); /* flush */;
+
+  t = hd->bctx.nblocks;
+  if (sizeof t == sizeof hd->bctx.nblocks)
+    th = hd->bctx.nblocks_high;
+  else
+    th = hd->bctx.nblocks >> 32;
 
-  t = hd->nblocks;
   /* multiply by 64 to make a byte count */
   lsb = t << 6;
-  msb = t >> 26;
+  msb = (th << 6) | (t >> 26);
   /* add the count */
   t = lsb;
-  if( (lsb += hd->count) < t )
+  if( (lsb += hd->bctx.count) < t )
     msb++;
   /* multiply by 8 to make a bit count */
   t = lsb;
@@ -259,39 +219,28 @@ md4_final( void *context )
   msb <<= 3;
   msb |= t >> 29;
 
-  if( hd->count < 56 )  /* enough room */
+  if( hd->bctx.count < 56 )  /* enough room */
     {
-      hd->buf[hd->count++] = 0x80; /* pad */
-      while( hd->count < 56 )
-        hd->buf[hd->count++] = 0;  /* pad */
+      hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
+      while( hd->bctx.count < 56 )
+        hd->bctx.buf[hd->bctx.count++] = 0;  /* pad */
     }
   else /* need one extra block */
     {
-      hd->buf[hd->count++] = 0x80; /* pad character */
-      while( hd->count < 64 )
-        hd->buf[hd->count++] = 0;
-      md4_write(hd, NULL, 0);  /* flush */;
-      memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+      hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
+      while( hd->bctx.count < 64 )
+        hd->bctx.buf[hd->bctx.count++] = 0;
+      _gcry_md_block_write(hd, NULL, 0);  /* flush */;
+      memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
     }
   /* append the 64 bit count */
-  hd->buf[56] = lsb       ;
-  hd->buf[57] = lsb >>  8;
-  hd->buf[58] = lsb >> 16;
-  hd->buf[59] = lsb >> 24;
-  hd->buf[60] = msb       ;
-  hd->buf[61] = msb >>  8;
-  hd->buf[62] = msb >> 16;
-  hd->buf[63] = msb >> 24;
-  transform( hd, hd->buf );
-  _gcry_burn_stack (80+6*sizeof(void*));
-
-  p = hd->buf;
-#ifdef WORDS_BIGENDIAN
-#define X(a) do { *p++ = hd->a      ; *p++ = hd->a >> 8;      \
-                 *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0)
-#else /* little endian */
-#define X(a) do { *(u32*)p = (*hd).a ; p += 4; } while(0)
-#endif
+  buf_put_le32(hd->bctx.buf + 56, lsb);
+  buf_put_le32(hd->bctx.buf + 60, msb);
+  burn = transform( hd, hd->bctx.buf );
+  _gcry_burn_stack (burn);
+
+  p = hd->bctx.buf;
+#define X(a) do { *(u32*)p = le_bswap32((*hd).a) ; p += 4; } while(0)
   X(A);
   X(B);
   X(C);
@@ -304,7 +253,7 @@ static byte *
 md4_read (void *context)
 {
   MD4_CONTEXT *hd = context;
-  return hd->buf;
+  return hd->bctx.buf;
 }
 
 static byte asn[18] = /* Object ID is 1.2.840.113549.2.4 */
@@ -320,7 +269,8 @@ static gcry_md_oid_spec_t oid_spec_md4[] =
 
 gcry_md_spec_t _gcry_digest_spec_md4 =
   {
+    GCRY_MD_MD4, {0, 0},
     "MD4", asn, DIM (asn), oid_spec_md4,16,
-    md4_init, md4_write, md4_final, md4_read,
+    md4_init, _gcry_md_block_write, md4_final, md4_read,
     sizeof (MD4_CONTEXT)
   };
index 4793882..b0187c9 100644 (file)
 #include "cipher.h"
 
 #include "bithelp.h"
+#include "bufhelp.h"
+#include "hash-common.h"
 
 
 typedef struct {
+    gcry_md_block_ctx_t bctx;
     u32 A,B,C,D;         /* chaining variables */
-    u32  nblocks;
-    byte buf[64];
-    int  count;
 } MD5_CONTEXT;
 
+static unsigned int
+transform ( void *ctx, const unsigned char *data );
 
 static void
-md5_init( void *context )
+md5_init( void *context, unsigned int flags)
 {
   MD5_CONTEXT *ctx = context;
 
+  (void)flags;
+
   ctx->A = 0x67452301;
   ctx->B = 0xefcdab89;
   ctx->C = 0x98badcfe;
   ctx->D = 0x10325476;
 
-  ctx->nblocks = 0;
-  ctx->count = 0;
+  ctx->bctx.nblocks = 0;
+  ctx->bctx.nblocks_high = 0;
+  ctx->bctx.count = 0;
+  ctx->bctx.blocksize = 64;
+  ctx->bctx.bwrite = transform;
 }
 
 
@@ -78,32 +85,20 @@ md5_init( void *context )
 /****************
  * transform n*64 bytes
  */
-static void
-transform ( MD5_CONTEXT *ctx, const unsigned char *data )
+static unsigned int
+transform ( void *c, const unsigned char *data )
 {
+  MD5_CONTEXT *ctx = c;
   u32 correct_words[16];
   register u32 A = ctx->A;
   register u32 B = ctx->B;
   register u32 C = ctx->C;
   register u32 D = ctx->D;
   u32 *cwp = correct_words;
+  int i;
 
-#ifdef WORDS_BIGENDIAN
-  {
-    int i;
-    byte *p2, *p1;
-    for(i=0, p1=data, p2=(byte*)correct_words; i < 16; i++, p2 += 4 )
-      {
-        p2[3] = *p1++;
-       p2[2] = *p1++;
-       p2[1] = *p1++;
-       p2[0] = *p1++;
-      }
-  }
-#else
-  memcpy( correct_words, data, 64 );
-#endif
-
+  for ( i = 0; i < 16; i++ )
+    correct_words[i] = buf_get_le32(data + i * 4);
 
 #define OP(a, b, c, d, s, T) \
   do                                      \
@@ -207,51 +202,8 @@ transform ( MD5_CONTEXT *ctx, const unsigned char *data )
   ctx->B += B;
   ctx->C += C;
   ctx->D += D;
-}
-
-
-
-/* The routine updates the message-digest context to
- * account for the presence of each of the characters inBuf[0..inLen-1]
- * in the message whose digest is being computed.
- */
-static void
-md5_write( void *context, const void *inbuf_arg , size_t inlen)
-{
-  const unsigned char *inbuf = inbuf_arg;
-  MD5_CONTEXT *hd = context;
-
-  if( hd->count == 64 )  /* flush the buffer */
-    {
-      transform( hd, hd->buf );
-      _gcry_burn_stack (80+6*sizeof(void*));
-      hd->count = 0;
-      hd->nblocks++;
-    }
-  if( !inbuf )
-    return;
-
-  if( hd->count )
-    {
-      for( ; inlen && hd->count < 64; inlen-- )
-        hd->buf[hd->count++] = *inbuf++;
-      md5_write( hd, NULL, 0 );
-      if( !inlen )
-        return;
-    }
-  _gcry_burn_stack (80+6*sizeof(void*));
-
-  while( inlen >= 64 )
-    {
-      transform( hd, inbuf );
-      hd->count = 0;
-      hd->nblocks++;
-      inlen -= 64;
-      inbuf += 64;
-    }
-  for( ; inlen && hd->count < 64; inlen-- )
-    hd->buf[hd->count++] = *inbuf++;
 
+  return /*burn_stack*/ 80+6*sizeof(void*);
 }
 
 
@@ -266,18 +218,24 @@ static void
 md5_final( void *context)
 {
   MD5_CONTEXT *hd = context;
-  u32 t, msb, lsb;
+  u32 t, th, msb, lsb;
   byte *p;
+  unsigned int burn;
 
-  md5_write(hd, NULL, 0); /* flush */;
+  _gcry_md_block_write(hd, NULL, 0); /* flush */;
+
+  t = hd->bctx.nblocks;
+  if (sizeof t == sizeof hd->bctx.nblocks)
+    th = hd->bctx.nblocks_high;
+  else
+    th = hd->bctx.nblocks >> 32;
 
-  t = hd->nblocks;
   /* multiply by 64 to make a byte count */
   lsb = t << 6;
-  msb = t >> 26;
+  msb = (th << 6) | (t >> 26);
   /* add the count */
   t = lsb;
-  if( (lsb += hd->count) < t )
+  if( (lsb += hd->bctx.count) < t )
     msb++;
   /* multiply by 8 to make a bit count */
   t = lsb;
@@ -285,39 +243,28 @@ md5_final( void *context)
   msb <<= 3;
   msb |= t >> 29;
 
-  if( hd->count < 56 )  /* enough room */
+  if( hd->bctx.count < 56 )  /* enough room */
     {
-      hd->buf[hd->count++] = 0x80; /* pad */
-      while( hd->count < 56 )
-        hd->buf[hd->count++] = 0;  /* pad */
+      hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
+      while( hd->bctx.count < 56 )
+        hd->bctx.buf[hd->bctx.count++] = 0;  /* pad */
     }
   else  /* need one extra block */
     {
-      hd->buf[hd->count++] = 0x80; /* pad character */
-      while( hd->count < 64 )
-        hd->buf[hd->count++] = 0;
-      md5_write(hd, NULL, 0);  /* flush */;
-      memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+      hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
+      while( hd->bctx.count < 64 )
+        hd->bctx.buf[hd->bctx.count++] = 0;
+      _gcry_md_block_write(hd, NULL, 0);  /* flush */;
+      memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
     }
   /* append the 64 bit count */
-  hd->buf[56] = lsb       ;
-  hd->buf[57] = lsb >>  8;
-  hd->buf[58] = lsb >> 16;
-  hd->buf[59] = lsb >> 24;
-  hd->buf[60] = msb       ;
-  hd->buf[61] = msb >>  8;
-  hd->buf[62] = msb >> 16;
-  hd->buf[63] = msb >> 24;
-  transform( hd, hd->buf );
-  _gcry_burn_stack (80+6*sizeof(void*));
-
-  p = hd->buf;
-#ifdef WORDS_BIGENDIAN
-#define X(a) do { *p++ = hd->a      ; *p++ = hd->a >> 8;      \
-                 *p++ = hd->a >> 16; *p++ = hd->a >> 24; } while(0)
-#else /* little endian */
-#define X(a) do { *(u32*)p = (*hd).a ; p += 4; } while(0)
-#endif
+  buf_put_le32(hd->bctx.buf + 56, lsb);
+  buf_put_le32(hd->bctx.buf + 60, msb);
+  burn = transform( hd, hd->bctx.buf );
+  _gcry_burn_stack (burn);
+
+  p = hd->bctx.buf;
+#define X(a) do { *(u32*)p = le_bswap32((*hd).a) ; p += 4; } while(0)
   X(A);
   X(B);
   X(C);
@@ -330,7 +277,7 @@ static byte *
 md5_read( void *context )
 {
   MD5_CONTEXT *hd = (MD5_CONTEXT *) context;
-  return hd->buf;
+  return hd->bctx.buf;
 }
 
 static byte asn[18] = /* Object ID is 1.2.840.113549.2.5 */
@@ -348,7 +295,8 @@ static gcry_md_oid_spec_t oid_spec_md5[] =
 
 gcry_md_spec_t _gcry_digest_spec_md5 =
   {
+    GCRY_MD_MD5, {0, 1},
     "MD5", asn, DIM (asn), oid_spec_md5, 16,
-    md5_init, md5_write, md5_final, md5_read,
+    md5_init, _gcry_md_block_write, md5_final, md5_read,
     sizeof (MD5_CONTEXT)
   };
index 2788e34..645b0f8 100644 (file)
@@ -141,9 +141,20 @@ struct primepool_s
 };
 struct primepool_s *primepool;
 /* Mutex used to protect access to the primepool.  */
-static ath_mutex_t primepool_lock = ATH_MUTEX_INITIALIZER;
+static ath_mutex_t 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;
+}
+
 
 /* Save PRIME which has been generated at RANDOMLEVEL for later
    use. Needs to be called while primepool_lock is being hold.  Note
@@ -168,7 +179,7 @@ save_pool_prime (gcry_mpi_t prime, gcry_random_level_t randomlevel)
         {
           if (i >= n/3*2)
             {
-              gcry_mpi_release (item2->prime);
+              _gcry_mpi_release (item2->prime);
               item2->prime = NULL;
               if (!item)
                 item = item2;
@@ -177,11 +188,11 @@ save_pool_prime (gcry_mpi_t prime, gcry_random_level_t randomlevel)
     }
   if (!item)
     {
-      item = gcry_calloc (1, sizeof *item);
+      item = xtrycalloc (1, sizeof *item);
       if (!item)
         {
           /* Out of memory.  Silently giving up. */
-          gcry_mpi_release (prime);
+          _gcry_mpi_release (prime);
           return;
         }
       item->next = primepool;
@@ -195,7 +206,7 @@ save_pool_prime (gcry_mpi_t prime, gcry_random_level_t randomlevel)
 
 /* Return a prime for the prime pool or NULL if none has been found.
    The prime needs to match NBITS and randomlevel. This function needs
-   to be called why the primepool_look is being hold. */
+   to be called with the primepool_look is being hold. */
 static gcry_mpi_t
 get_pool_prime (unsigned int nbits, gcry_random_level_t randomlevel)
 {
@@ -365,7 +376,7 @@ prime_generate_internal (int need_q_factor,
                pbits, req_qbits, qbits, fbits, n);
 
   /* Allocate an integer to old the new prime. */
-  prime = gcry_mpi_new (pbits);
+  prime = mpi_new (pbits);
 
   /* Generate first prime factor.  */
   q = gen_prime (qbits, is_secret, randomlevel, NULL, NULL);
@@ -375,7 +386,7 @@ prime_generate_internal (int need_q_factor,
     q_factor = gen_prime (req_qbits, is_secret, randomlevel, NULL, NULL);
 
   /* Allocate an array to hold all factors + 2 for later usage.  */
-  factors = gcry_calloc (n + 2, sizeof (*factors));
+  factors = xtrycalloc (n + 2, sizeof (*factors));
   if (!factors)
     {
       err = gpg_err_code_from_errno (errno);
@@ -383,7 +394,7 @@ prime_generate_internal (int need_q_factor,
     }
 
   /* Allocate an array to track pool usage. */
-  pool_in_use = gcry_malloc (n * sizeof *pool_in_use);
+  pool_in_use = xtrymalloc (n * sizeof *pool_in_use);
   if (!pool_in_use)
     {
       err = gpg_err_code_from_errno (errno);
@@ -402,7 +413,7 @@ prime_generate_internal (int need_q_factor,
     m += 5;
   if (m < 30)
     m = 30;
-  pool = gcry_calloc (m , sizeof (*pool));
+  pool = xtrycalloc (m , sizeof (*pool));
   if (! pool)
     {
       err = gpg_err_code_from_errno (errno);
@@ -428,7 +439,7 @@ prime_generate_internal (int need_q_factor,
             }
 
           /* Init m_out_of_n().  */
-          perms = gcry_calloc (1, m);
+          perms = xtrycalloc (1, m);
           if (!perms)
             {
               err = gpg_err_code_from_errno (errno);
@@ -520,7 +531,7 @@ prime_generate_internal (int need_q_factor,
           if (i == n)
             {
               /* Ran out of permutations: Allocate new primes.  */
-              gcry_free (perms);
+              xfree (perms);
               perms = NULL;
               progress ('!');
               goto next_try;
@@ -575,25 +586,25 @@ prime_generate_internal (int need_q_factor,
   if (DBG_CIPHER)
     {
       progress ('\n');
-      log_mpidump ("prime    ", prime);
-      log_mpidump ("factor  q", q);
+      log_mpidump ("prime    ", prime);
+      log_mpidump ("factor  q", q);
       if (need_q_factor)
-        log_mpidump ("factor q0", q_factor);
+        log_mpidump ("factor q0", q_factor);
       for (i = 0; i < n; i++)
-        log_mpidump ("factor pi", factors[i]);
+        log_mpidump ("factor pi", factors[i]);
       log_debug ("bit sizes: prime=%u, q=%u",
                  mpi_get_nbits (prime), mpi_get_nbits (q));
       if (need_q_factor)
-        log_debug (", q0=%u", mpi_get_nbits (q_factor));
+        log_printf (", q0=%u", mpi_get_nbits (q_factor));
       for (i = 0; i < n; i++)
-        log_debug (", p%d=%u", i, mpi_get_nbits (factors[i]));
-      progress('\n');
+        log_printf (", p%d=%u", i, mpi_get_nbits (factors[i]));
+      log_printf ("\n");
     }
 
   if (ret_factors)
     {
       /* Caller wants the factors.  */
-      factors_new = gcry_calloc (n + 4, sizeof (*factors_new));
+      factors_new = xtrycalloc (n + 4, sizeof (*factors_new));
       if (! factors_new)
         {
           err = gpg_err_code_from_errno (errno);
@@ -603,7 +614,7 @@ prime_generate_internal (int need_q_factor,
       if (all_factors)
         {
           i = 0;
-          factors_new[i++] = gcry_mpi_set_ui (NULL, 2);
+          factors_new[i++] = mpi_set_ui (NULL, 2);
           factors_new[i++] = mpi_copy (q);
           if (need_q_factor)
             factors_new[i++] = mpi_copy (q_factor);
@@ -644,11 +655,7 @@ prime_generate_internal (int need_q_factor,
             {
               mpi_add_ui (g, g, 1);
               if (DBG_CIPHER)
-                {
-                  log_debug ("checking g:");
-                  gcry_mpi_dump (g);
-                  log_printf ("\n");
-                }
+                log_printmpi ("checking g", g);
               else
                 progress('^');
               for (i = 0; i < n + 2; i++)
@@ -656,7 +663,7 @@ prime_generate_internal (int need_q_factor,
                   mpi_fdiv_q (tmp, pmin1, factors[i]);
                   /* No mpi_pow(), but it is okay to use this with mod
                      prime.  */
-                  gcry_mpi_powm (b, g, tmp, prime);
+                  mpi_powm (b, g, tmp, prime);
                   if (! mpi_cmp_ui (b, 1))
                     break;
                 }
@@ -699,13 +706,13 @@ prime_generate_internal (int need_q_factor,
       if (is_locked && ath_mutex_unlock (&primepool_lock))
         err = GPG_ERR_INTERNAL;
       is_locked = 0;
-      gcry_free (pool);
+      xfree (pool);
     }
-  gcry_free (pool_in_use);
+  xfree (pool_in_use);
   if (factors)
-    gcry_free (factors);  /* Factors are shallow copies.  */
+    xfree (factors);  /* Factors are shallow copies.  */
   if (perms)
-    gcry_free (perms);
+    xfree (perms);
 
   mpi_free (val_2);
   mpi_free (q);
@@ -723,7 +730,7 @@ prime_generate_internal (int need_q_factor,
        {
          for (i = 0; factors_new[i]; i++)
            mpi_free (factors_new[i]);
-         gcry_free (factors_new);
+         xfree (factors_new);
        }
       mpi_free (prime);
     }
@@ -765,11 +772,11 @@ gen_prime (unsigned int nbits, int secret, int randomlevel,
   if (nbits < 16)
     log_fatal ("can't generate a prime with less than %d bits\n", 16);
 
-  mods = gcry_xmalloc( no_of_small_prime_numbers * sizeof *mods );
+  mods = xmalloc (no_of_small_prime_numbers * sizeof *mods);
   /* Make nbits fit into gcry_mpi_t implementation. */
   val_2  = mpi_alloc_set_ui( 2 );
   val_3 = mpi_alloc_set_ui( 3);
-  prime  = secret? gcry_mpi_snew ( nbits ): gcry_mpi_new ( nbits );
+  prime  = secret? mpi_snew (nbits): mpi_new (nbits);
   result = mpi_alloc_like( prime );
   pminus1= mpi_alloc_like( prime );
   ptest  = mpi_alloc_like( prime );
@@ -779,7 +786,7 @@ gen_prime (unsigned int nbits, int secret, int randomlevel,
       int dotcount=0;
 
       /* generate a random number */
-      gcry_mpi_randomize( prime, nbits, randomlevel );
+      _gcry_mpi_randomize( prime, nbits, randomlevel );
 
       /* Set high order bit to 1, set low order bit to 1.  If we are
          generating a secret prime we are most probably doing that
@@ -814,7 +821,7 @@ gen_prime (unsigned int nbits, int secret, int randomlevel,
           /* Do a fast Fermat test now. */
           count2++;
           mpi_sub_ui( pminus1, ptest, 1);
-          gcry_mpi_powm( result, val_2, pminus1, ptest );
+          mpi_powm( result, val_2, pminus1, ptest );
           if ( !mpi_cmp_ui( result, 1 ) )
             {
               /* Not composite, perform stronger tests */
@@ -841,7 +848,7 @@ gen_prime (unsigned int nbits, int secret, int randomlevel,
                       mpi_free(result);
                       mpi_free(pminus1);
                       mpi_free(prime);
-                      gcry_free(mods);
+                      xfree(mods);
                       return ptest;
                     }
                 }
@@ -880,7 +887,7 @@ check_prime( gcry_mpi_t prime, gcry_mpi_t val_2, int rm_rounds,
     gcry_mpi_t result = mpi_alloc_like( prime );
     gcry_mpi_t pminus1 = mpi_alloc_like( prime );
     mpi_sub_ui( pminus1, prime, 1);
-    gcry_mpi_powm( result, val_2, pminus1, prime );
+    mpi_powm( result, val_2, pminus1, prime );
     mpi_free( pminus1 );
     if ( mpi_cmp_ui( result, 1 ) )
       {
@@ -942,7 +949,7 @@ is_prime (gcry_mpi_t n, int steps, unsigned int *count)
         }
       else
         {
-          gcry_mpi_randomize( x, nbits, GCRY_WEAK_RANDOM );
+          _gcry_mpi_randomize( x, nbits, GCRY_WEAK_RANDOM );
 
           /* Make sure that the number is smaller than the prime and
              keep the randomness of the high bit. */
@@ -957,12 +964,12 @@ is_prime (gcry_mpi_t n, int steps, unsigned int *count)
             }
           gcry_assert (mpi_cmp (x, nminus1) < 0 && mpi_cmp_ui (x, 1) > 0);
        }
-      gcry_mpi_powm ( y, x, q, n);
+      mpi_powm ( y, x, q, n);
       if ( mpi_cmp_ui(y, 1) && mpi_cmp( y, nminus1 ) )
         {
           for ( j=1; j < k && mpi_cmp( y, nminus1 ); j++ )
             {
-              gcry_mpi_powm(y, y, a2, n);
+              mpi_powm(y, y, a2, n);
               if( !mpi_cmp_ui( y, 1 ) )
                 goto leave; /* Not a prime. */
             }
@@ -1114,67 +1121,66 @@ m_out_of_n ( char *array, int m, int n )
    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)
+gcry_err_code_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)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_err_code_t rc = 0;
   gcry_mpi_t *factors_generated = NULL;
   gcry_mpi_t prime_generated = NULL;
   unsigned int mode = 0;
 
   if (!prime)
-    return gpg_error (GPG_ERR_INV_ARG);
+    return GPG_ERR_INV_ARG;
   *prime = NULL;
 
   if (flags & GCRY_PRIME_FLAG_SPECIAL_FACTOR)
     mode = 1;
 
   /* Generate.  */
-  err = prime_generate_internal ((mode==1), &prime_generated, prime_bits,
-                                factor_bits, NULL,
-                                 factors? &factors_generated : NULL,
-                                random_level, flags, 1,
-                                 cb_func, cb_arg);
+  rc = prime_generate_internal ((mode==1), &prime_generated, prime_bits,
+                                factor_bits, NULL,
+                                factors? &factors_generated : NULL,
+                                random_level, flags, 1,
+                                cb_func, cb_arg);
 
-  if (! err)
-    if (cb_func)
-      {
-       /* Additional check. */
-       if ( !cb_func (cb_arg, GCRY_PRIME_CHECK_AT_FINISH, prime_generated))
-         {
-           /* Failed, deallocate resources.  */
-           unsigned int i;
+  if (!rc && cb_func)
+    {
+      /* Additional check. */
+      if ( !cb_func (cb_arg, GCRY_PRIME_CHECK_AT_FINISH, prime_generated))
+        {
+          /* Failed, deallocate resources.  */
+          unsigned int i;
 
-           mpi_free (prime_generated);
-            if (factors)
-              {
-                for (i = 0; factors_generated[i]; i++)
-                  mpi_free (factors_generated[i]);
-                gcry_free (factors_generated);
-              }
-           err = GPG_ERR_GENERAL;
-         }
-      }
+          mpi_free (prime_generated);
+          if (factors)
+            {
+              for (i = 0; factors_generated[i]; i++)
+                mpi_free (factors_generated[i]);
+              xfree (factors_generated);
+            }
+          rc = GPG_ERR_GENERAL;
+        }
+    }
 
-  if (! err)
+  if (!rc)
     {
       if (factors)
         *factors = factors_generated;
       *prime = prime_generated;
     }
 
-  return gcry_error (err);
+  return rc;
 }
 
 /* Check whether the number X is prime.  */
-gcry_error_t
-gcry_prime_check (gcry_mpi_t x, unsigned int flags)
+gcry_err_code_t
+_gcry_prime_check (gcry_mpi_t x, unsigned int flags)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_err_code_t rc = 0;
   gcry_mpi_t val_2 = mpi_alloc_set_ui (2); /* Used by the Fermat test. */
 
   (void)flags;
@@ -1182,37 +1188,37 @@ gcry_prime_check (gcry_mpi_t x, unsigned int flags)
   /* 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))
-    err = GPG_ERR_NO_PRIME;
+    rc = GPG_ERR_NO_PRIME;
 
   mpi_free (val_2);
 
-  return gcry_error (err);
+  return rc;
 }
 
 /* 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
    atart for the search. Returns 0 on success.*/
-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)
+gcry_err_code_t
+_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 = gcry_mpi_new (0);
-  gcry_mpi_t b = gcry_mpi_new (0);
-  gcry_mpi_t pmin1 = gcry_mpi_new (0);
-  gcry_mpi_t g = start_g? gcry_mpi_copy (start_g) : gcry_mpi_set_ui (NULL, 3);
+  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)
-    return gpg_error (GPG_ERR_INV_ARG);
+    return GPG_ERR_INV_ARG;
   *r_g = NULL;
 
   for (n=0; factors[n]; n++)
     ;
   if (n < 2)
-    return gpg_error (GPG_ERR_INV_ARG);
+    return GPG_ERR_INV_ARG;
 
   /* Extra sanity check - usually disabled. */
 /*   mpi_set (tmp, factors[0]); */
@@ -1222,27 +1228,23 @@ gcry_prime_group_generator (gcry_mpi_t *r_g,
 /*   if (mpi_cmp (prime, tmp)) */
 /*     return gpg_error (GPG_ERR_INV_ARG); */
 
-  gcry_mpi_sub_ui (pmin1, prime, 1);
+  mpi_sub_ui (pmin1, prime, 1);
   do
     {
       if (first)
         first = 0;
       else
-        gcry_mpi_add_ui (g, g, 1);
+        mpi_add_ui (g, g, 1);
 
       if (DBG_CIPHER)
-        {
-          log_debug ("checking g:");
-          gcry_mpi_dump (g);
-          log_debug ("\n");
-        }
+        log_printmpi ("checking g", g);
       else
         progress('^');
 
       for (i = 0; i < n; i++)
         {
           mpi_fdiv_q (tmp, pmin1, factors[i]);
-          gcry_mpi_powm (b, g, tmp, prime);
+          mpi_powm (b, g, tmp, prime);
           if (! mpi_cmp_ui (b, 1))
             break;
         }
@@ -1251,9 +1253,9 @@ gcry_prime_group_generator (gcry_mpi_t *r_g,
     }
   while (i < n);
 
-  gcry_mpi_release (tmp);
-  gcry_mpi_release (b);
-  gcry_mpi_release (pmin1);
+  _gcry_mpi_release (tmp);
+  _gcry_mpi_release (b);
+  _gcry_mpi_release (pmin1);
   *r_g = g;
 
   return 0;
@@ -1261,7 +1263,7 @@ gcry_prime_group_generator (gcry_mpi_t *r_g,
 
 /* Convenience function to release the factors array. */
 void
-gcry_prime_release_factors (gcry_mpi_t *factors)
+_gcry_prime_release_factors (gcry_mpi_t *factors)
 {
   if (factors)
     {
@@ -1269,7 +1271,7 @@ gcry_prime_release_factors (gcry_mpi_t *factors)
 
       for (i=0; factors[i]; i++)
         mpi_free (factors[i]);
-      gcry_free (factors);
+      xfree (factors);
     }
 }
 
@@ -1282,7 +1284,7 @@ find_x931_prime (const gcry_mpi_t pfirst)
   gcry_mpi_t val_2 = mpi_alloc_set_ui (2);
   gcry_mpi_t prime;
 
-  prime = gcry_mpi_copy (pfirst);
+  prime = mpi_copy (pfirst);
   /* If P is even add 1.  */
   mpi_set_bit (prime, 0);
 
@@ -1340,7 +1342,7 @@ _gcry_derive_x931_prime (const gcry_mpi_t xp,
     mpi_sub (r1, r1, tmp);
 
     /* Fixup a negative value.  */
-    if (mpi_is_neg (r1))
+    if (mpi_has_sign (r1))
       mpi_add (r1, r1, p1p2);
 
     /* yp0 = xp + (r1 - xp mod p1*p2)  */
@@ -1386,7 +1388,7 @@ _gcry_derive_x931_prime (const gcry_mpi_t xp,
     mpi_sub_ui (yp0, yp0, 1);   /* Ditto.  */
     for (;;)
       {
-        gcdres = gcry_mpi_gcd (gcdtmp, e, yp0);
+        gcdres = mpi_gcd (gcdtmp, e, yp0);
         mpi_add_ui (yp0, yp0, 1);
         if (!gcdres)
           progress ('/');  /* gcd (e, yp0-1) != 1  */
@@ -1455,7 +1457,7 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits,
     return GPG_ERR_INV_ARG;
 
   /* Allocate a buffer to later compute SEED+some_increment. */
-  seed_plus = gcry_malloc (seedlen < 20? 20:seedlen);
+  seed_plus = xtrymalloc (seedlen < 20? 20:seedlen);
   if (!seed_plus)
     {
       ec = gpg_err_code_from_syserror ();
@@ -1465,8 +1467,8 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits,
   val_2   = mpi_alloc_set_ui (2);
   value_n = (pbits - 1) / qbits;
   value_b = (pbits - 1) - value_n * qbits;
-  value_w = gcry_mpi_new (pbits);
-  value_x = gcry_mpi_new (pbits);
+  value_w = mpi_new (pbits);
+  value_x = mpi_new (pbits);
 
  restart:
   /* Generate Q.  */
@@ -1476,7 +1478,7 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits,
       if (!seed)
         {
           seedlen = sizeof seed_help_buffer;
-          gcry_create_nonce (seed_help_buffer, seedlen);
+          _gcry_create_nonce (seed_help_buffer, seedlen);
           seed = seed_help_buffer;
         }
 
@@ -1488,15 +1490,15 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits,
           if (seed_plus[i])
             break;
         }
-      gcry_md_hash_buffer (GCRY_MD_SHA1, value_u, seed, seedlen);
-      gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
+      _gcry_md_hash_buffer (GCRY_MD_SHA1, value_u, seed, seedlen);
+      _gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
       for (i=0; i < sizeof value_u; i++)
         value_u[i] ^= digest[i];
 
       /* Step 3:  Form q from U  */
-      gcry_mpi_release (prime_q); prime_q = NULL;
-      ec = gpg_err_code (gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG,
-                                        value_u, sizeof value_u, NULL));
+      _gcry_mpi_release (prime_q); prime_q = NULL;
+      ec = _gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG,
+                           value_u, sizeof value_u, NULL);
       if (ec)
         goto leave;
       mpi_set_highbit (prime_q, qbits-1 );
@@ -1515,7 +1517,7 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits,
   counter = 0;
 
   /* Generate P. */
-  prime_p = gcry_mpi_new (pbits);
+  prime_p = mpi_new (pbits);
   for (;;)
     {
       /* Step 7: For k = 0,...n let
@@ -1541,11 +1543,11 @@ _gcry_generate_fips186_2_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 (GCRY_MD_SHA1, digest, seed_plus, seedlen);
 
-          gcry_mpi_release (tmpval); tmpval = NULL;
-          ec = gpg_err_code (gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG,
-                                            digest, sizeof digest, NULL));
+          _gcry_mpi_release (tmpval); tmpval = NULL;
+          ec = _gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG,
+                               digest, sizeof digest, NULL);
           if (ec)
             goto leave;
           if (value_k == value_n)
@@ -1607,13 +1609,13 @@ _gcry_generate_fips186_2_prime (unsigned int pbits, unsigned int qbits,
 
 
  leave:
-  gcry_mpi_release (tmpval);
-  gcry_mpi_release (value_x);
-  gcry_mpi_release (value_w);
-  gcry_mpi_release (prime_p);
-  gcry_mpi_release (prime_q);
-  gcry_free (seed_plus);
-  gcry_mpi_release (val_2);
+  _gcry_mpi_release (tmpval);
+  _gcry_mpi_release (value_x);
+  _gcry_mpi_release (value_w);
+  _gcry_mpi_release (prime_p);
+  _gcry_mpi_release (prime_q);
+  xfree (seed_plus);
+  _gcry_mpi_release (val_2);
   return ec;
 }
 
@@ -1678,11 +1680,11 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
     return GPG_ERR_INV_KEYLEN;
 
   /* Also check that the hash algorithm is available.  */
-  ec = gpg_err_code (gcry_md_test_algo (hashalgo));
+  ec = _gcry_md_test_algo (hashalgo);
   if (ec)
     return ec;
   gcry_assert (qbits/8 <= sizeof digest);
-  gcry_assert (gcry_md_get_algo_dlen (hashalgo) == qbits/8);
+  gcry_assert (_gcry_md_get_algo_dlen (hashalgo) == qbits/8);
 
 
   /* Step 2:  Check seedlen.  */
@@ -1693,16 +1695,16 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
 
   /* Allocate a buffer to later compute SEED+some_increment and a few
      helper variables.  */
-  seed_plus = gcry_malloc (seedlen < sizeof seed_help_buffer?
-                           sizeof seed_help_buffer : seedlen);
+  seed_plus = xtrymalloc (seedlen < sizeof seed_help_buffer?
+                          sizeof seed_help_buffer : seedlen);
   if (!seed_plus)
     {
       ec = gpg_err_code_from_syserror ();
       goto leave;
     }
   val_2   = mpi_alloc_set_ui (2);
-  value_w = gcry_mpi_new (pbits);
-  value_x = gcry_mpi_new (pbits);
+  value_w = mpi_new (pbits);
+  value_x = mpi_new (pbits);
 
   /* Step 3: n = \lceil L / outlen \rceil - 1  */
   value_n = (pbits + qbits - 1) / qbits - 1;
@@ -1718,12 +1720,12 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
         {
           seedlen = qbits/8;
           gcry_assert (seedlen <= sizeof seed_help_buffer);
-          gcry_create_nonce (seed_help_buffer, seedlen);
+          _gcry_create_nonce (seed_help_buffer, seedlen);
           seed = seed_help_buffer;
         }
 
       /* Step 6:  U = hash(seed)  */
-      gcry_md_hash_buffer (hashalgo, value_u, seed, seedlen);
+      _gcry_md_hash_buffer (hashalgo, value_u, seed, seedlen);
 
       /* Step 7:  q = 2^{N-1} + U + 1 - (U mod 2)  */
       if ( !(value_u[qbits/8-1] & 0x01) )
@@ -1735,9 +1737,9 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
                 break;
             }
         }
-      gcry_mpi_release (prime_q); prime_q = NULL;
-      ec = gpg_err_code (gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG,
-                                        value_u, sizeof value_u, NULL));
+      _gcry_mpi_release (prime_q); prime_q = NULL;
+      ec = _gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG,
+                           value_u, sizeof value_u, NULL);
       if (ec)
         goto leave;
       mpi_set_highbit (prime_q, qbits-1 );
@@ -1758,7 +1760,7 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
   counter = 0;
 
   /* Generate P. */
-  prime_p = gcry_mpi_new (pbits);
+  prime_p = mpi_new (pbits);
   for (;;)
     {
       /* Step 11.1: For j = 0,...n let
@@ -1782,11 +1784,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 (GCRY_MD_SHA1, digest, seed_plus, seedlen);
 
-          gcry_mpi_release (tmpval); tmpval = NULL;
-          ec = gpg_err_code (gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG,
-                                            digest, sizeof digest, NULL));
+          _gcry_mpi_release (tmpval); tmpval = NULL;
+          ec = _gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG,
+                               digest, sizeof digest, NULL);
           if (ec)
             goto leave;
           if (value_j == value_n)
@@ -1824,9 +1826,9 @@ _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_mpidump ("fips186-3 prime p", prime_p);
-  log_mpidump ("fips186-3 prime q", prime_q);
+  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;
@@ -1850,12 +1852,12 @@ _gcry_generate_fips186_3_prime (unsigned int pbits, unsigned int qbits,
     *r_hashalgo = hashalgo;
 
  leave:
-  gcry_mpi_release (tmpval);
-  gcry_mpi_release (value_x);
-  gcry_mpi_release (value_w);
-  gcry_mpi_release (prime_p);
-  gcry_mpi_release (prime_q);
-  gcry_free (seed_plus);
-  gcry_mpi_release (val_2);
+  _gcry_mpi_release (tmpval);
+  _gcry_mpi_release (value_x);
+  _gcry_mpi_release (value_w);
+  _gcry_mpi_release (prime_p);
+  _gcry_mpi_release (prime_q);
+  xfree (seed_plus);
+  _gcry_mpi_release (val_2);
   return ec;
 }
diff --git a/cipher/pubkey-internal.h b/cipher/pubkey-internal.h
new file mode 100644 (file)
index 0000000..193248c
--- /dev/null
@@ -0,0 +1,100 @@
+/* pubkey-internal.h  - Internal defs for pubkey.c
+ * Copyright (C) 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/>.
+ */
+
+#ifndef GCRY_PUBKEY_INTERNAL_H
+#define GCRY_PUBKEY_INTERNAL_H
+
+/*-- pubkey-util.c --*/
+gpg_err_code_t _gcry_pk_util_parse_flaglist (gcry_sexp_t list,
+                                             int *r_flags,
+                                             enum pk_encoding *r_encoding);
+gpg_err_code_t _gcry_pk_util_get_nbits (gcry_sexp_t list,
+                                        unsigned int *r_nbits);
+gpg_err_code_t _gcry_pk_util_get_rsa_use_e (gcry_sexp_t list,
+                                            unsigned long *r_e);
+gpg_err_code_t _gcry_pk_util_preparse_sigval (gcry_sexp_t s_sig,
+                                              const char **algo_names,
+                                              gcry_sexp_t *r_parms,
+                                              int *r_eccflags);
+gpg_err_code_t _gcry_pk_util_preparse_encval (gcry_sexp_t sexp,
+                                              const char **algo_names,
+                                              gcry_sexp_t *r_parms,
+                                              struct pk_encoding_ctx *ctx);
+void _gcry_pk_util_init_encoding_ctx (struct pk_encoding_ctx *ctx,
+                                      enum pk_operation op,
+                                      unsigned int nbits);
+void _gcry_pk_util_free_encoding_ctx (struct pk_encoding_ctx *ctx);
+gcry_err_code_t _gcry_pk_util_data_to_mpi (gcry_sexp_t input,
+                                           gcry_mpi_t *ret_mpi,
+                                           struct pk_encoding_ctx *ctx);
+
+
+
+/*-- rsa-common.c --*/
+gpg_err_code_t
+_gcry_rsa_pkcs1_encode_for_enc (gcry_mpi_t *r_result, unsigned int nbits,
+                                const unsigned char *value, size_t valuelen,
+                                const unsigned char *random_override,
+                                size_t random_override_len);
+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_for_sig (gcry_mpi_t *r_result, unsigned int nbits,
+                                const unsigned char *value, size_t valuelen,
+                                int algo);
+gpg_err_code_t
+_gcry_rsa_oaep_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
+                       const unsigned char *value, size_t valuelen,
+                       const unsigned char *label, size_t labellen,
+                       const void *random_override, size_t random_override_len);
+gpg_err_code_t
+_gcry_rsa_oaep_decode (unsigned char **r_result, size_t *r_resultlen,
+                       unsigned int nbits, int algo,
+                       gcry_mpi_t value,
+                       const unsigned char *label, size_t labellen);
+gpg_err_code_t
+_gcry_rsa_pss_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
+                      const unsigned char *value, size_t valuelen, int saltlen,
+                      const void *random_override, size_t random_override_len);
+gpg_err_code_t
+_gcry_rsa_pss_verify (gcry_mpi_t value, gcry_mpi_t encoded,
+                      unsigned int nbits, int algo, size_t saltlen);
+
+
+
+/*-- dsa-common.c --*/
+gcry_mpi_t _gcry_dsa_gen_k (gcry_mpi_t q, int security_level);
+gpg_err_code_t _gcry_dsa_gen_rfc6979_k (gcry_mpi_t *r_k,
+                                        gcry_mpi_t dsa_q, gcry_mpi_t dsa_x,
+                                        const unsigned char *h1,
+                                        unsigned int h1len,
+                                        int halgo,
+                                        unsigned int extraloops);
+
+gpg_err_code_t _gcry_dsa_normalize_hash (gcry_mpi_t input,
+                                         gcry_mpi_t *out,
+                                         unsigned int qbits);
+
+/*-- ecc.c --*/
+gpg_err_code_t _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode,
+                                      mpi_ec_t ec);
+
+
+#endif /*GCRY_PUBKEY_INTERNAL_H*/
diff --git a/cipher/pubkey-util.c b/cipher/pubkey-util.c
new file mode 100644 (file)
index 0000000..616b499
--- /dev/null
@@ -0,0 +1,1050 @@
+/* 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
+ *
+ * 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 "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "pubkey-internal.h"
+
+
+/* Callback for the pubkey algorithm code to verify PSS signatures.
+   OPAQUE is the data provided by the actual caller.  The meaning of
+   TMP depends on the actual algorithm (but there is only RSA); now
+   for RSA it is the output of running the public key function on the
+   input.  */
+static int
+pss_verify_cmp (void *opaque, gcry_mpi_t tmp)
+{
+  struct pk_encoding_ctx *ctx = opaque;
+  gcry_mpi_t hash = ctx->verify_arg;
+
+  return _gcry_rsa_pss_verify (hash, tmp, ctx->nbits - 1,
+                               ctx->hash_algo, ctx->saltlen);
+}
+
+
+/* Parser for a flag list.  On return the encoding is stored at
+   R_ENCODING and the flags are stored at R_FLAGS.  If any of them is
+   not needed, NULL may be passed.  The function returns 0 on success
+   or an error code. */
+gpg_err_code_t
+_gcry_pk_util_parse_flaglist (gcry_sexp_t list,
+                              int *r_flags, enum pk_encoding *r_encoding)
+{
+  gpg_err_code_t rc = 0;
+  const char *s;
+  size_t n;
+  int i;
+  int encoding = PUBKEY_ENC_UNKNOWN;
+  int flags = 0;
+  int igninvflag = 0;
+
+  for (i = list ? sexp_length (list)-1 : 0; i > 0; i--)
+    {
+      s = sexp_nth_data (list, i, &n);
+      if (!s)
+        continue; /* Not a data element. */
+
+      switch (n)
+        {
+        case 3:
+          if (!memcmp (s, "pss", 3) && encoding == PUBKEY_ENC_UNKNOWN)
+            {
+              encoding = PUBKEY_ENC_PSS;
+              flags |= PUBKEY_FLAG_FIXEDLEN;
+            }
+          else if (!memcmp (s, "raw", 3) && encoding == PUBKEY_ENC_UNKNOWN)
+            {
+              encoding = PUBKEY_ENC_RAW;
+              flags |= PUBKEY_FLAG_RAW_FLAG; /* Explicitly given.  */
+            }
+          else if (!igninvflag)
+            rc = GPG_ERR_INV_FLAG;
+          break;
+
+        case 4:
+          if (!memcmp (s, "comp", 4))
+            flags |= PUBKEY_FLAG_COMP;
+          else if (!memcmp (s, "oaep", 4) && encoding == PUBKEY_ENC_UNKNOWN)
+            {
+              encoding = PUBKEY_ENC_OAEP;
+              flags |= PUBKEY_FLAG_FIXEDLEN;
+            }
+          else if (!memcmp (s, "gost", 4))
+            {
+              encoding = PUBKEY_ENC_RAW;
+              flags |= PUBKEY_FLAG_GOST;
+            }
+          else if (!igninvflag)
+            rc = GPG_ERR_INV_FLAG;
+          break;
+
+        case 5:
+          if (!memcmp (s, "eddsa", 5))
+            {
+              encoding = PUBKEY_ENC_RAW;
+              flags |= PUBKEY_FLAG_EDDSA;
+            }
+          else if (!memcmp (s, "pkcs1", 5) && encoding == PUBKEY_ENC_UNKNOWN)
+            {
+              encoding = PUBKEY_ENC_PKCS1;
+              flags |= PUBKEY_FLAG_FIXEDLEN;
+            }
+          else if (!memcmp (s, "param", 5))
+            flags |= PUBKEY_FLAG_PARAM;
+          else if (!igninvflag)
+            rc = GPG_ERR_INV_FLAG;
+          break;
+
+        case 6:
+          if (!memcmp (s, "nocomp", 6))
+            flags |= PUBKEY_FLAG_NOCOMP;
+          else if (!igninvflag)
+            rc = GPG_ERR_INV_FLAG;
+          break;
+
+        case 7:
+          if (!memcmp (s, "rfc6979", 7))
+            flags |= PUBKEY_FLAG_RFC6979;
+          else if (!memcmp (s, "noparam", 7))
+            ; /* Ignore - it is the default.  */
+          else if (!igninvflag)
+            rc = GPG_ERR_INV_FLAG;
+          break;
+
+        case 8:
+          if (!memcmp (s, "use-x931", 8))
+            flags |= PUBKEY_FLAG_USE_X931;
+          else if (!igninvflag)
+            rc = GPG_ERR_INV_FLAG;
+          break;
+
+        case 10:
+          if (!memcmp (s, "igninvflag", 10))
+            igninvflag = 1;
+          break;
+
+        case 11:
+          if (!memcmp (s, "no-blinding", 11))
+            flags |= PUBKEY_FLAG_NO_BLINDING;
+          else if (!memcmp (s, "use-fips186", 11))
+            flags |= PUBKEY_FLAG_USE_FIPS186;
+          else if (!igninvflag)
+            rc = GPG_ERR_INV_FLAG;
+          break;
+
+        case 13:
+          if (!memcmp (s, "use-fips186-2", 13))
+            flags |= PUBKEY_FLAG_USE_FIPS186_2;
+          else if (!memcmp (s, "transient-key", 13))
+            flags |= PUBKEY_FLAG_TRANSIENT_KEY;
+          else if (!igninvflag)
+            rc = GPG_ERR_INV_FLAG;
+          break;
+
+        default:
+          if (!igninvflag)
+            rc = GPG_ERR_INV_FLAG;
+          break;
+        }
+    }
+
+  if (r_flags)
+    *r_flags = flags;
+  if (r_encoding)
+    *r_encoding = encoding;
+
+  return rc;
+}
+
+
+static int
+get_hash_algo (const char *s, size_t n)
+{
+  static const struct { const char *name; int algo; } hashnames[] = {
+    { "sha1",   GCRY_MD_SHA1 },
+    { "md5",    GCRY_MD_MD5 },
+    { "sha256", GCRY_MD_SHA256 },
+    { "ripemd160", GCRY_MD_RMD160 },
+    { "rmd160", GCRY_MD_RMD160 },
+    { "sha384", GCRY_MD_SHA384 },
+    { "sha512", GCRY_MD_SHA512 },
+    { "sha224", GCRY_MD_SHA224 },
+    { "md2",    GCRY_MD_MD2 },
+    { "md4",    GCRY_MD_MD4 },
+    { "tiger",  GCRY_MD_TIGER },
+    { "haval",  GCRY_MD_HAVAL },
+    { NULL, 0 }
+  };
+  int algo;
+  int i;
+
+  for (i=0; hashnames[i].name; i++)
+    {
+      if ( strlen (hashnames[i].name) == n
+          && !memcmp (hashnames[i].name, s, n))
+       break;
+    }
+  if (hashnames[i].name)
+    algo = hashnames[i].algo;
+  else
+    {
+      /* In case of not listed or dynamically allocated hash
+        algorithm we fall back to this somewhat slower
+        method.  Further, it also allows to use OIDs as
+        algorithm names. */
+      char *tmpname;
+
+      tmpname = xtrymalloc (n+1);
+      if (!tmpname)
+       algo = 0;  /* Out of core - silently give up.  */
+      else
+       {
+         memcpy (tmpname, s, n);
+         tmpname[n] = 0;
+         algo = _gcry_md_map_name (tmpname);
+         xfree (tmpname);
+       }
+    }
+  return algo;
+}
+
+
+/* Get the "nbits" parameter from an s-expression of the format:
+ *
+ *   (algo
+ *     (parameter_name_1 ....)
+ *      ....
+ *     (parameter_name_n ....))
+ *
+ * Example:
+ *
+ *   (rsa
+ *     (nbits 4:2048))
+ *
+ * On success the value for nbits is stored at R_NBITS.  If no nbits
+ * parameter is found, the function returns success and stores 0 at
+ * R_NBITS.  For parsing errors the function returns an error code and
+ * stores 0 at R_NBITS.
+ */
+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 = sexp_find_token (list, "nbits", 0);
+  if (!list)
+    return 0; /* No NBITS found.  */
+
+  s = sexp_nth_data (list, 1, &n);
+  if (!s || n >= DIM (buf) - 1 )
+    {
+      /* NBITS given without a cdr.  */
+      sexp_release (list);
+      return GPG_ERR_INV_OBJ;
+    }
+  memcpy (buf, s, n);
+  buf[n] = 0;
+  *r_nbits = (unsigned int)strtoul (buf, NULL, 0);
+  sexp_release (list);
+  return 0;
+}
+
+
+/* Get the optional "rsa-use-e" parameter from an s-expression of the
+ * format:
+ *
+ *   (algo
+ *     (parameter_name_1 ....)
+ *      ....
+ *     (parameter_name_n ....))
+ *
+ * Example:
+ *
+ *   (rsa
+ *     (nbits 4:2048)
+ *     (rsa-use-e 2:41))
+ *
+ * On success the value for nbits is stored at R_E.  If no rsa-use-e
+ * parameter is found, the function returns success and stores 65537 at
+ * R_E.  For parsing errors the function returns an error code and
+ * stores 0 at R_E.
+ */
+gpg_err_code_t
+_gcry_pk_util_get_rsa_use_e (gcry_sexp_t list, unsigned long *r_e)
+{
+  char buf[50];
+  const char *s;
+  size_t n;
+
+  *r_e = 0;
+
+  list = sexp_find_token (list, "rsa-use-e", 0);
+  if (!list)
+    {
+      *r_e = 65537; /* Not given, use the value generated by old versions. */
+      return 0;
+    }
+
+  s = sexp_nth_data (list, 1, &n);
+  if (!s || n >= DIM (buf) - 1 )
+    {
+      /* No value or value too large.  */
+      sexp_release (list);
+      return GPG_ERR_INV_OBJ;
+    }
+  memcpy (buf, s, n);
+  buf[n] = 0;
+  *r_e = strtoul (buf, NULL, 0);
+  sexp_release (list);
+  return 0;
+}
+
+
+/* Parse a "sig-val" s-expression and store the inner parameter list at
+   R_PARMS.  ALGO_NAMES is used to verify that the algorithm in
+   "sig-val" is valid.  Returns 0 on success and stores a new list at
+   R_PARMS which must be freed by the caller.  On error R_PARMS is set
+   to NULL and an error code returned.  If R_ECCFLAGS is not NULL flag
+   values are set into it; as of now they are only used with ecc
+   algorithms.  */
+gpg_err_code_t
+_gcry_pk_util_preparse_sigval (gcry_sexp_t s_sig, const char **algo_names,
+                               gcry_sexp_t *r_parms, int *r_eccflags)
+{
+  gpg_err_code_t rc;
+  gcry_sexp_t l1 = NULL;
+  gcry_sexp_t l2 = NULL;
+  char *name = NULL;
+  int i;
+
+  *r_parms = NULL;
+  if (r_eccflags)
+    *r_eccflags = 0;
+
+  /* Extract the signature value.  */
+  l1 = sexp_find_token (s_sig, "sig-val", 0);
+  if (!l1)
+    {
+      rc = GPG_ERR_INV_OBJ; /* Does not contain a signature value object.  */
+      goto leave;
+    }
+
+  l2 = sexp_nth (l1, 1);
+  if (!l2)
+    {
+      rc = GPG_ERR_NO_OBJ;   /* No cadr for the sig object.  */
+      goto leave;
+    }
+  name = sexp_nth_string (l2, 0);
+  if (!name)
+    {
+      rc = GPG_ERR_INV_OBJ;  /* Invalid structure of object.  */
+      goto leave;
+    }
+  else if (!strcmp (name, "flags"))
+    {
+      /* Skip a "flags" parameter and look again for the algorithm
+        name.  This is not used but here just for the sake of
+        consistent S-expressions we need to handle it. */
+      sexp_release (l2);
+      l2 = sexp_nth (l1, 2);
+      if (!l2)
+       {
+         rc = GPG_ERR_INV_OBJ;
+          goto leave;
+       }
+      xfree (name);
+      name = sexp_nth_string (l2, 0);
+      if (!name)
+        {
+          rc = GPG_ERR_INV_OBJ;  /* Invalid structure of object.  */
+          goto leave;
+        }
+    }
+
+  for (i=0; algo_names[i]; i++)
+    if (!stricmp (name, algo_names[i]))
+      break;
+  if (!algo_names[i])
+    {
+      rc = GPG_ERR_CONFLICT; /* "sig-val" uses an unexpected algo. */
+      goto leave;
+    }
+  if (r_eccflags)
+    {
+      if (!strcmp (name, "eddsa"))
+        *r_eccflags = PUBKEY_FLAG_EDDSA;
+      if (!strcmp (name, "gost"))
+        *r_eccflags = PUBKEY_FLAG_GOST;
+    }
+
+  *r_parms = l2;
+  l2 = NULL;
+  rc = 0;
+
+ leave:
+  xfree (name);
+  sexp_release (l2);
+  sexp_release (l1);
+  return rc;
+}
+
+
+/* Parse a "enc-val" s-expression and store the inner parameter list
+   at R_PARMS.  ALGO_NAMES is used to verify that the algorithm in
+   "enc-val" is valid.  Returns 0 on success and stores a new list at
+   R_PARMS which must be freed by the caller.  On error R_PARMS is set
+   to NULL and an error code returned.  If R_ECCFLAGS is not NULL flag
+   values are set into it; as of now they are only used with ecc
+   algorithms.
+
+     (enc-val
+       [(flags [raw, pkcs1, oaep, no-blinding])]
+       [(hash-algo <algo>)]
+       [(label <label>)]
+        (<algo>
+          (<param_name1> <mpi>)
+          ...
+          (<param_namen> <mpi>)))
+
+   HASH-ALGO and LABEL are specific to OAEP.  CTX will be updated with
+   encoding information.  */
+gpg_err_code_t
+_gcry_pk_util_preparse_encval (gcry_sexp_t sexp, const char **algo_names,
+                               gcry_sexp_t *r_parms,
+                               struct pk_encoding_ctx *ctx)
+{
+  gcry_err_code_t rc = 0;
+  gcry_sexp_t l1 = NULL;
+  gcry_sexp_t l2 = NULL;
+  char *name = NULL;
+  size_t n;
+  int parsed_flags = 0;
+  int i;
+
+  *r_parms = NULL;
+
+  /* Check that the first element is valid.  */
+  l1 = sexp_find_token (sexp, "enc-val" , 0);
+  if (!l1)
+    {
+      rc = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object.  */
+      goto leave;
+    }
+
+  l2 = sexp_nth (l1, 1);
+  if (!l2)
+    {
+      rc = GPG_ERR_NO_OBJ;  /* No cadr for the data object.  */
+      goto leave;
+    }
+
+  /* Extract identifier of sublist.  */
+  name = sexp_nth_string (l2, 0);
+  if (!name)
+    {
+      rc = GPG_ERR_INV_OBJ; /* Invalid structure of object.  */
+      goto leave;
+    }
+
+  if (!strcmp (name, "flags"))
+    {
+      const char *s;
+
+      /* There is a flags element - process it.  */
+      rc = _gcry_pk_util_parse_flaglist (l2, &parsed_flags, &ctx->encoding);
+      if (rc)
+        goto leave;
+      if (ctx->encoding == PUBKEY_ENC_PSS)
+        {
+          rc = GPG_ERR_CONFLICT;
+          goto leave;
+        }
+
+      /* Get the OAEP parameters HASH-ALGO and LABEL, if any. */
+      if (ctx->encoding == PUBKEY_ENC_OAEP)
+       {
+         /* Get HASH-ALGO. */
+          sexp_release (l2);
+         l2 = sexp_find_token (l1, "hash-algo", 0);
+         if (l2)
+           {
+             s = sexp_nth_data (l2, 1, &n);
+             if (!s)
+               rc = GPG_ERR_NO_OBJ;
+             else
+               {
+                 ctx->hash_algo = get_hash_algo (s, n);
+                 if (!ctx->hash_algo)
+                   rc = GPG_ERR_DIGEST_ALGO;
+               }
+             if (rc)
+               goto leave;
+           }
+
+         /* Get LABEL. */
+          sexp_release (l2);
+         l2 = sexp_find_token (l1, "label", 0);
+         if (l2)
+           {
+             s = sexp_nth_data (l2, 1, &n);
+             if (!s)
+               rc = GPG_ERR_NO_OBJ;
+             else if (n > 0)
+               {
+                 ctx->label = xtrymalloc (n);
+                 if (!ctx->label)
+                   rc = gpg_err_code_from_syserror ();
+                 else
+                   {
+                     memcpy (ctx->label, s, n);
+                     ctx->labellen = n;
+                   }
+               }
+             if (rc)
+               goto leave;
+           }
+       }
+
+      /* Get the next which has the actual data - skip HASH-ALGO and LABEL. */
+      for (i = 2; (sexp_release (l2), l2 = sexp_nth (l1, i)); i++)
+       {
+         s = sexp_nth_data (l2, 0, &n);
+         if (!(n == 9 && !memcmp (s, "hash-algo", 9))
+             && !(n == 5 && !memcmp (s, "label", 5))
+             && !(n == 15 && !memcmp (s, "random-override", 15)))
+           break;
+       }
+      if (!l2)
+        {
+          rc = GPG_ERR_NO_OBJ; /* No cadr for the data object. */
+          goto leave;
+        }
+
+      /* Extract sublist identifier.  */
+      xfree (name);
+      name = sexp_nth_string (l2, 0);
+      if (!name)
+        {
+          rc = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
+          goto leave;
+        }
+    }
+  else /* No flags - flag as legacy structure.  */
+    parsed_flags |= PUBKEY_FLAG_LEGACYRESULT;
+
+  for (i=0; algo_names[i]; i++)
+    if (!stricmp (name, algo_names[i]))
+      break;
+  if (!algo_names[i])
+    {
+      rc = GPG_ERR_CONFLICT; /* "enc-val" uses an unexpected algo. */
+      goto leave;
+    }
+
+  *r_parms = l2;
+  l2 = NULL;
+  ctx->flags |= parsed_flags;
+  rc = 0;
+
+ leave:
+  xfree (name);
+  sexp_release (l2);
+  sexp_release (l1);
+  return rc;
+}
+
+
+/* Initialize an encoding context.  */
+void
+_gcry_pk_util_init_encoding_ctx (struct pk_encoding_ctx *ctx,
+                                 enum pk_operation op,
+                                 unsigned int nbits)
+{
+  ctx->op = op;
+  ctx->nbits = nbits;
+  ctx->encoding = PUBKEY_ENC_UNKNOWN;
+  ctx->flags = 0;
+  ctx->hash_algo = GCRY_MD_SHA1;
+  ctx->label = NULL;
+  ctx->labellen = 0;
+  ctx->saltlen = 20;
+  ctx->verify_cmp = NULL;
+  ctx->verify_arg = NULL;
+}
+
+/* Free a context initialzied by _gcry_pk_util_init_encoding_ctx.  */
+void
+_gcry_pk_util_free_encoding_ctx (struct pk_encoding_ctx *ctx)
+{
+  xfree (ctx->label);
+}
+
+
+/* Take the hash value and convert into an MPI, suitable for
+   passing to the low level functions.  We currently support the
+   old style way of passing just a MPI and the modern interface which
+   allows to pass flags so that we can choose between raw and pkcs1
+   padding - may be more padding options later.
+
+   (<mpi>)
+   or
+   (data
+    [(flags [raw, direct, pkcs1, oaep, pss, no-blinding, rfc6979, eddsa])]
+    [(hash <algo> <value>)]
+    [(value <text>)]
+    [(hash-algo <algo>)]
+    [(label <label>)]
+    [(salt-length <length>)]
+    [(random-override <data>)]
+   )
+
+   Either the VALUE or the HASH element must be present for use
+   with signatures.  VALUE is used for encryption.
+
+   HASH-ALGO is specific to OAEP and EDDSA.
+
+   LABEL is specific to OAEP.
+
+   SALT-LENGTH is for PSS.
+
+   RANDOM-OVERRIDE is used to replace random nonces for regression
+   testing.  */
+gcry_err_code_t
+_gcry_pk_util_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
+                           struct pk_encoding_ctx *ctx)
+{
+  gcry_err_code_t rc = 0;
+  gcry_sexp_t ldata, lhash, lvalue;
+  size_t n;
+  const char *s;
+  int unknown_flag = 0;
+  int parsed_flags = 0;
+
+  *ret_mpi = NULL;
+  ldata = sexp_find_token (input, "data", 0);
+  if (!ldata)
+    { /* assume old style */
+      *ret_mpi = sexp_nth_mpi (input, 0, 0);
+      return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
+    }
+
+  /* See whether there is a flags list.  */
+  {
+    gcry_sexp_t lflags = sexp_find_token (ldata, "flags", 0);
+    if (lflags)
+      {
+        if (_gcry_pk_util_parse_flaglist (lflags,
+                                          &parsed_flags, &ctx->encoding))
+          unknown_flag = 1;
+        sexp_release (lflags);
+      }
+  }
+
+  if (ctx->encoding == PUBKEY_ENC_UNKNOWN)
+    ctx->encoding = PUBKEY_ENC_RAW; /* default to raw */
+
+  /* Get HASH or MPI */
+  lhash = sexp_find_token (ldata, "hash", 0);
+  lvalue = lhash? NULL : sexp_find_token (ldata, "value", 0);
+
+  if (!(!lhash ^ !lvalue))
+    rc = GPG_ERR_INV_OBJ; /* none or both given */
+  else if (unknown_flag)
+    rc = GPG_ERR_INV_FLAG;
+  else if (ctx->encoding == PUBKEY_ENC_RAW
+           && (parsed_flags & PUBKEY_FLAG_EDDSA))
+    {
+      /* Prepare for EdDSA.  */
+      gcry_sexp_t list;
+      void *value;
+      size_t valuelen;
+
+      if (!lvalue)
+        {
+          rc = GPG_ERR_INV_OBJ;
+          goto leave;
+        }
+      /* Get HASH-ALGO. */
+      list = sexp_find_token (ldata, "hash-algo", 0);
+      if (list)
+        {
+          s = sexp_nth_data (list, 1, &n);
+          if (!s)
+            rc = GPG_ERR_NO_OBJ;
+          else
+            {
+              ctx->hash_algo = get_hash_algo (s, n);
+              if (!ctx->hash_algo)
+                rc = GPG_ERR_DIGEST_ALGO;
+            }
+          sexp_release (list);
+        }
+      else
+        rc = GPG_ERR_INV_OBJ;
+      if (rc)
+        goto leave;
+
+      /* Get VALUE.  */
+      value = sexp_nth_buffer (lvalue, 1, &valuelen);
+      if (!value)
+        {
+          /* We assume that a zero length message is meant by
+             "(value)".  This is commonly used by test vectors.  Note
+             that S-expression do not allow zero length items. */
+          valuelen = 0;
+          value = xtrymalloc (1);
+          if (!value)
+            rc = gpg_err_code_from_syserror ();
+        }
+      else if ((valuelen * 8) < valuelen)
+        {
+          xfree (value);
+          rc = GPG_ERR_TOO_LARGE;
+        }
+      if (rc)
+        goto leave;
+
+      /* Note that mpi_set_opaque takes ownership of VALUE.  */
+      *ret_mpi = mpi_set_opaque (NULL, value, valuelen*8);
+    }
+  else if (ctx->encoding == PUBKEY_ENC_RAW && lhash
+           && ((parsed_flags & PUBKEY_FLAG_RAW_FLAG)
+               || (parsed_flags & PUBKEY_FLAG_RFC6979)))
+    {
+      /* Raw encoding along with a hash element.  This is commonly
+         used for DSA.  For better backward error compatibility we
+         allow this only if either the rfc6979 flag has been given or
+         the raw flags was explicitly given.  */
+      if (sexp_length (lhash) != 3)
+        rc = GPG_ERR_INV_OBJ;
+      else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
+        rc = GPG_ERR_INV_OBJ;
+      else
+        {
+          void *value;
+          size_t valuelen;
+
+         ctx->hash_algo = get_hash_algo (s, n);
+          if (!ctx->hash_algo)
+            rc = GPG_ERR_DIGEST_ALGO;
+          else if (!(value=sexp_nth_buffer (lhash, 2, &valuelen)))
+            rc = GPG_ERR_INV_OBJ;
+          else if ((valuelen * 8) < valuelen)
+            {
+              xfree (value);
+              rc = GPG_ERR_TOO_LARGE;
+            }
+          else
+            *ret_mpi = mpi_set_opaque (NULL, value, valuelen*8);
+        }
+    }
+  else if (ctx->encoding == PUBKEY_ENC_RAW && lvalue)
+    {
+      /* RFC6969 may only be used with the a hash value and not the
+         MPI based value.  */
+      if (parsed_flags & PUBKEY_FLAG_RFC6979)
+        {
+          rc = GPG_ERR_CONFLICT;
+          goto leave;
+        }
+
+      /* Get the value */
+      *ret_mpi = sexp_nth_mpi (lvalue, 1, GCRYMPI_FMT_USG);
+      if (!*ret_mpi)
+        rc = GPG_ERR_INV_OBJ;
+    }
+  else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lvalue
+          && ctx->op == PUBKEY_OP_ENCRYPT)
+    {
+      const void * value;
+      size_t valuelen;
+      gcry_sexp_t list;
+      void *random_override = NULL;
+      size_t random_override_len = 0;
+
+      if ( !(value=sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
+        rc = GPG_ERR_INV_OBJ;
+      else
+        {
+          /* Get optional RANDOM-OVERRIDE.  */
+          list = sexp_find_token (ldata, "random-override", 0);
+          if (list)
+            {
+              s = sexp_nth_data (list, 1, &n);
+              if (!s)
+                rc = GPG_ERR_NO_OBJ;
+              else if (n > 0)
+                {
+                  random_override = xtrymalloc (n);
+                  if (!random_override)
+                    rc = gpg_err_code_from_syserror ();
+                  else
+                    {
+                      memcpy (random_override, s, n);
+                      random_override_len = n;
+                    }
+                }
+              sexp_release (list);
+              if (rc)
+                goto leave;
+            }
+
+          rc = _gcry_rsa_pkcs1_encode_for_enc (ret_mpi, ctx->nbits,
+                                               value, valuelen,
+                                               random_override,
+                                               random_override_len);
+          xfree (random_override);
+        }
+    }
+  else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lhash
+          && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY))
+    {
+      if (sexp_length (lhash) != 3)
+        rc = GPG_ERR_INV_OBJ;
+      else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
+        rc = GPG_ERR_INV_OBJ;
+      else
+        {
+          const void * value;
+          size_t valuelen;
+
+         ctx->hash_algo = get_hash_algo (s, n);
+
+          if (!ctx->hash_algo)
+            rc = GPG_ERR_DIGEST_ALGO;
+          else if ( !(value=sexp_nth_data (lhash, 2, &valuelen))
+                    || !valuelen )
+            rc = GPG_ERR_INV_OBJ;
+          else
+           rc = _gcry_rsa_pkcs1_encode_for_sig (ret_mpi, ctx->nbits,
+                                                 value, valuelen,
+                                                 ctx->hash_algo);
+        }
+    }
+  else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue
+          && ctx->op == PUBKEY_OP_ENCRYPT)
+    {
+      const void * value;
+      size_t valuelen;
+
+      if ( !(value=sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
+       rc = GPG_ERR_INV_OBJ;
+      else
+       {
+         gcry_sexp_t list;
+          void *random_override = NULL;
+          size_t random_override_len = 0;
+
+         /* Get HASH-ALGO. */
+         list = sexp_find_token (ldata, "hash-algo", 0);
+         if (list)
+           {
+             s = sexp_nth_data (list, 1, &n);
+             if (!s)
+               rc = GPG_ERR_NO_OBJ;
+             else
+               {
+                 ctx->hash_algo = get_hash_algo (s, n);
+                 if (!ctx->hash_algo)
+                   rc = GPG_ERR_DIGEST_ALGO;
+               }
+             sexp_release (list);
+             if (rc)
+               goto leave;
+           }
+
+         /* Get LABEL. */
+         list = sexp_find_token (ldata, "label", 0);
+         if (list)
+           {
+             s = sexp_nth_data (list, 1, &n);
+             if (!s)
+               rc = GPG_ERR_NO_OBJ;
+             else if (n > 0)
+               {
+                 ctx->label = xtrymalloc (n);
+                 if (!ctx->label)
+                   rc = gpg_err_code_from_syserror ();
+                 else
+                   {
+                     memcpy (ctx->label, s, n);
+                     ctx->labellen = n;
+                   }
+               }
+             sexp_release (list);
+             if (rc)
+               goto leave;
+           }
+          /* Get optional RANDOM-OVERRIDE.  */
+          list = sexp_find_token (ldata, "random-override", 0);
+          if (list)
+            {
+              s = sexp_nth_data (list, 1, &n);
+              if (!s)
+                rc = GPG_ERR_NO_OBJ;
+              else if (n > 0)
+                {
+                  random_override = xtrymalloc (n);
+                  if (!random_override)
+                    rc = gpg_err_code_from_syserror ();
+                  else
+                    {
+                      memcpy (random_override, s, n);
+                      random_override_len = n;
+                    }
+                }
+              sexp_release (list);
+              if (rc)
+                goto leave;
+            }
+
+         rc = _gcry_rsa_oaep_encode (ret_mpi, ctx->nbits, ctx->hash_algo,
+                                      value, valuelen,
+                                      ctx->label, ctx->labellen,
+                                      random_override, random_override_len);
+
+          xfree (random_override);
+       }
+    }
+  else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
+          && ctx->op == PUBKEY_OP_SIGN)
+    {
+      if (sexp_length (lhash) != 3)
+        rc = GPG_ERR_INV_OBJ;
+      else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
+        rc = GPG_ERR_INV_OBJ;
+      else
+        {
+          const void * value;
+          size_t valuelen;
+          void *random_override = NULL;
+          size_t random_override_len = 0;
+
+         ctx->hash_algo = get_hash_algo (s, n);
+
+          if (!ctx->hash_algo)
+            rc = GPG_ERR_DIGEST_ALGO;
+          else if ( !(value=sexp_nth_data (lhash, 2, &valuelen))
+                    || !valuelen )
+            rc = GPG_ERR_INV_OBJ;
+          else
+           {
+             gcry_sexp_t list;
+
+             /* Get SALT-LENGTH. */
+             list = sexp_find_token (ldata, "salt-length", 0);
+             if (list)
+               {
+                 s = sexp_nth_data (list, 1, &n);
+                 if (!s)
+                   {
+                     rc = GPG_ERR_NO_OBJ;
+                     goto leave;
+                   }
+                 ctx->saltlen = (unsigned int)strtoul (s, NULL, 10);
+                 sexp_release (list);
+               }
+
+              /* Get optional RANDOM-OVERRIDE.  */
+              list = sexp_find_token (ldata, "random-override", 0);
+              if (list)
+                {
+                  s = sexp_nth_data (list, 1, &n);
+                  if (!s)
+                    rc = GPG_ERR_NO_OBJ;
+                  else if (n > 0)
+                    {
+                      random_override = xtrymalloc (n);
+                      if (!random_override)
+                        rc = gpg_err_code_from_syserror ();
+                      else
+                        {
+                          memcpy (random_override, s, n);
+                          random_override_len = n;
+                        }
+                    }
+                  sexp_release (list);
+                  if (rc)
+                    goto leave;
+                }
+
+              /* Encode the data.  (NBITS-1 is due to 8.1.1, step 1.) */
+             rc = _gcry_rsa_pss_encode (ret_mpi, ctx->nbits - 1,
+                                         ctx->hash_algo,
+                                         value, valuelen, ctx->saltlen,
+                                         random_override, random_override_len);
+
+              xfree (random_override);
+           }
+        }
+    }
+  else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
+          && ctx->op == PUBKEY_OP_VERIFY)
+    {
+      if (sexp_length (lhash) != 3)
+        rc = GPG_ERR_INV_OBJ;
+      else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
+        rc = GPG_ERR_INV_OBJ;
+      else
+        {
+         ctx->hash_algo = get_hash_algo (s, n);
+
+          if (!ctx->hash_algo)
+            rc = GPG_ERR_DIGEST_ALGO;
+         else
+           {
+             *ret_mpi = sexp_nth_mpi (lhash, 2, GCRYMPI_FMT_USG);
+             if (!*ret_mpi)
+               rc = GPG_ERR_INV_OBJ;
+             ctx->verify_cmp = pss_verify_cmp;
+             ctx->verify_arg = *ret_mpi;
+           }
+       }
+    }
+  else
+    rc = GPG_ERR_CONFLICT;
+
+ leave:
+  sexp_release (ldata);
+  sexp_release (lhash);
+  sexp_release (lvalue);
+
+  if (!rc)
+    ctx->flags = parsed_flags;
+  else
+    {
+      xfree (ctx->label);
+      ctx->label = NULL;
+    }
+
+  return rc;
+}
index 9109821..d130388 100644 (file)
@@ -1,6 +1,7 @@
 /* pubkey.c  - pubkey dispatcher
  * Copyright (C) 1998, 1999, 2000, 2002, 2003, 2005,
  *               2007, 2008, 2011 Free Software Foundation, Inc.
+ * Copyright (C) 2013 g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
 #include "mpi.h"
 #include "cipher.h"
 #include "ath.h"
+#include "context.h"
+#include "pubkey-internal.h"
 
 
-static gcry_err_code_t pubkey_decrypt (int algo, gcry_mpi_t *result,
-                                       gcry_mpi_t *data, gcry_mpi_t *skey,
-                                       int flags);
-static gcry_err_code_t pubkey_sign (int algo, gcry_mpi_t *resarr,
-                                    gcry_mpi_t hash, gcry_mpi_t *skey);
-static gcry_err_code_t pubkey_verify (int algo, gcry_mpi_t hash,
-                                      gcry_mpi_t *data, gcry_mpi_t *pkey,
-                                    int (*cmp) (void *, gcry_mpi_t),
-                                      void *opaque);
-
-
-/* A dummy extraspec so that we do not need to tests the extraspec
-   field from the module specification against NULL and instead
-   directly test the respective fields of extraspecs.  */
-static pk_extra_spec_t dummy_extra_spec;
-
-
-/* This is the list of the default public-key ciphers included in
-   libgcrypt.  FIPS_ALLOWED indicated whether the algorithm is used in
-   FIPS mode. */
-static struct pubkey_table_entry
-{
-  gcry_pk_spec_t *pubkey;
-  pk_extra_spec_t *extraspec;
-  unsigned int algorithm;
-  int fips_allowed;
-} pubkey_table[] =
+/* This is the list of the public-key algorithms included in
+   Libgcrypt.  */
+static gcry_pk_spec_t *pubkey_list[] =
   {
-#if USE_RSA
-    { &_gcry_pubkey_spec_rsa,
-      &_gcry_pubkey_extraspec_rsa,   GCRY_PK_RSA, 1},
+#if USE_ECC
+    &_gcry_pubkey_spec_ecc,
 #endif
-#if USE_ELGAMAL
-    { &_gcry_pubkey_spec_elg,
-      &_gcry_pubkey_extraspec_elg,    GCRY_PK_ELG   },
-    { &_gcry_pubkey_spec_elg,
-      &_gcry_pubkey_extraspec_elg,    GCRY_PK_ELG_E },
+#if USE_RSA
+    &_gcry_pubkey_spec_rsa,
 #endif
 #if USE_DSA
-    { &_gcry_pubkey_spec_dsa,
-      &_gcry_pubkey_extraspec_dsa,   GCRY_PK_DSA, 1   },
+    &_gcry_pubkey_spec_dsa,
 #endif
-#if USE_ECC
-    { &_gcry_pubkey_spec_ecdsa,
-      &_gcry_pubkey_extraspec_ecdsa, GCRY_PK_ECDSA, 0 },
-    { &_gcry_pubkey_spec_ecdh,
-      &_gcry_pubkey_extraspec_ecdsa, GCRY_PK_ECDH, 0 },
+#if USE_ELGAMAL
+    &_gcry_pubkey_spec_elg,
 #endif
-    { NULL, 0 },
+    NULL
   };
 
-/* List of registered ciphers.  */
-static gcry_module_t pubkeys_registered;
-
-/* This is the lock protecting PUBKEYS_REGISTERED.  */
-static ath_mutex_t pubkeys_registered_lock = ATH_MUTEX_INITIALIZER;;
-
-/* Flag to check whether the default pubkeys have already been
-   registered.  */
-static int default_pubkeys_registered;
-
-/* Convenient macro for registering the default digests.  */
-#define REGISTER_DEFAULT_PUBKEYS                   \
-  do                                               \
-    {                                              \
-      ath_mutex_lock (&pubkeys_registered_lock);   \
-      if (! default_pubkeys_registered)            \
-        {                                          \
-          pk_register_default ();                  \
-          default_pubkeys_registered = 1;          \
-        }                                          \
-      ath_mutex_unlock (&pubkeys_registered_lock); \
-    }                                              \
-  while (0)
-
-/* These dummy functions are used in case a cipher implementation
-   refuses to provide it's own functions.  */
 
-static gcry_err_code_t
-dummy_generate (int algorithm, unsigned int nbits, unsigned long dummy,
-                gcry_mpi_t *skey, gcry_mpi_t **retfactors)
+static int
+map_algo (int algo)
 {
-  (void)algorithm;
-  (void)nbits;
-  (void)dummy;
-  (void)skey;
-  (void)retfactors;
-  fips_signal_error ("using dummy public key function");
-  return GPG_ERR_NOT_IMPLEMENTED;
+ switch (algo)
+   {
+   case GCRY_PK_ECDSA:
+   case GCRY_PK_ECDH:
+     return GCRY_PK_ECC;
+   case GCRY_PK_ELG_E:
+     return GCRY_PK_ELG;
+   default:
+     return algo;
+   }
 }
 
-static gcry_err_code_t
-dummy_check_secret_key (int algorithm, gcry_mpi_t *skey)
-{
-  (void)algorithm;
-  (void)skey;
-  fips_signal_error ("using dummy public key function");
-  return GPG_ERR_NOT_IMPLEMENTED;
-}
 
-static gcry_err_code_t
-dummy_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
-               gcry_mpi_t *pkey, int flags)
-{
-  (void)algorithm;
-  (void)resarr;
-  (void)data;
-  (void)pkey;
-  (void)flags;
-  fips_signal_error ("using dummy public key function");
-  return GPG_ERR_NOT_IMPLEMENTED;
-}
 
-static gcry_err_code_t
-dummy_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
-               gcry_mpi_t *skey, int flags)
+/* Return the spec structure for the public key algorithm ALGO.  For
+   an unknown algorithm NULL is returned.  */
+static gcry_pk_spec_t *
+spec_from_algo (int algo)
 {
-  (void)algorithm;
-  (void)result;
-  (void)data;
-  (void)skey;
-  (void)flags;
-  fips_signal_error ("using dummy public key function");
-  return GPG_ERR_NOT_IMPLEMENTED;
-}
+  int idx;
+  gcry_pk_spec_t *spec;
 
-static gcry_err_code_t
-dummy_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
-            gcry_mpi_t *skey)
-{
-  (void)algorithm;
-  (void)resarr;
-  (void)data;
-  (void)skey;
-  fips_signal_error ("using dummy public key function");
-  return GPG_ERR_NOT_IMPLEMENTED;
-}
+  algo = map_algo (algo);
 
-static gcry_err_code_t
-dummy_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
-              gcry_mpi_t *pkey,
-             int (*cmp) (void *, gcry_mpi_t), void *opaquev)
-{
-  (void)algorithm;
-  (void)hash;
-  (void)data;
-  (void)pkey;
-  (void)cmp;
-  (void)opaquev;
-  fips_signal_error ("using dummy public key function");
-  return GPG_ERR_NOT_IMPLEMENTED;
+  for (idx = 0; (spec = pubkey_list[idx]); idx++)
+    if (algo == spec->algo)
+      return spec;
+  return NULL;
 }
 
-static unsigned
-dummy_get_nbits (int algorithm, gcry_mpi_t *pkey)
-{
-  (void)algorithm;
-  (void)pkey;
-  fips_signal_error ("using dummy public key function");
-  return 0;
-}
 
-/* Internal function.  Register all the pubkeys included in
-   PUBKEY_TABLE.  Returns zero on success or an error code.  */
-static void
-pk_register_default (void)
+/* Return the spec structure for the public key algorithm with NAME.
+   For an unknown name NULL is returned.  */
+static gcry_pk_spec_t *
+spec_from_name (const char *name)
 {
-  gcry_err_code_t err = 0;
-  int i;
+  gcry_pk_spec_t *spec;
+  int idx;
+  const char **aliases;
 
-  for (i = 0; (! err) && pubkey_table[i].pubkey; i++)
+  for (idx=0; (spec = pubkey_list[idx]); idx++)
     {
-#define pubkey_use_dummy(func)                       \
-      if (! pubkey_table[i].pubkey->func)            \
-       pubkey_table[i].pubkey->func = dummy_##func;
-
-      pubkey_use_dummy (generate);
-      pubkey_use_dummy (check_secret_key);
-      pubkey_use_dummy (encrypt);
-      pubkey_use_dummy (decrypt);
-      pubkey_use_dummy (sign);
-      pubkey_use_dummy (verify);
-      pubkey_use_dummy (get_nbits);
-#undef pubkey_use_dummy
-
-      err = _gcry_module_add (&pubkeys_registered,
-                             pubkey_table[i].algorithm,
-                             (void *) pubkey_table[i].pubkey,
-                             (void *) pubkey_table[i].extraspec,
-                              NULL);
+      if (!stricmp (name, spec->name))
+        return spec;
+      for (aliases = spec->aliases; *aliases; aliases++)
+        if (!stricmp (name, *aliases))
+          return spec;
     }
 
-  if (err)
-    BUG ();
-}
-
-/* Internal callback function.  Used via _gcry_module_lookup.  */
-static int
-gcry_pk_lookup_func_name (void *spec, void *data)
-{
-  gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) spec;
-  char *name = (char *) data;
-  const char **aliases = pubkey->aliases;
-  int ret = stricmp (name, pubkey->name);
-
-  while (ret && *aliases)
-    ret = stricmp (name, *aliases++);
-
-  return ! ret;
+  return NULL;
 }
 
-/* Internal function.  Lookup a pubkey entry by it's name.  */
-static gcry_module_t
-gcry_pk_lookup_name (const char *name)
-{
-  gcry_module_t pubkey;
-
-  pubkey = _gcry_module_lookup (pubkeys_registered, (void *) name,
-                               gcry_pk_lookup_func_name);
 
-  return pubkey;
-}
 
-/* Register a new pubkey module whose specification can be found in
-   PUBKEY.  On success, a new algorithm ID is stored in ALGORITHM_ID
-   and a pointer representhing this module is stored in MODULE.  */
-gcry_error_t
-_gcry_pk_register (gcry_pk_spec_t *pubkey,
-                   pk_extra_spec_t *extraspec,
-                   unsigned int *algorithm_id,
-                   gcry_module_t *module)
+/* Given the s-expression SEXP with the first element be either
+ * "private-key" or "public-key" return the spec structure for it.  We
+ * look through the list to find a list beginning with "private-key"
+ * or "public-key" - the first one found is used.  If WANT_PRIVATE is
+ * 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
+ * "private-key" or "public-key" is stored there and the caller must
+ * call gcry_sexp_release on it.
+ */
+static gcry_err_code_t
+spec_from_sexp (gcry_sexp_t sexp, int want_private,
+                gcry_pk_spec_t **r_spec, gcry_sexp_t *r_parms)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  gcry_module_t mod;
-
-  /* We do not support module loading in fips mode.  */
-  if (fips_mode ())
-    return gpg_error (GPG_ERR_NOT_SUPPORTED);
+  gcry_sexp_t list, l2;
+  char *name;
+  gcry_pk_spec_t *spec;
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  err = _gcry_module_add (&pubkeys_registered, 0,
-                         (void *) pubkey,
-                         (void *)(extraspec? extraspec : &dummy_extra_spec),
-                          &mod);
-  ath_mutex_unlock (&pubkeys_registered_lock);
+  *r_spec = NULL;
+  if (r_parms)
+    *r_parms = NULL;
+
+  /* Check that the first element is valid.  If we are looking for a
+     public key but a private key was supplied, we allow the use of
+     the private key anyway.  The rationale for this is that the
+     private key is a superset of the public key.  */
+  list = sexp_find_token (sexp, want_private? "private-key":"public-key", 0);
+  if (!list && !want_private)
+    list = sexp_find_token (sexp, "private-key", 0);
+  if (!list)
+    return GPG_ERR_INV_OBJ; /* Does not contain a key object.  */
 
-  if (! err)
+  l2 = sexp_cadr (list);
+  sexp_release (list);
+  list = l2;
+  name = sexp_nth_string (list, 0);
+  if (!name)
     {
-      *module = mod;
-      *algorithm_id = mod->mod_id;
+      sexp_release ( list );
+      return GPG_ERR_INV_OBJ;      /* Invalid structure of object. */
     }
-
-  return err;
+  spec = spec_from_name (name);
+  xfree (name);
+  if (!spec)
+    {
+      sexp_release (list);
+      return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
+    }
+  *r_spec = spec;
+  if (r_parms)
+    *r_parms = list;
+  else
+    sexp_release (list);
+  return 0;
 }
 
-/* Unregister the pubkey identified by ID, which must have been
-   registered with gcry_pk_register.  */
-void
-gcry_pk_unregister (gcry_module_t module)
-{
-  ath_mutex_lock (&pubkeys_registered_lock);
-  _gcry_module_release (module);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-}
 
+
+/* Disable the use of the algorithm ALGO.  This is not thread safe and
+   should thus be called early.  */
 static void
-release_mpi_array (gcry_mpi_t *array)
+disable_pubkey_algo (int algo)
 {
-  for (; *array; array++)
-    {
-      mpi_free(*array);
-      *array = NULL;
-    }
+  gcry_pk_spec_t *spec = spec_from_algo (algo);
+
+  if (spec)
+    spec->flags.disabled = 1;
 }
 
-/****************
+
+\f
+/*
  * Map a string to the pubkey algo
  */
 int
-gcry_pk_map_name (const char *string)
+_gcry_pk_map_name (const char *string)
 {
-  gcry_module_t pubkey;
-  int algorithm = 0;
+  gcry_pk_spec_t *spec;
 
   if (!string)
     return 0;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = gcry_pk_lookup_name (string);
-  if (pubkey)
-    {
-      algorithm = pubkey->mod_id;
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return algorithm;
+  spec = spec_from_name (string);
+  if (!spec)
+    return 0;
+  if (spec->flags.disabled)
+    return 0;
+  return spec->algo;
 }
 
 
@@ -336,70 +205,14 @@ gcry_pk_map_name (const char *string)
    a string representation of the algorithm name.  For unknown
    algorithm IDs this functions returns "?". */
 const char *
-gcry_pk_algo_name (int algorithm)
-{
-  gcry_module_t pubkey;
-  const char *name;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      name = ((gcry_pk_spec_t *) pubkey->spec)->name;
-      _gcry_module_release (pubkey);
-    }
-  else
-    name = "?";
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return name;
-}
-
-
-/* A special version of gcry_pk_algo name to return the first aliased
-   name of the algorithm.  This is required to adhere to the spki
-   specs where the algorithm names are lowercase. */
-const char *
-_gcry_pk_aliased_algo_name (int algorithm)
-{
-  const char *name = NULL;
-  gcry_module_t module;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (module)
-    {
-      gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) module->spec;
-
-      name = pubkey->aliases? *pubkey->aliases : NULL;
-      if (!name || !*name)
-        name = pubkey->name;
-      _gcry_module_release (module);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return name;
-}
-
-
-static void
-disable_pubkey_algo (int algorithm)
+_gcry_pk_algo_name (int algo)
 {
-  gcry_module_t pubkey;
+  gcry_pk_spec_t *spec;
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      if (! (pubkey-> flags & FLAG_MODULE_DISABLED))
-       pubkey->flags |= FLAG_MODULE_DISABLED;
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
+  spec = spec_from_algo (algo);
+  if (spec)
+    return spec->name;
+  return "?";
 }
 
 
@@ -407,32 +220,22 @@ disable_pubkey_algo (int algorithm)
  * A USE of 0 means: don't care.
  */
 static gcry_err_code_t
-check_pubkey_algo (int algorithm, unsigned use)
+check_pubkey_algo (int algo, unsigned use)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  gcry_pk_spec_t *pubkey;
-  gcry_module_t module;
-
-  REGISTER_DEFAULT_PUBKEYS;
+  gcry_err_code_t err = 0;
+  gcry_pk_spec_t *spec;
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (module)
+  spec = spec_from_algo (algo);
+  if (spec)
     {
-      pubkey = (gcry_pk_spec_t *) module->spec;
-
       if (((use & GCRY_PK_USAGE_SIGN)
-          && (! (pubkey->use & GCRY_PK_USAGE_SIGN)))
+          && (! (spec->use & GCRY_PK_USAGE_SIGN)))
          || ((use & GCRY_PK_USAGE_ENCR)
-             && (! (pubkey->use & GCRY_PK_USAGE_ENCR))))
+             && (! (spec->use & GCRY_PK_USAGE_ENCR))))
        err = GPG_ERR_WRONG_PUBKEY_ALGO;
-      else if (module->flags & FLAG_MODULE_DISABLED)
-       err = GPG_ERR_PUBKEY_ALGO;
-      _gcry_module_release (module);
     }
   else
     err = GPG_ERR_PUBKEY_ALGO;
-  ath_mutex_unlock (&pubkeys_registered_lock);
 
   return err;
 }
@@ -442,2547 +245,96 @@ check_pubkey_algo (int algorithm, unsigned use)
  * Return the number of public key material numbers
  */
 static int
-pubkey_get_npkey (int algorithm)
+pubkey_get_npkey (int algo)
 {
-  gcry_module_t pubkey;
-  int npkey = 0;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      npkey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_pkey);
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
+  gcry_pk_spec_t *spec = spec_from_algo (algo);
 
-  return npkey;
+  return spec? strlen (spec->elements_pkey) : 0;
 }
 
+
 /****************
  * Return the number of secret key material numbers
  */
 static int
-pubkey_get_nskey (int algorithm)
+pubkey_get_nskey (int algo)
 {
-  gcry_module_t pubkey;
-  int nskey = 0;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      nskey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_skey);
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
+  gcry_pk_spec_t *spec = spec_from_algo (algo);
 
-  return nskey;
+  return spec? strlen (spec->elements_skey) : 0;
 }
 
+
 /****************
  * Return the number of signature material numbers
  */
 static int
-pubkey_get_nsig (int algorithm)
+pubkey_get_nsig (int algo)
 {
-  gcry_module_t pubkey;
-  int nsig = 0;
-
-  REGISTER_DEFAULT_PUBKEYS;
+  gcry_pk_spec_t *spec = spec_from_algo (algo);
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      nsig = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_sig);
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return nsig;
+  return spec? strlen (spec->elements_sig) : 0;
 }
 
 /****************
  * Return the number of encryption material numbers
  */
 static int
-pubkey_get_nenc (int algorithm)
-{
-  gcry_module_t pubkey;
-  int nenc = 0;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      nenc = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_enc);
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return nenc;
-}
-
-
-/* Generate a new public key with algorithm ALGORITHM of size NBITS
-   and return it at SKEY.  USE_E depends on the ALGORITHM.  GENPARMS
-   is passed to the algorithm module if it features an extended
-   generation function.  RETFACTOR is used by some algorithms to
-   return certain additional information which are in general not
-   required.
-
-   The function returns the error code number or 0 on success. */
-static gcry_err_code_t
-pubkey_generate (int algorithm,
-                 unsigned int nbits,
-                 unsigned long use_e,
-                 gcry_sexp_t genparms,
-                 gcry_mpi_t *skey, gcry_mpi_t **retfactors,
-                 gcry_sexp_t *r_extrainfo)
-{
-  gcry_err_code_t ec = GPG_ERR_PUBKEY_ALGO;
-  gcry_module_t pubkey;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      pk_extra_spec_t *extraspec = pubkey->extraspec;
-
-      if (extraspec && extraspec->ext_generate)
-        {
-          /* Use the extended generate function.  */
-          ec = extraspec->ext_generate
-            (algorithm, nbits, use_e, genparms, skey, retfactors, r_extrainfo);
-        }
-      else
-        {
-          /* Use the standard generate function.  */
-          ec = ((gcry_pk_spec_t *) pubkey->spec)->generate
-            (algorithm, nbits, use_e, skey, retfactors);
-        }
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return ec;
-}
-
-
-static gcry_err_code_t
-pubkey_check_secret_key (int algorithm, gcry_mpi_t *skey)
-{
-  gcry_err_code_t err = GPG_ERR_PUBKEY_ALGO;
-  gcry_module_t pubkey;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    {
-      err = ((gcry_pk_spec_t *) pubkey->spec)->check_secret_key
-        (algorithm, skey);
-      _gcry_module_release (pubkey);
-    }
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return err;
-}
-
-
-/****************
- * This is the interface to the public key encryption.  Encrypt DATA
- * with PKEY and put it into RESARR which should be an array of MPIs
- * of size PUBKEY_MAX_NENC (or less if the algorithm allows this -
- * check with pubkey_get_nenc() )
- */
-static gcry_err_code_t
-pubkey_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
-                gcry_mpi_t *pkey, int flags)
-{
-  gcry_pk_spec_t *pubkey;
-  gcry_module_t module;
-  gcry_err_code_t rc;
-  int i;
-
-  /* Note: In fips mode DBG_CIPHER will enver evaluate to true but as
-     an extra failsafe protection we explicitly test for fips mode
-     here. */
-  if (DBG_CIPHER && !fips_mode ())
-    {
-      log_debug ("pubkey_encrypt: algo=%d\n", algorithm);
-      for(i = 0; i < pubkey_get_npkey (algorithm); i++)
-       log_mpidump ("  pkey:", pkey[i]);
-      log_mpidump ("  data:", data);
-    }
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (module)
-    {
-      pubkey = (gcry_pk_spec_t *) module->spec;
-      rc = pubkey->encrypt (algorithm, resarr, data, pkey, flags);
-      _gcry_module_release (module);
-      goto ready;
-    }
-  rc = GPG_ERR_PUBKEY_ALGO;
-
- ready:
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  if (!rc && DBG_CIPHER && !fips_mode ())
-    {
-      for(i = 0; i < pubkey_get_nenc (algorithm); i++)
-       log_mpidump("  encr:", resarr[i] );
-    }
-  return rc;
-}
-
-
-/****************
- * This is the interface to the public key decryption.
- * ALGO gives the algorithm to use and this implicitly determines
- * the size of the arrays.
- * result is a pointer to a mpi variable which will receive a
- * newly allocated mpi or NULL in case of an error.
- */
-static gcry_err_code_t
-pubkey_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
-                gcry_mpi_t *skey, int flags)
+pubkey_get_nenc (int algo)
 {
-  gcry_pk_spec_t *pubkey;
-  gcry_module_t module;
-  gcry_err_code_t rc;
-  int i;
-
-  *result = NULL; /* so the caller can always do a mpi_free */
-  if (DBG_CIPHER && !fips_mode ())
-    {
-      log_debug ("pubkey_decrypt: algo=%d\n", algorithm);
-      for(i = 0; i < pubkey_get_nskey (algorithm); i++)
-       log_mpidump ("  skey:", skey[i]);
-      for(i = 0; i < pubkey_get_nenc (algorithm); i++)
-       log_mpidump ("  data:", data[i]);
-    }
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (module)
-    {
-      pubkey = (gcry_pk_spec_t *) module->spec;
-      rc = pubkey->decrypt (algorithm, result, data, skey, flags);
-      _gcry_module_release (module);
-      goto ready;
-    }
-
-  rc = GPG_ERR_PUBKEY_ALGO;
-
- ready:
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  if (!rc && DBG_CIPHER && !fips_mode ())
-    log_mpidump (" plain:", *result);
+  gcry_pk_spec_t *spec = spec_from_algo (algo);
 
-  return rc;
+  return spec? strlen (spec->elements_enc) : 0;
 }
 
 
-/****************
- * This is the interface to the public key signing.
- * Sign data with skey and put the result into resarr which
- * should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the
- * algorithm allows this - check with pubkey_get_nsig() )
- */
-static gcry_err_code_t
-pubkey_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
-             gcry_mpi_t *skey)
-{
-  gcry_pk_spec_t *pubkey;
-  gcry_module_t module;
-  gcry_err_code_t rc;
-  int i;
-
-  if (DBG_CIPHER && !fips_mode ())
-    {
-      log_debug ("pubkey_sign: algo=%d\n", algorithm);
-      for(i = 0; i < pubkey_get_nskey (algorithm); i++)
-       log_mpidump ("  skey:", skey[i]);
-      log_mpidump("  data:", data );
-    }
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (module)
-    {
-      pubkey = (gcry_pk_spec_t *) module->spec;
-      rc = pubkey->sign (algorithm, resarr, data, skey);
-      _gcry_module_release (module);
-      goto ready;
-    }
-
-  rc = GPG_ERR_PUBKEY_ALGO;
+\f
+/*
+   Do a PK encrypt operation
 
- ready:
-  ath_mutex_unlock (&pubkeys_registered_lock);
+   Caller has to provide a public key as the SEXP pkey and data as a
+   SEXP with just one MPI in it. Alternatively S_DATA might be a
+   complex S-Expression, similar to the one used for signature
+   verification.  This provides a flag which allows to handle PKCS#1
+   block type 2 padding.  The function returns a sexp which may be
+   passed to to pk_decrypt.
 
-  if (!rc && DBG_CIPHER && !fips_mode ())
-    for (i = 0; i < pubkey_get_nsig (algorithm); i++)
-      log_mpidump ("   sig:", resarr[i]);
+   Returns: 0 or an errorcode.
 
-  return rc;
-}
+   s_data = See comment for _gcry_pk_util_data_to_mpi
+   s_pkey = <key-as-defined-in-sexp_to_key>
+   r_ciph = (enc-val
+               (<algo>
+                 (<param_name1> <mpi>)
+                 ...
+                 (<param_namen> <mpi>)
+               ))
 
-/****************
- * Verify a public key signature.
- * Return 0 if the signature is good
- */
-static gcry_err_code_t
-pubkey_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
-               gcry_mpi_t *pkey,
-              int (*cmp)(void *, gcry_mpi_t), void *opaquev)
+*/
+gcry_err_code_t
+_gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
 {
-  gcry_pk_spec_t *pubkey;
-  gcry_module_t module;
   gcry_err_code_t rc;
-  int i;
-
-  if (DBG_CIPHER && !fips_mode ())
-    {
-      log_debug ("pubkey_verify: algo=%d\n", algorithm);
-      for (i = 0; i < pubkey_get_npkey (algorithm); i++)
-       log_mpidump ("  pkey", pkey[i]);
-      for (i = 0; i < pubkey_get_nsig (algorithm); i++)
-       log_mpidump ("   sig", data[i]);
-      log_mpidump ("  hash", hash);
-    }
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (module)
-    {
-      pubkey = (gcry_pk_spec_t *) module->spec;
-      rc = pubkey->verify (algorithm, hash, data, pkey, cmp, opaquev);
-      _gcry_module_release (module);
-      goto ready;
-    }
-
-  rc = GPG_ERR_PUBKEY_ALGO;
-
- ready:
-  ath_mutex_unlock (&pubkeys_registered_lock);
-  return rc;
-}
-
-
-/* Turn VALUE into an octet string and store it in an allocated buffer
-   at R_FRAME or - if R_RAME is NULL - copy it into the caller
-   provided buffer SPACE; either SPACE or R_FRAME may be used.  If
-   SPACE if not NULL, the caller must provide a buffer of at least
-   NBYTES.  If the resulting octet string is shorter than NBYTES pad
-   it to the left with zeroes.  If VALUE does not fit into NBYTES
-   return an error code.  */
-static gpg_err_code_t
-octet_string_from_mpi (unsigned char **r_frame, void *space,
-                       gcry_mpi_t value, size_t nbytes)
-{
-  gpg_err_code_t rc;
-  size_t nframe, noff, n;
-  unsigned char *frame;
-
-  if (!r_frame == !space)
-    return GPG_ERR_INV_ARG;  /* Only one may be used.  */
+  gcry_pk_spec_t *spec;
+  gcry_sexp_t keyparms;
 
-  if (r_frame)
-    *r_frame = NULL;
+  *r_ciph = NULL;
 
-  rc = gcry_err_code (gcry_mpi_print (GCRYMPI_FMT_USG,
-                                      NULL, 0, &nframe, value));
+  rc = spec_from_sexp (s_pkey, 0, &spec, &keyparms);
   if (rc)
-    return rc;
-  if (nframe > nbytes)
-    return GPG_ERR_TOO_LARGE; /* Value too long to fit into NBYTES.  */
-
-  noff = (nframe < nbytes)? nbytes - nframe : 0;
-  n = nframe + noff;
-  if (space)
-    frame = space;
+    goto leave;
+
+  if (spec->encrypt)
+    rc = spec->encrypt (r_ciph, s_data, keyparms);
   else
-    {
-      frame = mpi_is_secure (value)? gcry_malloc_secure (n) : gcry_malloc (n);
-      if (!frame)
-        {
-          rc = gpg_err_code_from_syserror ();
-          return rc;
-        }
-    }
-  if (noff)
-    memset (frame, 0, noff);
-  nframe += noff;
-  rc = gcry_err_code (gcry_mpi_print (GCRYMPI_FMT_USG,
-                                      frame+noff, nframe-noff, NULL, value));
-  if (rc)
-    {
-      gcry_free (frame);
-      return rc;
-    }
-
-  if (r_frame)
-    *r_frame = frame;
-  return 0;
-}
-
-
-/* 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
-   R_RESULT.  On error the value at R_RESULT is undefined.
-
-   If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as
-   the seed instead of using a random string for it.  This feature is
-   only useful for regression tests.  Note that this value may not
-   contain zero bytes.
-
-   We encode the value in this way:
-
-     0  2  RND(n bytes)  0  VALUE
-
-   0   is a marker we unfortunately can't encode because we return an
-       MPI which strips all leading zeroes.
-   2   is the block type.
-   RND are non-zero random bytes.
-
-   (Note that OpenPGP includes the cipher algorithm and a checksum in
-   VALUE; the caller needs to prepare the value accordingly.)
-  */
-static gcry_err_code_t
-pkcs1_encode_for_encryption (gcry_mpi_t *r_result, unsigned int nbits,
-                            const unsigned char *value, size_t valuelen,
-                             const unsigned char *random_override,
-                             size_t random_override_len)
-{
-  gcry_err_code_t rc = 0;
-  gcry_error_t err;
-  unsigned char *frame = NULL;
-  size_t nframe = (nbits+7) / 8;
-  int i;
-  size_t n;
-  unsigned char *p;
-
-  if (valuelen + 7 > nframe || !nframe)
-    {
-      /* Can't encode a VALUELEN value in a NFRAME bytes frame.  */
-      return GPG_ERR_TOO_SHORT; /* The key is too short.  */
-    }
-
-  if ( !(frame = gcry_malloc_secure (nframe)))
-    return gpg_err_code_from_syserror ();
-
-  n = 0;
-  frame[n++] = 0;
-  frame[n++] = 2; /* block type */
-  i = nframe - 3 - valuelen;
-  gcry_assert (i > 0);
-
-  if (random_override)
-    {
-      int j;
-
-      if (random_override_len != i)
-        {
-          gcry_free (frame);
-          return GPG_ERR_INV_ARG;
-        }
-      /* Check that random does not include a zero byte.  */
-      for (j=0; j < random_override_len; j++)
-        if (!random_override[j])
-          {
-            gcry_free (frame);
-            return GPG_ERR_INV_ARG;
-          }
-      memcpy (frame + n, random_override, random_override_len);
-      n += random_override_len;
-    }
-  else
-    {
-      p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
-      /* Replace zero bytes by new values. */
-      for (;;)
-        {
-          int j, k;
-          unsigned char *pp;
-
-          /* Count the zero bytes. */
-          for (j=k=0; j < i; j++)
-            {
-              if (!p[j])
-                k++;
-            }
-          if (!k)
-            break; /* Okay: no (more) zero bytes. */
-
-          k += k/128 + 3; /* Better get some more. */
-          pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
-          for (j=0; j < i && k; )
-            {
-              if (!p[j])
-                p[j] = pp[--k];
-              if (p[j])
-                j++;
-            }
-          gcry_free (pp);
-        }
-      memcpy (frame+n, p, i);
-      n += i;
-      gcry_free (p);
-    }
-
-  frame[n++] = 0;
-  memcpy (frame+n, value, valuelen);
-  n += valuelen;
-  gcry_assert (n == nframe);
-
-  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 2 encoded data", *r_result);
-  gcry_free (frame);
-
-  return rc;
-}
-
-
-/* Decode a plaintext in VALUE assuming pkcs#1 block type 2 padding.
-   NBITS is the size of the secret key.  On success the result is
-   stored as a newly allocated buffer at R_RESULT and its valid length at
-   R_RESULTLEN.  On error NULL is stored at R_RESULT.  */
-static gcry_err_code_t
-pkcs1_decode_for_encryption (unsigned char **r_result, size_t *r_resultlen,
-                             unsigned int nbits, gcry_mpi_t value)
-{
-  gcry_error_t err;
-  unsigned char *frame = NULL;
-  size_t nframe = (nbits+7) / 8;
-  size_t n;
-
-  *r_result = NULL;
-
-  if ( !(frame = gcry_malloc_secure (nframe)))
-    return gpg_err_code_from_syserror ();
-
-  err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &n, value);
-  if (err)
-    {
-      gcry_free (frame);
-      return gcry_err_code (err);
-    }
-
-  nframe = n; /* Set NFRAME to the actual length.  */
-
-  /* FRAME = 0x00 || 0x02 || PS || 0x00 || M
-
-     pkcs#1 requires that the first byte is zero.  Our MPIs usually
-     strip leading zero bytes; thus we are not able to detect them.
-     However due to the way gcry_mpi_print is implemented we may see
-     leading zero bytes nevertheless.  We handle this by making the
-     first zero byte optional.  */
-  if (nframe < 4)
-    {
-      gcry_free (frame);
-      return GPG_ERR_ENCODING_PROBLEM;  /* Too short.  */
-    }
-  n = 0;
-  if (!frame[0])
-    n++;
-  if (frame[n++] != 0x02)
-    {
-      gcry_free (frame);
-      return GPG_ERR_ENCODING_PROBLEM;  /* Wrong block type.  */
-    }
-
-  /* Skip the non-zero random bytes and the terminating zero byte.  */
-  for (; n < nframe && frame[n] != 0x00; n++)
-    ;
-  if (n+1 >= nframe)
-    {
-      gcry_free (frame);
-      return GPG_ERR_ENCODING_PROBLEM; /* No zero byte.  */
-    }
-  n++; /* Skip the zero byte.  */
-
-  /* To avoid an extra allocation we reuse the frame buffer.  The only
-     caller of this function will anyway free the result soon.  */
-  memmove (frame, frame + n, nframe - n);
-  *r_result = frame;
-  *r_resultlen = nframe - n;
-
-  if (DBG_CIPHER)
-    log_printhex ("value extracted from PKCS#1 block type 2 encoded data:",
-                  *r_result, *r_resultlen);
-
-  return 0;
-}
-
-
-/* Encode {VALUE,VALUELEN} for an NBITS keys and hash algorith ALGO
-   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  ASN(asnlen bytes) 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.
-   ASN is the DER encoding of the hash algorithm; along with the VALUE
-       it yields a valid DER encoding.
-
-   (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.)
-*/
-static gcry_err_code_t
-pkcs1_encode_for_signature (gcry_mpi_t *r_result, unsigned int nbits,
-                           const unsigned char *value, size_t valuelen,
-                           int algo)
-{
-  gcry_err_code_t rc = 0;
-  gcry_error_t err;
-  byte asn[100];
-  byte *frame = NULL;
-  size_t nframe = (nbits+7) / 8;
-  int i;
-  size_t n;
-  size_t asnlen, dlen;
-
-  asnlen = DIM(asn);
-  dlen = gcry_md_get_algo_dlen (algo);
-
-  if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
-    {
-      /* We don't have yet all of the above algorithms.  */
-      return GPG_ERR_NOT_IMPLEMENTED;
-    }
-
-  if ( valuelen != dlen )
-    {
-      /* Hash value does not match the length of digest for
-         the given algorithm.  */
-      return GPG_ERR_CONFLICT;
-    }
-
-  if ( !dlen || dlen + asnlen + 4 > nframe)
-    {
-      /* Can't encode an DLEN byte digest MD into an NFRAME byte
-         frame.  */
-      return GPG_ERR_TOO_SHORT;
-    }
-
-  if ( !(frame = gcry_malloc (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 - asnlen - 3 ;
-  gcry_assert (i > 1);
-  memset (frame+n, 0xff, i );
-  n += i;
-  frame[n++] = 0;
-  memcpy (frame+n, asn, asnlen);
-  n += asnlen;
-  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);
-  gcry_free (frame);
-
-  return rc;
-}
-
-
-/* Mask generation function for OAEP.  See RFC-3447 B.2.1.  */
-static gcry_err_code_t
-mgf1 (unsigned char *output, size_t outlen, unsigned char *seed, size_t seedlen,
-      int algo)
-{
-  size_t dlen, nbytes, n;
-  int idx;
-  gcry_md_hd_t hd;
-  gcry_error_t err;
-
-  err = gcry_md_open (&hd, algo, 0);
-  if (err)
-    return gpg_err_code (err);
-
-  dlen = gcry_md_get_algo_dlen (algo);
-
-  /* We skip step 1 which would be assert(OUTLEN <= 2^32).  The loop
-     in step 3 is merged with step 4 by concatenating no more octets
-     than what would fit into OUTPUT.  The ceiling for the counter IDX
-     is implemented indirectly.  */
-  nbytes = 0;  /* Step 2.  */
-  idx = 0;
-  while ( nbytes < outlen )
-    {
-      unsigned char c[4], *digest;
-
-      if (idx)
-        gcry_md_reset (hd);
-
-      c[0] = (idx >> 24) & 0xFF;
-      c[1] = (idx >> 16) & 0xFF;
-      c[2] = (idx >> 8) & 0xFF;
-      c[3] = idx & 0xFF;
-      idx++;
-
-      gcry_md_write (hd, seed, seedlen);
-      gcry_md_write (hd, c, 4);
-      digest = gcry_md_read (hd, 0);
-
-      n = (outlen - nbytes < dlen)? (outlen - nbytes) : dlen;
-      memcpy (output+nbytes, digest, n);
-      nbytes += n;
-    }
-
-  gcry_md_close (hd);
-  return GPG_ERR_NO_ERROR;
-}
-
-
-/* RFC-3447 (pkcs#1 v2.1) OAEP encoding.  NBITS is the length of the
-   key measured in bits.  ALGO is the hash function; it must be a
-   valid and usable algorithm.  {VALUE,VALUELEN} is the message to
-   encrypt.  {LABEL,LABELLEN} is the optional label to be associated
-   with the message, if LABEL is NULL the default is to use the empty
-   string as label.  On success the encoded ciphertext is returned at
-   R_RESULT.
-
-   If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as
-   the seed instead of using a random string for it.  This feature is
-   only useful for regression tests.
-
-   Here is figure 1 from the RFC depicting the process:
-
-                             +----------+---------+-------+
-                        DB = |  lHash   |    PS   |   M   |
-                             +----------+---------+-------+
-                                            |
-                  +----------+              V
-                  |   seed   |--> MGF ---> xor
-                  +----------+              |
-                        |                   |
-               +--+     V                   |
-               |00|    xor <----- MGF <-----|
-               +--+     |                   |
-                 |      |                   |
-                 V      V                   V
-               +--+----------+----------------------------+
-         EM =  |00|maskedSeed|          maskedDB          |
-               +--+----------+----------------------------+
-  */
-static gcry_err_code_t
-oaep_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
-             const unsigned char *value, size_t valuelen,
-             const unsigned char *label, size_t labellen,
-             const void *random_override, size_t random_override_len)
-{
-  gcry_err_code_t rc = 0;
-  gcry_error_t err;
-  unsigned char *frame = NULL;
-  size_t nframe = (nbits+7) / 8;
-  unsigned char *p;
-  size_t hlen;
-  size_t n;
-
-  *r_result = NULL;
-
-  /* Set defaults for LABEL.  */
-  if (!label || !labellen)
-    {
-      label = (const unsigned char*)"";
-      labellen = 0;
-    }
-
-  hlen = gcry_md_get_algo_dlen (algo);
-
-  /* We skip step 1a which would be to check that LABELLEN is not
-     greater than 2^61-1.  See rfc-3447 7.1.1. */
-
-  /* Step 1b.  Note that the obsolete rfc-2437 uses the check:
-     valuelen > nframe - 2 * hlen - 1 .  */
-  if (valuelen > nframe - 2 * hlen - 2 || !nframe)
-    {
-      /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
-      return GPG_ERR_TOO_SHORT; /* The key is too short.  */
-    }
-
-  /* Allocate the frame.  */
-  frame = gcry_calloc_secure (1, nframe);
-  if (!frame)
-    return gpg_err_code_from_syserror ();
-
-  /* Step 2a: Compute the hash of the label.  We store it in the frame
-     where later the maskedDB will commence.  */
-  gcry_md_hash_buffer (algo, frame + 1 + hlen, label, labellen);
-
-  /* Step 2b: Set octet string to zero.  */
-  /* This has already been done while allocating FRAME.  */
-
-  /* Step 2c: Create DB by concatenating lHash, PS, 0x01 and M.  */
-  n = nframe - valuelen - 1;
-  frame[n] = 0x01;
-  memcpy (frame + n + 1, value, valuelen);
-
-  /* Step 3d: Generate seed.  We store it where the maskedSeed will go
-     later. */
-  if (random_override)
-    {
-      if (random_override_len != hlen)
-        {
-          gcry_free (frame);
-          return GPG_ERR_INV_ARG;
-        }
-      memcpy (frame + 1, random_override, hlen);
-    }
-  else
-    gcry_randomize (frame + 1, hlen, GCRY_STRONG_RANDOM);
-
-  /* Step 2e and 2f: Create maskedDB.  */
-  {
-    unsigned char *dmask;
-
-    dmask = gcry_malloc_secure (nframe - hlen - 1);
-    if (!dmask)
-      {
-        rc = gpg_err_code_from_syserror ();
-        gcry_free (frame);
-        return rc;
-      }
-    rc = mgf1 (dmask, nframe - hlen - 1, frame+1, hlen, algo);
-    if (rc)
-      {
-        gcry_free (dmask);
-        gcry_free (frame);
-        return rc;
-      }
-    for (n = 1 + hlen, p = dmask; n < nframe; n++)
-      frame[n] ^= *p++;
-    gcry_free (dmask);
-  }
-
-  /* Step 2g and 2h: Create maskedSeed.  */
-  {
-    unsigned char *smask;
-
-    smask = gcry_malloc_secure (hlen);
-    if (!smask)
-      {
-        rc = gpg_err_code_from_syserror ();
-        gcry_free (frame);
-        return rc;
-      }
-    rc = mgf1 (smask, hlen, frame + 1 + hlen, nframe - hlen - 1, algo);
-    if (rc)
-      {
-        gcry_free (smask);
-        gcry_free (frame);
-        return rc;
-      }
-    for (n = 1, p = smask; n < 1 + hlen; n++)
-      frame[n] ^= *p++;
-    gcry_free (smask);
-  }
-
-  /* Step 2i: Concatenate 0x00, maskedSeed and maskedDB.  */
-  /* This has already been done by using in-place operations.  */
-
-  /* Convert the stuff into an MPI as expected by the caller.  */
-  err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, nframe, NULL);
-  if (err)
-    rc = gcry_err_code (err);
-  else if (DBG_CIPHER)
-    log_mpidump ("OAEP encoded data", *r_result);
-  gcry_free (frame);
-
-  return rc;
-}
-
-
-/* RFC-3447 (pkcs#1 v2.1) OAEP decoding.  NBITS is the length of the
-   key measured in bits.  ALGO is the hash function; it must be a
-   valid and usable algorithm.  VALUE is the raw decrypted message
-   {LABEL,LABELLEN} is the optional label to be associated with the
-   message, if LABEL is NULL the default is to use the empty string as
-   label.  On success the plaintext is returned as a newly allocated
-   buffer at R_RESULT; its valid length is stored at R_RESULTLEN.  On
-   error NULL is stored at R_RESULT.  */
-static gcry_err_code_t
-oaep_decode (unsigned char **r_result, size_t *r_resultlen,
-             unsigned int nbits, int algo,
-             gcry_mpi_t value, const unsigned char *label, size_t labellen)
-{
-  gcry_err_code_t rc;
-  unsigned char *frame = NULL; /* Encoded messages (EM).  */
-  unsigned char *masked_seed;  /* Points into FRAME.  */
-  unsigned char *masked_db;    /* Points into FRAME.  */
-  unsigned char *seed = NULL;  /* Allocated space for the seed and DB.  */
-  unsigned char *db;           /* Points into SEED.  */
-  unsigned char *lhash = NULL; /* Hash of the label.  */
-  size_t nframe;               /* Length of the ciphertext (EM).  */
-  size_t hlen;                 /* Length of the hash digest.  */
-  size_t db_len;               /* Length of DB and masked_db.  */
-  size_t nkey = (nbits+7)/8;   /* Length of the key in bytes.  */
-  int failed = 0;              /* Error indicator.  */
-  size_t n;
-
-  *r_result = NULL;
-
-  /* This code is implemented as described by rfc-3447 7.1.2.  */
-
-  /* Set defaults for LABEL.  */
-  if (!label || !labellen)
-    {
-      label = (const unsigned char*)"";
-      labellen = 0;
-    }
-
-  /* Get the length of the digest.  */
-  hlen = gcry_md_get_algo_dlen (algo);
-
-  /* Hash the label right away.  */
-  lhash = gcry_malloc (hlen);
-  if (!lhash)
-    return gpg_err_code_from_syserror ();
-  gcry_md_hash_buffer (algo, lhash, label, labellen);
-
-  /* Turn the MPI into an octet string.  If the octet string is
-     shorter than the key we pad it to the left with zeroes.  This may
-     happen due to the leading zero in OAEP frames and due to the
-     following random octets (seed^mask) which may have leading zero
-     bytes.  This all is needed to cope with our leading zeroes
-     suppressing MPI implementation.  The code implictly implements
-     Step 1b (bail out if NFRAME != N).  */
-  rc = octet_string_from_mpi (&frame, NULL, value, nkey);
-  if (rc)
-    {
-      gcry_free (lhash);
-      return GPG_ERR_ENCODING_PROBLEM;
-    }
-  nframe = nkey;
-
-  /* Step 1c: Check that the key is long enough.  */
-  if ( nframe < 2 * hlen + 2 )
-    {
-      gcry_free (frame);
-      gcry_free (lhash);
-      return GPG_ERR_ENCODING_PROBLEM;
-    }
-
-  /* Step 2 has already been done by the caller and the
-     gcry_mpi_aprint above.  */
-
-  /* Allocate space for SEED and DB.  */
-  seed = gcry_malloc_secure (nframe - 1);
-  if (!seed)
-    {
-      rc = gpg_err_code_from_syserror ();
-      gcry_free (frame);
-      gcry_free (lhash);
-      return rc;
-    }
-  db = seed + hlen;
-
-  /* To avoid choosen 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.  */
-
-  /* Step 3a: Hash the label.  */
-  /* This has already been done.  */
-
-  /* Step 3b: Separate the encoded message.  */
-  masked_seed = frame + 1;
-  masked_db   = frame + 1 + hlen;
-  db_len      = nframe - 1 - hlen;
-
-  /* Step 3c and 3d: seed = maskedSeed ^ mgf(maskedDB, hlen).  */
-  if (mgf1 (seed, hlen, masked_db, db_len, algo))
-    failed = 1;
-  for (n = 0; n < hlen; n++)
-    seed[n] ^= masked_seed[n];
-
-  /* Step 3e and 3f: db = maskedDB ^ mgf(seed, db_len).  */
-  if (mgf1 (db, db_len, seed, hlen, algo))
-    failed = 1;
-  for (n = 0; n < db_len; n++)
-    db[n] ^= masked_db[n];
-
-  /* Step 3g: Check lhash, an possible empty padding string terminated
-     by 0x01 and the first byte of EM being 0.  */
-  if (memcmp (lhash, db, hlen))
-    failed = 1;
-  for (n = hlen; n < db_len; n++)
-    if (db[n] == 0x01)
-      break;
-  if (n == db_len)
-    failed = 1;
-  if (frame[0])
-    failed = 1;
-
-  gcry_free (lhash);
-  gcry_free (frame);
-  if (failed)
-    {
-      gcry_free (seed);
-      return GPG_ERR_ENCODING_PROBLEM;
-    }
-
-  /* Step 4: Output M.  */
-  /* To avoid an extra allocation we reuse the seed buffer.  The only
-     caller of this function will anyway free the result soon.  */
-  n++;
-  memmove (seed, db + n, db_len - n);
-  *r_result = seed;
-  *r_resultlen = db_len - n;
-  seed = NULL;
-
-  if (DBG_CIPHER)
-    log_printhex ("value extracted from OAEP encoded data:",
-                  *r_result, *r_resultlen);
-
-  return 0;
-}
-
-
-/* RFC-3447 (pkcs#1 v2.1) PSS encoding.  Encode {VALUE,VALUELEN} for
-   an NBITS key.  Note that VALUE is already the mHash from the
-   picture below.  ALGO is a valid hash algorithm and SALTLEN is the
-   length of salt to be used.  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
-   the salt instead of using a random string for the salt.  This
-   feature is only useful for regression tests.
-
-   Here is figure 2 from the RFC (errata 595 applied) depicting the
-   process:
-
-                                  +-----------+
-                                  |     M     |
-                                  +-----------+
-                                        |
-                                        V
-                                      Hash
-                                        |
-                                        V
-                          +--------+----------+----------+
-                     M' = |Padding1|  mHash   |   salt   |
-                          +--------+----------+----------+
-                                         |
-               +--------+----------+     V
-         DB =  |Padding2| salt     |   Hash
-               +--------+----------+     |
-                         |               |
-                         V               |    +----+
-                        xor <--- MGF <---|    |0xbc|
-                         |               |    +----+
-                         |               |      |
-                         V               V      V
-               +-------------------+----------+----+
-         EM =  |    maskedDB       |     H    |0xbc|
-               +-------------------+----------+----+
-
-  */
-static gcry_err_code_t
-pss_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
-           const unsigned char *value, size_t valuelen, int saltlen,
-            const void *random_override, size_t random_override_len)
-{
-  gcry_err_code_t rc = 0;
-  gcry_error_t err;
-  size_t hlen;                 /* Length of the hash digest.  */
-  unsigned char *em = NULL;    /* Encoded message.  */
-  size_t emlen = (nbits+7)/8;  /* Length in bytes of EM.  */
-  unsigned char *h;            /* Points into EM.  */
-  unsigned char *buf = NULL;   /* Help buffer.  */
-  size_t buflen;               /* Length of BUF.  */
-  unsigned char *mhash;        /* Points into BUF.  */
-  unsigned char *salt;         /* Points into BUF.  */
-  unsigned char *dbmask;       /* Points into BUF.  */
-  unsigned char *p;
-  size_t n;
-
-  /* This code is implemented as described by rfc-3447 9.1.1.  */
-
-  /* Get the length of the digest.  */
-  hlen = gcry_md_get_algo_dlen (algo);
-  gcry_assert (hlen);  /* We expect a valid ALGO here.  */
-
-  /* Allocate a help buffer and setup some pointers.  */
-  buflen = 8 + hlen + saltlen + (emlen - hlen - 1);
-  buf = gcry_malloc (buflen);
-  if (!buf)
-    {
-      rc = gpg_err_code_from_syserror ();
-      goto leave;
-    }
-  mhash = buf + 8;
-  salt  = mhash + hlen;
-  dbmask= salt + saltlen;
-
-  /* Step 2: That would be: mHash = Hash(M) but our input is already
-     mHash thus we do only a consistency check and copy to MHASH.  */
-  if (valuelen != hlen)
-    {
-      rc = GPG_ERR_INV_LENGTH;
-      goto leave;
-    }
-  memcpy (mhash, value, hlen);
-
-  /* Step 3: Check length constraints.  */
-  if (emlen < hlen + saltlen + 2)
-    {
-      rc = GPG_ERR_TOO_SHORT;
-      goto leave;
-    }
-
-  /* Allocate space for EM.  */
-  em = gcry_malloc (emlen);
-  if (!em)
-    {
-      rc = gpg_err_code_from_syserror ();
-      goto leave;
-    }
-  h = em + emlen - 1 - hlen;
-
-  /* Step 4: Create a salt.  */
-  if (saltlen)
-    {
-      if (random_override)
-        {
-          if (random_override_len != saltlen)
-            {
-              rc = GPG_ERR_INV_ARG;
-              goto leave;
-            }
-          memcpy (salt, random_override, saltlen);
-        }
-      else
-        gcry_randomize (salt, saltlen, GCRY_STRONG_RANDOM);
-    }
-
-  /* Step 5 and 6: M' = Hash(Padding1 || mHash || salt).  */
-  memset (buf, 0, 8);  /* Padding.  */
-  gcry_md_hash_buffer (algo, h, buf, 8 + hlen + saltlen);
-
-  /* Step 7 and 8: DB = PS || 0x01 || salt.  */
-  /* Note that we use EM to store DB and later Xor in-place.  */
-  p = em + emlen - 1 - hlen - saltlen - 1;
-  memset (em, 0, p - em);
-  *p++ = 0x01;
-  memcpy (p, salt, saltlen);
-
-  /* Step 9: dbmask = MGF(H, emlen - hlen - 1).  */
-  mgf1 (dbmask, emlen - hlen - 1, h, hlen, algo);
-
-  /* Step 10: maskedDB = DB ^ dbMask */
-  for (n = 0, p = dbmask; n < emlen - hlen - 1; n++, p++)
-    em[n] ^= *p;
-
-  /* Step 11: Set the leftmost bits to zero.  */
-  em[0] &= 0xFF >> (8 * emlen - nbits);
-
-  /* Step 12: EM = maskedDB || H || 0xbc.  */
-  em[emlen-1] = 0xbc;
-
-  /* Convert EM into an MPI.  */
-  err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, em, emlen, NULL);
-  if (err)
-    rc = gcry_err_code (err);
-  else if (DBG_CIPHER)
-    log_mpidump ("PSS encoded data", *r_result);
-
- leave:
-  if (em)
-    {
-      wipememory (em, emlen);
-      gcry_free (em);
-    }
-  if (buf)
-    {
-      wipememory (buf, buflen);
-      gcry_free (buf);
-    }
-  return rc;
-}
-
-
-/* Verify a signature assuming PSS padding.  VALUE is the hash of the
-   message (mHash) encoded as an MPI; its length must match the digest
-   length of ALGO.  ENCODED is the output of the RSA public key
-   function (EM).  NBITS is the size of the public key.  ALGO is the
-   hash algorithm and SALTLEN is the length of the used salt.  The
-   function returns 0 on success or on error code.  */
-static gcry_err_code_t
-pss_verify (gcry_mpi_t value, gcry_mpi_t encoded, unsigned int nbits, int algo,
-            size_t saltlen)
-{
-  gcry_err_code_t rc = 0;
-  size_t hlen;                 /* Length of the hash digest.  */
-  unsigned char *em = NULL;    /* Encoded message.  */
-  size_t emlen = (nbits+7)/8;  /* Length in bytes of EM.  */
-  unsigned char *salt;         /* Points into EM.  */
-  unsigned char *h;            /* Points into EM.  */
-  unsigned char *buf = NULL;   /* Help buffer.  */
-  size_t buflen;               /* Length of BUF.  */
-  unsigned char *dbmask;       /* Points into BUF.  */
-  unsigned char *mhash;        /* Points into BUF.  */
-  unsigned char *p;
-  size_t n;
-
-  /* This code is implemented as described by rfc-3447 9.1.2.  */
-
-  /* Get the length of the digest.  */
-  hlen = gcry_md_get_algo_dlen (algo);
-  gcry_assert (hlen);  /* We expect a valid ALGO here.  */
-
-  /* Allocate a help buffer and setup some pointers.
-     This buffer is used for two purposes:
-        +------------------------------+-------+
-     1. | dbmask                       | mHash |
-        +------------------------------+-------+
-           emlen - hlen - 1              hlen
-
-        +----------+-------+---------+-+-------+
-     2. | padding1 | mHash | salt    | | mHash |
-        +----------+-------+---------+-+-------+
-             8       hlen    saltlen     hlen
-  */
-  buflen = 8 + hlen + saltlen;
-  if (buflen < emlen - hlen - 1)
-    buflen = emlen - hlen - 1;
-  buflen += hlen;
-  buf = gcry_malloc (buflen);
-  if (!buf)
-    {
-      rc = gpg_err_code_from_syserror ();
-      goto leave;
-    }
-  dbmask = buf;
-  mhash = buf + buflen - hlen;
-
-  /* Step 2: That would be: mHash = Hash(M) but our input is already
-     mHash thus we only need to convert VALUE into MHASH.  */
-  rc = octet_string_from_mpi (NULL, mhash, value, hlen);
-  if (rc)
-    goto leave;
-
-  /* Convert the signature into an octet string.  */
-  rc = octet_string_from_mpi (&em, NULL, encoded, emlen);
-  if (rc)
-    goto leave;
-
-  /* Step 3: Check length of EM.  Because we internally use MPI
-     functions we can't do this properly; EMLEN is always the length
-     of the key because octet_string_from_mpi needs to left pad the
-     result with zero to cope with the fact that our MPIs suppress all
-     leading zeroes.  Thus what we test here are merely the digest and
-     salt lengths to the key.  */
-  if (emlen < hlen + saltlen + 2)
-    {
-      rc = GPG_ERR_TOO_SHORT; /* For the hash and saltlen.  */
-      goto leave;
-    }
-
-  /* Step 4: Check last octet.  */
-  if (em[emlen - 1] != 0xbc)
-    {
-      rc = GPG_ERR_BAD_SIGNATURE;
-      goto leave;
-    }
-
-  /* Step 5: Split EM.  */
-  h = em + emlen - 1 - hlen;
-
-  /* Step 6: Check the leftmost bits.  */
-  if ((em[0] & ~(0xFF >> (8 * emlen - nbits))))
-    {
-      rc = GPG_ERR_BAD_SIGNATURE;
-      goto leave;
-    }
-
-  /* Step 7: dbmask = MGF(H, emlen - hlen - 1).  */
-  mgf1 (dbmask, emlen - hlen - 1, h, hlen, algo);
-
-  /* Step 8: maskedDB = DB ^ dbMask.  */
-  for (n = 0, p = dbmask; n < emlen - hlen - 1; n++, p++)
-    em[n] ^= *p;
-
-  /* Step 9: Set leftmost bits in DB to zero.  */
-  em[0] &= 0xFF >> (8 * emlen - nbits);
-
-  /* Step 10: Check the padding of DB.  */
-  for (n = 0; n < emlen - hlen - saltlen - 2 && !em[n]; n++)
-    ;
-  if (n != emlen - hlen - saltlen - 2 || em[n++] != 1)
-    {
-      rc = GPG_ERR_BAD_SIGNATURE;
-      goto leave;
-    }
-
-  /* Step 11: Extract salt from DB.  */
-  salt = em + n;
-
-  /* Step 12:  M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt */
-  memset (buf, 0, 8);
-  memcpy (buf+8, mhash, hlen);
-  memcpy (buf+8+hlen, salt, saltlen);
-
-  /* Step 13:  H' = Hash(M').  */
-  gcry_md_hash_buffer (algo, buf, buf, 8 + hlen + saltlen);
-
-  /* Step 14:  Check H == H'.   */
-  rc = memcmp (h, buf, hlen) ? GPG_ERR_BAD_SIGNATURE : GPG_ERR_NO_ERROR;
-
- leave:
-  if (em)
-    {
-      wipememory (em, emlen);
-      gcry_free (em);
-    }
-  if (buf)
-    {
-      wipememory (buf, buflen);
-      gcry_free (buf);
-    }
-  return rc;
-}
-
-
-/* Callback for the pubkey algorithm code to verify PSS signatures.
-   OPAQUE is the data provided by the actual caller.  The meaning of
-   TMP depends on the actual algorithm (but there is only RSA); now
-   for RSA it is the output of running the public key function on the
-   input.  */
-static int
-pss_verify_cmp (void *opaque, gcry_mpi_t tmp)
-{
-  struct pk_encoding_ctx *ctx = opaque;
-  gcry_mpi_t hash = ctx->verify_arg;
-
-  return pss_verify (hash, tmp, ctx->nbits - 1, ctx->hash_algo, ctx->saltlen);
-}
-
-
-/* Internal function.   */
-static gcry_err_code_t
-sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names,
-                      gcry_mpi_t *elements, const char *algo_name)
-{
-  gcry_err_code_t err = 0;
-  int i, idx;
-  const char *name;
-  gcry_sexp_t list;
-
-  for (name = element_names, idx = 0; *name && !err; name++, idx++)
-    {
-      list = gcry_sexp_find_token (key_sexp, name, 1);
-      if (!list)
-       elements[idx] = NULL;
-      else
-       {
-         elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
-         gcry_sexp_release (list);
-         if (!elements[idx])
-           err = GPG_ERR_INV_OBJ;
-       }
-    }
-
-  if (!err)
-    {
-      /* Check that all elements are available.  */
-      for (name = element_names, idx = 0; *name; name++, idx++)
-        if (!elements[idx])
-          break;
-      if (*name)
-        {
-          err = GPG_ERR_NO_OBJ;
-          /* Some are missing.  Before bailing out we test for
-             optional parameters.  */
-          if (algo_name && !strcmp (algo_name, "RSA")
-              && !strcmp (element_names, "nedpqu") )
-            {
-              /* This is RSA.  Test whether we got N, E and D and that
-                 the optional P, Q and U are all missing.  */
-              if (elements[0] && elements[1] && elements[2]
-                  && !elements[3] && !elements[4] && !elements[5])
-                err = 0;
-            }
-        }
-    }
-
-
-  if (err)
-    {
-      for (i = 0; i < idx; i++)
-        if (elements[i])
-          gcry_free (elements[i]);
-    }
-  return err;
-}
-
-
-/* Internal function used for ecc.  Note, that this function makes use
-   of its intimate knowledge about the ECC parameters from ecc.c. */
-static gcry_err_code_t
-sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names,
-                           gcry_mpi_t *elements, pk_extra_spec_t *extraspec)
-
-{
-  gcry_err_code_t err = 0;
-  int idx;
-  const char *name;
-  gcry_sexp_t list;
-
-  /* Clear the array for easier error cleanup. */
-  for (name = element_names, idx = 0; *name; name++, idx++)
-    elements[idx] = NULL;
-  gcry_assert (idx >= 5); /* We know that ECC has at least 5 elements
-                             (params only) or 6 (full public key).  */
-  if (idx == 5)
-    elements[5] = NULL;   /* Extra clear for the params only case.  */
-
-
-  /* Init the array with the available curve parameters. */
-  for (name = element_names, idx = 0; *name && !err; name++, idx++)
-    {
-      list = gcry_sexp_find_token (key_sexp, name, 1);
-      if (!list)
-       elements[idx] = NULL;
-      else
-       {
-         elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
-         gcry_sexp_release (list);
-         if (!elements[idx])
-            {
-              err = GPG_ERR_INV_OBJ;
-              goto leave;
-            }
-       }
-    }
-
-  /* Check whether a curve parameter has been given and then fill any
-     missing elements.  */
-  list = gcry_sexp_find_token (key_sexp, "curve", 5);
-  if (list)
-    {
-      if (extraspec->get_param)
-        {
-          char *curve;
-          gcry_mpi_t params[6];
-
-          for (idx = 0; idx < DIM(params); idx++)
-            params[idx] = NULL;
-
-          curve = _gcry_sexp_nth_string (list, 1);
-          gcry_sexp_release (list);
-          if (!curve)
-            {
-              /* No curve name given (or out of core). */
-              err = GPG_ERR_INV_OBJ;
-              goto leave;
-            }
-          err = extraspec->get_param (curve, params);
-          gcry_free (curve);
-          if (err)
-            goto leave;
-
-          for (idx = 0; idx < DIM(params); idx++)
-            {
-              if (!elements[idx])
-                elements[idx] = params[idx];
-              else
-                mpi_free (params[idx]);
-            }
-        }
-      else
-        {
-          gcry_sexp_release (list);
-          err = GPG_ERR_INV_OBJ; /* "curve" given but ECC not supported. */
-          goto leave;
-        }
-    }
-
-  /* Check that all parameters are known.  */
-  for (name = element_names, idx = 0; *name; name++, idx++)
-    if (!elements[idx])
-      {
-        err = GPG_ERR_NO_OBJ;
-        goto leave;
-      }
-
- leave:
-  if (err)
-    {
-      for (name = element_names, idx = 0; *name; name++, idx++)
-        if (elements[idx])
-          gcry_free (elements[idx]);
-    }
-  return err;
-}
-
-
-
-/****************
- * Convert a S-Exp with either a private or a public key to our
- * internal format. Currently we do only support the following
- * algorithms:
- *    dsa
- *    rsa
- *    openpgp-dsa
- *    openpgp-rsa
- *    openpgp-elg
- *    openpgp-elg-sig
- *    ecdsa
- *    ecdh
- * Provide a SE with the first element be either "private-key" or
- * or "public-key". It is followed by a list with its first element
- * be one of the above algorithm identifiers and the remaning
- * elements are pairs with parameter-id and value.
- * NOTE: we look through the list to find a list beginning with
- * "private-key" or "public-key" - the first one found is used.
- *
- * If OVERRIDE_ELEMS is not NULL those elems override the parameter
- * specification taken from the module.  This ise used by
- * gcry_pk_get_curve.
- *
- * Returns: A pointer to an allocated array of MPIs if the return value is
- *         zero; the caller has to release this array.
- *
- * Example of a DSA public key:
- *  (private-key
- *    (dsa
- *     (p <mpi>)
- *     (g <mpi>)
- *     (y <mpi>)
- *     (x <mpi>)
- *    )
- *  )
- * The <mpi> are expected to be in GCRYMPI_FMT_USG
- */
-static gcry_err_code_t
-sexp_to_key (gcry_sexp_t sexp, int want_private, const char *override_elems,
-             gcry_mpi_t **retarray, gcry_module_t *retalgo)
-{
-  gcry_err_code_t err = 0;
-  gcry_sexp_t list, l2;
-  char *name;
-  const char *elems;
-  gcry_mpi_t *array;
-  gcry_module_t module;
-  gcry_pk_spec_t *pubkey;
-  pk_extra_spec_t *extraspec;
-  int is_ecc;
-
-  /* Check that the first element is valid.  */
-  list = gcry_sexp_find_token (sexp,
-                               want_private? "private-key":"public-key", 0);
-  if (!list)
-    return GPG_ERR_INV_OBJ; /* Does not contain a key object.  */
-
-  l2 = gcry_sexp_cadr( list );
-  gcry_sexp_release ( list );
-  list = l2;
-  name = _gcry_sexp_nth_string (list, 0);
-  if (!name)
-    {
-      gcry_sexp_release ( list );
-      return GPG_ERR_INV_OBJ;      /* Invalid structure of object. */
-    }
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = gcry_pk_lookup_name (name);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  /* Fixme: We should make sure that an ECC key is always named "ecc"
-     and not "ecdsa".  "ecdsa" should be used for the signature
-     itself.  We need a function to test whether an algorithm given
-     with a key is compatible with an application of the key (signing,
-     encryption).  For RSA this is easy, but ECC is the first
-     algorithm which has many flavours.  */
-  is_ecc = ( !strcmp (name, "ecdsa")
-             || !strcmp (name, "ecdh")
-             || !strcmp (name, "ecc") );
-  gcry_free (name);
-
-  if (!module)
-    {
-      gcry_sexp_release (list);
-      return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
-    }
-  else
-    {
-      pubkey = (gcry_pk_spec_t *) module->spec;
-      extraspec = module->extraspec;
-    }
-
-  if (override_elems)
-    elems = override_elems;
-  else if (want_private)
-    elems = pubkey->elements_skey;
-  else
-    elems = pubkey->elements_pkey;
-  array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
-  if (!array)
-    err = gpg_err_code_from_syserror ();
-  if (!err)
-    {
-      if (is_ecc)
-        err = sexp_elements_extract_ecc (list, elems, array, extraspec);
-      else
-        err = sexp_elements_extract (list, elems, array, pubkey->name);
-    }
-
-  gcry_sexp_release (list);
-
-  if (err)
-    {
-      gcry_free (array);
-
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
-  else
-    {
-      *retarray = array;
-      *retalgo = module;
-    }
-
-  return err;
-}
-
-
-static gcry_err_code_t
-sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray,
-            gcry_module_t *retalgo)
-{
-  gcry_err_code_t err = 0;
-  gcry_sexp_t list, l2;
-  char *name;
-  const char *elems;
-  gcry_mpi_t *array;
-  gcry_module_t module;
-  gcry_pk_spec_t *pubkey;
-
-  /* Check that the first element is valid.  */
-  list = gcry_sexp_find_token( sexp, "sig-val" , 0 );
-  if (!list)
-    return GPG_ERR_INV_OBJ; /* Does not contain a signature value object.  */
-
-  l2 = gcry_sexp_nth (list, 1);
-  if (!l2)
-    {
-      gcry_sexp_release (list);
-      return GPG_ERR_NO_OBJ;   /* No cadr for the sig object.  */
-    }
-  name = _gcry_sexp_nth_string (l2, 0);
-  if (!name)
-    {
-      gcry_sexp_release (list);
-      gcry_sexp_release (l2);
-      return GPG_ERR_INV_OBJ;  /* Invalid structure of object.  */
-    }
-  else if (!strcmp (name, "flags"))
-    {
-      /* Skip flags, since they are not used but here just for the
-        sake of consistent S-expressions.  */
-      gcry_free (name);
-      gcry_sexp_release (l2);
-      l2 = gcry_sexp_nth (list, 2);
-      if (!l2)
-       {
-         gcry_sexp_release (list);
-         return GPG_ERR_INV_OBJ;
-       }
-      name = _gcry_sexp_nth_string (l2, 0);
-    }
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = gcry_pk_lookup_name (name);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-  gcry_free (name);
-  name = NULL;
-
-  if (!module)
-    {
-      gcry_sexp_release (l2);
-      gcry_sexp_release (list);
-      return GPG_ERR_PUBKEY_ALGO;  /* Unknown algorithm. */
-    }
-  else
-    pubkey = (gcry_pk_spec_t *) module->spec;
-
-  elems = pubkey->elements_sig;
-  array = gcry_calloc (strlen (elems) + 1 , sizeof *array );
-  if (!array)
-    err = gpg_err_code_from_syserror ();
-
-  if (!err)
-    err = sexp_elements_extract (list, elems, array, NULL);
-
-  gcry_sexp_release (l2);
-  gcry_sexp_release (list);
-
-  if (err)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-
-      gcry_free (array);
-    }
-  else
-    {
-      *retarray = array;
-      *retalgo = module;
-    }
-
-  return err;
-}
-
-static inline int
-get_hash_algo (const char *s, size_t n)
-{
-  static const struct { const char *name; int algo; } hashnames[] = {
-    { "sha1",   GCRY_MD_SHA1 },
-    { "md5",    GCRY_MD_MD5 },
-    { "sha256", GCRY_MD_SHA256 },
-    { "ripemd160", GCRY_MD_RMD160 },
-    { "rmd160", GCRY_MD_RMD160 },
-    { "sha384", GCRY_MD_SHA384 },
-    { "sha512", GCRY_MD_SHA512 },
-    { "sha224", GCRY_MD_SHA224 },
-    { "md2",    GCRY_MD_MD2 },
-    { "md4",    GCRY_MD_MD4 },
-    { "tiger",  GCRY_MD_TIGER },
-    { "haval",  GCRY_MD_HAVAL },
-    { NULL, 0 }
-  };
-  int algo;
-  int i;
-
-  for (i=0; hashnames[i].name; i++)
-    {
-      if ( strlen (hashnames[i].name) == n
-          && !memcmp (hashnames[i].name, s, n))
-       break;
-    }
-  if (hashnames[i].name)
-    algo = hashnames[i].algo;
-  else
-    {
-      /* In case of not listed or dynamically allocated hash
-        algorithm we fall back to this somewhat slower
-        method.  Further, it also allows to use OIDs as
-        algorithm names. */
-      char *tmpname;
-
-      tmpname = gcry_malloc (n+1);
-      if (!tmpname)
-       algo = 0;  /* Out of core - silently give up.  */
-      else
-       {
-         memcpy (tmpname, s, n);
-         tmpname[n] = 0;
-         algo = gcry_md_map_name (tmpname);
-         gcry_free (tmpname);
-       }
-    }
-  return algo;
-}
-
-
-/****************
- * Take sexp and return an array of MPI as used for our internal decrypt
- * function.
- * s_data = (enc-val
- *           [(flags [raw, pkcs1, oaep, no-blinding])]
- *           [(hash-algo <algo>)]
- *           [(label <label>)]
- *           (<algo>
- *             (<param_name1> <mpi>)
- *             ...
- *             (<param_namen> <mpi>)
- *           ))
- * HASH-ALGO and LABEL are specific to OAEP.
- * RET_MODERN is set to true when at least an empty flags list has been found.
- * CTX is used to return encoding information; it may be NULL in which
- * case raw encoding is used.
- */
-static gcry_err_code_t
-sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
-             int *ret_modern, int *flags, struct pk_encoding_ctx *ctx)
-{
-  gcry_err_code_t err = 0;
-  gcry_sexp_t list = NULL, l2 = NULL;
-  gcry_pk_spec_t *pubkey = NULL;
-  gcry_module_t module = NULL;
-  char *name = NULL;
-  size_t n;
-  int parsed_flags = 0;
-  const char *elems;
-  gcry_mpi_t *array = NULL;
-
-  *ret_modern = 0;
-
-  /* Check that the first element is valid.  */
-  list = gcry_sexp_find_token (sexp, "enc-val" , 0);
-  if (!list)
-    {
-      err = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object.  */
-      goto leave;
-    }
-
-  l2 = gcry_sexp_nth (list, 1);
-  if (!l2)
-    {
-      err = GPG_ERR_NO_OBJ; /* No cdr for the data object.  */
-      goto leave;
-    }
-
-  /* Extract identifier of sublist.  */
-  name = _gcry_sexp_nth_string (l2, 0);
-  if (!name)
-    {
-      err = GPG_ERR_INV_OBJ; /* Invalid structure of object.  */
-      goto leave;
-    }
-
-  if (!strcmp (name, "flags"))
-    {
-      /* There is a flags element - process it.  */
-      const char *s;
-      int i;
-
-      *ret_modern = 1;
-      for (i = gcry_sexp_length (l2) - 1; i > 0; i--)
-        {
-          s = gcry_sexp_nth_data (l2, i, &n);
-          if (! s)
-            ; /* Not a data element - ignore.  */
-          else if (n == 3 && !memcmp (s, "raw", 3)
-                   && ctx->encoding == PUBKEY_ENC_UNKNOWN)
-            ctx->encoding = PUBKEY_ENC_RAW;
-          else if (n == 5 && !memcmp (s, "pkcs1", 5)
-                   && ctx->encoding == PUBKEY_ENC_UNKNOWN)
-           ctx->encoding = PUBKEY_ENC_PKCS1;
-          else if (n == 4 && !memcmp (s, "oaep", 4)
-                   && ctx->encoding == PUBKEY_ENC_UNKNOWN)
-           ctx->encoding = PUBKEY_ENC_OAEP;
-          else if (n == 3 && !memcmp (s, "pss", 3)
-                   && ctx->encoding == PUBKEY_ENC_UNKNOWN)
-           {
-             err = GPG_ERR_CONFLICT;
-             goto leave;
-           }
-          else if (n == 11 && ! memcmp (s, "no-blinding", 11))
-            parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
-          else
-            {
-              err = GPG_ERR_INV_FLAG;
-              goto leave;
-            }
-        }
-      gcry_sexp_release (l2);
-
-      /* Get the OAEP parameters HASH-ALGO and LABEL, if any. */
-      if (ctx->encoding == PUBKEY_ENC_OAEP)
-       {
-         /* Get HASH-ALGO. */
-         l2 = gcry_sexp_find_token (list, "hash-algo", 0);
-         if (l2)
-           {
-             s = gcry_sexp_nth_data (l2, 1, &n);
-             if (!s)
-               err = GPG_ERR_NO_OBJ;
-             else
-               {
-                 ctx->hash_algo = get_hash_algo (s, n);
-                 if (!ctx->hash_algo)
-                   err = GPG_ERR_DIGEST_ALGO;
-               }
-             gcry_sexp_release (l2);
-             if (err)
-               goto leave;
-           }
-
-         /* Get LABEL. */
-         l2 = gcry_sexp_find_token (list, "label", 0);
-         if (l2)
-           {
-             s = gcry_sexp_nth_data (l2, 1, &n);
-             if (!s)
-               err = GPG_ERR_NO_OBJ;
-             else if (n > 0)
-               {
-                 ctx->label = gcry_malloc (n);
-                 if (!ctx->label)
-                   err = gpg_err_code_from_syserror ();
-                 else
-                   {
-                     memcpy (ctx->label, s, n);
-                     ctx->labellen = n;
-                   }
-               }
-             gcry_sexp_release (l2);
-             if (err)
-               goto leave;
-           }
-       }
-
-      /* Get the next which has the actual data - skip HASH-ALGO and LABEL. */
-      for (i = 2; (l2 = gcry_sexp_nth (list, i)) != NULL; i++)
-       {
-         s = gcry_sexp_nth_data (l2, 0, &n);
-         if (!(n == 9 && !memcmp (s, "hash-algo", 9))
-             && !(n == 5 && !memcmp (s, "label", 5))
-             && !(n == 15 && !memcmp (s, "random-override", 15)))
-           break;
-         gcry_sexp_release (l2);
-       }
-
-      if (!l2)
-        {
-          err = GPG_ERR_NO_OBJ; /* No cdr for the data object. */
-          goto leave;
-        }
-
-      /* Extract sublist identifier.  */
-      gcry_free (name);
-      name = _gcry_sexp_nth_string (l2, 0);
-      if (!name)
-        {
-          err = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
-          goto leave;
-        }
-
-      gcry_sexp_release (list);
-      list = l2;
-      l2 = NULL;
-    }
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = gcry_pk_lookup_name (name);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  if (!module)
-    {
-      err = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
-      goto leave;
-    }
-  pubkey = (gcry_pk_spec_t *) module->spec;
-
-  elems = pubkey->elements_enc;
-  array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
-  if (!array)
-    {
-      err = gpg_err_code_from_syserror ();
-      goto leave;
-    }
-
-  err = sexp_elements_extract (list, elems, array, NULL);
-
- leave:
-  gcry_sexp_release (list);
-  gcry_sexp_release (l2);
-  gcry_free (name);
-
-  if (err)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-      gcry_free (array);
-      gcry_free (ctx->label);
-      ctx->label = NULL;
-    }
-  else
-    {
-      *retarray = array;
-      *retalgo = module;
-      *flags = parsed_flags;
-    }
-
-  return err;
-}
-
-/* Take the hash value and convert into an MPI, suitable for
-   passing to the low level functions.  We currently support the
-   old style way of passing just a MPI and the modern interface which
-   allows to pass flags so that we can choose between raw and pkcs1
-   padding - may be more padding options later.
-
-   (<mpi>)
-   or
-   (data
-    [(flags [raw, pkcs1, oaep, pss, no-blinding])]
-    [(hash <algo> <value>)]
-    [(value <text>)]
-    [(hash-algo <algo>)]
-    [(label <label>)]
-    [(salt-length <length>)]
-    [(random-override <data>)]
-   )
-
-   Either the VALUE or the HASH element must be present for use
-   with signatures.  VALUE is used for encryption.
-
-   HASH-ALGO and LABEL are specific to OAEP.
-
-   SALT-LENGTH is for PSS.
-
-   RANDOM-OVERRIDE is used to replace random nonces for regression
-   testing.  */
-static gcry_err_code_t
-sexp_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
-                 struct pk_encoding_ctx *ctx)
-{
-  gcry_err_code_t rc = 0;
-  gcry_sexp_t ldata, lhash, lvalue;
-  int i;
-  size_t n;
-  const char *s;
-  int unknown_flag=0;
-  int parsed_flags = 0;
-
-  *ret_mpi = NULL;
-  ldata = gcry_sexp_find_token (input, "data", 0);
-  if (!ldata)
-    { /* assume old style */
-      *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0);
-      return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
-    }
-
-  /* see whether there is a flags object */
-  {
-    gcry_sexp_t lflags = gcry_sexp_find_token (ldata, "flags", 0);
-    if (lflags)
-      { /* parse the flags list. */
-        for (i=gcry_sexp_length (lflags)-1; i > 0; i--)
-          {
-            s = gcry_sexp_nth_data (lflags, i, &n);
-            if (!s)
-              ; /* not a data element*/
-            else if ( n == 3 && !memcmp (s, "raw", 3)
-                      && ctx->encoding == PUBKEY_ENC_UNKNOWN)
-              ctx->encoding = PUBKEY_ENC_RAW;
-            else if ( n == 5 && !memcmp (s, "pkcs1", 5)
-                      && ctx->encoding == PUBKEY_ENC_UNKNOWN)
-              ctx->encoding = PUBKEY_ENC_PKCS1;
-            else if ( n == 4 && !memcmp (s, "oaep", 4)
-                      && ctx->encoding == PUBKEY_ENC_UNKNOWN)
-              ctx->encoding = PUBKEY_ENC_OAEP;
-            else if ( n == 3 && !memcmp (s, "pss", 3)
-                      && ctx->encoding == PUBKEY_ENC_UNKNOWN)
-              ctx->encoding = PUBKEY_ENC_PSS;
-           else if (n == 11 && ! memcmp (s, "no-blinding", 11))
-             parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
-            else
-              unknown_flag = 1;
-          }
-        gcry_sexp_release (lflags);
-      }
-  }
-
-  if (ctx->encoding == PUBKEY_ENC_UNKNOWN)
-    ctx->encoding = PUBKEY_ENC_RAW; /* default to raw */
-
-  /* Get HASH or MPI */
-  lhash = gcry_sexp_find_token (ldata, "hash", 0);
-  lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0);
-
-  if (!(!lhash ^ !lvalue))
-    rc = GPG_ERR_INV_OBJ; /* none or both given */
-  else if (unknown_flag)
-    rc = GPG_ERR_INV_FLAG;
-  else if (ctx->encoding == PUBKEY_ENC_RAW && lvalue)
-    {
-      *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, GCRYMPI_FMT_USG);
-      if (!*ret_mpi)
-        rc = GPG_ERR_INV_OBJ;
-    }
-  else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lvalue
-          && ctx->op == PUBKEY_OP_ENCRYPT)
-    {
-      const void * value;
-      size_t valuelen;
-      gcry_sexp_t list;
-      void *random_override = NULL;
-      size_t random_override_len = 0;
-
-      if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
-        rc = GPG_ERR_INV_OBJ;
-      else
-        {
-          /* Get optional RANDOM-OVERRIDE.  */
-          list = gcry_sexp_find_token (ldata, "random-override", 0);
-          if (list)
-            {
-              s = gcry_sexp_nth_data (list, 1, &n);
-              if (!s)
-                rc = GPG_ERR_NO_OBJ;
-              else if (n > 0)
-                {
-                  random_override = gcry_malloc (n);
-                  if (!random_override)
-                    rc = gpg_err_code_from_syserror ();
-                  else
-                    {
-                      memcpy (random_override, s, n);
-                      random_override_len = n;
-                    }
-                }
-              gcry_sexp_release (list);
-              if (rc)
-                goto leave;
-            }
-
-          rc = pkcs1_encode_for_encryption (ret_mpi, ctx->nbits,
-                                            value, valuelen,
-                                            random_override,
-                                            random_override_len);
-          gcry_free (random_override);
-        }
-    }
-  else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lhash
-          && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY))
-    {
-      if (gcry_sexp_length (lhash) != 3)
-        rc = GPG_ERR_INV_OBJ;
-      else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
-        rc = GPG_ERR_INV_OBJ;
-      else
-        {
-          const void * value;
-          size_t valuelen;
-
-         ctx->hash_algo = get_hash_algo (s, n);
-
-          if (!ctx->hash_algo)
-            rc = GPG_ERR_DIGEST_ALGO;
-          else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
-                    || !valuelen )
-            rc = GPG_ERR_INV_OBJ;
-          else
-           rc = pkcs1_encode_for_signature (ret_mpi, ctx->nbits,
-                                            value, valuelen,
-                                            ctx->hash_algo);
-        }
-    }
-  else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue
-          && ctx->op == PUBKEY_OP_ENCRYPT)
-    {
-      const void * value;
-      size_t valuelen;
-
-      if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
-       rc = GPG_ERR_INV_OBJ;
-      else
-       {
-         gcry_sexp_t list;
-          void *random_override = NULL;
-          size_t random_override_len = 0;
-
-         /* Get HASH-ALGO. */
-         list = gcry_sexp_find_token (ldata, "hash-algo", 0);
-         if (list)
-           {
-             s = gcry_sexp_nth_data (list, 1, &n);
-             if (!s)
-               rc = GPG_ERR_NO_OBJ;
-             else
-               {
-                 ctx->hash_algo = get_hash_algo (s, n);
-                 if (!ctx->hash_algo)
-                   rc = GPG_ERR_DIGEST_ALGO;
-               }
-             gcry_sexp_release (list);
-             if (rc)
-               goto leave;
-           }
-
-         /* Get LABEL. */
-         list = gcry_sexp_find_token (ldata, "label", 0);
-         if (list)
-           {
-             s = gcry_sexp_nth_data (list, 1, &n);
-             if (!s)
-               rc = GPG_ERR_NO_OBJ;
-             else if (n > 0)
-               {
-                 ctx->label = gcry_malloc (n);
-                 if (!ctx->label)
-                   rc = gpg_err_code_from_syserror ();
-                 else
-                   {
-                     memcpy (ctx->label, s, n);
-                     ctx->labellen = n;
-                   }
-               }
-             gcry_sexp_release (list);
-             if (rc)
-               goto leave;
-           }
-          /* Get optional RANDOM-OVERRIDE.  */
-          list = gcry_sexp_find_token (ldata, "random-override", 0);
-          if (list)
-            {
-              s = gcry_sexp_nth_data (list, 1, &n);
-              if (!s)
-                rc = GPG_ERR_NO_OBJ;
-              else if (n > 0)
-                {
-                  random_override = gcry_malloc (n);
-                  if (!random_override)
-                    rc = gpg_err_code_from_syserror ();
-                  else
-                    {
-                      memcpy (random_override, s, n);
-                      random_override_len = n;
-                    }
-                }
-              gcry_sexp_release (list);
-              if (rc)
-                goto leave;
-            }
-
-         rc = oaep_encode (ret_mpi, ctx->nbits, ctx->hash_algo,
-                           value, valuelen,
-                           ctx->label, ctx->labellen,
-                            random_override, random_override_len);
-
-          gcry_free (random_override);
-       }
-    }
-  else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
-          && ctx->op == PUBKEY_OP_SIGN)
-    {
-      if (gcry_sexp_length (lhash) != 3)
-        rc = GPG_ERR_INV_OBJ;
-      else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
-        rc = GPG_ERR_INV_OBJ;
-      else
-        {
-          const void * value;
-          size_t valuelen;
-          void *random_override = NULL;
-          size_t random_override_len = 0;
-
-         ctx->hash_algo = get_hash_algo (s, n);
-
-          if (!ctx->hash_algo)
-            rc = GPG_ERR_DIGEST_ALGO;
-          else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
-                    || !valuelen )
-            rc = GPG_ERR_INV_OBJ;
-          else
-           {
-             gcry_sexp_t list;
-
-             /* Get SALT-LENGTH. */
-             list = gcry_sexp_find_token (ldata, "salt-length", 0);
-             if (list)
-               {
-                 s = gcry_sexp_nth_data (list, 1, &n);
-                 if (!s)
-                   {
-                     rc = GPG_ERR_NO_OBJ;
-                     goto leave;
-                   }
-                 ctx->saltlen = (unsigned int)strtoul (s, NULL, 10);
-                 gcry_sexp_release (list);
-               }
-
-              /* Get optional RANDOM-OVERRIDE.  */
-              list = gcry_sexp_find_token (ldata, "random-override", 0);
-              if (list)
-                {
-                  s = gcry_sexp_nth_data (list, 1, &n);
-                  if (!s)
-                    rc = GPG_ERR_NO_OBJ;
-                  else if (n > 0)
-                    {
-                      random_override = gcry_malloc (n);
-                      if (!random_override)
-                        rc = gpg_err_code_from_syserror ();
-                      else
-                        {
-                          memcpy (random_override, s, n);
-                          random_override_len = n;
-                        }
-                    }
-                  gcry_sexp_release (list);
-                  if (rc)
-                    goto leave;
-                }
-
-              /* Encode the data.  (NBITS-1 is due to 8.1.1, step 1.) */
-             rc = pss_encode (ret_mpi, ctx->nbits - 1, ctx->hash_algo,
-                              value, valuelen, ctx->saltlen,
-                               random_override, random_override_len);
-
-              gcry_free (random_override);
-           }
-        }
-    }
-  else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
-          && ctx->op == PUBKEY_OP_VERIFY)
-    {
-      if (gcry_sexp_length (lhash) != 3)
-        rc = GPG_ERR_INV_OBJ;
-      else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
-        rc = GPG_ERR_INV_OBJ;
-      else
-        {
-         ctx->hash_algo = get_hash_algo (s, n);
-
-          if (!ctx->hash_algo)
-            rc = GPG_ERR_DIGEST_ALGO;
-         else
-           {
-             *ret_mpi = gcry_sexp_nth_mpi (lhash, 2, GCRYMPI_FMT_USG);
-             if (!*ret_mpi)
-               rc = GPG_ERR_INV_OBJ;
-             ctx->verify_cmp = pss_verify_cmp;
-             ctx->verify_arg = *ret_mpi;
-           }
-       }
-    }
-  else
-    rc = GPG_ERR_CONFLICT;
-
- leave:
-  gcry_sexp_release (ldata);
-  gcry_sexp_release (lhash);
-  gcry_sexp_release (lvalue);
-
-  if (!rc)
-    ctx->flags = parsed_flags;
-  else
-    {
-      gcry_free (ctx->label);
-      ctx->label = NULL;
-    }
-
-  return rc;
-}
-
-static void
-init_encoding_ctx (struct pk_encoding_ctx *ctx, enum pk_operation op,
-                  unsigned int nbits)
-{
-  ctx->op = op;
-  ctx->nbits = nbits;
-  ctx->encoding = PUBKEY_ENC_UNKNOWN;
-  ctx->flags = 0;
-  ctx->hash_algo = GCRY_MD_SHA1;
-  ctx->label = NULL;
-  ctx->labellen = 0;
-  ctx->saltlen = 20;
-  ctx->verify_cmp = NULL;
-  ctx->verify_arg = NULL;
-}
-
-
-/*
-   Do a PK encrypt operation
-
-   Caller has to provide a public key as the SEXP pkey and data as a
-   SEXP with just one MPI in it. Alternatively S_DATA might be a
-   complex S-Expression, similar to the one used for signature
-   verification.  This provides a flag which allows to handle PKCS#1
-   block type 2 padding.  The function returns a sexp which may be
-   passed to to pk_decrypt.
-
-   Returns: 0 or an errorcode.
-
-   s_data = See comment for sexp_data_to_mpi
-   s_pkey = <key-as-defined-in-sexp_to_key>
-   r_ciph = (enc-val
-               (<algo>
-                 (<param_name1> <mpi>)
-                 ...
-                 (<param_namen> <mpi>)
-               ))
-
-*/
-gcry_error_t
-gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
-{
-  gcry_mpi_t *pkey = NULL, data = NULL, *ciph = NULL;
-  const char *algo_name, *algo_elems;
-  struct pk_encoding_ctx ctx;
-  gcry_err_code_t rc;
-  gcry_pk_spec_t *pubkey = NULL;
-  gcry_module_t module = NULL;
-
-  *r_ciph = NULL;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  /* Get the key. */
-  rc = sexp_to_key (s_pkey, 0, NULL, &pkey, &module);
-  if (rc)
-    goto leave;
-
-  gcry_assert (module);
-  pubkey = (gcry_pk_spec_t *) module->spec;
-
-  /* If aliases for the algorithm name exists, take the first one
-     instead of the regular name to adhere to SPKI conventions.  We
-     assume that the first alias name is the lowercase version of the
-     regular one.  This change is required for compatibility with
-     1.1.12 generated S-expressions. */
-  algo_name = pubkey->aliases? *pubkey->aliases : NULL;
-  if (!algo_name || !*algo_name)
-    algo_name = pubkey->name;
-
-  algo_elems = pubkey->elements_enc;
-
-  /* Get the stuff we want to encrypt. */
-  init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, gcry_pk_get_nbits (s_pkey));
-  rc = sexp_data_to_mpi (s_data, &data, &ctx);
-  if (rc)
-    goto leave;
-
-  /* Now we can encrypt DATA to CIPH. */
-  ciph = gcry_calloc (strlen (algo_elems) + 1, sizeof (*ciph));
-  if (!ciph)
-    {
-      rc = gpg_err_code_from_syserror ();
-      goto leave;
-    }
-  rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, ctx.flags);
-  mpi_free (data);
-  data = NULL;
-  if (rc)
-    goto leave;
-
-  /* We did it.  Now build the return list */
-  if (ctx.encoding == PUBKEY_ENC_OAEP
-      || ctx.encoding == PUBKEY_ENC_PKCS1)
-    {
-      /* We need to make sure to return the correct length to avoid
-         problems with missing leading zeroes.  We know that this
-         encoding does only make sense with RSA thus we don't need to
-         build the S-expression on the fly.  */
-      unsigned char *em;
-      size_t emlen = (ctx.nbits+7)/8;
-
-      rc = octet_string_from_mpi (&em, NULL, ciph[0], emlen);
-      if (rc)
-        goto leave;
-      rc = gcry_err_code (gcry_sexp_build (r_ciph, NULL,
-                                           "(enc-val(%s(a%b)))",
-                                           algo_name, (int)emlen, em));
-      gcry_free (em);
-      if (rc)
-        goto leave;
-    }
-  else
-    {
-      char *string, *p;
-      int i;
-      size_t nelem = strlen (algo_elems);
-      size_t needed = 19 + strlen (algo_name) + (nelem * 5);
-      void **arg_list;
-
-      /* Build the string.  */
-      string = p = gcry_malloc (needed);
-      if (!string)
-        {
-          rc = gpg_err_code_from_syserror ();
-          goto leave;
-        }
-      p = stpcpy ( p, "(enc-val(" );
-      p = stpcpy ( p, algo_name );
-      for (i=0; algo_elems[i]; i++ )
-        {
-          *p++ = '(';
-          *p++ = algo_elems[i];
-          p = stpcpy ( p, "%m)" );
-        }
-      strcpy ( p, "))" );
-
-      /* And now the ugly part: We don't have a function to pass an
-       * array to a format string, so we have to do it this way :-(.  */
-      /* FIXME: There is now such a format specifier, so we can
-         change the code to be more clear. */
-      arg_list = malloc (nelem * sizeof *arg_list);
-      if (!arg_list)
-        {
-          rc = gpg_err_code_from_syserror ();
-          goto leave;
-        }
-
-      for (i = 0; i < nelem; i++)
-        arg_list[i] = ciph + i;
-
-      rc = gcry_sexp_build_array (r_ciph, NULL, string, arg_list);
-      free (arg_list);
-      if (rc)
-        BUG ();
-      gcry_free (string);
-    }
+    rc = GPG_ERR_NOT_IMPLEMENTED;
 
  leave:
-  if (pkey)
-    {
-      release_mpi_array (pkey);
-      gcry_free (pkey);
-    }
-
-  if (ciph)
-    {
-      release_mpi_array (ciph);
-      gcry_free (ciph);
-    }
-
-  if (module)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
-
-  gcry_free (ctx.label);
-
-  return gcry_error (rc);
+  sexp_release (keyparms);
+  return rc;
 }
 
+
 /*
    Do a PK decrypt operation
 
@@ -3011,103 +363,27 @@ gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
             With pkcs1 or oaep decoding enabled the returned value is a
             verbatim octet string.
  */
-gcry_error_t
-gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
+gcry_err_code_t
+_gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
 {
-  gcry_mpi_t *skey = NULL, *data = NULL, plain = NULL;
-  unsigned char *unpad = NULL;
-  size_t unpadlen = 0;
-  int modern, flags;
-  struct pk_encoding_ctx ctx;
   gcry_err_code_t rc;
-  gcry_module_t module_enc = NULL, module_key = NULL;
+  gcry_pk_spec_t *spec;
+  gcry_sexp_t keyparms;
 
   *r_plain = NULL;
-  ctx.label = NULL;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  rc = sexp_to_key (s_skey, 1, NULL, &skey, &module_key);
-  if (rc)
-    goto leave;
 
-  init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT, gcry_pk_get_nbits (s_skey));
-  rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &flags, &ctx);
+  rc = spec_from_sexp (s_skey, 1, &spec, &keyparms);
   if (rc)
     goto leave;
 
-  if (module_key->mod_id != module_enc->mod_id)
-    {
-      rc = GPG_ERR_CONFLICT; /* Key algo does not match data algo. */
-      goto leave;
-    }
-
-  rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags);
-  if (rc)
-    goto leave;
-
-  /* Do un-padding if necessary. */
-  switch (ctx.encoding)
-    {
-    case PUBKEY_ENC_PKCS1:
-      rc = pkcs1_decode_for_encryption (&unpad, &unpadlen,
-                                        gcry_pk_get_nbits (s_skey), plain);
-      mpi_free (plain);
-      plain = NULL;
-      if (!rc)
-        rc = gcry_err_code (gcry_sexp_build (r_plain, NULL, "(value %b)",
-                                             (int)unpadlen, unpad));
-      break;
-
-    case PUBKEY_ENC_OAEP:
-      rc = oaep_decode (&unpad, &unpadlen,
-                        gcry_pk_get_nbits (s_skey), ctx.hash_algo,
-                       plain, ctx.label, ctx.labellen);
-      mpi_free (plain);
-      plain = NULL;
-      if (!rc)
-        rc = gcry_err_code (gcry_sexp_build (r_plain, NULL, "(value %b)",
-                                             (int)unpadlen, unpad));
-      break;
-
-    default:
-      /* Raw format.  For backward compatibility we need to assume a
-         signed mpi by using the sexp format string "%m".  */
-      rc = gcry_err_code (gcry_sexp_build
-                          (r_plain, NULL, modern? "(value %m)" : "%m", plain));
-      break;
-    }
+  if (spec->decrypt)
+    rc = spec->decrypt (r_plain, s_data, keyparms);
+  else
+    rc = GPG_ERR_NOT_IMPLEMENTED;
 
  leave:
-  gcry_free (unpad);
-
-  if (skey)
-    {
-      release_mpi_array (skey);
-      gcry_free (skey);
-    }
-
-  mpi_free (plain);
-
-  if (data)
-    {
-      release_mpi_array (data);
-      gcry_free (data);
-    }
-
-  if (module_key || module_enc)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      if (module_key)
-       _gcry_module_release (module_key);
-      if (module_enc)
-       _gcry_module_release (module_enc);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
-
-  gcry_free (ctx.label);
-
-  return gcry_error (rc);
+  sexp_release (keyparms);
+  return rc;
 }
 
 
@@ -3128,7 +404,7 @@ gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
             other arguments but is always suitable to be passed to
             gcry_pk_verify
 
-   s_hash = See comment for sexp_data_to_mpi
+   s_hash = See comment for _gcry-pk_util_data_to_mpi
 
    s_skey = <key-as-defined-in-sexp_to_key>
    r_sig  = (sig-val
@@ -3140,133 +416,27 @@ gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
 
   Note that (hash algo) in R_SIG is not used.
 */
-gcry_error_t
-gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
+gcry_err_code_t
+_gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
 {
-  gcry_mpi_t *skey = NULL, hash = NULL, *result = NULL;
-  gcry_pk_spec_t *pubkey = NULL;
-  gcry_module_t module = NULL;
-  const char *algo_name, *algo_elems;
-  struct pk_encoding_ctx ctx;
-  int i;
   gcry_err_code_t rc;
+  gcry_pk_spec_t *spec;
+  gcry_sexp_t keyparms;
 
   *r_sig = NULL;
 
-  REGISTER_DEFAULT_PUBKEYS;
-
-  rc = sexp_to_key (s_skey, 1, NULL, &skey, &module);
-  if (rc)
-    goto leave;
-
-  gcry_assert (module);
-  pubkey = (gcry_pk_spec_t *) module->spec;
-  algo_name = pubkey->aliases? *pubkey->aliases : NULL;
-  if (!algo_name || !*algo_name)
-    algo_name = pubkey->name;
-
-  algo_elems = pubkey->elements_sig;
-
-  /* Get the stuff we want to sign.  Note that pk_get_nbits does also
-      work on a private key. */
-  init_encoding_ctx (&ctx, PUBKEY_OP_SIGN, gcry_pk_get_nbits (s_skey));
-  rc = sexp_data_to_mpi (s_hash, &hash, &ctx);
-  if (rc)
-    goto leave;
-
-  result = gcry_calloc (strlen (algo_elems) + 1, sizeof (*result));
-  if (!result)
-    {
-      rc = gpg_err_code_from_syserror ();
-      goto leave;
-    }
-  rc = pubkey_sign (module->mod_id, result, hash, skey);
+  rc = spec_from_sexp (s_skey, 1, &spec, &keyparms);
   if (rc)
     goto leave;
 
-  if (ctx.encoding == PUBKEY_ENC_PSS
-      || ctx.encoding == PUBKEY_ENC_PKCS1)
-    {
-      /* We need to make sure to return the correct length to avoid
-         problems with missing leading zeroes.  We know that this
-         encoding does only make sense with RSA thus we don't need to
-         build the S-expression on the fly.  */
-      unsigned char *em;
-      size_t emlen = (ctx.nbits+7)/8;
-
-      rc = octet_string_from_mpi (&em, NULL, result[0], emlen);
-      if (rc)
-        goto leave;
-      rc = gcry_err_code (gcry_sexp_build (r_sig, NULL,
-                                           "(sig-val(%s(s%b)))",
-                                           algo_name, (int)emlen, em));
-      gcry_free (em);
-      if (rc)
-        goto leave;
-    }
+  if (spec->sign)
+    rc = spec->sign (r_sig, s_hash, keyparms);
   else
-    {
-      /* General purpose output encoding.  Do it on the fly.  */
-      char *string, *p;
-      size_t nelem, needed = strlen (algo_name) + 20;
-      void **arg_list;
-
-      nelem = strlen (algo_elems);
-
-      /* Count elements, so that we can allocate enough space. */
-      needed += 10 * nelem;
-
-      /* Build the string. */
-      string = p = gcry_malloc (needed);
-      if (!string)
-        {
-          rc = gpg_err_code_from_syserror ();
-          goto leave;
-        }
-      p = stpcpy (p, "(sig-val(");
-      p = stpcpy (p, algo_name);
-      for (i = 0; algo_elems[i]; i++)
-        {
-          *p++ = '(';
-          *p++ = algo_elems[i];
-          p = stpcpy (p, "%M)");
-        }
-      strcpy (p, "))");
-
-      arg_list = malloc (nelem * sizeof *arg_list);
-      if (!arg_list)
-        {
-          rc = gpg_err_code_from_syserror ();
-          goto leave;
-        }
-
-      for (i = 0; i < nelem; i++)
-        arg_list[i] = result + i;
-
-      rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list);
-      free (arg_list);
-      if (rc)
-        BUG ();
-      gcry_free (string);
-    }
+    rc = GPG_ERR_NOT_IMPLEMENTED;
 
  leave:
-  if (skey)
-    {
-      release_mpi_array (skey);
-      gcry_free (skey);
-    }
-
-  if (hash)
-    mpi_free (hash);
-
-  if (result)
-    {
-      release_mpi_array (result);
-      gcry_free (result);
-    }
-
-  return gcry_error (rc);
+  sexp_release (keyparms);
+  return rc;
 }
 
 
@@ -3277,67 +447,25 @@ gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
    hashvalue data.  Public key has to be a standard public key given
    as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
    must be an S-Exp like the one in sign too.  */
-gcry_error_t
-gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
+gcry_err_code_t
+_gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
 {
-  gcry_module_t module_key = NULL, module_sig = NULL;
-  gcry_mpi_t *pkey = NULL, hash = NULL, *sig = NULL;
-  struct pk_encoding_ctx ctx;
   gcry_err_code_t rc;
+  gcry_pk_spec_t *spec;
+  gcry_sexp_t keyparms;
 
-  REGISTER_DEFAULT_PUBKEYS;
-
-  rc = sexp_to_key (s_pkey, 0, NULL, &pkey, &module_key);
-  if (rc)
-    goto leave;
-
-  rc = sexp_to_sig (s_sig, &sig, &module_sig);
-  if (rc)
-    goto leave;
-
-  /* Fixme: Check that the algorithm of S_SIG is compatible to the one
-     of S_PKEY.  */
-
-  if (module_key->mod_id != module_sig->mod_id)
-    {
-      rc = GPG_ERR_CONFLICT;
-      goto leave;
-    }
-
-  /* Get the stuff we want to verify. */
-  init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY, gcry_pk_get_nbits (s_pkey));
-  rc = sexp_data_to_mpi (s_hash, &hash, &ctx);
+  rc = spec_from_sexp (s_pkey, 0, &spec, &keyparms);
   if (rc)
     goto leave;
 
-  rc = pubkey_verify (module_key->mod_id, hash, sig, pkey,
-                     ctx.verify_cmp, &ctx);
+  if (spec->verify)
+    rc = spec->verify (s_sig, s_hash, keyparms);
+  else
+    rc = GPG_ERR_NOT_IMPLEMENTED;
 
  leave:
-  if (pkey)
-    {
-      release_mpi_array (pkey);
-      gcry_free (pkey);
-    }
-  if (sig)
-    {
-      release_mpi_array (sig);
-      gcry_free (sig);
-    }
-  if (hash)
-    mpi_free (hash);
-
-  if (module_key || module_sig)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      if (module_key)
-       _gcry_module_release (module_key);
-      if (module_sig)
-       _gcry_module_release (module_sig);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
-
-  return gcry_error (rc);
+  sexp_release (keyparms);
+  return rc;
 }
 
 
@@ -3349,25 +477,26 @@ gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
 
    Returns: 0 or an errorcode.
 
-   s_key = <key-as-defined-in-sexp_to_key> */
-gcry_error_t
-gcry_pk_testkey (gcry_sexp_t s_key)
+   NOTE: We currently support only secret key checking. */
+gcry_err_code_t
+_gcry_pk_testkey (gcry_sexp_t s_key)
 {
-  gcry_module_t module = NULL;
-  gcry_mpi_t *key = NULL;
   gcry_err_code_t rc;
+  gcry_pk_spec_t *spec;
+  gcry_sexp_t keyparms;
 
-  REGISTER_DEFAULT_PUBKEYS;
+  rc = spec_from_sexp (s_key, 1, &spec, &keyparms);
+  if (rc)
+    goto leave;
 
-  /* Note we currently support only secret key checking. */
-  rc = sexp_to_key (s_key, 1, NULL, &key, &module);
-  if (! rc)
-    {
-      rc = pubkey_check_secret_key (module->mod_id, key);
-      release_mpi_array (key);
-      gcry_free (key);
-    }
-  return gcry_error (rc);
+  if (spec->check_secret_key)
+    rc = spec->check_secret_key (keyparms);
+  else
+    rc = GPG_ERR_NOT_IMPLEMENTED;
+
+ leave:
+  sexp_release (keyparms);
+  return rc;
 }
 
 
@@ -3404,41 +533,26 @@ gcry_pk_testkey (gcry_sexp_t s_key)
       (pm1-factors n1 n2 ... nn)
    ))
  */
-gcry_error_t
-gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
+gcry_err_code_t
+_gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
 {
-  gcry_pk_spec_t *pubkey = NULL;
-  gcry_module_t module = NULL;
+  gcry_pk_spec_t *spec = NULL;
   gcry_sexp_t list = NULL;
   gcry_sexp_t l2 = NULL;
-  gcry_sexp_t l3 = NULL;
   char *name = NULL;
-  size_t n;
-  gcry_err_code_t rc = GPG_ERR_NO_ERROR;
-  int i, j;
-  const char *algo_name = NULL;
-  int algo;
-  const char *sec_elems = NULL, *pub_elems = NULL;
-  gcry_mpi_t skey[12];
-  gcry_mpi_t *factors = NULL;
-  gcry_sexp_t extrainfo = NULL;
-  unsigned int nbits = 0;
-  unsigned long use_e = 0;
-
-  skey[0] = NULL;
-  *r_key = NULL;
+  gcry_err_code_t rc;
 
-  REGISTER_DEFAULT_PUBKEYS;
+  *r_key = NULL;
 
-  list = gcry_sexp_find_token (s_parms, "genkey", 0);
+  list = sexp_find_token (s_parms, "genkey", 0);
   if (!list)
     {
       rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
       goto leave;
     }
 
-  l2 = gcry_sexp_cadr (list);
-  gcry_sexp_release (list);
+  l2 = sexp_cadr (list);
+  sexp_release (list);
   list = l2;
   l2 = NULL;
   if (! list)
@@ -3454,222 +568,26 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
       goto leave;
     }
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = gcry_pk_lookup_name (name);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-  gcry_free (name);
+  spec = spec_from_name (name);
+  xfree (name);
   name = NULL;
-  if (!module)
+  if (!spec)
     {
       rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
       goto leave;
     }
 
-  pubkey = (gcry_pk_spec_t *) module->spec;
-  algo = module->mod_id;
-  algo_name = pubkey->aliases? *pubkey->aliases : NULL;
-  if (!algo_name || !*algo_name)
-    algo_name = pubkey->name;
-  pub_elems = pubkey->elements_pkey;
-  sec_elems = pubkey->elements_skey;
-  if (strlen (sec_elems) >= DIM(skey))
-    BUG ();
-
-  /* Handle the optional rsa-use-e element.  Actually this belong into
-     the algorithm module but we have this parameter in the public
-     module API, so we need to parse it right here.  */
-  l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
-  if (l2)
-    {
-      char buf[50];
-      const char *s;
-
-      s = gcry_sexp_nth_data (l2, 1, &n);
-      if ( !s || n >= DIM (buf) - 1 )
-        {
-          rc = GPG_ERR_INV_OBJ; /* No value or value too large.  */
-          goto leave;
-        }
-      memcpy (buf, s, n);
-      buf[n] = 0;
-      use_e = strtoul (buf, NULL, 0);
-      gcry_sexp_release (l2);
-      l2 = NULL;
-    }
-  else
-    use_e = 65537; /* Not given, use the value generated by old versions. */
-
-
-  /* Get the "nbits" parameter.  */
-  l2 = gcry_sexp_find_token (list, "nbits", 0);
-  if (l2)
-    {
-      char buf[50];
-      const char *s;
-
-      s = gcry_sexp_nth_data (l2, 1, &n);
-      if (!s || n >= DIM (buf) - 1 )
-        {
-          rc = GPG_ERR_INV_OBJ; /* NBITS given without a cdr.  */
-          goto leave;
-        }
-      memcpy (buf, s, n);
-      buf[n] = 0;
-      nbits = (unsigned int)strtoul (buf, NULL, 0);
-      gcry_sexp_release (l2); l2 = NULL;
-    }
+  if (spec->generate)
+    rc = spec->generate (list, r_key);
   else
-    nbits = 0;
-
-  /* Pass control to the algorithm module. */
-  rc = pubkey_generate (module->mod_id, nbits, use_e, list, skey,
-                        &factors, &extrainfo);
-  gcry_sexp_release (list); list = NULL;
-  if (rc)
-    goto leave;
-
-  /* Key generation succeeded: Build an S-expression.  */
-  {
-    char *string, *p;
-    size_t nelem=0, nelem_cp = 0, needed=0;
-    gcry_mpi_t mpis[30];
-    int percent_s_idx = -1;
-
-    /* Estimate size of format string.  */
-    nelem = strlen (pub_elems) + strlen (sec_elems);
-    if (factors)
-      {
-        for (i = 0; factors[i]; i++)
-          nelem++;
-      }
-    nelem_cp = nelem;
-
-    needed += nelem * 10;
-    /* (+5 is for EXTRAINFO ("%S")).  */
-    needed += 2 * strlen (algo_name) + 300 + 5;
-    if (nelem > DIM (mpis))
-      BUG ();
-
-    /* Build the string. */
-    nelem = 0;
-    string = p = gcry_malloc (needed);
-    if (!string)
-      {
-        rc = gpg_err_code_from_syserror ();
-        goto leave;
-      }
-    p = stpcpy (p, "(key-data");
-    p = stpcpy (p, "(public-key(");
-    p = stpcpy (p, algo_name);
-    for(i = 0; pub_elems[i]; i++)
-      {
-        *p++ = '(';
-        *p++ = pub_elems[i];
-        p = stpcpy (p, "%m)");
-        mpis[nelem++] = skey[i];
-      }
-    if (extrainfo && (algo == GCRY_PK_ECDSA || algo == GCRY_PK_ECDH))
-      {
-        /* Very ugly hack to insert the used curve parameter into the
-           list of public key parameters.  */
-        percent_s_idx = nelem;
-        p = stpcpy (p, "%S");
-      }
-    p = stpcpy (p, "))");
-    p = stpcpy (p, "(private-key(");
-    p = stpcpy (p, algo_name);
-    for (i = 0; sec_elems[i]; i++)
-      {
-        *p++ = '(';
-        *p++ = sec_elems[i];
-        p = stpcpy (p, "%m)");
-        mpis[nelem++] = skey[i];
-      }
-    p = stpcpy (p, "))");
-
-    /* Hack to make release_mpi_array() work.  */
-    skey[i] = NULL;
-
-    if (extrainfo && percent_s_idx == -1)
-      {
-        /* If we have extrainfo we should not have any factors.  */
-        p = stpcpy (p, "%S");
-      }
-    else if (factors && factors[0])
-      {
-        p = stpcpy (p, "(misc-key-info(pm1-factors");
-        for(i = 0; factors[i]; i++)
-          {
-            p = stpcpy (p, "%m");
-            mpis[nelem++] = factors[i];
-          }
-        p = stpcpy (p, "))");
-      }
-    strcpy (p, ")");
-    gcry_assert (p - string < needed);
-
-    while (nelem < DIM (mpis))
-      mpis[nelem++] = NULL;
-
-    {
-      int elem_n = strlen (pub_elems) + strlen (sec_elems);
-      void **arg_list;
-
-      /* Allocate one extra for EXTRAINFO ("%S").  */
-      arg_list = gcry_calloc (nelem_cp+1, sizeof *arg_list);
-      if (!arg_list)
-        {
-          rc = gpg_err_code_from_syserror ();
-          goto leave;
-        }
-      for (i = j = 0; i < elem_n; i++)
-        {
-          if (i == percent_s_idx)
-            arg_list[j++] = &extrainfo;
-          arg_list[j++] = mpis + i;
-        }
-      if (extrainfo && percent_s_idx == -1)
-        arg_list[j] = &extrainfo;
-      else if (factors && factors[0])
-        {
-          for (; i < nelem_cp; i++)
-            arg_list[j++] = factors + i - elem_n;
-        }
-      rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
-      gcry_free (arg_list);
-      if (rc)
-       BUG ();
-      gcry_assert (DIM (mpis) == 30); /* Reminder to make sure that
-                                         the array gets increased if
-                                         new parameters are added. */
-    }
-    gcry_free (string);
-  }
+    rc = GPG_ERR_NOT_IMPLEMENTED;
 
  leave:
-  gcry_free (name);
-  gcry_sexp_release (extrainfo);
-  release_mpi_array (skey);
-  /* Don't free SKEY itself, it is an stack allocated array. */
-
-  if (factors)
-    {
-      release_mpi_array ( factors );
-      gcry_free (factors);
-    }
-
-  gcry_sexp_release (l3);
-  gcry_sexp_release (l2);
-  gcry_sexp_release (list);
-
-  if (module)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
+  sexp_release (list);
+  xfree (name);
+  sexp_release (l2);
 
-  return gcry_error (rc);
+  return rc;
 }
 
 
@@ -3679,32 +597,23 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
    Hmmm: Should we have really this function or is it better to have a
    more general function to retrieve different properties of the key?  */
 unsigned int
-gcry_pk_get_nbits (gcry_sexp_t key)
+_gcry_pk_get_nbits (gcry_sexp_t key)
 {
-  gcry_module_t module = NULL;
-  gcry_pk_spec_t *pubkey;
-  gcry_mpi_t *keyarr = NULL;
-  unsigned int nbits = 0;
-  gcry_err_code_t rc;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  rc = sexp_to_key (key, 0, NULL, &keyarr, &module);
-  if (rc == GPG_ERR_INV_OBJ)
-    rc = sexp_to_key (key, 1, NULL, &keyarr, &module);
-  if (rc)
-    return 0; /* Error - 0 is a suitable indication for that. */
-
-  pubkey = (gcry_pk_spec_t *) module->spec;
-  nbits = (*pubkey->get_nbits) (module->mod_id, keyarr);
+  gcry_pk_spec_t *spec;
+  gcry_sexp_t parms;
+  unsigned int nbits;
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  _gcry_module_release (module);
-  ath_mutex_unlock (&pubkeys_registered_lock);
+  /* Parsing KEY might be considered too much overhead.  For example
+     for RSA we would only need to look at P and stop parsing right
+     away.  However, with ECC things are more complicate in that only
+     a curve name might be specified.  Thus we need to tear the sexp
+     apart. */
 
-  release_mpi_array (keyarr);
-  gcry_free (keyarr);
+  if (spec_from_sexp (key, 0, &spec, &parms))
+    return 0; /* Error - 0 is a suitable indication for that.  */
 
+  nbits = spec->get_nbits (parms);
+  sexp_release (parms);
   return nbits;
 }
 
@@ -3717,12 +626,11 @@ gcry_pk_get_nbits (gcry_sexp_t key)
    NULL is returned to indicate an error which is most likely an
    unknown algorithm.  The function accepts public or secret keys. */
 unsigned char *
-gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
+_gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
 {
-  gcry_sexp_t list = NULL, l2 = NULL;
-  gcry_pk_spec_t *pubkey = NULL;
-  gcry_module_t module = NULL;
-  pk_extra_spec_t *extraspec;
+  gcry_sexp_t list = NULL;
+  gcry_sexp_t l2 = NULL;
+  gcry_pk_spec_t *spec = NULL;
   const char *s;
   char *name = NULL;
   int idx;
@@ -3730,21 +638,19 @@ gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
   gcry_md_hd_t md = NULL;
   int okay = 0;
 
-  REGISTER_DEFAULT_PUBKEYS;
-
   /* Check that the first element is valid. */
-  list = gcry_sexp_find_token (key, "public-key", 0);
+  list = sexp_find_token (key, "public-key", 0);
   if (! list)
-    list = gcry_sexp_find_token (key, "private-key", 0);
+    list = sexp_find_token (key, "private-key", 0);
   if (! list)
-    list = gcry_sexp_find_token (key, "protected-private-key", 0);
+    list = sexp_find_token (key, "protected-private-key", 0);
   if (! list)
-    list = gcry_sexp_find_token (key, "shadowed-private-key", 0);
+    list = sexp_find_token (key, "shadowed-private-key", 0);
   if (! list)
     return NULL; /* No public- or private-key object. */
 
-  l2 = gcry_sexp_cadr (list);
-  gcry_sexp_release (list);
+  l2 = sexp_cadr (list);
+  sexp_release (list);
   list = l2;
   l2 = NULL;
 
@@ -3752,27 +658,21 @@ gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
   if (!name)
     goto fail; /* Invalid structure of object. */
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = gcry_pk_lookup_name (name);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  if (!module)
+  spec = spec_from_name (name);
+  if (!spec)
     goto fail; /* Unknown algorithm.  */
 
-  pubkey = (gcry_pk_spec_t *) module->spec;
-  extraspec = module->extraspec;
-
-  elems = pubkey->elements_grip;
+  elems = spec->elements_grip;
   if (!elems)
     goto fail; /* No grip parameter.  */
 
-  if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
+  if (_gcry_md_open (&md, GCRY_MD_SHA1, 0))
     goto fail;
 
-  if (extraspec && extraspec->comp_keygrip)
+  if (spec->comp_keygrip)
     {
       /* Module specific method to compute a keygrip.  */
-      if (extraspec->comp_keygrip (md, list))
+      if (spec->comp_keygrip (md, list))
         goto fail;
     }
   else
@@ -3784,157 +684,101 @@ gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
           size_t datalen;
           char buf[30];
 
-          l2 = gcry_sexp_find_token (list, s, 1);
+          l2 = sexp_find_token (list, s, 1);
           if (! l2)
             goto fail;
-          data = gcry_sexp_nth_data (l2, 1, &datalen);
+          data = sexp_nth_data (l2, 1, &datalen);
           if (! data)
             goto fail;
 
           snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen);
-          gcry_md_write (md, buf, strlen (buf));
-          gcry_md_write (md, data, datalen);
-          gcry_sexp_release (l2);
+          _gcry_md_write (md, buf, strlen (buf));
+          _gcry_md_write (md, data, datalen);
+          sexp_release (l2);
           l2 = NULL;
-          gcry_md_write (md, ")", 1);
+          _gcry_md_write (md, ")", 1);
         }
     }
 
   if (!array)
     {
-      array = gcry_malloc (20);
+      array = xtrymalloc (20);
       if (! array)
         goto fail;
     }
 
-  memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
+  memcpy (array, _gcry_md_read (md, GCRY_MD_SHA1), 20);
   okay = 1;
 
  fail:
-  gcry_free (name);
-  gcry_sexp_release (l2);
-  gcry_md_close (md);
-  gcry_sexp_release (list);
+  xfree (name);
+  sexp_release (l2);
+  _gcry_md_close (md);
+  sexp_release (list);
   return okay? array : NULL;
 }
 
 
 \f
 const char *
-gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
+_gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
 {
-  gcry_mpi_t *pkey = NULL;
-  gcry_sexp_t list = NULL;
-  gcry_sexp_t l2;
-  gcry_module_t module = NULL;
-  pk_extra_spec_t *extraspec;
-  char *name = NULL;
   const char *result = NULL;
-  int want_private = 1;
+  gcry_pk_spec_t *spec;
+  gcry_sexp_t keyparms = NULL;
 
   if (r_nbits)
     *r_nbits = 0;
 
-  REGISTER_DEFAULT_PUBKEYS;
-
   if (key)
     {
       iterator = 0;
 
-      /* Check that the first element is valid. */
-      list = gcry_sexp_find_token (key, "public-key", 0);
-      if (list)
-        want_private = 0;
-      if (!list)
-        list = gcry_sexp_find_token (key, "private-key", 0);
-      if (!list)
-        return NULL; /* No public- or private-key object. */
-
-      l2 = gcry_sexp_cadr (list);
-      gcry_sexp_release (list);
-      list = l2;
-      l2 = NULL;
-
-      name = _gcry_sexp_nth_string (list, 0);
-      if (!name)
-        goto leave; /* Invalid structure of object. */
-
-      /* Get the key.  We pass the names of the parameters for
-         override_elems; this allows to call this function without the
-         actual public key parameter.  */
-      if (sexp_to_key (key, want_private, "pabgn", &pkey, &module))
-        goto leave;
+      if (spec_from_sexp (key, 0, &spec, &keyparms))
+        return NULL;
     }
   else
     {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      module = gcry_pk_lookup_name ("ecc");
-      ath_mutex_unlock (&pubkeys_registered_lock);
-      if (!module)
-        goto leave;
+      spec = spec_from_name ("ecc");
+      if (!spec)
+        return NULL;
     }
 
-  extraspec = module->extraspec;
-  if (!extraspec || !extraspec->get_curve)
-    goto leave;
-
-  result = extraspec->get_curve (pkey, iterator, r_nbits);
+  if (spec->get_curve)
+    result = spec->get_curve (keyparms, iterator, r_nbits);
 
- leave:
-  if (pkey)
-    {
-      release_mpi_array (pkey);
-      gcry_free (pkey);
-    }
-  if (module)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
-  gcry_free (name);
-  gcry_sexp_release (list);
+  sexp_release (keyparms);
   return result;
 }
 
 
 \f
 gcry_sexp_t
-gcry_pk_get_param (int algo, const char *name)
+_gcry_pk_get_param (int algo, const char *name)
 {
-  gcry_module_t module = NULL;
-  pk_extra_spec_t *extraspec;
   gcry_sexp_t result = NULL;
+  gcry_pk_spec_t *spec = NULL;
 
-  if (algo != GCRY_PK_ECDSA && algo != GCRY_PK_ECDH)
-    return NULL;
+  algo = map_algo (algo);
 
-  REGISTER_DEFAULT_PUBKEYS;
+  if (algo != GCRY_PK_ECC)
+    return NULL;
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = gcry_pk_lookup_name ("ecc");
-  ath_mutex_unlock (&pubkeys_registered_lock);
-  if (module)
+  spec = spec_from_name ("ecc");
+  if (spec)
     {
-      extraspec = module->extraspec;
-      if (extraspec && extraspec->get_curve_param)
-        result = extraspec->get_curve_param (name);
-
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
+      if (spec && spec->get_curve_param)
+        result = spec->get_curve_param (name);
     }
   return result;
 }
 
 
 \f
-gcry_error_t
-gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
+gcry_err_code_t
+_gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
-  REGISTER_DEFAULT_PUBKEYS;
+  gcry_err_code_t rc = 0;
 
   switch (cmd)
     {
@@ -3942,16 +786,16 @@ gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
       /* This one expects a buffer pointing to an integer with the
          algo number.  */
       if ((! buffer) || (buflen != sizeof (int)))
-       err = GPG_ERR_INV_ARG;
+       rc = GPG_ERR_INV_ARG;
       else
        disable_pubkey_algo (*((int *) buffer));
       break;
 
     default:
-      err = GPG_ERR_INV_OP;
+      rc = GPG_ERR_INV_OP;
     }
 
-  return gcry_error (err);
+  return rc;
 }
 
 
@@ -3976,10 +820,10 @@ gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
    the return value.  The caller will in all cases consult the value
    and thereby detecting whether a error occurred or not (i.e. while
    checking the block size) */
-gcry_error_t
-gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
+gcry_err_code_t
+_gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
+  gcry_err_code_t rc = 0;
 
   switch (what)
     {
@@ -3987,31 +831,18 @@ gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
       {
        int use = nbytes ? *nbytes : 0;
        if (buffer)
-         err = GPG_ERR_INV_ARG;
+         rc = GPG_ERR_INV_ARG;
        else if (check_pubkey_algo (algorithm, use))
-         err = GPG_ERR_PUBKEY_ALGO;
+         rc = GPG_ERR_PUBKEY_ALGO;
        break;
       }
 
     case GCRYCTL_GET_ALGO_USAGE:
       {
-       gcry_module_t pubkey;
-       int use = 0;
-
-       REGISTER_DEFAULT_PUBKEYS;
-
-       ath_mutex_lock (&pubkeys_registered_lock);
-       pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-       if (pubkey)
-         {
-           use = ((gcry_pk_spec_t *) pubkey->spec)->use;
-           _gcry_module_release (pubkey);
-         }
-       ath_mutex_unlock (&pubkeys_registered_lock);
-
-       /* FIXME? */
-       *nbytes = use;
+       gcry_pk_spec_t *spec;
 
+       spec = spec_from_algo (algorithm);
+        *nbytes = spec? spec->use : 0;
        break;
       }
 
@@ -4045,69 +876,60 @@ gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
       }
 
     default:
-      err = GPG_ERR_INV_OP;
+      rc = GPG_ERR_INV_OP;
     }
 
-  return gcry_error (err);
+  return rc;
 }
 
 
-/* Explicitly initialize this module.  */
-gcry_err_code_t
-_gcry_pk_init (void)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  return err;
-}
-
+/* 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 a new S-expression is stored at R_SEXP and
+   0 is returned, on error NULL is store there and an error code is
+   returned.  MODE is either 0 or one of the GCRY_PK_GET_xxx values.
 
+   As of now it only support 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.  Note also that the name
+   of the function is gcry_pubkey_xxx and not gcry_pk_xxx.  The idea
+   is that we will eventually provide variants of the existing
+   gcry_pk_xxx functions which will take a context parameter.   */
 gcry_err_code_t
-_gcry_pk_module_lookup (int algorithm, gcry_module_t *module)
+_gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp, int mode, gcry_ctx_t ctx)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  gcry_module_t pubkey;
+  mpi_ec_t ec;
 
-  REGISTER_DEFAULT_PUBKEYS;
+  if (!r_sexp)
+    return GPG_ERR_INV_VALUE;
+  *r_sexp = NULL;
+  switch (mode)
+    {
+    case 0:
+    case GCRY_PK_GET_PUBKEY:
+    case GCRY_PK_GET_SECKEY:
+      break;
+    default:
+      return GPG_ERR_INV_VALUE;
+    }
+  if (!ctx)
+    return GPG_ERR_NO_CRYPT_CTX;
 
-  ath_mutex_lock (&pubkeys_registered_lock);
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
-  if (pubkey)
-    *module = pubkey;
-  else
-    err = GPG_ERR_PUBKEY_ALGO;
-  ath_mutex_unlock (&pubkeys_registered_lock);
+  ec = _gcry_ctx_find_pointer (ctx, CONTEXT_TYPE_EC);
+  if (ec)
+    return _gcry_pk_ecc_get_sexp (r_sexp, mode, ec);
 
-  return err;
+  return GPG_ERR_WRONG_CRYPT_CTX;
 }
 
 
-void
-_gcry_pk_module_release (gcry_module_t module)
-{
-  ath_mutex_lock (&pubkeys_registered_lock);
-  _gcry_module_release (module);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-}
-
-/* Get a list consisting of the IDs of the loaded pubkey modules.  If
-   LIST is zero, write the number of loaded pubkey modules to
-   LIST_LENGTH and return.  If LIST is non-zero, the first
-   *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
-   according size.  In case there are less pubkey modules than
-   *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
-gcry_error_t
-gcry_pk_list (int *list, int *list_length)
+\f
+/* Explicitly initialize this module.  */
+gcry_err_code_t
+_gcry_pk_init (void)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  err = _gcry_module_list (pubkeys_registered, list, list_length);
-  ath_mutex_unlock (&pubkeys_registered_lock);
-
-  return err;
+  return 0;
 }
 
 
@@ -4116,97 +938,25 @@ gcry_pk_list (int *list, int *list_length)
 gpg_error_t
 _gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
 {
-  gcry_module_t module = NULL;
-  pk_extra_spec_t *extraspec = NULL;
-  gcry_err_code_t ec = 0;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  ath_mutex_lock (&pubkeys_registered_lock);
-  module = _gcry_module_lookup_id (pubkeys_registered, algo);
-  if (module && !(module->flags & FLAG_MODULE_DISABLED))
-    extraspec = module->extraspec;
-  ath_mutex_unlock (&pubkeys_registered_lock);
-  if (extraspec && extraspec->selftest)
-    ec = extraspec->selftest (algo, extended, report);
+  gcry_err_code_t ec;
+  gcry_pk_spec_t *spec;
+
+  algo = map_algo (algo);
+  spec = spec_from_algo (algo);
+  if (spec && !spec->flags.disabled && spec->selftest)
+    ec = spec->selftest (algo, extended, report);
   else
     {
       ec = GPG_ERR_PUBKEY_ALGO;
+      /* Fixme: We need to change the report fucntion to allow passing
+         of an encryption mode (e.g. pkcs1, ecdsa, or ecdh).  */
       if (report)
         report ("pubkey", algo, "module",
-                module && !(module->flags & FLAG_MODULE_DISABLED)?
+                spec && !spec->flags.disabled?
                 "no selftest available" :
-                module? "algorithm disabled" : "algorithm not found");
+                spec? "algorithm disabled" :
+                "algorithm not found");
     }
 
-  if (module)
-    {
-      ath_mutex_lock (&pubkeys_registered_lock);
-      _gcry_module_release (module);
-      ath_mutex_unlock (&pubkeys_registered_lock);
-    }
   return gpg_error (ec);
 }
-
-
-/* This function is only used by ac.c!  */
-gcry_err_code_t
-_gcry_pk_get_elements (int algo, char **enc, char **sig)
-{
-  gcry_module_t pubkey;
-  gcry_pk_spec_t *spec;
-  gcry_err_code_t err;
-  char *enc_cp;
-  char *sig_cp;
-
-  REGISTER_DEFAULT_PUBKEYS;
-
-  enc_cp = NULL;
-  sig_cp = NULL;
-  spec = NULL;
-
-  pubkey = _gcry_module_lookup_id (pubkeys_registered, algo);
-  if (! pubkey)
-    {
-      err = GPG_ERR_INTERNAL;
-      goto out;
-    }
-  spec = pubkey->spec;
-
-  if (enc)
-    {
-      enc_cp = strdup (spec->elements_enc);
-      if (! enc_cp)
-       {
-         err = gpg_err_code_from_syserror ();
-         goto out;
-       }
-    }
-
-  if (sig)
-    {
-      sig_cp = strdup (spec->elements_sig);
-      if (! sig_cp)
-       {
-         err = gpg_err_code_from_syserror ();
-         goto out;
-       }
-    }
-
-  if (enc)
-    *enc = enc_cp;
-  if (sig)
-    *sig = sig_cp;
-  err = 0;
-
- out:
-
-  _gcry_module_release (pubkey);
-  if (err)
-    {
-      free (enc_cp);
-      free (sig_cp);
-    }
-
-  return err;
-}
index 1c9c8d4..aed8cad 100644 (file)
@@ -136,6 +136,13 @@ do_encrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf)
   outbuf[7] = word3 >> 8;
 }
 
+static unsigned int
+encrypt_block (void *context, unsigned char *outbuf, const unsigned char *inbuf)
+{
+  do_encrypt (context, outbuf, inbuf);
+  return /*burn_stack*/ (4 * sizeof(void *) + sizeof(void *) + sizeof(u32) * 4);
+}
+
 static void
 do_decrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf)
 {
@@ -188,6 +195,13 @@ do_decrypt (void *context, unsigned char *outbuf, const unsigned char *inbuf)
   outbuf[7] = word3 >> 8;
 }
 
+static unsigned int
+decrypt_block (void *context, unsigned char *outbuf, const unsigned char *inbuf)
+{
+  do_decrypt (context, outbuf, inbuf);
+  return /*burn_stack*/ (4 * sizeof(void *) + sizeof(void *) + sizeof(u32) * 4);
+}
+
 
 static gpg_err_code_t
 setkey_core (void *context, const unsigned char *key, unsigned int keylen, int with_phase2)
@@ -337,8 +351,25 @@ static gcry_cipher_oid_spec_t oids_rfc2268_40[] =
     { NULL }
   };
 
-gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40 = {
-  "RFC2268_40", NULL, oids_rfc2268_40,
-  RFC2268_BLOCKSIZE, 40, sizeof(RFC2268_context),
-  do_setkey, do_encrypt, do_decrypt
-};
+static gcry_cipher_oid_spec_t oids_rfc2268_128[] =
+  {
+    /* pbeWithSHAAnd128BitRC2_CBC */
+    { "1.2.840.113549.1.12.1.5", GCRY_CIPHER_MODE_CBC },
+    { NULL }
+  };
+
+gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40 =
+  {
+    GCRY_CIPHER_RFC2268_40, {0, 0},
+    "RFC2268_40", NULL, oids_rfc2268_40,
+    RFC2268_BLOCKSIZE, 40, sizeof(RFC2268_context),
+    do_setkey, encrypt_block, decrypt_block
+  };
+
+gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_128 =
+  {
+    GCRY_CIPHER_RFC2268_128, {0, 0},
+    "RFC2268_128", NULL, oids_rfc2268_128,
+    RFC2268_BLOCKSIZE, 128, sizeof(RFC2268_context),
+    do_setkey, encrypt_block, decrypt_block
+  };
diff --git a/cipher/rijndael-amd64.S b/cipher/rijndael-amd64.S
new file mode 100644 (file)
index 0000000..35a9d26
--- /dev/null
@@ -0,0 +1,1416 @@
+/* rinjdael-amd64.S  -  AMD64 assembly implementation of AES cipher
+ *
+ * Copyright © 2013 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(USE_AES)
+
+#ifdef __PIC__
+#  define RIP (%rip)
+#else
+#  define RIP
+#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 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
+
+/* register macros */
+#define CTX    %rdi
+#define RTAB   %r12
+
+#define RA     %rax
+#define RB     %rbx
+#define RC     %rcx
+#define RD     %rdx
+
+#define RAd    %eax
+#define RBd    %ebx
+#define RCd    %ecx
+#define RDd    %edx
+
+#define RAbl   %al
+#define RBbl   %bl
+#define RCbl   %cl
+#define RDbl   %dl
+
+#define RAbh   %ah
+#define RBbh   %bh
+#define RCbh   %ch
+#define RDbh   %dh
+
+#define RNA    %r8
+#define RNB    %r9
+#define RNC    %r10
+#define RND    %r11
+
+#define RNAd   %r8d
+#define RNBd   %r9d
+#define RNCd   %r10d
+#define RNDd   %r11d
+
+#define RT0    %rbp
+#define RT1    %rsi
+
+#define RT0d   %ebp
+#define RT1d   %esi
+
+/* helper macros */
+#define do16bit(op, source, tablemul, table1, dest1, table2, dest2, t0, t1) \
+       movzbl source ## bh,                    t1 ## d; \
+       movzbl source ## bl,                    t0 ## d; \
+       op ## l table1(RTAB,t0,tablemul),       dest1 ## d; \
+       op ## l table2(RTAB,t1,tablemul),       dest2 ## d;
+
+#define 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; \
+       op ## l table1(RTAB,t0,tablemul),       dest1 ## d; \
+       op ## l table2(RTAB,t1,tablemul),       dest2 ## d;
+
+/***********************************************************************
+ * AMD64 assembly implementation of the AES cipher
+ ***********************************************************************/
+#define addroundkey(round, ra, rb, rc, rd) \
+       xorl (((round) * 16) + 0 * 4)(CTX), ra ## d; \
+       xorl (((round) * 16) + 1 * 4)(CTX), rb ## d; \
+       xorl (((round) * 16) + 2 * 4)(CTX), rc ## d; \
+       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); \
+       movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \
+       xorl RNAd, RAd; \
+       \
+       do16bit_shr(16, xor, RD, Esize, E0, RND, E1, RNC, RT0, RT1); \
+       do16bit(        xor, RD, Esize, E2, RNB, E3, RA,  RT0, RT1); \
+       movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \
+       xorl RNDd, RDd; \
+       \
+       do16bit_shr(16, xor, RC, Esize, E0, RNC, E1, RNB, RT0, RT1); \
+       do16bit(        xor, RC, Esize, E2, RA,  E3, RD,  RT0, RT1); \
+       movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \
+       xorl RNCd, RCd; \
+       \
+       do16bit_shr(16, xor, RB, Esize, E0, RNB, E1, RA,  RT0, RT1); \
+       do16bit(        xor, RB, Esize, E2, RD,  E3, RC,  RT0, RT1); \
+       movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \
+       xorl RNBd, RBd;
+
+#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,  or, RB, Esize, Es0, RNB, Es1, RNA, RT0, RT1); \
+       do16bit(         or, RB, Esize, Es2, RND, Es3, RNC, RT0, RT1); \
+       \
+       do16bit_shr(16,  or, RC, Esize, Es0, RNC, Es1, RNB, RT0, RT1); \
+       do16bit(         or, RC, Esize, Es2, RNA, Es3, RND, RT0, RT1); \
+       \
+       do16bit_shr(16,  or, RD, Esize, Es0, RND, Es1, RNC, RT0, RT1); \
+       do16bit(         or, RD, Esize, Es2, RNB, Es3, RNA, RT0, RT1);
+
+#define firstencround(round) \
+       addroundkey(round, RA, RB, RC, RD); \
+       do_encround((round) + 1);
+
+#define encround(round) \
+       do_encround((round) + 1);
+
+#define lastencround(round) \
+       do_lastencround(); \
+       addroundkey((round) + 1, RNA, RNB, RNC, RND);
+
+.align 8
+.globl _gcry_aes_amd64_encrypt_block
+.type   _gcry_aes_amd64_encrypt_block,@function;
+
+_gcry_aes_amd64_encrypt_block:
+       /* input:
+        *      %rdi: keysched, CTX
+        *      %rsi: dst
+        *      %rdx: src
+        *      %ecx: number of rounds.. 10, 12 or 14
+        */
+       subq $(5 * 8), %rsp;
+       movq %rsi, (0 * 8)(%rsp);
+       movl %ecx, (1 * 8)(%rsp);
+       movq %rbp, (2 * 8)(%rsp);
+       movq %rbx, (3 * 8)(%rsp);
+       movq %r12, (4 * 8)(%rsp);
+
+       leaq .LtableE0 RIP, RTAB;
+
+       /* read input block */
+       movl 0 * 4(%rdx), RAd;
+       movl 1 * 4(%rdx), RBd;
+       movl 2 * 4(%rdx), RCd;
+       movl 3 * 4(%rdx), RDd;
+
+       firstencround(0);
+       encround(1);
+       encround(2);
+       encround(3);
+       encround(4);
+       encround(5);
+       encround(6);
+       encround(7);
+       encround(8);
+       cmpl $12, (1 * 8)(%rsp);
+       jnb .Lenc_not_128;
+       lastencround(9);
+
+.align 4
+.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);
+
+       movq (4 * 8)(%rsp), %r12;
+       movq (3 * 8)(%rsp), %rbx;
+       movq (2 * 8)(%rsp), %rbp;
+       addq $(5 * 8), %rsp;
+
+       ret;
+
+.align 4
+.Lenc_not_128:
+       je .Lenc_192
+
+       encround(9);
+       encround(10);
+       encround(11);
+       encround(12);
+       lastencround(13);
+
+       jmp .Lenc_done;
+
+.align 4
+.Lenc_192:
+       encround(9);
+       encround(10);
+       lastencround(11);
+
+       jmp .Lenc_done;
+.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); \
+       movl (((next_r) * 16) + 0 * 4)(CTX), RAd; \
+       xorl RNAd, RAd; \
+       \
+       do16bit_shr(16, xor, RB, Dsize, D0, RNB, D1, RNC, RT0, RT1); \
+       do16bit(        xor, RB, Dsize, D2, RND, D3, RA,  RT0, RT1); \
+       movl (((next_r) * 16) + 1 * 4)(CTX), RBd; \
+       xorl RNBd, RBd; \
+       \
+       do16bit_shr(16, xor, RC, Dsize, D0, RNC, D1, RND, RT0, RT1); \
+       do16bit(        xor, RC, Dsize, D2, RA,  D3, RB,  RT0, RT1); \
+       movl (((next_r) * 16) + 2 * 4)(CTX), RCd; \
+       xorl RNCd, RCd; \
+       \
+       do16bit_shr(16, xor, RD, Dsize, D0, RND, D1, RA,  RT0, RT1); \
+       do16bit(        xor, RD, Dsize, D2, RB,  D3, RC,  RT0, RT1); \
+       movl (((next_r) * 16) + 3 * 4)(CTX), RDd; \
+       xorl RNDd, RDd; \
+
+#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); \
+       \
+       do16bit_shr(16,  or, RB, Dsize, Ds0, RNB, Ds1, RNC, RT0, RT1); \
+       do16bit(         or, RB, Dsize, Ds2, RND, Ds3, RNA, RT0, RT1); \
+       \
+       do16bit_shr(16,  or, RC, Dsize, Ds0, RNC, Ds1, RND, RT0, RT1); \
+       do16bit(         or, RC, Dsize, Ds2, RNA, Ds3, RNB, RT0, RT1); \
+       \
+       do16bit_shr(16,  or, RD, Dsize, Ds0, RND, Ds1, RNA, RT0, RT1); \
+       do16bit(         or, RD, Dsize, Ds2, RNB, Ds3, RNC, RT0, RT1);
+
+#define firstdecround(round) \
+       addroundkey((round + 1), RA, RB, RC, RD); \
+       do_decround(round);
+
+#define decround(round) \
+       do_decround(round);
+
+#define lastdecround(round) \
+       do_lastdecround(); \
+       addroundkey(round, RNA, RNB, RNC, RND);
+
+.align 8
+.globl _gcry_aes_amd64_decrypt_block
+.type   _gcry_aes_amd64_decrypt_block,@function;
+
+_gcry_aes_amd64_decrypt_block:
+       /* input:
+        *      %rdi: keysched, CTX
+        *      %rsi: dst
+        *      %rdx: src
+        *      %ecx: number of rounds.. 10, 12 or 14
+        */
+       subq $(5 * 8), %rsp;
+       movq %rsi, (0 * 8)(%rsp);
+       movl %ecx, (1 * 8)(%rsp);
+       movq %rbp, (2 * 8)(%rsp);
+       movq %rbx, (3 * 8)(%rsp);
+       movq %r12, (4 * 8)(%rsp);
+
+       leaq .LtableD0 RIP, RTAB;
+
+       /* read input block */
+       movl 0 * 4(%rdx), RAd;
+       movl 1 * 4(%rdx), RBd;
+       movl 2 * 4(%rdx), RCd;
+       movl 3 * 4(%rdx), RDd;
+
+       cmpl $12, (1 * 8)(%rsp);
+       jnb .Ldec_256;
+
+       firstdecround(9);
+.align 4
+.Ldec_tail:
+       decround(8);
+       decround(7);
+       decround(6);
+       decround(5);
+       decround(4);
+       decround(3);
+       decround(2);
+       decround(1);
+       lastdecround(0);
+
+       /* 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);
+
+       movq (4 * 8)(%rsp), %r12;
+       movq (3 * 8)(%rsp), %rbx;
+       movq (2 * 8)(%rsp), %rbp;
+       addq $(5 * 8), %rsp;
+
+       ret;
+
+.align 4
+.Ldec_256:
+       je .Ldec_192;
+
+       firstdecround(13);
+       decround(12);
+       decround(11);
+       decround(10);
+       decround(9);
+
+       jmp .Ldec_tail;
+
+.align 4
+.Ldec_192:
+       firstdecround(11);
+       decround(10);
+       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
+
+#endif /*USE_AES*/
+#endif /*__x86_64*/
diff --git a/cipher/rijndael-arm.S b/cipher/rijndael-arm.S
new file mode 100644 (file)
index 0000000..22c350c
--- /dev/null
@@ -0,0 +1,853 @@
+/* rijndael-arm.S  -  ARM assembly implementation of AES cipher
+ *
+ * Copyright © 2013 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
+
+/* register macros */
+#define CTX    %r0
+#define RTAB   %lr
+#define RMASK  %ip
+
+#define RA     %r4
+#define RB     %r5
+#define RC     %r6
+#define RD     %r7
+
+#define RNA    %r8
+#define RNB    %r9
+#define RNC    %r10
+#define RND    %r11
+
+#define RT0    %r1
+#define RT1    %r2
+#define RT2    %r3
+
+/* helper macros */
+#define ldr_unaligned_le(rout, rsrc, offs, rtmp) \
+       ldrb rout, [rsrc, #((offs) + 0)]; \
+       ldrb rtmp, [rsrc, #((offs) + 1)]; \
+       orr rout, rout, rtmp, lsl #8; \
+       ldrb rtmp, [rsrc, #((offs) + 2)]; \
+       orr rout, rout, rtmp, lsl #16; \
+       ldrb rtmp, [rsrc, #((offs) + 3)]; \
+       orr rout, rout, rtmp, lsl #24;
+
+#define str_unaligned_le(rin, rdst, offs, rtmp0, rtmp1) \
+       mov rtmp0, rin, lsr #8; \
+       strb rin, [rdst, #((offs) + 0)]; \
+       mov rtmp1, rin, lsr #16; \
+       strb rtmp0, [rdst, #((offs) + 1)]; \
+       mov rtmp0, rin, lsr #24; \
+       strb rtmp1, [rdst, #((offs) + 2)]; \
+       strb rtmp0, [rdst, #((offs) + 3)];
+
+/***********************************************************************
+ * ARM assembly implementation of the AES cipher
+ ***********************************************************************/
+#define preload_first_key(round, ra) \
+       ldr ra, [CTX, #(((round) * 16) + 0 * 4)];
+
+#define dummy(round, ra) /* nothing */
+
+#define addroundkey(ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key) \
+       ldm CTX, {rna, rnb, rnc, rnd}; \
+       eor ra, rna; \
+       eor rb, rnb; \
+       eor rc, rnc; \
+       preload_key(1, rna); \
+       eor rd, rnd;
+
+#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; \
+       ldr rnc, [CTX, #(((next_r) * 16) + 2 * 4)]; \
+       and RT1, RMASK, ra, lsr#(8 - 3); \
+       ldr rnd, [CTX, #(((next_r) * 16) + 3 * 4)]; \
+       and RT2, RMASK, ra, lsr#(16 - 3); \
+       ldr RT0, [RTAB, RT0]; \
+       and ra,  RMASK, ra, lsr#(24 - 3); \
+       \
+       ldr RT1, [RTAB, RT1]; \
+       eor rna, rna, RT0; \
+       ldr RT2, [RTAB, RT2]; \
+       and RT0, RMASK, rd, lsl#3; \
+       ldr ra,  [RTAB, ra]; \
+       \
+       eor rnd, rnd, RT1, ror #24; \
+       and RT1, RMASK, rd, lsr#(8 - 3); \
+       eor rnc, rnc, RT2, ror #16; \
+       and RT2, RMASK, rd, lsr#(16 - 3); \
+       eor rnb, rnb, ra, ror #8; \
+       ldr RT0, [RTAB, RT0]; \
+       and rd,  RMASK, rd, lsr#(24 - 3); \
+       \
+       ldr RT1, [RTAB, RT1]; \
+       eor rnd, rnd, RT0; \
+       ldr RT2, [RTAB, RT2]; \
+       and RT0, RMASK, rc, lsl#3; \
+       ldr rd,  [RTAB, rd]; \
+       \
+       eor rnc, rnc, RT1, ror #24; \
+       and RT1, RMASK, rc, lsr#(8 - 3); \
+       eor rnb, rnb, RT2, ror #16; \
+       and RT2, RMASK, rc, lsr#(16 - 3); \
+       eor rna, rna, rd, ror #8; \
+       ldr RT0, [RTAB, RT0]; \
+       and rc,  RMASK, rc, lsr#(24 - 3); \
+       \
+       ldr RT1, [RTAB, RT1]; \
+       eor rnc, rnc, RT0; \
+       ldr RT2, [RTAB, RT2]; \
+       and RT0, RMASK, rb, lsl#3; \
+       ldr rc,  [RTAB, rc]; \
+       \
+       eor rnb, rnb, RT1, ror #24; \
+       and RT1, RMASK, rb, lsr#(8 - 3); \
+       eor rna, rna, RT2, ror #16; \
+       and RT2, RMASK, rb, lsr#(16 - 3); \
+       eor rnd, rnd, rc, ror #8; \
+       ldr RT0, [RTAB, RT0]; \
+       and rb,  RMASK, rb, lsr#(24 - 3); \
+       \
+       ldr RT1, [RTAB, RT1]; \
+       eor rnb, rnb, RT0; \
+       ldr RT2, [RTAB, RT2]; \
+       eor rna, rna, RT1, ror #24; \
+       ldr rb,  [RTAB, rb]; \
+       \
+       eor rnd, rnd, RT2, ror #16; \
+       preload_key((next_r) + 1, ra); \
+       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]; \
+       mov rnd, rnd, ror #24; \
+       ldr rnb, [RTAB, ra]; \
+       and RT1, RMASK, rd, lsr#(8 - 3); \
+       mov rnc, rnc, ror #16; \
+       and RT2, RMASK, rd, lsr#(16 - 3); \
+       mov rnb, rnb, ror #8; \
+       ldr RT0, [RTAB, RT0]; \
+       and rd,  RMASK, rd, lsr#(24 - 3); \
+       ldr RT1, [RTAB, RT1]; \
+       \
+       orr rnd, rnd, RT0; \
+       ldr RT2, [RTAB, RT2]; \
+       and RT0, RMASK, rc, lsl#3; \
+       ldr rd,  [RTAB, rd]; \
+       orr rnc, rnc, RT1, ror #24; \
+       and RT1, RMASK, rc, lsr#(8 - 3); \
+       orr rnb, rnb, RT2, ror #16; \
+       and RT2, RMASK, rc, lsr#(16 - 3); \
+       orr rna, rna, rd, ror #8; \
+       ldr RT0, [RTAB, RT0]; \
+       and rc,  RMASK, rc, lsr#(24 - 3); \
+       ldr RT1, [RTAB, RT1]; \
+       \
+       orr rnc, rnc, RT0; \
+       ldr RT2, [RTAB, RT2]; \
+       and RT0, RMASK, rb, lsl#3; \
+       ldr rc,  [RTAB, rc]; \
+       orr rnb, rnb, RT1, ror #24; \
+       and RT1, RMASK, rb, lsr#(8 - 3); \
+       orr rna, rna, RT2, ror #16; \
+       ldr RT0, [RTAB, RT0]; \
+       and RT2, RMASK, rb, lsr#(16 - 3); \
+       ldr RT1, [RTAB, RT1]; \
+       orr rnd, rnd, rc, ror #8; \
+       ldr RT2, [RTAB, RT2]; \
+       and rb,  RMASK, rb, lsr#(24 - 3); \
+       ldr rb,  [RTAB, rb]; \
+       \
+       orr rnb, rnb, RT0; \
+       orr rna, rna, RT1, ror #24; \
+       orr rnd, rnd, RT2, ror #16; \
+       orr rnc, rnc, rb, ror #8;
+
+#define firstencround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \
+       addroundkey(ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_first_key); \
+       do_encround((round) + 1, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_first_key);
+
+#define encround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key) \
+       do_encround((round) + 1, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_key);
+
+#define lastencround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \
+       add CTX, #(((round) + 1) * 16); \
+       add RTAB, #4; \
+       do_lastencround(ra, rb, rc, rd, rna, rnb, rnc, rnd); \
+       addroundkey(rna, rnb, rnc, rnd, ra, rb, rc, rd, dummy);
+
+.align 3
+.globl _gcry_aes_arm_encrypt_block
+.type   _gcry_aes_arm_encrypt_block,%function;
+
+_gcry_aes_arm_encrypt_block:
+       /* input:
+        *      %r0: keysched, CTX
+        *      %r1: dst
+        *      %r2: src
+        *      %r3: number of rounds.. 10, 12 or 14
+        */
+       push {%r4-%r11, %ip, %lr};
+
+       /* read input block */
+#ifndef __ARM_FEATURE_UNALIGNED
+       /* test if src is unaligned */
+       tst     %r2, #3;
+       beq     1f;
+
+       /* unaligned load */
+       ldr_unaligned_le(RA, %r2, 0, RNA);
+       ldr_unaligned_le(RB, %r2, 4, RNB);
+       ldr_unaligned_le(RC, %r2, 8, RNA);
+       ldr_unaligned_le(RD, %r2, 12, RNB);
+       b       2f;
+.ltorg
+1:
+#endif
+       /* aligned load */
+       ldm     %r2, {RA, RB, RC, RD};
+#ifndef __ARMEL__
+       rev     RA, RA;
+       rev     RB, RB;
+       rev     RC, RC;
+       rev     RD, RD;
+#endif
+2:
+       sub     %sp, #16;
+
+       ldr     RTAB, =.LtableE0;
+
+       str     %r1, [%sp, #4];         /* dst */
+       mov     RMASK, #0xff;
+       str     %r3, [%sp, #8];         /* nrounds */
+       mov     RMASK, RMASK, lsl#3;    /* 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);
+       encround(2, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+       encround(3, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+       encround(4, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+       encround(5, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+       encround(6, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+       encround(7, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+
+       ldr     RT0, [%sp, #8];         /* nrounds */
+       cmp     RT0, #12;
+       bge     .Lenc_not_128;
+
+       encround(8, RA, RB, RC, RD, RNA, RNB, RNC, RND, dummy);
+       lastencround(9, RNA, RNB, RNC, RND, RA, RB, RC, RD);
+
+.Lenc_done:
+       ldr     RT0, [%sp, #4];         /* dst */
+       add     %sp, #16;
+
+       /* store output block */
+#ifndef __ARM_FEATURE_UNALIGNED
+       /* test if dst is unaligned */
+       tst     RT0, #3;
+       beq     1f;
+
+       /* unaligned store */
+       str_unaligned_le(RA, RT0, 0, RNA, RNB);
+       str_unaligned_le(RB, RT0, 4, RNA, RNB);
+       str_unaligned_le(RC, RT0, 8, RNA, RNB);
+       str_unaligned_le(RD, RT0, 12, RNA, RNB);
+       b       2f;
+.ltorg
+1:
+#endif
+       /* aligned store */
+#ifndef __ARMEL__
+       rev     RA, RA;
+       rev     RB, RB;
+       rev     RC, RC;
+       rev     RD, RD;
+#endif
+       /* write output block */
+       stm     RT0, {RA, RB, RC, RD};
+2:
+       pop {%r4-%r11, %ip, %pc};
+
+.ltorg
+.Lenc_not_128:
+       beq .Lenc_192
+
+       encround(8, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+       encround(9, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+       encround(10, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+       encround(11, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+       encround(12, RA, RB, RC, RD, RNA, RNB, RNC, RND, dummy);
+       lastencround(13, RNA, RNB, RNC, RND, RA, RB, RC, RD);
+
+       b .Lenc_done;
+
+.ltorg
+.Lenc_192:
+       encround(8, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+       encround(9, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+       encround(10, RA, RB, RC, RD, RNA, RNB, RNC, RND, dummy);
+       lastencround(11, RNA, RNB, RNC, RND, RA, RB, RC, RD);
+
+       b .Lenc_done;
+.size _gcry_aes_arm_encrypt_block,.-_gcry_aes_arm_encrypt_block;
+
+#define addroundkey_dec(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \
+       ldr rna, [CTX, #(((round) * 16) + 0 * 4)]; \
+       ldr rnb, [CTX, #(((round) * 16) + 1 * 4)]; \
+       eor ra, rna; \
+       ldr rnc, [CTX, #(((round) * 16) + 2 * 4)]; \
+       eor rb, rnb; \
+       ldr rnd, [CTX, #(((round) * 16) + 3 * 4)]; \
+       eor rc, rnc; \
+       preload_first_key((round) - 1, rna); \
+       eor rd, rnd;
+
+#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; \
+       ldr rnc, [CTX, #(((next_r) * 16) + 2 * 4)]; \
+       and RT1, RMASK, ra, lsr#(8 - 3); \
+       ldr rnd, [CTX, #(((next_r) * 16) + 3 * 4)]; \
+       and RT2, RMASK, ra, lsr#(16 - 3); \
+       ldr RT0, [RTAB, RT0]; \
+       and ra,  RMASK, ra, lsr#(24 - 3); \
+       \
+       ldr RT1, [RTAB, RT1]; \
+       eor rna, rna, RT0; \
+       ldr RT2, [RTAB, RT2]; \
+       and RT0, RMASK, rb, lsl#3; \
+       ldr ra,  [RTAB, ra]; \
+       \
+       eor rnb, rnb, RT1, ror #24; \
+       and RT1, RMASK, rb, lsr#(8 - 3); \
+       eor rnc, rnc, RT2, ror #16; \
+       and RT2, RMASK, rb, lsr#(16 - 3); \
+       eor rnd, rnd, ra, ror #8; \
+       ldr RT0, [RTAB, RT0]; \
+       and rb,  RMASK, rb, lsr#(24 - 3); \
+       \
+       ldr RT1, [RTAB, RT1]; \
+       eor rnb, rnb, RT0; \
+       ldr RT2, [RTAB, RT2]; \
+       and RT0, RMASK, rc, lsl#3; \
+       ldr rb,  [RTAB, rb]; \
+       \
+       eor rnc, rnc, RT1, ror #24; \
+       and RT1, RMASK, rc, lsr#(8 - 3); \
+       eor rnd, rnd, RT2, ror #16; \
+       and RT2, RMASK, rc, lsr#(16 - 3); \
+       eor rna, rna, rb, ror #8; \
+       ldr RT0, [RTAB, RT0]; \
+       and rc,  RMASK, rc, lsr#(24 - 3); \
+       \
+       ldr RT1, [RTAB, RT1]; \
+       eor rnc, rnc, RT0; \
+       ldr RT2, [RTAB, RT2]; \
+       and RT0, RMASK, rd, lsl#3; \
+       ldr rc,  [RTAB, rc]; \
+       \
+       eor rnd, rnd, RT1, ror #24; \
+       and RT1, RMASK, rd, lsr#(8 - 3); \
+       eor rna, rna, RT2, ror #16; \
+       and RT2, RMASK, rd, lsr#(16 - 3); \
+       eor rnb, rnb, rc, ror #8; \
+       ldr RT0, [RTAB, RT0]; \
+       and rd,  RMASK, rd, lsr#(24 - 3); \
+       \
+       ldr RT1, [RTAB, RT1]; \
+       eor rnd, rnd, RT0; \
+       ldr RT2, [RTAB, RT2]; \
+       eor rna, rna, RT1, ror #24; \
+       ldr rd,  [RTAB, rd]; \
+       \
+       eor rnb, rnb, RT2, ror #16; \
+       preload_key((next_r) - 1, ra); \
+       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]; \
+       mov rnb, rnb, ror #24; \
+       ldr rnd, [RTAB, ra]; \
+       and RT1, RMASK, rb, lsr#(8 - 3); \
+       mov rnc, rnc, ror #16; \
+       and RT2, RMASK, rb, lsr#(16 - 3); \
+       mov rnd, rnd, ror #8; \
+       ldr RT0, [RTAB, RT0]; \
+       and rb,  RMASK, rb, lsr#(24 - 3); \
+       ldr RT1, [RTAB, RT1]; \
+       \
+       orr rnb, rnb, RT0; \
+       ldr RT2, [RTAB, RT2]; \
+       and RT0, RMASK, rc, lsl#3; \
+       ldr rb,  [RTAB, rb]; \
+       orr rnc, rnc, RT1, ror #24; \
+       and RT1, RMASK, rc, lsr#(8 - 3); \
+       orr rnd, rnd, RT2, ror #16; \
+       and RT2, RMASK, rc, lsr#(16 - 3); \
+       orr rna, rna, rb, ror #8; \
+       ldr RT0, [RTAB, RT0]; \
+       and rc,  RMASK, rc, lsr#(24 - 3); \
+       ldr RT1, [RTAB, RT1]; \
+       \
+       orr rnc, rnc, RT0; \
+       ldr RT2, [RTAB, RT2]; \
+       and RT0, RMASK, rd, lsl#3; \
+       ldr rc,  [RTAB, rc]; \
+       orr rnd, rnd, RT1, ror #24; \
+       and RT1, RMASK, rd, lsr#(8 - 3); \
+       orr rna, rna, RT2, ror #16; \
+       ldr RT0, [RTAB, RT0]; \
+       and RT2, RMASK, rd, lsr#(16 - 3); \
+       ldr RT1, [RTAB, RT1]; \
+       orr rnb, rnb, rc, ror #8; \
+       ldr RT2, [RTAB, RT2]; \
+       and rd,  RMASK, rd, lsr#(24 - 3); \
+       ldr rd,  [RTAB, rd]; \
+       \
+       orr rnd, rnd, RT0; \
+       orr rna, rna, RT1, ror #24; \
+       orr rnb, rnb, RT2, ror #16; \
+       orr rnc, rnc, rd, ror #8;
+
+#define firstdecround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \
+       addroundkey_dec(((round) + 1), ra, rb, rc, rd, rna, rnb, rnc, rnd); \
+       do_decround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd, preload_first_key);
+
+#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 lastdecround(round, ra, rb, rc, rd, rna, rnb, rnc, rnd) \
+       add RTAB, #4; \
+       do_lastdecround(ra, rb, rc, rd, rna, rnb, rnc, rnd); \
+       addroundkey(rna, rnb, rnc, rnd, ra, rb, rc, rd, dummy);
+
+.align 3
+.globl _gcry_aes_arm_decrypt_block
+.type   _gcry_aes_arm_decrypt_block,%function;
+
+_gcry_aes_arm_decrypt_block:
+       /* input:
+        *      %r0: keysched, CTX
+        *      %r1: dst
+        *      %r2: src
+        *      %r3: number of rounds.. 10, 12 or 14
+        */
+       push {%r4-%r11, %ip, %lr};
+
+       /* read input block */
+#ifndef __ARM_FEATURE_UNALIGNED
+       /* test if src is unaligned */
+       tst     %r2, #3;
+       beq     1f;
+
+       /* unaligned load */
+       ldr_unaligned_le(RA, %r2, 0, RNA);
+       ldr_unaligned_le(RB, %r2, 4, RNB);
+       ldr_unaligned_le(RC, %r2, 8, RNA);
+       ldr_unaligned_le(RD, %r2, 12, RNB);
+       b       2f;
+.ltorg
+1:
+#endif
+       /* aligned load */
+       ldm     %r2, {RA, RB, RC, RD};
+#ifndef __ARMEL__
+       rev     RA, RA;
+       rev     RB, RB;
+       rev     RC, RC;
+       rev     RD, RD;
+#endif
+2:
+       sub     %sp, #16;
+
+       ldr     RTAB, =.LtableD0;
+
+       mov     RMASK, #0xff;
+       str     %r1, [%sp, #4];         /* dst */
+       mov     RMASK, RMASK, lsl#3;    /* byte mask */
+
+       cmp     %r3, #12;
+       bge     .Ldec_256;
+
+       firstdecround(9, RA, RB, RC, RD, RNA, RNB, RNC, RND);
+.Ldec_tail:
+       decround(8, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+       decround(7, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+       decround(6, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+       decround(5, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+       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);
+       lastdecround(0, RNA, RNB, RNC, RND, RA, RB, RC, RD);
+
+       ldr     RT0, [%sp, #4];         /* dst */
+       add     %sp, #16;
+
+       /* store output block */
+#ifndef __ARM_FEATURE_UNALIGNED
+       /* test if dst is unaligned */
+       tst     RT0, #3;
+       beq     1f;
+
+       /* unaligned store */
+       str_unaligned_le(RA, RT0, 0, RNA, RNB);
+       str_unaligned_le(RB, RT0, 4, RNA, RNB);
+       str_unaligned_le(RC, RT0, 8, RNA, RNB);
+       str_unaligned_le(RD, RT0, 12, RNA, RNB);
+       b       2f;
+.ltorg
+1:
+#endif
+       /* aligned store */
+#ifndef __ARMEL__
+       rev     RA, RA;
+       rev     RB, RB;
+       rev     RC, RC;
+       rev     RD, RD;
+#endif
+       /* write output block */
+       stm     RT0, {RA, RB, RC, RD};
+2:
+       pop {%r4-%r11, %ip, %pc};
+
+.ltorg
+.Ldec_256:
+       beq .Ldec_192;
+
+       firstdecround(13, RA, RB, RC, RD, RNA, RNB, RNC, RND);
+       decround(12, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+       decround(11, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+       decround(10, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+       decround(9, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+
+       b .Ldec_tail;
+
+.ltorg
+.Ldec_192:
+       firstdecround(11, RA, RB, RC, RD, RNA, RNB, RNC, RND);
+       decround(10, RNA, RNB, RNC, RND, RA, RB, RC, RD, preload_first_key);
+       decround(9, RA, RB, RC, RD, RNA, RNB, RNC, RND, preload_first_key);
+
+       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__ */
index 2df8ea9..8019f0a 100644 (file)
@@ -1,6 +1,6 @@
 /* Rijndael (AES) for GnuPG
  * Copyright (C) 2000, 2001, 2002, 2003, 2007,
- *               2008, 2011 Free Software Foundation, Inc.
+ *               2008, 2011, 2012 Free Software Foundation, Inc.
  *
  * This file is part of Libgcrypt.
  *
@@ -45,6 +45,8 @@
 #include "types.h"  /* for byte and u32 typedefs */
 #include "g10lib.h"
 #include "cipher.h"
+#include "bufhelp.h"
+#include "cipher-selftest.h"
 
 #define MAXKC                  (256/32)
 #define MAXROUNDS              14
 
 
 /* Helper macro to force alignment to 16 bytes.  */
-#ifdef __GNUC__
+#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)
+# define USE_AMD64_ASM 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
-# if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__)
-#  define USE_PADLOCK 1
+# 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*/
 
    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 && __GNUC__ >= 4
-#  define USE_AESNI 1
+# 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 int m128i_t __attribute__ ((__vector_size__ (16)));
+  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.  */
@@ -90,6 +110,33 @@ typedef u32           u32_a_t;
 #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);
+#endif /*USE_ARM_ASM*/
+
+
 \f
 /* Our context object.  */
 typedef struct
@@ -116,15 +163,15 @@ typedef struct
     PROPERLY_ALIGNED_TYPE dummy;
     byte keyschedule[MAXROUNDS+1][4][4];
   } u2;
-  int rounds;               /* Key-length-dependent number of rounds.  */
-  int decryption_prepared;  /* The decryption key schedule is available.  */
+  int rounds;                /* Key-length-dependent number of rounds.  */
+  unsigned int decryption_prepared:1; /* The decryption key schedule is available.  */
 #ifdef USE_PADLOCK
-  int use_padlock;          /* Padlock shall be used.  */
+  unsigned int use_padlock:1;         /* Padlock shall be used.  */
 #endif /*USE_PADLOCK*/
 #ifdef USE_AESNI
-  int use_aesni;            /* AES-NI shall be used.  */
+  unsigned int use_aesni:1;           /* AES-NI shall be used.  */
 #endif /*USE_AESNI*/
-} RIJNDAEL_context;
+} RIJNDAEL_context ATTR_ALIGNED_16;
 
 /* Macros defining alias for the keyschedules.  */
 #define keyschenc  u1.keyschedule
@@ -142,10 +189,12 @@ typedef struct
   do { asm volatile ("pxor %%xmm0, %%xmm0\n\t"                          \
                      "pxor %%xmm1, %%xmm1\n" :: );                      \
   } while (0)
-# define aesni_cleanup_2_4()                                            \
+# define aesni_cleanup_2_6()                                            \
   do { asm volatile ("pxor %%xmm2, %%xmm2\n\t"                          \
                      "pxor %%xmm3, %%xmm3\n"                            \
-                     "pxor %%xmm4, %%xmm4\n":: );                       \
+                     "pxor %%xmm4, %%xmm4\n"                            \
+                     "pxor %%xmm5, %%xmm5\n"                            \
+                     "pxor %%xmm6, %%xmm6\n":: );                       \
   } while (0)
 #else
 # define aesni_prepare() do { } while (0)
@@ -159,8 +208,8 @@ typedef struct
 
 \f
 /* Function prototypes.  */
-#ifdef USE_AESNI
-/* We don't want to inline these functions to help gcc allocate enough
+#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)
@@ -174,6 +223,239 @@ static const char *selftest(void);
 
 
 \f
+#ifdef USE_AESNI
+static void
+aesni_do_setkey (RIJNDAEL_context *ctx, const byte *key)
+{
+  aesni_prepare();
+
+  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();
+}
+#endif /*USE_AESNI*/
+
+
+\f
 /* Perform the key setup.  */
 static gcry_err_code_t
 do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
@@ -183,18 +465,9 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
   int rounds;
   int i,j, r, t, rconpointer = 0;
   int KC;
-  union
-  {
-    PROPERLY_ALIGNED_TYPE dummy;
-    byte k[MAXKC][4];
-  } k;
-#define k k.k
-  union
-  {
-    PROPERLY_ALIGNED_TYPE dummy;
-    byte tk[MAXKC][4];
-  } tk;
-#define tk tk.tk
+#if defined(USE_AESNI) || defined(USE_PADLOCK)
+  unsigned int hwfeatures;
+#endif
 
   /* The on-the-fly self tests are only run in non-fips mode. In fips
      mode explicit self-tests are required.  Actually the on-the-fly
@@ -213,6 +486,10 @@ 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;
@@ -227,16 +504,18 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
       KC = 4;
 
       if (0)
-        ;
+        {
+          ;
+        }
 #ifdef USE_PADLOCK
-      else if ((_gcry_get_hw_features () & HWF_PADLOCK_AES))
+      else if (hwfeatures & HWF_PADLOCK_AES)
         {
           ctx->use_padlock = 1;
           memcpy (ctx->padlockkey, key, keylen);
         }
 #endif
 #ifdef USE_AESNI
-      else if ((_gcry_get_hw_features () & HWF_INTEL_AESNI))
+      else if (hwfeatures & HWF_INTEL_AESNI)
         {
           ctx->use_aesni = 1;
         }
@@ -252,7 +531,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
           ;
         }
 #ifdef USE_AESNI
-      else if ((_gcry_get_hw_features () & HWF_INTEL_AESNI))
+      else if (hwfeatures & HWF_INTEL_AESNI)
         {
           ctx->use_aesni = 1;
         }
@@ -268,7 +547,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
           ;
         }
 #ifdef USE_AESNI
-      else if ((_gcry_get_hw_features () & HWF_INTEL_AESNI))
+      else if (hwfeatures & HWF_INTEL_AESNI)
         {
           ctx->use_aesni = 1;
         }
@@ -279,81 +558,25 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
 
   ctx->rounds = rounds;
 
+  /* NB: We don't yet support Padlock hardware key generation.  */
+
   if (0)
-    ;
-#ifdef USE_PADLOCK
-  else if (ctx->use_padlock)
     {
-      /* Nothing to do as we support only hardware key generation for
-         now.  */
+      ;
     }
-#endif /*USE_PADLOCK*/
-#ifdef USE_AESNI_is_disabled_here
-  else if (ctx->use_aesni && ctx->rounds == 10)
-    {
-      /* Note: This code works for AES-128 but it is not much better
-         than using the standard key schedule.  We disable it for
-         now and don't put any effort into implementing this for
-         AES-192 and AES-256.  */
-      asm volatile ("movl   %[key], %%esi\n\t"
-                    "movdqu (%%esi), %%xmm1\n\t"     /* xmm1 := key   */
-                    "movl   %[ksch], %%esi\n\t"
-                    "movdqa %%xmm1, (%%esi)\n\t"     /* ksch[0] := xmm1  */
-                    "aeskeygenassist $0x01, %%xmm1, %%xmm2\n\t"
-                    "call .Lexpand128_%=\n\t"
-                    "movdqa %%xmm1, 0x10(%%esi)\n\t" /* ksch[1] := xmm1  */
-                    "aeskeygenassist $0x02, %%xmm1, %%xmm2\n\t"
-                    "call .Lexpand128_%=\n\t"
-                    "movdqa %%xmm1, 0x20(%%esi)\n\t" /* ksch[2] := xmm1  */
-                    "aeskeygenassist $0x04, %%xmm1, %%xmm2\n\t"
-                    "call .Lexpand128_%=\n\t"
-                    "movdqa %%xmm1, 0x30(%%esi)\n\t" /* ksch[3] := xmm1  */
-                    "aeskeygenassist $0x08, %%xmm1, %%xmm2\n\t"
-                    "call .Lexpand128_%=\n\t"
-                    "movdqa %%xmm1, 0x40(%%esi)\n\t" /* ksch[4] := xmm1  */
-                    "aeskeygenassist $0x10, %%xmm1, %%xmm2\n\t"
-                    "call .Lexpand128_%=\n\t"
-                    "movdqa %%xmm1, 0x50(%%esi)\n\t" /* ksch[5] := xmm1  */
-                    "aeskeygenassist $0x20, %%xmm1, %%xmm2\n\t"
-                    "call .Lexpand128_%=\n\t"
-                    "movdqa %%xmm1, 0x60(%%esi)\n\t" /* ksch[6] := xmm1  */
-                    "aeskeygenassist $0x40, %%xmm1, %%xmm2\n\t"
-                    "call .Lexpand128_%=\n\t"
-                    "movdqa %%xmm1, 0x70(%%esi)\n\t" /* ksch[7] := xmm1  */
-                    "aeskeygenassist $0x80, %%xmm1, %%xmm2\n\t"
-                    "call .Lexpand128_%=\n\t"
-                    "movdqa %%xmm1, 0x80(%%esi)\n\t" /* ksch[8] := xmm1  */
-                    "aeskeygenassist $0x1b, %%xmm1, %%xmm2\n\t"
-                    "call .Lexpand128_%=\n\t"
-                    "movdqa %%xmm1, 0x90(%%esi)\n\t" /* ksch[9] := xmm1  */
-                    "aeskeygenassist $0x36, %%xmm1, %%xmm2\n\t"
-                    "call .Lexpand128_%=\n\t"
-                    "movdqa %%xmm1, 0xa0(%%esi)\n\t" /* ksch[10] := xmm1  */
-                    "jmp .Lleave%=\n"
-
-                    ".Lexpand128_%=:\n\t"
-                    "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"
-                    "ret\n"
-
-                    ".Lleave%=:\n\t"
-                    "pxor %%xmm1, %%xmm1\n\t"
-                    "pxor %%xmm2, %%xmm2\n\t"
-                    "pxor %%xmm3, %%xmm3\n"
-                    :
-                    : [key] "g" (key), [ksch] "g" (ctx->keyschenc)
-                    : "%esi", "cc", "memory" );
-    }
-#endif /*USE_AESNI*/
+#ifdef USE_AESNI
+  else if (ctx->use_aesni)
+    aesni_do_setkey(ctx, key);
+#endif
   else
     {
+      union
+        {
+          PROPERLY_ALIGNED_TYPE dummy;
+          byte data[MAXKC][4];
+        } k, tk;
+#define k k.data
+#define tk tk.data
 #define W (ctx->keyschenc)
       for (i = 0; i < keylen; i++)
         {
@@ -362,7 +585,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
 
       for (j = KC-1; j >= 0; j--)
         {
-          *((u32*)tk[j]) = *((u32*)k[j]);
+          *((u32_a_t*)tk[j]) = *((u32_a_t*)k[j]);
         }
       r = 0;
       t = 0;
@@ -371,7 +594,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
         {
           for (; (j < KC) && (t < 4); j++, t++)
             {
-              *((u32*)W[r][t]) = *((u32*)tk[j]);
+              *((u32_a_t*)W[r][t]) = *((u32_a_t*)tk[j]);
             }
           if (t == 4)
             {
@@ -394,14 +617,14 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
             {
               for (j = 1; j < KC; j++)
                 {
-                  *((u32*)tk[j]) ^= *((u32*)tk[j-1]);
+                  *((u32_a_t*)tk[j]) ^= *((u32_a_t*)tk[j-1]);
                 }
             }
           else
             {
               for (j = 1; j < KC/2; j++)
                 {
-                  *((u32*)tk[j]) ^= *((u32*)tk[j-1]);
+                  *((u32_a_t*)tk[j]) ^= *((u32_a_t*)tk[j-1]);
                 }
               tk[KC/2][0] ^= S[tk[KC/2 - 1][0]];
               tk[KC/2][1] ^= S[tk[KC/2 - 1][1]];
@@ -409,7 +632,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
               tk[KC/2][3] ^= S[tk[KC/2 - 1][3]];
               for (j = KC/2 + 1; j < KC; j++)
                 {
-                  *((u32*)tk[j]) ^= *((u32*)tk[j-1]);
+                  *((u32_a_t*)tk[j]) ^= *((u32_a_t*)tk[j-1]);
                 }
             }
 
@@ -418,7 +641,7 @@ do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
             {
               for (; (j < KC) && (t < 4); j++, t++)
                 {
-                  *((u32*)W[r][t]) = *((u32*)tk[j]);
+                  *((u32_a_t*)W[r][t]) = *((u32_a_t*)tk[j]);
                 }
               if (t == 4)
                 {
@@ -428,11 +651,13 @@ 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));
     }
 
   return 0;
-#undef tk
-#undef k
 }
 
 
@@ -440,10 +665,7 @@ static gcry_err_code_t
 rijndael_setkey (void *context, const byte *key, const unsigned keylen)
 {
   RIJNDAEL_context *ctx = context;
-
-  int rc = do_setkey (ctx, key, keylen);
-  _gcry_burn_stack ( 100 + 16*sizeof(int));
-  return rc;
+  return do_setkey (ctx, key, keylen);
 }
 
 
@@ -459,22 +681,49 @@ 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.  */
-        m128i_t *ekey = (m128i_t*)ctx->keyschenc;
-        m128i_t *dkey = (m128i_t*)ctx->keyschdec;
+        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];
-        for (r=1, rr=ctx->rounds-1; r < ctx->rounds; r++, rr--)
-          {
-            asm volatile
-              ("movdqu %[ekey], %%xmm1\n\t"
-               /*"aesimc %%xmm1, %%xmm1\n\t"*/
-               ".byte 0x66, 0x0f, 0x38, 0xdb, 0xc9\n\t"
-               "movdqu %%xmm1, %[dkey]"
-               : [dkey] "=m" (dkey[r])
-               : [ekey] "m" (ekey[rr]) );
-          }
+        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();
     }
   else
 #endif /*USE_AESNI*/
@@ -488,32 +737,33 @@ prepare_decryption( RIJNDAEL_context *ctx )
 
       for (r=0; r < MAXROUNDS+1; r++ )
         {
-          *((u32*)ctx->keyschdec[r][0]) = *((u32*)ctx->keyschenc[r][0]);
-          *((u32*)ctx->keyschdec[r][1]) = *((u32*)ctx->keyschenc[r][1]);
-          *((u32*)ctx->keyschdec[r][2]) = *((u32*)ctx->keyschenc[r][2]);
-          *((u32*)ctx->keyschdec[r][3]) = *((u32*)ctx->keyschenc[r][3]);
+          *((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*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
-            ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[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]]);
 
           w = W[r][1];
-          *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
-            ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[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]]);
 
           w = W[r][2];
-          *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
-        ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[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]]);
 
           w = W[r][3];
-          *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
-            ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[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]]);
         }
 #undef W
 #undef w
+      wipememory(&w, sizeof(w));
     }
 }
 
@@ -524,6 +774,11 @@ static void
 do_encrypt_aligned (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)
   int rounds = ctx->rounds;
   int r;
@@ -605,6 +860,7 @@ do_encrypt_aligned (const RIJNDAEL_context *ctx,
   *((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*/
 }
 
 
@@ -612,6 +868,7 @@ 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))
@@ -627,11 +884,12 @@ do_encrypt (const RIJNDAEL_context *ctx,
         byte b[16] ATTR_ALIGNED_16;
       } b;
 
-      memcpy (a.a, ax, 16);
+      buf_cpy (a.a, ax, 16);
       do_encrypt_aligned (ctx, b.b, a.a);
-      memcpy (bx, b.b, 16);
+      buf_cpy (bx, b.b, 16);
     }
   else
+#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/
     {
       do_encrypt_aligned (ctx, bx, ax);
     }
@@ -650,6 +908,7 @@ do_padlock (const RIJNDAEL_context *ctx, int decrypt_flag,
   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
@@ -663,17 +922,28 @@ do_padlock (const RIJNDAEL_context *ctx, int decrypt_flag,
 
   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.  */
-     "movl $1, %%ecx\n\t"  /* Init counter for just one block.  */
-     ".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t" /* REP XSTORE ECB. */
+     ".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)
-     : "%ecx", "cc", "memory"
+     : "S" (a), "D" (b), "d" (cword), "r" (ctx->padlockkey), "c" (blocks)
+     : "cc", "memory"
      );
+#endif
 
   memcpy (bx, b, 16);
 
@@ -683,7 +953,7 @@ do_padlock (const RIJNDAEL_context *ctx, int decrypt_flag,
 
 #ifdef USE_AESNI
 /* Encrypt one block using the Intel AES-NI instructions.  A and B may
-   be the same; they need to be properly aligned to 16 bytes.
+   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
@@ -695,9 +965,9 @@ do_padlock (const RIJNDAEL_context *ctx, int decrypt_flag,
    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 void
-do_aesni_enc_aligned (const RIJNDAEL_context *ctx,
-                      unsigned char *b, const unsigned char *a)
+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"
@@ -708,40 +978,39 @@ do_aesni_enc_aligned (const RIJNDAEL_context *ctx,
      aligned but that is a special case.  We should better implement
      CFB direct in asm.  */
   asm volatile ("movdqu %[src], %%xmm0\n\t"     /* xmm0 := *a     */
-                "movl   %[key], %%esi\n\t"      /* esi  := keyschenc */
-                "movdqa (%%esi), %%xmm1\n\t"    /* xmm1 := key[0] */
+                "movdqa (%[key]), %%xmm1\n\t"    /* xmm1 := key[0] */
                 "pxor   %%xmm1, %%xmm0\n\t"     /* xmm0 ^= key[0] */
-                "movdqa 0x10(%%esi), %%xmm1\n\t"
+                "movdqa 0x10(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x20(%%esi), %%xmm1\n\t"
+                "movdqa 0x20(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x30(%%esi), %%xmm1\n\t"
+                "movdqa 0x30(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x40(%%esi), %%xmm1\n\t"
+                "movdqa 0x40(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x50(%%esi), %%xmm1\n\t"
+                "movdqa 0x50(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x60(%%esi), %%xmm1\n\t"
+                "movdqa 0x60(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x70(%%esi), %%xmm1\n\t"
+                "movdqa 0x70(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x80(%%esi), %%xmm1\n\t"
+                "movdqa 0x80(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x90(%%esi), %%xmm1\n\t"
+                "movdqa 0x90(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0xa0(%%esi), %%xmm1\n\t"
-                "cmp $10, %[rounds]\n\t"
+                "movdqa 0xa0(%[key]), %%xmm1\n\t"
+                "cmpl $10, %[rounds]\n\t"
                 "jz .Lenclast%=\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0xb0(%%esi), %%xmm1\n\t"
+                "movdqa 0xb0(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0xc0(%%esi), %%xmm1\n\t"
-                "cmp $12, %[rounds]\n\t"
+                "movdqa 0xc0(%[key]), %%xmm1\n\t"
+                "cmpl $12, %[rounds]\n\t"
                 "jz .Lenclast%=\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0xd0(%%esi), %%xmm1\n\t"
+                "movdqa 0xd0(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0xe0(%%esi), %%xmm1\n"
+                "movdqa 0xe0(%[key]), %%xmm1\n"
 
                 ".Lenclast%=:\n\t"
                 aesenclast_xmm1_xmm0
@@ -750,53 +1019,52 @@ do_aesni_enc_aligned (const RIJNDAEL_context *ctx,
                 : [src] "m" (*a),
                   [key] "r" (ctx->keyschenc),
                   [rounds] "r" (ctx->rounds)
-                : "%esi", "cc", "memory");
+                : "cc", "memory");
 #undef aesenc_xmm1_xmm0
 #undef aesenclast_xmm1_xmm0
 }
 
 
-static void
-do_aesni_dec_aligned (const RIJNDAEL_context *ctx,
-                      unsigned char *b, const unsigned char *a)
+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     */
-                "movl   %[key], %%esi\n\t"
-                "movdqa (%%esi), %%xmm1\n\t"
+                "movdqa (%[key]), %%xmm1\n\t"
                 "pxor   %%xmm1, %%xmm0\n\t"     /* xmm0 ^= key[0] */
-                "movdqa 0x10(%%esi), %%xmm1\n\t"
+                "movdqa 0x10(%[key]), %%xmm1\n\t"
                 aesdec_xmm1_xmm0
-                "movdqa 0x20(%%esi), %%xmm1\n\t"
+                "movdqa 0x20(%[key]), %%xmm1\n\t"
                 aesdec_xmm1_xmm0
-                "movdqa 0x30(%%esi), %%xmm1\n\t"
+                "movdqa 0x30(%[key]), %%xmm1\n\t"
                 aesdec_xmm1_xmm0
-                "movdqa 0x40(%%esi), %%xmm1\n\t"
+                "movdqa 0x40(%[key]), %%xmm1\n\t"
                 aesdec_xmm1_xmm0
-                "movdqa 0x50(%%esi), %%xmm1\n\t"
+                "movdqa 0x50(%[key]), %%xmm1\n\t"
                 aesdec_xmm1_xmm0
-                "movdqa 0x60(%%esi), %%xmm1\n\t"
+                "movdqa 0x60(%[key]), %%xmm1\n\t"
                 aesdec_xmm1_xmm0
-                "movdqa 0x70(%%esi), %%xmm1\n\t"
+                "movdqa 0x70(%[key]), %%xmm1\n\t"
                 aesdec_xmm1_xmm0
-                "movdqa 0x80(%%esi), %%xmm1\n\t"
+                "movdqa 0x80(%[key]), %%xmm1\n\t"
                 aesdec_xmm1_xmm0
-                "movdqa 0x90(%%esi), %%xmm1\n\t"
+                "movdqa 0x90(%[key]), %%xmm1\n\t"
                 aesdec_xmm1_xmm0
-                "movdqa 0xa0(%%esi), %%xmm1\n\t"
-                "cmp $10, %[rounds]\n\t"
+                "movdqa 0xa0(%[key]), %%xmm1\n\t"
+                "cmpl $10, %[rounds]\n\t"
                 "jz .Ldeclast%=\n\t"
                 aesdec_xmm1_xmm0
-                "movdqa 0xb0(%%esi), %%xmm1\n\t"
+                "movdqa 0xb0(%[key]), %%xmm1\n\t"
                 aesdec_xmm1_xmm0
-                "movdqa 0xc0(%%esi), %%xmm1\n\t"
-                "cmp $12, %[rounds]\n\t"
+                "movdqa 0xc0(%[key]), %%xmm1\n\t"
+                "cmpl $12, %[rounds]\n\t"
                 "jz .Ldeclast%=\n\t"
                 aesdec_xmm1_xmm0
-                "movdqa 0xd0(%%esi), %%xmm1\n\t"
+                "movdqa 0xd0(%[key]), %%xmm1\n\t"
                 aesdec_xmm1_xmm0
-                "movdqa 0xe0(%%esi), %%xmm1\n"
+                "movdqa 0xe0(%[key]), %%xmm1\n"
 
                 ".Ldeclast%=:\n\t"
                 aesdeclast_xmm1_xmm0
@@ -805,12 +1073,230 @@ do_aesni_dec_aligned (const RIJNDAEL_context *ctx,
                 : [src] "m" (*a),
                   [key] "r" (ctx->keyschdec),
                   [rounds] "r" (ctx->rounds)
-                : "%esi", "cc", "memory");
+                : "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 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
@@ -822,47 +1308,46 @@ do_aesni_cfb (const RIJNDAEL_context *ctx, int decrypt_flag,
 #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     */
-                "movl   %[key], %%esi\n\t"      /* esi  := keyschenc */
-                "movdqa (%%esi), %%xmm1\n\t"    /* xmm1 := key[0] */
+                "movdqa (%[key]), %%xmm1\n\t"    /* xmm1 := key[0] */
                 "pxor   %%xmm1, %%xmm0\n\t"     /* xmm0 ^= key[0] */
-                "movdqa 0x10(%%esi), %%xmm1\n\t"
+                "movdqa 0x10(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x20(%%esi), %%xmm1\n\t"
+                "movdqa 0x20(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x30(%%esi), %%xmm1\n\t"
+                "movdqa 0x30(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x40(%%esi), %%xmm1\n\t"
+                "movdqa 0x40(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x50(%%esi), %%xmm1\n\t"
+                "movdqa 0x50(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x60(%%esi), %%xmm1\n\t"
+                "movdqa 0x60(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x70(%%esi), %%xmm1\n\t"
+                "movdqa 0x70(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x80(%%esi), %%xmm1\n\t"
+                "movdqa 0x80(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x90(%%esi), %%xmm1\n\t"
+                "movdqa 0x90(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0xa0(%%esi), %%xmm1\n\t"
-                "cmp $10, %[rounds]\n\t"
+                "movdqa 0xa0(%[key]), %%xmm1\n\t"
+                "cmpl $10, %[rounds]\n\t"
                 "jz .Lenclast%=\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0xb0(%%esi), %%xmm1\n\t"
+                "movdqa 0xb0(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0xc0(%%esi), %%xmm1\n\t"
-                "cmp $12, %[rounds]\n\t"
+                "movdqa 0xc0(%[key]), %%xmm1\n\t"
+                "cmpl $12, %[rounds]\n\t"
                 "jz .Lenclast%=\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0xd0(%%esi), %%xmm1\n\t"
+                "movdqa 0xd0(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0xe0(%%esi), %%xmm1\n"
+                "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  */
 
-                "cmp $1, %[decrypt]\n\t"
+                "cmpl $1, %[decrypt]\n\t"
                 "jz .Ldecrypt_%=\n\t"
                 "movdqa %%xmm0, %[iv]\n\t"       /* [encrypt] Store IV.  */
                 "jmp .Lleave_%=\n"
@@ -872,10 +1357,10 @@ do_aesni_cfb (const RIJNDAEL_context *ctx, int decrypt_flag,
                 "movdqu %%xmm0, %[dst]\n"        /* Store output.   */
                 : [iv] "+m" (*iv), [dst] "=m" (*b)
                 : [src] "m" (*a),
-                  [key] "g" (ctx->keyschenc),
+                  [key] "r" (ctx->keyschenc),
                   [rounds] "g" (ctx->rounds),
                   [decrypt] "m" (decrypt_flag)
-                : "%esi", "cc", "memory");
+                : "cc", "memory");
 #undef aesenc_xmm1_xmm0
 #undef aesenclast_xmm1_xmm0
 }
@@ -889,52 +1374,60 @@ do_aesni_ctr (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"
-  static unsigned char be_mask[16] __attribute__ ((aligned (16))) =
-    { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
-
-  asm volatile ("movdqa %[ctr], %%xmm0\n\t"     /* xmm0, xmm2 := CTR   */
-                "movaps %%xmm0, %%xmm2\n\t"
-                "mov    $1, %%esi\n\t"          /* xmm2++ (big-endian) */
-                "movd   %%esi, %%xmm1\n\t"
-                "pshufb %[mask], %%xmm2\n\t"
-                "paddq  %%xmm1, %%xmm2\n\t"
-                "pshufb %[mask], %%xmm2\n\t"
-                "movdqa %%xmm2, %[ctr]\n"       /* Update CTR.         */
-
-                "movl   %[key], %%esi\n\t"      /* esi  := keyschenc */
-                "movdqa (%%esi), %%xmm1\n\t"    /* xmm1 := key[0]    */
-                "pxor   %%xmm1, %%xmm0\n\t"     /* xmm0 ^= key[0]    */
-                "movdqa 0x10(%%esi), %%xmm1\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(%%esi), %%xmm1\n\t"
+                "movdqa 0x20(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x30(%%esi), %%xmm1\n\t"
+                "movdqa 0x30(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x40(%%esi), %%xmm1\n\t"
+                "movdqa 0x40(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x50(%%esi), %%xmm1\n\t"
+                "movdqa 0x50(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x60(%%esi), %%xmm1\n\t"
+                "movdqa 0x60(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x70(%%esi), %%xmm1\n\t"
+                "movdqa 0x70(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x80(%%esi), %%xmm1\n\t"
+                "movdqa 0x80(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0x90(%%esi), %%xmm1\n\t"
+                "movdqa 0x90(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0xa0(%%esi), %%xmm1\n\t"
-                "cmp $10, %[rounds]\n\t"
+                "movdqa 0xa0(%[key]), %%xmm1\n\t"
+                "cmpl $10, %[rounds]\n\t"
                 "jz .Lenclast%=\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0xb0(%%esi), %%xmm1\n\t"
+                "movdqa 0xb0(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0xc0(%%esi), %%xmm1\n\t"
-                "cmp $12, %[rounds]\n\t"
+                "movdqa 0xc0(%[key]), %%xmm1\n\t"
+                "cmpl $12, %[rounds]\n\t"
                 "jz .Lenclast%=\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0xd0(%%esi), %%xmm1\n\t"
+                "movdqa 0xd0(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
-                "movdqa 0xe0(%%esi), %%xmm1\n"
+                "movdqa 0xe0(%[key]), %%xmm1\n"
 
                 ".Lenclast%=:\n\t"
                 aesenclast_xmm1_xmm0
@@ -942,12 +1435,12 @@ do_aesni_ctr (const RIJNDAEL_context *ctx,
                 "pxor %%xmm1, %%xmm0\n\t"        /* EncCTR ^= input  */
                 "movdqu %%xmm0, %[dst]"          /* Store EncCTR.    */
 
-                : [ctr] "+m" (*ctr), [dst] "=m" (*b)
+                : [dst] "=m" (*b)
                 : [src] "m" (*a),
-                  [key] "g" (ctx->keyschenc),
-                  [rounds] "g" (ctx->rounds),
-                  [mask] "m" (*be_mask)
-                : "%esi", "cc", "memory");
+                  [ctr] "r" (ctr),
+                  [key] "r" (ctx->keyschenc),
+                  [rounds] "g" (ctx->rounds)
+                : "cc", "memory");
 #undef aesenc_xmm1_xmm0
 #undef aesenclast_xmm1_xmm0
 }
@@ -967,9 +1460,6 @@ do_aesni_ctr_4 (const RIJNDAEL_context *ctx,
 #define aesenclast_xmm1_xmm3  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd9\n\t"
 #define aesenclast_xmm1_xmm4  ".byte 0x66, 0x0f, 0x38, 0xdd, 0xe1\n\t"
 
-  static unsigned char be_mask[16] __attribute__ ((aligned (16))) =
-    { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
-
   /* Register usage:
       esi   keyschedule
       xmm0  CTR-0
@@ -977,103 +1467,131 @@ do_aesni_ctr_4 (const RIJNDAEL_context *ctx,
       xmm2  CTR-1
       xmm3  CTR-2
       xmm4  CTR-3
-      xmm5  temp
+      xmm5  copy of *ctr
+      xmm6  endian swapping mask
    */
 
-  asm volatile ("movdqa %[ctr], %%xmm0\n\t"     /* xmm0, xmm2 := CTR   */
-                "movaps %%xmm0, %%xmm2\n\t"
-                "mov    $1, %%esi\n\t"          /* xmm1 := 1 */
-                "movd   %%esi, %%xmm1\n\t"
-                "pshufb %[mask], %%xmm2\n\t"    /* xmm2 := le(xmm2) */
-                "paddq  %%xmm1, %%xmm2\n\t"     /* xmm2++           */
-                "movaps %%xmm2, %%xmm3\n\t"     /* xmm3 := xmm2     */
-                "paddq  %%xmm1, %%xmm3\n\t"     /* xmm3++           */
-                "movaps %%xmm3, %%xmm4\n\t"     /* xmm4 := xmm3     */
-                "paddq  %%xmm1, %%xmm4\n\t"     /* xmm4++           */
-                "movaps %%xmm4, %%xmm5\n\t"     /* xmm5 := xmm4     */
-                "paddq  %%xmm1, %%xmm5\n\t"     /* xmm5++           */
-                "pshufb %[mask], %%xmm2\n\t"    /* xmm2 := be(xmm2) */
-                "pshufb %[mask], %%xmm3\n\t"    /* xmm3 := be(xmm3) */
-                "pshufb %[mask], %%xmm4\n\t"    /* xmm4 := be(xmm4) */
-                "pshufb %[mask], %%xmm5\n\t"    /* xmm5 := be(xmm5) */
-                "movdqa %%xmm5, %[ctr]\n"       /* Update CTR.      */
-
-                "movl   %[key], %%esi\n\t"      /* esi  := keyschenc */
-                "movdqa (%%esi), %%xmm1\n\t"    /* xmm1 := key[0]    */
+  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(%%esi), %%xmm1\n\t"
+                "movdqa 0x10(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
                 aesenc_xmm1_xmm2
                 aesenc_xmm1_xmm3
                 aesenc_xmm1_xmm4
-                "movdqa 0x20(%%esi), %%xmm1\n\t"
+                "movdqa 0x20(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
                 aesenc_xmm1_xmm2
                 aesenc_xmm1_xmm3
                 aesenc_xmm1_xmm4
-                "movdqa 0x30(%%esi), %%xmm1\n\t"
+                "movdqa 0x30(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
                 aesenc_xmm1_xmm2
                 aesenc_xmm1_xmm3
                 aesenc_xmm1_xmm4
-                "movdqa 0x40(%%esi), %%xmm1\n\t"
+                "movdqa 0x40(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
                 aesenc_xmm1_xmm2
                 aesenc_xmm1_xmm3
                 aesenc_xmm1_xmm4
-                "movdqa 0x50(%%esi), %%xmm1\n\t"
+                "movdqa 0x50(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
                 aesenc_xmm1_xmm2
                 aesenc_xmm1_xmm3
                 aesenc_xmm1_xmm4
-                "movdqa 0x60(%%esi), %%xmm1\n\t"
+                "movdqa 0x60(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
                 aesenc_xmm1_xmm2
                 aesenc_xmm1_xmm3
                 aesenc_xmm1_xmm4
-                "movdqa 0x70(%%esi), %%xmm1\n\t"
+                "movdqa 0x70(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
                 aesenc_xmm1_xmm2
                 aesenc_xmm1_xmm3
                 aesenc_xmm1_xmm4
-                "movdqa 0x80(%%esi), %%xmm1\n\t"
+                "movdqa 0x80(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
                 aesenc_xmm1_xmm2
                 aesenc_xmm1_xmm3
                 aesenc_xmm1_xmm4
-                "movdqa 0x90(%%esi), %%xmm1\n\t"
+                "movdqa 0x90(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
                 aesenc_xmm1_xmm2
                 aesenc_xmm1_xmm3
                 aesenc_xmm1_xmm4
-                "movdqa 0xa0(%%esi), %%xmm1\n\t"
-                "cmp $10, %[rounds]\n\t"
+                "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(%%esi), %%xmm1\n\t"
+                "movdqa 0xb0(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
                 aesenc_xmm1_xmm2
                 aesenc_xmm1_xmm3
                 aesenc_xmm1_xmm4
-                "movdqa 0xc0(%%esi), %%xmm1\n\t"
-                "cmp $12, %[rounds]\n\t"
+                "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(%%esi), %%xmm1\n\t"
+                "movdqa 0xd0(%[key]), %%xmm1\n\t"
                 aesenc_xmm1_xmm0
                 aesenc_xmm1_xmm2
                 aesenc_xmm1_xmm3
                 aesenc_xmm1_xmm4
-                "movdqa 0xe0(%%esi), %%xmm1\n"
+                "movdqa 0xe0(%[key]), %%xmm1\n"
 
                 ".Lenclast%=:\n\t"
                 aesenclast_xmm1_xmm0
@@ -1081,27 +1599,28 @@ do_aesni_ctr_4 (const RIJNDAEL_context *ctx,
                 aesenclast_xmm1_xmm3
                 aesenclast_xmm1_xmm4
 
-                "movdqu %[src], %%xmm1\n\t"      /* Get block 1.      */
+                "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 %%xmm0, (%[dst])\n\t"    /* Store block 1     */
 
-                "movdqu (16)%[src], %%xmm1\n\t"  /* Get block 2.      */
+                "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 %%xmm2, 16(%[dst])\n\t"  /* Store block 2.    */
 
-                "movdqu (32)%[src], %%xmm1\n\t"  /* Get block 3.      */
+                "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 %%xmm3, 32(%[dst])\n\t"  /* Store block 3.    */
 
-                "movdqu (48)%[src], %%xmm1\n\t"  /* Get block 4.      */
+                "movdqu 48(%[src]), %%xmm1\n\t"  /* Get block 4.      */
                 "pxor %%xmm1, %%xmm4\n\t"        /* EncCTR-4 ^= input */
-                "movdqu %%xmm4, (48)%[dst]"      /* Store block 4.   */
+                "movdqu %%xmm4, 48(%[dst])"      /* Store block 4.   */
 
-                : [ctr] "+m" (*ctr), [dst] "=m" (*b)
-                : [src] "m" (*a),
-                  [key] "g" (ctx->keyschenc),
-                  [rounds] "g" (ctx->rounds),
-                  [mask] "m" (*be_mask)
+                :
+                : [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
@@ -1113,31 +1632,14 @@ do_aesni_ctr_4 (const RIJNDAEL_context *ctx,
 #undef aesenclast_xmm1_xmm4
 }
 
-
-static void
-do_aesni (RIJNDAEL_context *ctx, int decrypt_flag,
-          unsigned char *bx, const unsigned char *ax)
-{
-
-  if (decrypt_flag)
-    {
-      if (!ctx->decryption_prepared )
-        {
-          prepare_decryption ( ctx );
-          ctx->decryption_prepared = 1;
-        }
-      do_aesni_dec_aligned (ctx, bx, ax);
-    }
-  else
-    do_aesni_enc_aligned (ctx, bx, ax);
-}
 #endif /*USE_AESNI*/
 
 
-static void
+static unsigned int
 rijndael_encrypt (void *context, byte *b, const byte *a)
 {
   RIJNDAEL_context *ctx = context;
+  unsigned int burn_stack;
 
   if (0)
     ;
@@ -1145,22 +1647,25 @@ rijndael_encrypt (void *context, byte *b, const byte *a)
   else if (ctx->use_padlock)
     {
       do_padlock (ctx, 0, b, a);
-      _gcry_burn_stack (48 + 15 /* possible padding for alignment */);
+      burn_stack = (48 + 15 /* possible padding for alignment */);
     }
 #endif /*USE_PADLOCK*/
 #ifdef USE_AESNI
   else if (ctx->use_aesni)
     {
       aesni_prepare ();
-      do_aesni (ctx, 0, b, a);
+      do_aesni_enc (ctx, b, a);
       aesni_cleanup ();
+      burn_stack = 0;
     }
 #endif /*USE_AESNI*/
   else
     {
       do_encrypt (ctx, b, a);
-      _gcry_burn_stack (56 + 2*sizeof(int));
+      burn_stack = (56 + 2*sizeof(int));
     }
+
+  return burn_stack;
 }
 
 
@@ -1171,13 +1676,12 @@ rijndael_encrypt (void *context, byte *b, const byte *a)
 void
 _gcry_aes_cfb_enc (void *context, unsigned char *iv,
                    void *outbuf_arg, const void *inbuf_arg,
-                   unsigned int nblocks)
+                   size_t nblocks)
 {
   RIJNDAEL_context *ctx = context;
   unsigned char *outbuf = outbuf_arg;
   const unsigned char *inbuf = inbuf_arg;
-  unsigned char *ivp;
-  int i;
+  unsigned int burn_depth = 48 + 2*sizeof(int);
 
   if (0)
     ;
@@ -1190,8 +1694,9 @@ _gcry_aes_cfb_enc (void *context, unsigned char *iv,
           /* Encrypt the IV. */
           do_padlock (ctx, 0, iv, iv);
           /* XOR the input with the IV and store input into IV.  */
-          for (ivp=iv,i=0; i < BLOCKSIZE; i++ )
-            *outbuf++ = (*ivp++ ^= *inbuf++);
+          buf_xor_2dst(outbuf, iv, inbuf, BLOCKSIZE);
+          outbuf += BLOCKSIZE;
+          inbuf  += BLOCKSIZE;
         }
     }
 #endif /*USE_PADLOCK*/
@@ -1206,6 +1711,8 @@ _gcry_aes_cfb_enc (void *context, unsigned char *iv,
           inbuf  += BLOCKSIZE;
         }
       aesni_cleanup ();
+
+      burn_depth = 0; /* No stack usage. */
     }
 #endif /*USE_AESNI*/
   else
@@ -1215,12 +1722,14 @@ _gcry_aes_cfb_enc (void *context, unsigned char *iv,
           /* Encrypt the IV. */
           do_encrypt_aligned (ctx, iv, iv);
           /* XOR the input with the IV and store input into IV.  */
-          for (ivp=iv,i=0; i < BLOCKSIZE; i++ )
-            *outbuf++ = (*ivp++ ^= *inbuf++);
+          buf_xor_2dst(outbuf, iv, inbuf, BLOCKSIZE);
+          outbuf += BLOCKSIZE;
+          inbuf  += BLOCKSIZE;
         }
     }
 
-  _gcry_burn_stack (48 + 2*sizeof(int));
+  if (burn_depth)
+    _gcry_burn_stack (burn_depth);
 }
 
 
@@ -1231,41 +1740,93 @@ _gcry_aes_cfb_enc (void *context, unsigned char *iv,
 void
 _gcry_aes_cbc_enc (void *context, unsigned char *iv,
                    void *outbuf_arg, const void *inbuf_arg,
-                   unsigned int nblocks, int cbc_mac)
+                   size_t nblocks, int cbc_mac)
 {
   RIJNDAEL_context *ctx = context;
   unsigned char *outbuf = outbuf_arg;
   const unsigned char *inbuf = inbuf_arg;
-  unsigned char *ivp;
-  int i;
+  unsigned char *last_iv;
+  unsigned int burn_depth = 48 + 2*sizeof(int);
+#ifdef USE_AESNI
+  int use_aesni = ctx->use_aesni;
+#endif
+
+#ifdef USE_AESNI
+  if (use_aesni)
+    aesni_prepare ();
+#endif /*USE_AESNI*/
+
+  last_iv = iv;
 
-  aesni_prepare ();
   for ( ;nblocks; nblocks-- )
     {
-      for (ivp=iv, i=0; i < BLOCKSIZE; i++ )
-        outbuf[i] = inbuf[i] ^ *ivp++;
-
       if (0)
         ;
-#ifdef USE_PADLOCK
-      else if (ctx->use_padlock)
-        do_padlock (ctx, 0, outbuf, outbuf);
-#endif /*USE_PADLOCK*/
 #ifdef USE_AESNI
-      else if (ctx->use_aesni)
-        do_aesni (ctx, 0, outbuf, outbuf);
+      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
-        do_encrypt (ctx, outbuf, outbuf );
+        {
+          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 );
+        }
 
-      memcpy (iv, outbuf, BLOCKSIZE);
+      last_iv = outbuf;
       inbuf += BLOCKSIZE;
       if (!cbc_mac)
         outbuf += BLOCKSIZE;
     }
-  aesni_cleanup ();
 
-  _gcry_burn_stack (48 + 2*sizeof(int));
+  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
+        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);
 }
 
 
@@ -1277,12 +1838,12 @@ _gcry_aes_cbc_enc (void *context, unsigned char *iv,
 void
 _gcry_aes_ctr_enc (void *context, unsigned char *ctr,
                    void *outbuf_arg, const void *inbuf_arg,
-                   unsigned int nblocks)
+                   size_t nblocks)
 {
   RIJNDAEL_context *ctx = context;
   unsigned char *outbuf = outbuf_arg;
   const unsigned char *inbuf = inbuf_arg;
-  unsigned char *p;
+  unsigned int burn_depth = 48 + 2*sizeof(int);
   int i;
 
   if (0)
@@ -1290,7 +1851,18 @@ _gcry_aes_ctr_enc (void *context, unsigned char *ctr,
 #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);
@@ -1304,7 +1876,9 @@ _gcry_aes_ctr_enc (void *context, unsigned char *ctr,
           inbuf  += BLOCKSIZE;
         }
       aesni_cleanup ();
-      aesni_cleanup_2_4 ();
+      aesni_cleanup_2_6 ();
+
+      burn_depth = 0; /* No stack usage. */
     }
 #endif /*USE_AESNI*/
   else
@@ -1316,8 +1890,9 @@ _gcry_aes_ctr_enc (void *context, unsigned char *ctr,
           /* Encrypt the counter. */
           do_encrypt_aligned (ctx, tmp.x1, ctr);
           /* XOR the input with the encrypted counter and store in output.  */
-          for (p=tmp.x1, i=0; i < BLOCKSIZE; i++)
-            *outbuf++ = (*p++ ^= *inbuf++);
+          buf_xor(outbuf, tmp.x1, inbuf, BLOCKSIZE);
+          outbuf += BLOCKSIZE;
+          inbuf  += BLOCKSIZE;
           /* Increment the counter.  */
           for (i = BLOCKSIZE; i > 0; i--)
             {
@@ -1328,7 +1903,8 @@ _gcry_aes_ctr_enc (void *context, unsigned char *ctr,
         }
     }
 
-  _gcry_burn_stack (48 + 2*sizeof(int));
+  if (burn_depth)
+    _gcry_burn_stack (burn_depth);
 }
 
 
@@ -1340,6 +1916,11 @@ static void
 do_decrypt_aligned (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)
   int rounds = ctx->rounds;
   int r;
@@ -1422,6 +2003,7 @@ do_decrypt_aligned (RIJNDAEL_context *ctx,
   *((u32_a_t*)(b+ 8)) ^= *((u32_a_t*)rk[0][2]);
   *((u32_a_t*)(b+12)) ^= *((u32_a_t*)rk[0][3]);
 #undef rk
+#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/
 }
 
 
@@ -1429,13 +2011,7 @@ do_decrypt_aligned (RIJNDAEL_context *ctx,
 static void
 do_decrypt (RIJNDAEL_context *ctx, byte *bx, const byte *ax)
 {
-  if ( !ctx->decryption_prepared )
-    {
-      prepare_decryption ( ctx );
-      _gcry_burn_stack (64);
-      ctx->decryption_prepared = 1;
-    }
-
+#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))
@@ -1451,23 +2027,42 @@ do_decrypt (RIJNDAEL_context *ctx, byte *bx, const byte *ax)
         byte b[16] ATTR_ALIGNED_16;
       } b;
 
-      memcpy (a.a, ax, 16);
+      buf_cpy (a.a, ax, 16);
       do_decrypt_aligned (ctx, b.b, a.a);
-      memcpy (bx, b.b, 16);
+      buf_cpy (bx, b.b, 16);
     }
   else
+#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/
     {
       do_decrypt_aligned (ctx, bx, ax);
     }
 }
 
 
+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 )
+    {
+      prepare_decryption ( ctx );
+      ctx->decryption_prepared = 1;
+    }
+}
 
 
-static void
+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)
     ;
@@ -1475,40 +2070,41 @@ rijndael_decrypt (void *context, byte *b, const byte *a)
   else if (ctx->use_padlock)
     {
       do_padlock (ctx, 1, b, a);
-      _gcry_burn_stack (48 + 2*sizeof(int) /* FIXME */);
+      burn_stack = (48 + 2*sizeof(int) /* FIXME */);
     }
 #endif /*USE_PADLOCK*/
 #ifdef USE_AESNI
   else if (ctx->use_aesni)
     {
       aesni_prepare ();
-      do_aesni (ctx, 1, b, a);
+      do_aesni_dec (ctx, b, a);
       aesni_cleanup ();
+      burn_stack = 0;
     }
 #endif /*USE_AESNI*/
   else
     {
       do_decrypt (ctx, b, a);
-      _gcry_burn_stack (56+2*sizeof(int));
+      burn_stack = (56+2*sizeof(int));
     }
+
+  return burn_stack;
 }
 
 
 /* Bulk decryption of complete blocks in CFB mode.  Caller needs to
-   make sure that IV is aligned on an unisgned lonhg boundary.  This
+   make sure that IV is aligned on an unsigned long boundary.  This
    function is only intended for the bulk encryption feature of
    cipher.c. */
 void
 _gcry_aes_cfb_dec (void *context, unsigned char *iv,
                    void *outbuf_arg, const void *inbuf_arg,
-                   unsigned int nblocks)
+                   size_t nblocks)
 {
   RIJNDAEL_context *ctx = context;
   unsigned char *outbuf = outbuf_arg;
   const unsigned char *inbuf = inbuf_arg;
-  unsigned char *ivp;
-  unsigned char temp;
-  int i;
+  unsigned int burn_depth = 48 + 2*sizeof(int);
 
   if (0)
     ;
@@ -1519,12 +2115,9 @@ _gcry_aes_cfb_dec (void *context, unsigned char *iv,
       for ( ;nblocks; nblocks-- )
         {
           do_padlock (ctx, 0, iv, iv);
-          for (ivp=iv,i=0; i < BLOCKSIZE; i++ )
-            {
-              temp = *inbuf++;
-              *outbuf++ = *ivp ^ temp;
-              *ivp++ = temp;
-            }
+          buf_xor_n_copy(outbuf, iv, inbuf, BLOCKSIZE);
+          outbuf += BLOCKSIZE;
+          inbuf  += BLOCKSIZE;
         }
     }
 #endif /*USE_PADLOCK*/
@@ -1532,6 +2125,50 @@ _gcry_aes_cfb_dec (void *context, unsigned char *iv,
   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);
@@ -1539,6 +2176,9 @@ _gcry_aes_cfb_dec (void *context, unsigned char *iv,
           inbuf  += BLOCKSIZE;
         }
       aesni_cleanup ();
+      aesni_cleanup_2_6 ();
+
+      burn_depth = 0; /* No stack usage. */
     }
 #endif /*USE_AESNI*/
   else
@@ -1546,16 +2186,14 @@ _gcry_aes_cfb_dec (void *context, unsigned char *iv,
       for ( ;nblocks; nblocks-- )
         {
           do_encrypt_aligned (ctx, iv, iv);
-          for (ivp=iv,i=0; i < BLOCKSIZE; i++ )
-            {
-              temp = *inbuf++;
-              *outbuf++ = *ivp ^ temp;
-              *ivp++ = temp;
-            }
+          buf_xor_n_copy(outbuf, iv, inbuf, BLOCKSIZE);
+          outbuf += BLOCKSIZE;
+          inbuf  += BLOCKSIZE;
         }
     }
 
-  _gcry_burn_stack (48 + 2*sizeof(int));
+  if (burn_depth)
+    _gcry_burn_stack (burn_depth);
 }
 
 
@@ -1566,44 +2204,131 @@ _gcry_aes_cfb_dec (void *context, unsigned char *iv,
 void
 _gcry_aes_cbc_dec (void *context, unsigned char *iv,
                    void *outbuf_arg, const void *inbuf_arg,
-                   unsigned int nblocks)
+                   size_t nblocks)
 {
   RIJNDAEL_context *ctx = context;
   unsigned char *outbuf = outbuf_arg;
   const unsigned char *inbuf = inbuf_arg;
-  unsigned char *ivp;
-  int i;
-  unsigned char savebuf[BLOCKSIZE];
+  unsigned int burn_depth = 48 + 2*sizeof(int) + 4*sizeof (char*);
 
-  aesni_prepare ();
-  for ( ;nblocks; nblocks-- )
+  check_decryption_preparation (ctx);
+
+  if (0)
+    ;
+#ifdef USE_AESNI
+  else if (ctx->use_aesni)
+    {
+      aesni_prepare ();
+
+      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], %%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");
+
+          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 ();
+
+      burn_depth = 0; /* No stack usage. */
+    }
+#endif /*USE_AESNI*/
+  else
     {
-      /* We need to save INBUF away because it may be identical to
-         OUTBUF.  */
-      memcpy (savebuf, inbuf, BLOCKSIZE);
+      unsigned char savebuf[BLOCKSIZE];
 
-      if (0)
-        ;
+      for ( ;nblocks; nblocks-- )
+        {
+          /* INBUF is needed later and it may be identical to OUTBUF, so store
+             the intermediate result to SAVEBUF.  */
+
+          if (0)
+            ;
 #ifdef USE_PADLOCK
-      else if (ctx->use_padlock)
-        do_padlock (ctx, 1, outbuf, inbuf);
+          else if (ctx->use_padlock)
+            do_padlock (ctx, 1, savebuf, inbuf);
 #endif /*USE_PADLOCK*/
-#ifdef USE_AESNI
-      else if (ctx->use_aesni)
-        do_aesni (ctx, 1, outbuf, inbuf);
-#endif /*USE_AESNI*/
-      else
-        do_decrypt (ctx, outbuf, inbuf);
+          else
+            do_decrypt (ctx, savebuf, inbuf);
 
-      for (ivp=iv, i=0; i < BLOCKSIZE; i++ )
-        outbuf[i] ^= *ivp++;
-      memcpy (iv, savebuf, BLOCKSIZE);
-      inbuf += BLOCKSIZE;
-      outbuf += BLOCKSIZE;
+          buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, BLOCKSIZE);
+          inbuf += BLOCKSIZE;
+          outbuf += BLOCKSIZE;
+        }
+
+      wipememory(savebuf, sizeof(savebuf));
     }
-  aesni_cleanup ();
 
-  _gcry_burn_stack (48 + 2*sizeof(int) + BLOCKSIZE + 4*sizeof (char*));
+  if (burn_depth)
+    _gcry_burn_stack (burn_depth);
 }
 
 
@@ -1739,6 +2464,52 @@ selftest_basic_256 (void)
   return NULL;
 }
 
+
+/* Run the self-tests for AES-CTR-128, tests IV increment of bulk CTR
+   encryption.  Returns NULL on success. */
+static const char*
+selftest_ctr_128 (void)
+{
+  const int nblocks = 8+1;
+  const int blocksize = BLOCKSIZE;
+  const int context_size = sizeof(RIJNDAEL_context);
+
+  return _gcry_selftest_helper_ctr("AES", &rijndael_setkey,
+           &rijndael_encrypt, &_gcry_aes_ctr_enc, nblocks, blocksize,
+          context_size);
+}
+
+
+/* Run the self-tests for AES-CBC-128, tests bulk CBC decryption.
+   Returns NULL on success. */
+static const char*
+selftest_cbc_128 (void)
+{
+  const int nblocks = 8+2;
+  const int blocksize = BLOCKSIZE;
+  const int context_size = sizeof(RIJNDAEL_context);
+
+  return _gcry_selftest_helper_cbc("AES", &rijndael_setkey,
+           &rijndael_encrypt, &_gcry_aes_cbc_dec, nblocks, blocksize,
+          context_size);
+}
+
+
+/* Run the self-tests for AES-CFB-128, tests bulk CFB decryption.
+   Returns NULL on success. */
+static const char*
+selftest_cfb_128 (void)
+{
+  const int nblocks = 8+2;
+  const int blocksize = BLOCKSIZE;
+  const int context_size = sizeof(RIJNDAEL_context);
+
+  return _gcry_selftest_helper_cfb("AES", &rijndael_setkey,
+           &rijndael_encrypt, &_gcry_aes_cfb_dec, nblocks, blocksize,
+          context_size);
+}
+
+
 /* Run all the self-tests and return NULL on success.  This function
    is used for the on-the-fly self-tests. */
 static const char *
@@ -1751,6 +2522,15 @@ selftest (void)
        || (r = selftest_basic_256 ()) )
     return r;
 
+  if ( (r = selftest_ctr_128 ()) )
+    return r;
+
+  if ( (r = selftest_cbc_128 ()) )
+    return r;
+
+  if ( (r = selftest_cfb_128 ()) )
+    return r;
+
   return r;
 }
 
@@ -1759,7 +2539,7 @@ selftest (void)
 static const char *
 selftest_fips_128_38a (int requested_mode)
 {
-  struct tv
+  static const struct tv
   {
     int mode;
     const unsigned char key[16];
@@ -2018,14 +2798,15 @@ static gcry_cipher_oid_spec_t rijndael_oids[] =
 
 gcry_cipher_spec_t _gcry_cipher_spec_aes =
   {
-    "AES", rijndael_names, rijndael_oids, 16, 128, sizeof (RIJNDAEL_context),
-    rijndael_setkey, rijndael_encrypt, rijndael_decrypt
-  };
-cipher_extra_spec_t _gcry_cipher_extraspec_aes =
-  {
+    GCRY_CIPHER_AES, {0, 1},
+    "AES", rijndael_names, rijndael_oids, 16, 128,
+    sizeof (RIJNDAEL_context),
+    rijndael_setkey, rijndael_encrypt, rijndael_decrypt,
+    NULL, NULL,
     run_selftests
   };
 
+
 static const char *rijndael192_names[] =
   {
     "RIJNDAEL192",
@@ -2044,14 +2825,15 @@ static gcry_cipher_oid_spec_t rijndael192_oids[] =
 
 gcry_cipher_spec_t _gcry_cipher_spec_aes192 =
   {
-    "AES192", rijndael192_names, rijndael192_oids, 16, 192, sizeof (RIJNDAEL_context),
-    rijndael_setkey, rijndael_encrypt, rijndael_decrypt
-  };
-cipher_extra_spec_t _gcry_cipher_extraspec_aes192 =
-  {
+    GCRY_CIPHER_AES192, {0, 1},
+    "AES192", rijndael192_names, rijndael192_oids, 16, 192,
+    sizeof (RIJNDAEL_context),
+    rijndael_setkey, rijndael_encrypt, rijndael_decrypt,
+    NULL, NULL,
     run_selftests
   };
 
+
 static const char *rijndael256_names[] =
   {
     "RIJNDAEL256",
@@ -2070,12 +2852,10 @@ static gcry_cipher_oid_spec_t rijndael256_oids[] =
 
 gcry_cipher_spec_t _gcry_cipher_spec_aes256 =
   {
+    GCRY_CIPHER_AES256, {0, 1},
     "AES256", rijndael256_names, rijndael256_oids, 16, 256,
     sizeof (RIJNDAEL_context),
-    rijndael_setkey, rijndael_encrypt, rijndael_decrypt
-  };
-
-cipher_extra_spec_t _gcry_cipher_extraspec_aes256 =
-  {
+    rijndael_setkey, rijndael_encrypt, rijndael_decrypt,
+    NULL, NULL,
     run_selftests
   };
index 6a9fe31..a56ee49 100644 (file)
 #ifndef G10_RMD_H
 #define G10_RMD_H
 
+#include "hash-common.h"
 
 /* We need this here because random.c must have direct access. */
 typedef struct
 {
+  gcry_md_block_ctx_t bctx;
   u32  h0,h1,h2,h3,h4;
-  u32  nblocks;
-  byte buf[64];
-  int  count;
 } RMD160_CONTEXT;
 
 void _gcry_rmd160_init ( void *context );
index 552cff9..08e8cb0 100644 (file)
@@ -28,6 +28,7 @@
 #include "cipher.h" /* Only used for the rmd160_hash_buffer() prototype. */
 
 #include "bithelp.h"
+#include "bufhelp.h"
 
 /*********************************
  * RIPEMD-160 is not patented, see (as of 25.10.97)
  * 1 million times "a"   52783243c1697bdbe16d37f97f68f08325dc1528
  */
 
+static unsigned int
+transform ( void *ctx, const unsigned char *data );
 
-void
-_gcry_rmd160_init (void *context)
+static void
+rmd160_init (void *context, unsigned int flags)
 {
   RMD160_CONTEXT *hd = context;
 
+  (void)flags;
+
   hd->h0 = 0x67452301;
   hd->h1 = 0xEFCDAB89;
   hd->h2 = 0x98BADCFE;
   hd->h3 = 0x10325476;
   hd->h4 = 0xC3D2E1F0;
-  hd->nblocks = 0;
-  hd->count = 0;
+
+  hd->bctx.nblocks = 0;
+  hd->bctx.nblocks_high = 0;
+  hd->bctx.count = 0;
+  hd->bctx.blocksize = 64;
+  hd->bctx.bwrite = transform;
 }
 
 
+void
+_gcry_rmd160_init (void *context)
+{
+  rmd160_init (context, 0);
+}
+
 
 /****************
  * Transform the message X which consists of 16 32-bit-words
  */
-static void
-transform ( RMD160_CONTEXT *hd, const unsigned char *data )
+static unsigned int
+transform ( void *ctx, const unsigned char *data )
 {
+  RMD160_CONTEXT *hd = ctx;
   register u32 a,b,c,d,e;
   u32 aa,bb,cc,dd,ee,t;
-#ifdef WORDS_BIGENDIAN
-  u32 x[16];
-  {
-    int i;
-    byte *p2, *p1;
-    for (i=0, p1=data, p2=(byte*)x; i < 16; i++, p2 += 4 )
-      {
-        p2[3] = *p1++;
-        p2[2] = *p1++;
-        p2[1] = *p1++;
-        p2[0] = *p1++;
-      }
-  }
-#else
-  /* This version is better because it is always aligned;
-   * The performance penalty on a 586-100 is about 6% which
-   * is acceptable - because the data is more local it might
-   * also be possible that this is faster on some machines.
-   * This function (when compiled with -02 on gcc 2.7.2)
-   * executes on a 586-100 (39.73 bogomips) at about 1900kb/sec;
-   * [measured with a 4MB data and "gpgm --print-md rmd160"] */
   u32 x[16];
-  memcpy( x, data, 64 );
-#endif
+  int i;
 
+  for ( i = 0; i < 16; i++ )
+    x[i] = buf_get_le32(data + i * 4);
 
 #define K0  0x00000000
 #define K1  0x5A827999
@@ -393,49 +389,11 @@ transform ( RMD160_CONTEXT *hd, const unsigned char *data )
   hd->h3 = hd->h4 + b + aa;
   hd->h4 = hd->h0 + c + bb;
   hd->h0 = t;
-}
 
-
-/* Update the message digest with the contents
- * of INBUF with length INLEN.
- */
-static void
-rmd160_write ( void *context, const void *inbuf_arg, size_t inlen)
-{
-  const unsigned char *inbuf = inbuf_arg;
-  RMD160_CONTEXT *hd = context;
-
-  if( hd->count == 64 )  /* flush the buffer */
-    {
-      transform( hd, hd->buf );
-      _gcry_burn_stack (108+5*sizeof(void*));
-      hd->count = 0;
-      hd->nblocks++;
-    }
-  if( !inbuf )
-    return;
-  if( hd->count )
-    {
-      for( ; inlen && hd->count < 64; inlen-- )
-        hd->buf[hd->count++] = *inbuf++;
-      rmd160_write( hd, NULL, 0 );
-      if( !inlen )
-        return;
-    }
-
-  while( inlen >= 64 )
-    {
-      transform( hd, inbuf );
-      hd->count = 0;
-      hd->nblocks++;
-      inlen -= 64;
-      inbuf += 64;
-    }
-  _gcry_burn_stack (108+5*sizeof(void*));
-  for( ; inlen && hd->count < 64; inlen-- )
-    hd->buf[hd->count++] = *inbuf++;
+  return /*burn_stack*/ 108+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
@@ -465,18 +423,24 @@ static void
 rmd160_final( void *context )
 {
   RMD160_CONTEXT *hd = context;
-  u32 t, msb, lsb;
+  u32 t, th, msb, lsb;
   byte *p;
+  unsigned int burn;
 
-  rmd160_write(hd, NULL, 0); /* flush */;
+  _gcry_md_block_write(hd, NULL, 0); /* flush */;
+
+  t = hd->bctx.nblocks;
+  if (sizeof t == sizeof hd->bctx.nblocks)
+    th = hd->bctx.nblocks_high;
+  else
+    th = hd->bctx.nblocks >> 32;
 
-  t = hd->nblocks;
   /* multiply by 64 to make a byte count */
   lsb = t << 6;
-  msb = t >> 26;
+  msb = (th << 6) | (t >> 26);
   /* add the count */
   t = lsb;
-  if( (lsb += hd->count) < t )
+  if( (lsb += hd->bctx.count) < t )
     msb++;
   /* multiply by 8 to make a bit count */
   t = lsb;
@@ -484,39 +448,28 @@ rmd160_final( void *context )
   msb <<= 3;
   msb |= t >> 29;
 
-  if( hd->count < 56 )  /* enough room */
+  if( hd->bctx.count < 56 )  /* enough room */
     {
-      hd->buf[hd->count++] = 0x80; /* pad */
-      while( hd->count < 56 )
-        hd->buf[hd->count++] = 0;  /* pad */
+      hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
+      while( hd->bctx.count < 56 )
+        hd->bctx.buf[hd->bctx.count++] = 0;  /* pad */
     }
   else  /* need one extra block */
     {
-      hd->buf[hd->count++] = 0x80; /* pad character */
-      while( hd->count < 64 )
-        hd->buf[hd->count++] = 0;
-      rmd160_write(hd, NULL, 0);  /* flush */;
-      memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+      hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
+      while( hd->bctx.count < 64 )
+        hd->bctx.buf[hd->bctx.count++] = 0;
+      _gcry_md_block_write(hd, NULL, 0);  /* flush */;
+      memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
     }
   /* append the 64 bit count */
-  hd->buf[56] = lsb       ;
-  hd->buf[57] = lsb >>  8;
-  hd->buf[58] = lsb >> 16;
-  hd->buf[59] = lsb >> 24;
-  hd->buf[60] = msb       ;
-  hd->buf[61] = msb >>  8;
-  hd->buf[62] = msb >> 16;
-  hd->buf[63] = msb >> 24;
-  transform( hd, hd->buf );
-  _gcry_burn_stack (108+5*sizeof(void*));
-
-  p = hd->buf;
-#ifdef WORDS_BIGENDIAN
-#define X(a) do { *p++ = hd->h##a         ; *p++ = hd->h##a >> 8;      \
-                 *p++ = hd->h##a >> 16; *p++ = hd->h##a >> 24; } while(0)
-#else /* little endian */
-#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
-#endif
+  buf_put_le32(hd->bctx.buf + 56, lsb);
+  buf_put_le32(hd->bctx.buf + 60, msb);
+  burn = transform( hd, hd->bctx.buf );
+  _gcry_burn_stack (burn);
+
+  p = hd->bctx.buf;
+#define X(a) do { *(u32*)p = le_bswap32(hd->h##a) ; p += 4; } while(0)
   X(0);
   X(1);
   X(2);
@@ -530,7 +483,7 @@ rmd160_read( void *context )
 {
   RMD160_CONTEXT *hd = context;
 
-  return hd->buf;
+  return hd->bctx.buf;
 }
 
 
@@ -545,9 +498,9 @@ _gcry_rmd160_hash_buffer (void *outbuf, const void *buffer, size_t length )
   RMD160_CONTEXT hd;
 
   _gcry_rmd160_init ( &hd );
-  rmd160_write ( &hd, buffer, length );
+  _gcry_md_block_write ( &hd, buffer, length );
   rmd160_final ( &hd );
-  memcpy ( outbuf, hd.buf, 20 );
+  memcpy ( outbuf, hd.bctx.buf, 20 );
 }
 
 static byte asn[15] = /* Object ID is 1.3.36.3.2.1 */
@@ -565,7 +518,8 @@ static gcry_md_oid_spec_t oid_spec_rmd160[] =
 
 gcry_md_spec_t _gcry_digest_spec_rmd160 =
   {
+    GCRY_MD_RMD160, {0, 0},
     "RIPEMD160", asn, DIM (asn), oid_spec_rmd160, 20,
-    _gcry_rmd160_init, rmd160_write, rmd160_final, rmd160_read,
+    rmd160_init, _gcry_md_block_write, rmd160_final, rmd160_read,
     sizeof (RMD160_CONTEXT)
   };
diff --git a/cipher/rsa-common.c b/cipher/rsa-common.c
new file mode 100644 (file)
index 0000000..4f5a659
--- /dev/null
@@ -0,0 +1,973 @@
+/* rsa-common.c - Supporting functions for RSA
+ * Copyright (C) 2011 Free Software Foundation, Inc.
+ * Copyright (C) 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/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "cipher.h"
+#include "pubkey-internal.h"
+
+
+/* Turn VALUE into an octet string and store it in an allocated buffer
+   at R_FRAME or - if R_RAME is NULL - copy it into the caller
+   provided buffer SPACE; either SPACE or R_FRAME may be used.  If
+   SPACE if not NULL, the caller must provide a buffer of at least
+   NBYTES.  If the resulting octet string is shorter than NBYTES pad
+   it to the left with zeroes.  If VALUE does not fit into NBYTES
+   return an error code.  */
+static gpg_err_code_t
+octet_string_from_mpi (unsigned char **r_frame, void *space,
+                       gcry_mpi_t value, size_t nbytes)
+{
+  return _gcry_mpi_to_octet_string (r_frame, space, value, nbytes);
+}
+
+
+
+/* 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
+   R_RESULT.  On error the value at R_RESULT is undefined.
+
+   If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as
+   the seed instead of using a random string for it.  This feature is
+   only useful for regression tests.  Note that this value may not
+   contain zero bytes.
+
+   We encode the value in this way:
+
+     0  2  RND(n bytes)  0  VALUE
+
+   0   is a marker we unfortunately can't encode because we return an
+       MPI which strips all leading zeroes.
+   2   is the block type.
+   RND are non-zero random bytes.
+
+   (Note that OpenPGP includes the cipher algorithm and a checksum in
+   VALUE; the caller needs to prepare the value accordingly.)
+  */
+gpg_err_code_t
+_gcry_rsa_pkcs1_encode_for_enc (gcry_mpi_t *r_result, unsigned int nbits,
+                                const unsigned char *value, size_t valuelen,
+                                const unsigned char *random_override,
+                                size_t random_override_len)
+{
+  gcry_err_code_t rc = 0;
+  unsigned char *frame = NULL;
+  size_t nframe = (nbits+7) / 8;
+  int i;
+  size_t n;
+  unsigned char *p;
+
+  if (valuelen + 7 > nframe || !nframe)
+    {
+      /* Can't encode a VALUELEN value in a NFRAME bytes frame.  */
+      return GPG_ERR_TOO_SHORT; /* The key is too short.  */
+    }
+
+  if ( !(frame = xtrymalloc_secure (nframe)))
+    return gpg_err_code_from_syserror ();
+
+  n = 0;
+  frame[n++] = 0;
+  frame[n++] = 2; /* block type */
+  i = nframe - 3 - valuelen;
+  gcry_assert (i > 0);
+
+  if (random_override)
+    {
+      int j;
+
+      if (random_override_len != i)
+        {
+          xfree (frame);
+          return GPG_ERR_INV_ARG;
+        }
+      /* Check that random does not include a zero byte.  */
+      for (j=0; j < random_override_len; j++)
+        if (!random_override[j])
+          {
+            xfree (frame);
+            return GPG_ERR_INV_ARG;
+          }
+      memcpy (frame + n, random_override, random_override_len);
+      n += random_override_len;
+    }
+  else
+    {
+      p = _gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
+      /* Replace zero bytes by new values. */
+      for (;;)
+        {
+          int j, k;
+          unsigned char *pp;
+
+          /* Count the zero bytes. */
+          for (j=k=0; j < i; j++)
+            {
+              if (!p[j])
+                k++;
+            }
+          if (!k)
+            break; /* Okay: no (more) zero bytes. */
+
+          k += k/128 + 3; /* Better get some more. */
+          pp = _gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
+          for (j=0; j < i && k; )
+            {
+              if (!p[j])
+                p[j] = pp[--k];
+              if (p[j])
+                j++;
+            }
+          xfree (pp);
+        }
+      memcpy (frame+n, p, i);
+      n += i;
+      xfree (p);
+    }
+
+  frame[n++] = 0;
+  memcpy (frame+n, value, valuelen);
+  n += valuelen;
+  gcry_assert (n == nframe);
+
+  rc = _gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
+  if (!rc &&DBG_CIPHER)
+    log_mpidump ("PKCS#1 block type 2 encoded data", *r_result);
+  xfree (frame);
+
+  return rc;
+}
+
+
+/* Decode a plaintext in VALUE assuming pkcs#1 block type 2 padding.
+   NBITS is the size of the secret key.  On success the result is
+   stored as a newly allocated buffer at R_RESULT and its valid length at
+   R_RESULTLEN.  On error NULL is stored at R_RESULT.  */
+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)
+{
+  gcry_error_t err;
+  unsigned char *frame = NULL;
+  size_t nframe = (nbits+7) / 8;
+  size_t n;
+
+  *r_result = NULL;
+
+  if ( !(frame = xtrymalloc_secure (nframe)))
+    return gpg_err_code_from_syserror ();
+
+  err = _gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &n, value);
+  if (err)
+    {
+      xfree (frame);
+      return gcry_err_code (err);
+    }
+
+  nframe = n; /* Set NFRAME to the actual length.  */
+
+  /* FRAME = 0x00 || 0x02 || PS || 0x00 || M
+
+     pkcs#1 requires that the first byte is zero.  Our MPIs usually
+     strip leading zero bytes; thus we are not able to detect them.
+     However due to the way gcry_mpi_print is implemented we may see
+     leading zero bytes nevertheless.  We handle this by making the
+     first zero byte optional.  */
+  if (nframe < 4)
+    {
+      xfree (frame);
+      return GPG_ERR_ENCODING_PROBLEM;  /* Too short.  */
+    }
+  n = 0;
+  if (!frame[0])
+    n++;
+  if (frame[n++] != 0x02)
+    {
+      xfree (frame);
+      return GPG_ERR_ENCODING_PROBLEM;  /* Wrong block type.  */
+    }
+
+  /* Skip the non-zero random bytes and the terminating zero byte.  */
+  for (; n < nframe && frame[n] != 0x00; n++)
+    ;
+  if (n+1 >= nframe)
+    {
+      xfree (frame);
+      return GPG_ERR_ENCODING_PROBLEM; /* No zero byte.  */
+    }
+  n++; /* Skip the zero byte.  */
+
+  /* To avoid an extra allocation we reuse the frame buffer.  The only
+     caller of this function will anyway free the result soon.  */
+  memmove (frame, frame + n, nframe - n);
+  *r_result = frame;
+  *r_resultlen = nframe - n;
+
+  if (DBG_CIPHER)
+    log_printhex ("value extracted from PKCS#1 block type 2 encoded data",
+                  *r_result, *r_resultlen);
+
+  return 0;
+}
+
+
+/* Encode {VALUE,VALUELEN} for an NBITS keys and hash algorith ALGO
+   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  ASN(asnlen bytes) 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.
+   ASN is the DER encoding of the hash algorithm; along with the VALUE
+       it yields a valid DER encoding.
+
+   (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_for_sig (gcry_mpi_t *r_result, unsigned int nbits,
+                                const unsigned char *value, size_t valuelen,
+                                int algo)
+{
+  gcry_err_code_t rc = 0;
+  byte asn[100];
+  byte *frame = NULL;
+  size_t nframe = (nbits+7) / 8;
+  int i;
+  size_t n;
+  size_t asnlen, dlen;
+
+  asnlen = DIM(asn);
+  dlen = _gcry_md_get_algo_dlen (algo);
+
+  if (_gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
+    {
+      /* We don't have yet all of the above algorithms.  */
+      return GPG_ERR_NOT_IMPLEMENTED;
+    }
+
+  if ( valuelen != dlen )
+    {
+      /* Hash value does not match the length of digest for
+         the given algorithm.  */
+      return GPG_ERR_CONFLICT;
+    }
+
+  if ( !dlen || dlen + asnlen + 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 - asnlen - 3 ;
+  gcry_assert (i > 1);
+  memset (frame+n, 0xff, i );
+  n += i;
+  frame[n++] = 0;
+  memcpy (frame+n, asn, asnlen);
+  n += asnlen;
+  memcpy (frame+n, value, valuelen );
+  n += valuelen;
+  gcry_assert (n == nframe);
+
+  /* Convert it into an MPI. */
+  rc = _gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
+  if (!rc && 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
+mgf1 (unsigned char *output, size_t outlen, unsigned char *seed, size_t seedlen,
+      int algo)
+{
+  size_t dlen, nbytes, n;
+  int idx;
+  gcry_md_hd_t hd;
+  gcry_error_t err;
+
+  err = _gcry_md_open (&hd, algo, 0);
+  if (err)
+    return err;
+
+  dlen = _gcry_md_get_algo_dlen (algo);
+
+  /* We skip step 1 which would be assert(OUTLEN <= 2^32).  The loop
+     in step 3 is merged with step 4 by concatenating no more octets
+     than what would fit into OUTPUT.  The ceiling for the counter IDX
+     is implemented indirectly.  */
+  nbytes = 0;  /* Step 2.  */
+  idx = 0;
+  while ( nbytes < outlen )
+    {
+      unsigned char c[4], *digest;
+
+      if (idx)
+        _gcry_md_reset (hd);
+
+      c[0] = (idx >> 24) & 0xFF;
+      c[1] = (idx >> 16) & 0xFF;
+      c[2] = (idx >> 8) & 0xFF;
+      c[3] = idx & 0xFF;
+      idx++;
+
+      _gcry_md_write (hd, seed, seedlen);
+      _gcry_md_write (hd, c, 4);
+      digest = _gcry_md_read (hd, 0);
+
+      n = (outlen - nbytes < dlen)? (outlen - nbytes) : dlen;
+      memcpy (output+nbytes, digest, n);
+      nbytes += n;
+    }
+
+  _gcry_md_close (hd);
+  return GPG_ERR_NO_ERROR;
+}
+
+
+/* RFC-3447 (pkcs#1 v2.1) OAEP encoding.  NBITS is the length of the
+   key measured in bits.  ALGO is the hash function; it must be a
+   valid and usable algorithm.  {VALUE,VALUELEN} is the message to
+   encrypt.  {LABEL,LABELLEN} is the optional label to be associated
+   with the message, if LABEL is NULL the default is to use the empty
+   string as label.  On success the encoded ciphertext is returned at
+   R_RESULT.
+
+   If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as
+   the seed instead of using a random string for it.  This feature is
+   only useful for regression tests.
+
+   Here is figure 1 from the RFC depicting the process:
+
+                             +----------+---------+-------+
+                        DB = |  lHash   |    PS   |   M   |
+                             +----------+---------+-------+
+                                            |
+                  +----------+              V
+                  |   seed   |--> MGF ---> xor
+                  +----------+              |
+                        |                   |
+               +--+     V                   |
+               |00|    xor <----- MGF <-----|
+               +--+     |                   |
+                 |      |                   |
+                 V      V                   V
+               +--+----------+----------------------------+
+         EM =  |00|maskedSeed|          maskedDB          |
+               +--+----------+----------------------------+
+  */
+gpg_err_code_t
+_gcry_rsa_oaep_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
+                       const unsigned char *value, size_t valuelen,
+                       const unsigned char *label, size_t labellen,
+                       const void *random_override, size_t random_override_len)
+{
+  gcry_err_code_t rc = 0;
+  unsigned char *frame = NULL;
+  size_t nframe = (nbits+7) / 8;
+  unsigned char *p;
+  size_t hlen;
+  size_t n;
+
+  *r_result = NULL;
+
+  /* Set defaults for LABEL.  */
+  if (!label || !labellen)
+    {
+      label = (const unsigned char*)"";
+      labellen = 0;
+    }
+
+  hlen = _gcry_md_get_algo_dlen (algo);
+
+  /* We skip step 1a which would be to check that LABELLEN is not
+     greater than 2^61-1.  See rfc-3447 7.1.1. */
+
+  /* Step 1b.  Note that the obsolete rfc-2437 uses the check:
+     valuelen > nframe - 2 * hlen - 1 .  */
+  if (valuelen > nframe - 2 * hlen - 2 || !nframe)
+    {
+      /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
+      return GPG_ERR_TOO_SHORT; /* The key is too short.  */
+    }
+
+  /* Allocate the frame.  */
+  frame = xtrycalloc_secure (1, nframe);
+  if (!frame)
+    return gpg_err_code_from_syserror ();
+
+  /* Step 2a: Compute the hash of the label.  We store it in the frame
+     where later the maskedDB will commence.  */
+  _gcry_md_hash_buffer (algo, frame + 1 + hlen, label, labellen);
+
+  /* Step 2b: Set octet string to zero.  */
+  /* This has already been done while allocating FRAME.  */
+
+  /* Step 2c: Create DB by concatenating lHash, PS, 0x01 and M.  */
+  n = nframe - valuelen - 1;
+  frame[n] = 0x01;
+  memcpy (frame + n + 1, value, valuelen);
+
+  /* Step 3d: Generate seed.  We store it where the maskedSeed will go
+     later. */
+  if (random_override)
+    {
+      if (random_override_len != hlen)
+        {
+          xfree (frame);
+          return GPG_ERR_INV_ARG;
+        }
+      memcpy (frame + 1, random_override, hlen);
+    }
+  else
+    _gcry_randomize (frame + 1, hlen, GCRY_STRONG_RANDOM);
+
+  /* Step 2e and 2f: Create maskedDB.  */
+  {
+    unsigned char *dmask;
+
+    dmask = xtrymalloc_secure (nframe - hlen - 1);
+    if (!dmask)
+      {
+        rc = gpg_err_code_from_syserror ();
+        xfree (frame);
+        return rc;
+      }
+    rc = mgf1 (dmask, nframe - hlen - 1, frame+1, hlen, algo);
+    if (rc)
+      {
+        xfree (dmask);
+        xfree (frame);
+        return rc;
+      }
+    for (n = 1 + hlen, p = dmask; n < nframe; n++)
+      frame[n] ^= *p++;
+    xfree (dmask);
+  }
+
+  /* Step 2g and 2h: Create maskedSeed.  */
+  {
+    unsigned char *smask;
+
+    smask = xtrymalloc_secure (hlen);
+    if (!smask)
+      {
+        rc = gpg_err_code_from_syserror ();
+        xfree (frame);
+        return rc;
+      }
+    rc = mgf1 (smask, hlen, frame + 1 + hlen, nframe - hlen - 1, algo);
+    if (rc)
+      {
+        xfree (smask);
+        xfree (frame);
+        return rc;
+      }
+    for (n = 1, p = smask; n < 1 + hlen; n++)
+      frame[n] ^= *p++;
+    xfree (smask);
+  }
+
+  /* Step 2i: Concatenate 0x00, maskedSeed and maskedDB.  */
+  /* This has already been done by using in-place operations.  */
+
+  /* Convert the stuff into an MPI as expected by the caller.  */
+  rc = _gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, nframe, NULL);
+  if (!rc && DBG_CIPHER)
+    log_mpidump ("OAEP encoded data", *r_result);
+  xfree (frame);
+
+  return rc;
+}
+
+
+/* RFC-3447 (pkcs#1 v2.1) OAEP decoding.  NBITS is the length of the
+   key measured in bits.  ALGO is the hash function; it must be a
+   valid and usable algorithm.  VALUE is the raw decrypted message
+   {LABEL,LABELLEN} is the optional label to be associated with the
+   message, if LABEL is NULL the default is to use the empty string as
+   label.  On success the plaintext is returned as a newly allocated
+   buffer at R_RESULT; its valid length is stored at R_RESULTLEN.  On
+   error NULL is stored at R_RESULT.  */
+gpg_err_code_t
+_gcry_rsa_oaep_decode (unsigned char **r_result, size_t *r_resultlen,
+                       unsigned int nbits, int algo,
+                       gcry_mpi_t value,
+                       const unsigned char *label, size_t labellen)
+{
+  gcry_err_code_t rc;
+  unsigned char *frame = NULL; /* Encoded messages (EM).  */
+  unsigned char *masked_seed;  /* Points into FRAME.  */
+  unsigned char *masked_db;    /* Points into FRAME.  */
+  unsigned char *seed = NULL;  /* Allocated space for the seed and DB.  */
+  unsigned char *db;           /* Points into SEED.  */
+  unsigned char *lhash = NULL; /* Hash of the label.  */
+  size_t nframe;               /* Length of the ciphertext (EM).  */
+  size_t hlen;                 /* Length of the hash digest.  */
+  size_t db_len;               /* Length of DB and masked_db.  */
+  size_t nkey = (nbits+7)/8;   /* Length of the key in bytes.  */
+  int failed = 0;              /* Error indicator.  */
+  size_t n;
+
+  *r_result = NULL;
+
+  /* This code is implemented as described by rfc-3447 7.1.2.  */
+
+  /* Set defaults for LABEL.  */
+  if (!label || !labellen)
+    {
+      label = (const unsigned char*)"";
+      labellen = 0;
+    }
+
+  /* Get the length of the digest.  */
+  hlen = _gcry_md_get_algo_dlen (algo);
+
+  /* Hash the label right away.  */
+  lhash = xtrymalloc (hlen);
+  if (!lhash)
+    return gpg_err_code_from_syserror ();
+  _gcry_md_hash_buffer (algo, lhash, label, labellen);
+
+  /* Turn the MPI into an octet string.  If the octet string is
+     shorter than the key we pad it to the left with zeroes.  This may
+     happen due to the leading zero in OAEP frames and due to the
+     following random octets (seed^mask) which may have leading zero
+     bytes.  This all is needed to cope with our leading zeroes
+     suppressing MPI implementation.  The code implictly implements
+     Step 1b (bail out if NFRAME != N).  */
+  rc = octet_string_from_mpi (&frame, NULL, value, nkey);
+  if (rc)
+    {
+      xfree (lhash);
+      return GPG_ERR_ENCODING_PROBLEM;
+    }
+  nframe = nkey;
+
+  /* Step 1c: Check that the key is long enough.  */
+  if ( nframe < 2 * hlen + 2 )
+    {
+      xfree (frame);
+      xfree (lhash);
+      return GPG_ERR_ENCODING_PROBLEM;
+    }
+
+  /* Step 2 has already been done by the caller and the
+     gcry_mpi_aprint above.  */
+
+  /* Allocate space for SEED and DB.  */
+  seed = xtrymalloc_secure (nframe - 1);
+  if (!seed)
+    {
+      rc = gpg_err_code_from_syserror ();
+      xfree (frame);
+      xfree (lhash);
+      return rc;
+    }
+  db = seed + hlen;
+
+  /* To avoid choosen 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.  */
+
+  /* Step 3a: Hash the label.  */
+  /* This has already been done.  */
+
+  /* Step 3b: Separate the encoded message.  */
+  masked_seed = frame + 1;
+  masked_db   = frame + 1 + hlen;
+  db_len      = nframe - 1 - hlen;
+
+  /* Step 3c and 3d: seed = maskedSeed ^ mgf(maskedDB, hlen).  */
+  if (mgf1 (seed, hlen, masked_db, db_len, algo))
+    failed = 1;
+  for (n = 0; n < hlen; n++)
+    seed[n] ^= masked_seed[n];
+
+  /* Step 3e and 3f: db = maskedDB ^ mgf(seed, db_len).  */
+  if (mgf1 (db, db_len, seed, hlen, algo))
+    failed = 1;
+  for (n = 0; n < db_len; n++)
+    db[n] ^= masked_db[n];
+
+  /* Step 3g: Check lhash, an possible empty padding string terminated
+     by 0x01 and the first byte of EM being 0.  */
+  if (memcmp (lhash, db, hlen))
+    failed = 1;
+  for (n = hlen; n < db_len; n++)
+    if (db[n] == 0x01)
+      break;
+  if (n == db_len)
+    failed = 1;
+  if (frame[0])
+    failed = 1;
+
+  xfree (lhash);
+  xfree (frame);
+  if (failed)
+    {
+      xfree (seed);
+      return GPG_ERR_ENCODING_PROBLEM;
+    }
+
+  /* Step 4: Output M.  */
+  /* To avoid an extra allocation we reuse the seed buffer.  The only
+     caller of this function will anyway free the result soon.  */
+  n++;
+  memmove (seed, db + n, db_len - n);
+  *r_result = seed;
+  *r_resultlen = db_len - n;
+  seed = NULL;
+
+  if (DBG_CIPHER)
+    log_printhex ("value extracted from OAEP encoded data",
+                  *r_result, *r_resultlen);
+
+  return 0;
+}
+
+
+/* RFC-3447 (pkcs#1 v2.1) PSS encoding.  Encode {VALUE,VALUELEN} for
+   an NBITS key.  Note that VALUE is already the mHash from the
+   picture below.  ALGO is a valid hash algorithm and SALTLEN is the
+   length of salt to be used.  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
+   the salt instead of using a random string for the salt.  This
+   feature is only useful for regression tests.
+
+   Here is figure 2 from the RFC (errata 595 applied) depicting the
+   process:
+
+                                  +-----------+
+                                  |     M     |
+                                  +-----------+
+                                        |
+                                        V
+                                      Hash
+                                        |
+                                        V
+                          +--------+----------+----------+
+                     M' = |Padding1|  mHash   |   salt   |
+                          +--------+----------+----------+
+                                         |
+               +--------+----------+     V
+         DB =  |Padding2| salt     |   Hash
+               +--------+----------+     |
+                         |               |
+                         V               |    +----+
+                        xor <--- MGF <---|    |0xbc|
+                         |               |    +----+
+                         |               |      |
+                         V               V      V
+               +-------------------+----------+----+
+         EM =  |    maskedDB       |     H    |0xbc|
+               +-------------------+----------+----+
+
+  */
+gpg_err_code_t
+_gcry_rsa_pss_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
+                      const unsigned char *value, size_t valuelen, int saltlen,
+                      const void *random_override, size_t random_override_len)
+{
+  gcry_err_code_t rc = 0;
+  size_t hlen;                 /* Length of the hash digest.  */
+  unsigned char *em = NULL;    /* Encoded message.  */
+  size_t emlen = (nbits+7)/8;  /* Length in bytes of EM.  */
+  unsigned char *h;            /* Points into EM.  */
+  unsigned char *buf = NULL;   /* Help buffer.  */
+  size_t buflen;               /* Length of BUF.  */
+  unsigned char *mhash;        /* Points into BUF.  */
+  unsigned char *salt;         /* Points into BUF.  */
+  unsigned char *dbmask;       /* Points into BUF.  */
+  unsigned char *p;
+  size_t n;
+
+  /* This code is implemented as described by rfc-3447 9.1.1.  */
+
+  /* Get the length of the digest.  */
+  hlen = _gcry_md_get_algo_dlen (algo);
+  gcry_assert (hlen);  /* We expect a valid ALGO here.  */
+
+  /* Allocate a help buffer and setup some pointers.  */
+  buflen = 8 + hlen + saltlen + (emlen - hlen - 1);
+  buf = xtrymalloc (buflen);
+  if (!buf)
+    {
+      rc = gpg_err_code_from_syserror ();
+      goto leave;
+    }
+  mhash = buf + 8;
+  salt  = mhash + hlen;
+  dbmask= salt + saltlen;
+
+  /* Step 2: That would be: mHash = Hash(M) but our input is already
+     mHash thus we do only a consistency check and copy to MHASH.  */
+  if (valuelen != hlen)
+    {
+      rc = GPG_ERR_INV_LENGTH;
+      goto leave;
+    }
+  memcpy (mhash, value, hlen);
+
+  /* Step 3: Check length constraints.  */
+  if (emlen < hlen + saltlen + 2)
+    {
+      rc = GPG_ERR_TOO_SHORT;
+      goto leave;
+    }
+
+  /* Allocate space for EM.  */
+  em = xtrymalloc (emlen);
+  if (!em)
+    {
+      rc = gpg_err_code_from_syserror ();
+      goto leave;
+    }
+  h = em + emlen - 1 - hlen;
+
+  /* Step 4: Create a salt.  */
+  if (saltlen)
+    {
+      if (random_override)
+        {
+          if (random_override_len != saltlen)
+            {
+              rc = GPG_ERR_INV_ARG;
+              goto leave;
+            }
+          memcpy (salt, random_override, saltlen);
+        }
+      else
+        _gcry_randomize (salt, saltlen, GCRY_STRONG_RANDOM);
+    }
+
+  /* Step 5 and 6: M' = Hash(Padding1 || mHash || salt).  */
+  memset (buf, 0, 8);  /* Padding.  */
+  _gcry_md_hash_buffer (algo, h, buf, 8 + hlen + saltlen);
+
+  /* Step 7 and 8: DB = PS || 0x01 || salt.  */
+  /* Note that we use EM to store DB and later Xor in-place.  */
+  p = em + emlen - 1 - hlen - saltlen - 1;
+  memset (em, 0, p - em);
+  *p++ = 0x01;
+  memcpy (p, salt, saltlen);
+
+  /* Step 9: dbmask = MGF(H, emlen - hlen - 1).  */
+  mgf1 (dbmask, emlen - hlen - 1, h, hlen, algo);
+
+  /* Step 10: maskedDB = DB ^ dbMask */
+  for (n = 0, p = dbmask; n < emlen - hlen - 1; n++, p++)
+    em[n] ^= *p;
+
+  /* Step 11: Set the leftmost bits to zero.  */
+  em[0] &= 0xFF >> (8 * emlen - nbits);
+
+  /* Step 12: EM = maskedDB || H || 0xbc.  */
+  em[emlen-1] = 0xbc;
+
+  /* Convert EM into an MPI.  */
+  rc = _gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, em, emlen, NULL);
+  if (!rc && DBG_CIPHER)
+    log_mpidump ("PSS encoded data", *r_result);
+
+ leave:
+  if (em)
+    {
+      wipememory (em, emlen);
+      xfree (em);
+    }
+  if (buf)
+    {
+      wipememory (buf, buflen);
+      xfree (buf);
+    }
+  return rc;
+}
+
+
+/* Verify a signature assuming PSS padding.  VALUE is the hash of the
+   message (mHash) encoded as an MPI; its length must match the digest
+   length of ALGO.  ENCODED is the output of the RSA public key
+   function (EM).  NBITS is the size of the public key.  ALGO is the
+   hash algorithm and SALTLEN is the length of the used salt.  The
+   function returns 0 on success or on error code.  */
+gpg_err_code_t
+_gcry_rsa_pss_verify (gcry_mpi_t value, gcry_mpi_t encoded,
+                      unsigned int nbits, int algo, size_t saltlen)
+{
+  gcry_err_code_t rc = 0;
+  size_t hlen;                 /* Length of the hash digest.  */
+  unsigned char *em = NULL;    /* Encoded message.  */
+  size_t emlen = (nbits+7)/8;  /* Length in bytes of EM.  */
+  unsigned char *salt;         /* Points into EM.  */
+  unsigned char *h;            /* Points into EM.  */
+  unsigned char *buf = NULL;   /* Help buffer.  */
+  size_t buflen;               /* Length of BUF.  */
+  unsigned char *dbmask;       /* Points into BUF.  */
+  unsigned char *mhash;        /* Points into BUF.  */
+  unsigned char *p;
+  size_t n;
+
+  /* This code is implemented as described by rfc-3447 9.1.2.  */
+
+  /* Get the length of the digest.  */
+  hlen = _gcry_md_get_algo_dlen (algo);
+  gcry_assert (hlen);  /* We expect a valid ALGO here.  */
+
+  /* Allocate a help buffer and setup some pointers.
+     This buffer is used for two purposes:
+        +------------------------------+-------+
+     1. | dbmask                       | mHash |
+        +------------------------------+-------+
+           emlen - hlen - 1              hlen
+
+        +----------+-------+---------+-+-------+
+     2. | padding1 | mHash | salt    | | mHash |
+        +----------+-------+---------+-+-------+
+             8       hlen    saltlen     hlen
+  */
+  buflen = 8 + hlen + saltlen;
+  if (buflen < emlen - hlen - 1)
+    buflen = emlen - hlen - 1;
+  buflen += hlen;
+  buf = xtrymalloc (buflen);
+  if (!buf)
+    {
+      rc = gpg_err_code_from_syserror ();
+      goto leave;
+    }
+  dbmask = buf;
+  mhash = buf + buflen - hlen;
+
+  /* Step 2: That would be: mHash = Hash(M) but our input is already
+     mHash thus we only need to convert VALUE into MHASH.  */
+  rc = octet_string_from_mpi (NULL, mhash, value, hlen);
+  if (rc)
+    goto leave;
+
+  /* Convert the signature into an octet string.  */
+  rc = octet_string_from_mpi (&em, NULL, encoded, emlen);
+  if (rc)
+    goto leave;
+
+  /* Step 3: Check length of EM.  Because we internally use MPI
+     functions we can't do this properly; EMLEN is always the length
+     of the key because octet_string_from_mpi needs to left pad the
+     result with zero to cope with the fact that our MPIs suppress all
+     leading zeroes.  Thus what we test here are merely the digest and
+     salt lengths to the key.  */
+  if (emlen < hlen + saltlen + 2)
+    {
+      rc = GPG_ERR_TOO_SHORT; /* For the hash and saltlen.  */
+      goto leave;
+    }
+
+  /* Step 4: Check last octet.  */
+  if (em[emlen - 1] != 0xbc)
+    {
+      rc = GPG_ERR_BAD_SIGNATURE;
+      goto leave;
+    }
+
+  /* Step 5: Split EM.  */
+  h = em + emlen - 1 - hlen;
+
+  /* Step 6: Check the leftmost bits.  */
+  if ((em[0] & ~(0xFF >> (8 * emlen - nbits))))
+    {
+      rc = GPG_ERR_BAD_SIGNATURE;
+      goto leave;
+    }
+
+  /* Step 7: dbmask = MGF(H, emlen - hlen - 1).  */
+  mgf1 (dbmask, emlen - hlen - 1, h, hlen, algo);
+
+  /* Step 8: maskedDB = DB ^ dbMask.  */
+  for (n = 0, p = dbmask; n < emlen - hlen - 1; n++, p++)
+    em[n] ^= *p;
+
+  /* Step 9: Set leftmost bits in DB to zero.  */
+  em[0] &= 0xFF >> (8 * emlen - nbits);
+
+  /* Step 10: Check the padding of DB.  */
+  for (n = 0; n < emlen - hlen - saltlen - 2 && !em[n]; n++)
+    ;
+  if (n != emlen - hlen - saltlen - 2 || em[n++] != 1)
+    {
+      rc = GPG_ERR_BAD_SIGNATURE;
+      goto leave;
+    }
+
+  /* Step 11: Extract salt from DB.  */
+  salt = em + n;
+
+  /* Step 12:  M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt */
+  memset (buf, 0, 8);
+  memcpy (buf+8, mhash, hlen);
+  memcpy (buf+8+hlen, salt, saltlen);
+
+  /* Step 13:  H' = Hash(M').  */
+  _gcry_md_hash_buffer (algo, buf, buf, 8 + hlen + saltlen);
+
+  /* Step 14:  Check H == H'.   */
+  rc = memcmp (h, buf, hlen) ? GPG_ERR_BAD_SIGNATURE : GPG_ERR_NO_ERROR;
+
+ leave:
+  if (em)
+    {
+      wipememory (em, emlen);
+      xfree (em);
+    }
+  if (buf)
+    {
+      wipememory (buf, buflen);
+      xfree (buf);
+    }
+  return rc;
+}
index ccc9f96..9a8d235 100644 (file)
@@ -32,6 +32,7 @@
 #include "g10lib.h"
 #include "mpi.h"
 #include "cipher.h"
+#include "pubkey-internal.h"
 
 
 typedef struct
@@ -52,6 +53,15 @@ typedef struct
 } RSA_secret_key;
 
 
+static const char *rsa_names[] =
+  {
+    "rsa",
+    "openpgp-rsa",
+    "oid.1.2.840.113549.1.1.1",
+    NULL,
+  };
+
+
 /* A sample 1024 bit RSA key used for the selftests.  */
 static const char sample_secret_key[] =
 "(private-key"
@@ -88,6 +98,7 @@ static int test_keys (RSA_secret_key *sk, unsigned nbits);
 static int  check_secret_key (RSA_secret_key *sk);
 static void public (gcry_mpi_t output, gcry_mpi_t input, RSA_public_key *skey);
 static void secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey);
+static unsigned int rsa_get_nbits (gcry_sexp_t parms);
 
 
 /* Check that a freshly generated key actually works.  Returns 0 on success. */
@@ -96,56 +107,56 @@ test_keys (RSA_secret_key *sk, unsigned int nbits)
 {
   int result = -1; /* Default to failure.  */
   RSA_public_key pk;
-  gcry_mpi_t plaintext = gcry_mpi_new (nbits);
-  gcry_mpi_t ciphertext = gcry_mpi_new (nbits);
-  gcry_mpi_t decr_plaintext = gcry_mpi_new (nbits);
-  gcry_mpi_t signature = gcry_mpi_new (nbits);
+  gcry_mpi_t plaintext = mpi_new (nbits);
+  gcry_mpi_t ciphertext = mpi_new (nbits);
+  gcry_mpi_t decr_plaintext = mpi_new (nbits);
+  gcry_mpi_t signature = mpi_new (nbits);
 
   /* Put the relevant parameters into a public key structure.  */
   pk.n = sk->n;
   pk.e = sk->e;
 
   /* Create a random plaintext.  */
-  gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
+  _gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
 
   /* Encrypt using the public key.  */
   public (ciphertext, plaintext, &pk);
 
   /* Check that the cipher text does not match the plaintext.  */
-  if (!gcry_mpi_cmp (ciphertext, plaintext))
+  if (!mpi_cmp (ciphertext, plaintext))
     goto leave; /* Ciphertext is identical to the plaintext.  */
 
   /* Decrypt using the secret key.  */
   secret (decr_plaintext, ciphertext, sk);
 
   /* Check that the decrypted plaintext matches the original plaintext.  */
-  if (gcry_mpi_cmp (decr_plaintext, plaintext))
+  if (mpi_cmp (decr_plaintext, plaintext))
     goto leave; /* Plaintext does not match.  */
 
   /* Create another random plaintext as data for signature checking.  */
-  gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
+  _gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
 
   /* Use the RSA secret function to create a signature of the plaintext.  */
   secret (signature, plaintext, sk);
 
   /* Use the RSA public function to verify this signature.  */
   public (decr_plaintext, signature, &pk);
-  if (gcry_mpi_cmp (decr_plaintext, plaintext))
+  if (mpi_cmp (decr_plaintext, plaintext))
     goto leave; /* Signature does not match.  */
 
   /* Modify the signature and check that the signing fails.  */
-  gcry_mpi_add_ui (signature, signature, 1);
+  mpi_add_ui (signature, signature, 1);
   public (decr_plaintext, signature, &pk);
-  if (!gcry_mpi_cmp (decr_plaintext, plaintext))
+  if (!mpi_cmp (decr_plaintext, plaintext))
     goto leave; /* Signature matches but should not.  */
 
   result = 0; /* All tests succeeded.  */
 
  leave:
-  gcry_mpi_release (signature);
-  gcry_mpi_release (decr_plaintext);
-  gcry_mpi_release (ciphertext);
-  gcry_mpi_release (plaintext);
+  _gcry_mpi_release (signature);
+  _gcry_mpi_release (decr_plaintext);
+  _gcry_mpi_release (ciphertext);
+  _gcry_mpi_release (plaintext);
   return result;
 }
 
@@ -161,8 +172,8 @@ check_exponent (void *arg, gcry_mpi_t a)
 
   mpi_sub_ui (a, a, 1);
   tmp = _gcry_mpi_alloc_like (a);
-  result = !gcry_mpi_gcd(tmp, e, a); /* GCD is not 1. */
-  gcry_mpi_release (tmp);
+  result = !mpi_gcd(tmp, e, a); /* GCD is not 1. */
+  _gcry_mpi_release (tmp);
   mpi_add_ui (a, a, 1);
   return result;
 }
@@ -228,16 +239,16 @@ generate_std (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e,
       mpi_set_ui (e, use_e);
     }
 
-  n = gcry_mpi_new (nbits);
+  n = mpi_new (nbits);
 
   p = q = NULL;
   do
     {
       /* select two (very secret) primes */
       if (p)
-        gcry_mpi_release (p);
+        _gcry_mpi_release (p);
       if (q)
-        gcry_mpi_release (q);
+        _gcry_mpi_release (q);
       if (use_e)
         { /* Do an extra test to ensure that the given exponent is
              suitable. */
@@ -261,16 +272,16 @@ generate_std (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e,
   /* calculate Euler totient: phi = (p-1)(q-1) */
   t1 = mpi_alloc_secure( mpi_get_nlimbs(p) );
   t2 = mpi_alloc_secure( mpi_get_nlimbs(p) );
-  phi = gcry_mpi_snew ( nbits );
-  g    = gcry_mpi_snew ( nbits );
-  f    = gcry_mpi_snew ( nbits );
+  phi   = mpi_snew ( nbits );
+  g    = mpi_snew ( nbits );
+  f    = mpi_snew ( nbits );
   mpi_sub_ui( t1, p, 1 );
   mpi_sub_ui( t2, q, 1 );
   mpi_mul( phi, t1, t2 );
-  gcry_mpi_gcd(g, t1, t2);
+  mpi_gcd (g, t1, t2);
   mpi_fdiv_q(f, phi, g);
 
-  while (!gcry_mpi_gcd(t1, e, phi)) /* (while gcd is not 1) */
+  while (!mpi_gcd(t1, e, phi)) /* (while gcd is not 1) */
     {
       if (use_e)
         BUG (); /* The prime generator already made sure that we
@@ -279,10 +290,10 @@ generate_std (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e,
     }
 
   /* calculate the secret key d = e^1 mod phi */
-  d = gcry_mpi_snew ( nbits );
-  mpi_invm(d, e, f );
+  d = mpi_snew ( nbits );
+  mpi_invm (d, e, f );
   /* calculate the inverse of p and q (used for chinese remainder theorem)*/
-  u = gcry_mpi_snew ( nbits );
+  u = mpi_snew ( nbits );
   mpi_invm(u, p, q );
 
   if( DBG_CIPHER )
@@ -298,11 +309,11 @@ generate_std (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e,
       log_mpidump("  u= ", u );
     }
 
-  gcry_mpi_release (t1);
-  gcry_mpi_release (t2);
-  gcry_mpi_release (phi);
-  gcry_mpi_release (f);
-  gcry_mpi_release (g);
+  _gcry_mpi_release (t1);
+  _gcry_mpi_release (t2);
+  _gcry_mpi_release (phi);
+  _gcry_mpi_release (f);
+  _gcry_mpi_release (g);
 
   sk->n = n;
   sk->e = e;
@@ -314,12 +325,12 @@ generate_std (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e,
   /* Now we can test our keys. */
   if (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;
+      _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;
       fips_signal_error ("self-test after key generation failed");
       return GPG_ERR_SELFTEST_FAILED;
     }
@@ -334,8 +345,8 @@ gen_x931_parm_xp (unsigned int nbits)
 {
   gcry_mpi_t xp;
 
-  xp = gcry_mpi_snew (nbits);
-  gcry_mpi_randomize (xp, nbits, GCRY_VERY_STRONG_RANDOM);
+  xp = mpi_snew (nbits);
+  _gcry_mpi_randomize (xp, nbits, GCRY_VERY_STRONG_RANDOM);
 
   /* The requirement for Xp is:
 
@@ -358,8 +369,8 @@ gen_x931_parm_xi (void)
 {
   gcry_mpi_t xi;
 
-  xi = gcry_mpi_snew (101);
-  gcry_mpi_randomize (xi, 101, GCRY_VERY_STRONG_RANDOM);
+  xi = mpi_snew (101);
+  _gcry_mpi_randomize (xi, 101, GCRY_VERY_STRONG_RANDOM);
   mpi_set_highbit (xi, 100);
   gcry_assert ( mpi_get_nbits (xi) == 101 );
 
@@ -425,15 +436,15 @@ generate_x931 (RSA_secret_key *sk, unsigned int nbits, unsigned long e_value,
         /* Not given: Generate them.  */
         xp = gen_x931_parm_xp (nbits/2);
         /* Make sure that |xp - xq| > 2^{nbits - 100} holds.  */
-        tmpval = gcry_mpi_snew (nbits/2);
+        tmpval = mpi_snew (nbits/2);
         do
           {
-            gcry_mpi_release (xq);
+            _gcry_mpi_release (xq);
             xq = gen_x931_parm_xp (nbits/2);
             mpi_sub (tmpval, xp, xq);
           }
         while (mpi_get_nbits (tmpval) <= (nbits/2 - 100));
-        gcry_mpi_release (tmpval);
+        _gcry_mpi_release (tmpval);
 
         xp1 = gen_x931_parm_xi ();
         xp2 = gen_x931_parm_xi ();
@@ -468,12 +479,11 @@ generate_x931 (RSA_secret_key *sk, unsigned int nbits, unsigned long e_value,
 
         for (idx=0; tbl[idx].name; idx++)
           {
-            oneparm = gcry_sexp_find_token (deriveparms, tbl[idx].name, 0);
+            oneparm = sexp_find_token (deriveparms, tbl[idx].name, 0);
             if (oneparm)
               {
-                *tbl[idx].value = gcry_sexp_nth_mpi (oneparm, 1,
-                                                     GCRYMPI_FMT_USG);
-                gcry_sexp_release (oneparm);
+                *tbl[idx].value = sexp_nth_mpi (oneparm, 1, GCRYMPI_FMT_USG);
+                sexp_release (oneparm);
               }
           }
         for (idx=0; tbl[idx].name; idx++)
@@ -483,7 +493,7 @@ generate_x931 (RSA_secret_key *sk, unsigned int nbits, unsigned long e_value,
           {
             /* At least one parameter is missing.  */
             for (idx=0; tbl[idx].name; idx++)
-              gcry_mpi_release (*tbl[idx].value);
+              _gcry_mpi_release (*tbl[idx].value);
             return GPG_ERR_MISSING_VALUE;
           }
       }
@@ -493,17 +503,17 @@ generate_x931 (RSA_secret_key *sk, unsigned int nbits, unsigned long e_value,
     /* Find two prime numbers.  */
     p = _gcry_derive_x931_prime (xp, xp1, xp2, e, NULL, NULL);
     q = _gcry_derive_x931_prime (xq, xq1, xq2, e, NULL, NULL);
-    gcry_mpi_release (xp);  xp  = NULL;
-    gcry_mpi_release (xp1); xp1 = NULL;
-    gcry_mpi_release (xp2); xp2 = NULL;
-    gcry_mpi_release (xq);  xq  = NULL;
-    gcry_mpi_release (xq1); xq1 = NULL;
-    gcry_mpi_release (xq2); xq2 = NULL;
+    _gcry_mpi_release (xp);  xp  = NULL;
+    _gcry_mpi_release (xp1); xp1 = NULL;
+    _gcry_mpi_release (xp2); xp2 = NULL;
+    _gcry_mpi_release (xq);  xq  = NULL;
+    _gcry_mpi_release (xq1); xq1 = NULL;
+    _gcry_mpi_release (xq2); xq2 = NULL;
     if (!p || !q)
       {
-        gcry_mpi_release (p);
-        gcry_mpi_release (q);
-        gcry_mpi_release (e);
+        _gcry_mpi_release (p);
+        _gcry_mpi_release (q);
+        _gcry_mpi_release (e);
         return GPG_ERR_NO_PRIME;
       }
   }
@@ -516,26 +526,26 @@ generate_x931 (RSA_secret_key *sk, unsigned int nbits, unsigned long e_value,
       mpi_swap (p, q);
       *swapped = 1;
     }
-  n = gcry_mpi_new (nbits);
+  n = mpi_new (nbits);
   mpi_mul (n, p, q);
 
   /* Compute the Euler totient:  phi = (p-1)(q-1)  */
-  pm1 = gcry_mpi_snew (nbits/2);
-  qm1 = gcry_mpi_snew (nbits/2);
-  phi = gcry_mpi_snew (nbits);
+  pm1 = mpi_snew (nbits/2);
+  qm1 = mpi_snew (nbits/2);
+  phi = mpi_snew (nbits);
   mpi_sub_ui (pm1, p, 1);
   mpi_sub_ui (qm1, q, 1);
   mpi_mul (phi, pm1, qm1);
 
-  g = gcry_mpi_snew (nbits);
-  gcry_assert (gcry_mpi_gcd (g, e, phi));
+  g = mpi_snew (nbits);
+  gcry_assert (mpi_gcd (g, e, phi));
 
   /* Compute: f = lcm(p-1,q-1) = phi / gcd(p-1,q-1) */
-  gcry_mpi_gcd (g, pm1, qm1);
+  mpi_gcd (g, pm1, qm1);
   f = pm1; pm1 = NULL;
-  gcry_mpi_release (qm1); qm1 = NULL;
+  _gcry_mpi_release (qm1); qm1 = NULL;
   mpi_fdiv_q (f, phi, g);
-  gcry_mpi_release (phi); phi = NULL;
+  _gcry_mpi_release (phi); phi = NULL;
   d = g; g = NULL;
   /* Compute the secret key:  d = e^{-1} mod lcm(p-1,q-1) */
   mpi_invm (d, e, f);
@@ -567,12 +577,12 @@ generate_x931 (RSA_secret_key *sk, unsigned int nbits, unsigned long e_value,
   /* Now we can test our keys. */
   if (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;
+      _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;
       fips_signal_error ("self-test after key generation failed");
       return GPG_ERR_SELFTEST_FAILED;
     }
@@ -662,7 +672,7 @@ stronger_key_check ( RSA_secret_key *skey )
       {
         log_info ( "RSA Oops: d is wrong - fixed\n");
         mpi_set (skey->d, t);
-        _gcry_log_mpidump ("  fixed d", skey->d);
+        log_printmpi ("  fixed d", skey->d);
       }
 
     /* check for correctness of u */
@@ -671,7 +681,7 @@ stronger_key_check ( RSA_secret_key *skey )
       {
         log_info ( "RSA Oops: u is wrong - fixed\n");
         mpi_set (skey->u, t);
-        _gcry_log_mpidump ("  fixed u", skey->u);
+        log_printmpi ("  fixed u", skey->u);
       }
 
     log_info ( "RSA secret key check finished\n");
@@ -700,8 +710,11 @@ stronger_key_check ( RSA_secret_key *skey )
  * Where m is OUTPUT, c is INPUT and d,n,p,q,u are elements of SKEY.
  */
 static void
-secret(gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey )
+secret (gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey )
 {
+  /* Remove superfluous leading zeroes from INPUT.  */
+  mpi_normalize (input);
+
   if (!skey->p || !skey->q || !skey->u)
     {
       mpi_powm (output, input, skey->d, skey->n);
@@ -722,7 +735,7 @@ secret(gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey )
       mpi_powm( m2, input, h, skey->q );
       /* h = u * ( m2 - m1 ) mod q */
       mpi_sub( h, m2, m1 );
-      if ( mpi_is_neg( h ) )
+      if ( mpi_has_sign ( h ) )
         mpi_add ( h, h, skey->q );
       mpi_mulm( h, skey->u, h, skey->q );
       /* m = m2 + h * p */
@@ -737,321 +750,540 @@ secret(gcry_mpi_t output, gcry_mpi_t input, RSA_secret_key *skey )
 
 
 
-/* Perform RSA blinding.  */
-static gcry_mpi_t
-rsa_blind (gcry_mpi_t x, gcry_mpi_t r, gcry_mpi_t e, gcry_mpi_t n)
-{
-  /* A helper.  */
-  gcry_mpi_t a;
-
-  /* Result.  */
-  gcry_mpi_t y;
-
-  a = gcry_mpi_snew (gcry_mpi_get_nbits (n));
-  y = gcry_mpi_snew (gcry_mpi_get_nbits (n));
-
-  /* Now 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.  */
-  gcry_mpi_powm (a, r, e, n);
-  gcry_mpi_mulm (y, a, x, n);
-
-  gcry_mpi_release (a);
-
-  return y;
-}
-
-/* Undo RSA blinding.  */
-static gcry_mpi_t
-rsa_unblind (gcry_mpi_t x, gcry_mpi_t ri, gcry_mpi_t n)
-{
-  gcry_mpi_t y;
-
-  y = gcry_mpi_snew (gcry_mpi_get_nbits (n));
-
-  /* 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.  */
-
-  gcry_mpi_mulm (y, ri, x, n);
-
-  return y;
-}
-
 /*********************************************
  **************  interface  ******************
  *********************************************/
 
 static gcry_err_code_t
-rsa_generate_ext (int algo, unsigned int nbits, unsigned long evalue,
-                  const gcry_sexp_t genparms,
-                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
-                  gcry_sexp_t *r_extrainfo)
+rsa_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey)
 {
-  RSA_secret_key sk;
   gpg_err_code_t ec;
+  unsigned int nbits;
+  unsigned long evalue;
+  RSA_secret_key sk;
   gcry_sexp_t deriveparms;
-  int transient_key = 0;
-  int use_x931 = 0;
+  int flags = 0;
   gcry_sexp_t l1;
+  gcry_sexp_t swap_info = NULL;
 
-  (void)algo;
+  memset (&sk, 0, sizeof sk);
 
-  *retfactors = NULL; /* We don't return them.  */
+  ec = _gcry_pk_util_get_nbits (genparms, &nbits);
+  if (ec)
+    return ec;
+
+  ec = _gcry_pk_util_get_rsa_use_e (genparms, &evalue);
+  if (ec)
+    return ec;
+
+  /* Parse the optional flags list.  */
+  l1 = sexp_find_token (genparms, "flags", 0);
+  if (l1)
+    {
+      ec = _gcry_pk_util_parse_flaglist (l1, &flags, NULL);
+      sexp_release (l1);
+      if (ec)
+        return ec;
+    }
 
   deriveparms = (genparms?
-                 gcry_sexp_find_token (genparms, "derive-parms", 0) : NULL);
+                 sexp_find_token (genparms, "derive-parms", 0) : NULL);
   if (!deriveparms)
     {
       /* Parse the optional "use-x931" flag. */
-      l1 = gcry_sexp_find_token (genparms, "use-x931", 0);
+      l1 = sexp_find_token (genparms, "use-x931", 0);
       if (l1)
         {
-          use_x931 = 1;
-          gcry_sexp_release (l1);
+          flags |= PUBKEY_FLAG_USE_X931;
+          sexp_release (l1);
         }
     }
 
-  if (deriveparms || use_x931 || fips_mode ())
+  if (deriveparms || (flags & PUBKEY_FLAG_USE_X931) || fips_mode ())
     {
       int swapped;
       ec = generate_x931 (&sk, nbits, evalue, deriveparms, &swapped);
-      gcry_sexp_release (deriveparms);
-      if (!ec && r_extrainfo && swapped)
-        {
-          ec = gcry_sexp_new (r_extrainfo,
-                              "(misc-key-info(p-q-swapped))", 0, 1);
-          if (ec)
-            {
-              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;
-            }
-        }
+      sexp_release (deriveparms);
+      if (!ec && swapped)
+        ec = sexp_new (&swap_info, "(misc-key-info(p-q-swapped))", 0, 1);
     }
   else
     {
       /* Parse the optional "transient-key" flag. */
-      l1 = gcry_sexp_find_token (genparms, "transient-key", 0);
-      if (l1)
+      if (!(flags & PUBKEY_FLAG_TRANSIENT_KEY))
         {
-          transient_key = 1;
-          gcry_sexp_release (l1);
+          l1 = sexp_find_token (genparms, "transient-key", 0);
+          if (l1)
+            {
+              flags |= PUBKEY_FLAG_TRANSIENT_KEY;
+              sexp_release (l1);
+            }
         }
       /* Generate.  */
-      ec = generate_std (&sk, nbits, evalue, transient_key);
+      ec = generate_std (&sk, nbits, evalue,
+                         !!(flags & PUBKEY_FLAG_TRANSIENT_KEY));
     }
 
   if (!ec)
     {
-      skey[0] = sk.n;
-      skey[1] = sk.e;
-      skey[2] = sk.d;
-      skey[3] = sk.p;
-      skey[4] = sk.q;
-      skey[5] = sk.u;
+      ec = sexp_build (r_skey, NULL,
+                       "(key-data"
+                       " (public-key"
+                       "  (rsa(n%m)(e%m)))"
+                       " (private-key"
+                       "  (rsa(n%m)(e%m)(d%m)(p%m)(q%m)(u%m)))"
+                       " %S)",
+                       sk.n, sk.e,
+                       sk.n, sk.e, sk.d, sk.p, sk.q, sk.u,
+                       swap_info);
     }
 
-  return ec;
-}
-
+  mpi_free (sk.n);
+  mpi_free (sk.e);
+  mpi_free (sk.p);
+  mpi_free (sk.q);
+  mpi_free (sk.d);
+  mpi_free (sk.u);
+  sexp_release (swap_info);
 
-static gcry_err_code_t
-rsa_generate (int algo, unsigned int nbits, unsigned long evalue,
-              gcry_mpi_t *skey, gcry_mpi_t **retfactors)
-{
-  return rsa_generate_ext (algo, nbits, evalue, NULL, skey, retfactors, NULL);
+  return ec;
 }
 
 
 static gcry_err_code_t
-rsa_check_secret_key (int algo, gcry_mpi_t *skey)
+rsa_check_secret_key (gcry_sexp_t keyparms)
 {
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  RSA_secret_key sk;
-
-  (void)algo;
+  gcry_err_code_t rc;
+  RSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL, NULL};
 
-  sk.n = skey[0];
-  sk.e = skey[1];
-  sk.d = skey[2];
-  sk.p = skey[3];
-  sk.q = skey[4];
-  sk.u = skey[5];
+  /* To check the key we need the optional parameters. */
+  rc = sexp_extract_param (keyparms, NULL, "nedpqu",
+                           &sk.n, &sk.e, &sk.d, &sk.p, &sk.q, &sk.u,
+                           NULL);
+  if (rc)
+    goto leave;
 
-  if (!sk.p || !sk.q || !sk.u)
-    err = GPG_ERR_NO_OBJ;  /* To check the key we need the optional
-                              parameters. */
-  else if (!check_secret_key (&sk))
-    err = GPG_ERR_BAD_SECKEY;
+  if (!check_secret_key (&sk))
+    rc = GPG_ERR_BAD_SECKEY;
 
-  return err;
+ leave:
+  _gcry_mpi_release (sk.n);
+  _gcry_mpi_release (sk.e);
+  _gcry_mpi_release (sk.d);
+  _gcry_mpi_release (sk.p);
+  _gcry_mpi_release (sk.q);
+  _gcry_mpi_release (sk.u);
+  if (DBG_CIPHER)
+    log_debug ("rsa_testkey    => %s\n", gpg_strerror (rc));
+  return rc;
 }
 
 
 static gcry_err_code_t
-rsa_encrypt (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
-             gcry_mpi_t *pkey, int flags)
+rsa_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms)
 {
-  RSA_public_key pk;
+  gcry_err_code_t rc;
+  struct pk_encoding_ctx ctx;
+  gcry_mpi_t data = NULL;
+  RSA_public_key pk = {NULL, NULL};
+  gcry_mpi_t ciph = NULL;
+
+  _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT,
+                                   rsa_get_nbits (keyparms));
+
+  /* Extract the data.  */
+  rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    log_mpidump ("rsa_encrypt data", data);
+  if (mpi_is_opaque (data))
+    {
+      rc = GPG_ERR_INV_DATA;
+      goto leave;
+    }
 
-  (void)algo;
-  (void)flags;
+  /* Extract the key.  */
+  rc = sexp_extract_param (keyparms, NULL, "ne", &pk.n, &pk.e, NULL);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    {
+      log_mpidump ("rsa_encrypt    n", pk.n);
+      log_mpidump ("rsa_encrypt    e", pk.e);
+    }
 
-  pk.n = pkey[0];
-  pk.e = pkey[1];
-  resarr[0] = mpi_alloc (mpi_get_nlimbs (pk.n));
-  public (resarr[0], data, &pk);
+  /* Do RSA computation and build result.  */
+  ciph = mpi_new (0);
+  public (ciph, data, &pk);
+  if (DBG_CIPHER)
+    log_mpidump ("rsa_encrypt  res", ciph);
+  if ((ctx.flags & PUBKEY_FLAG_FIXEDLEN))
+    {
+      /* We need to make sure to return the correct length to avoid
+         problems with missing leading zeroes.  */
+      unsigned char *em;
+      size_t emlen = (mpi_get_nbits (pk.n)+7)/8;
+
+      rc = _gcry_mpi_to_octet_string (&em, NULL, ciph, emlen);
+      if (!rc)
+        {
+          rc = sexp_build (r_ciph, NULL, "(enc-val(rsa(a%b)))", (int)emlen, em);
+          xfree (em);
+        }
+    }
+  else
+    rc = sexp_build (r_ciph, NULL, "(enc-val(rsa(a%m)))", ciph);
 
-  return GPG_ERR_NO_ERROR;
+ leave:
+  _gcry_mpi_release (ciph);
+  _gcry_mpi_release (pk.n);
+  _gcry_mpi_release (pk.e);
+  _gcry_mpi_release (data);
+  _gcry_pk_util_free_encoding_ctx (&ctx);
+  if (DBG_CIPHER)
+    log_debug ("rsa_encrypt    => %s\n", gpg_strerror (rc));
+  return rc;
 }
 
 
 static gcry_err_code_t
-rsa_decrypt (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
-             gcry_mpi_t *skey, int flags)
+rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms)
+
 {
-  RSA_secret_key sk;
-  gcry_mpi_t r = MPI_NULL;     /* Random number needed for blinding.  */
-  gcry_mpi_t ri = MPI_NULL;    /* Modular multiplicative inverse of
-                                  r.  */
-  gcry_mpi_t x = MPI_NULL;     /* Data to decrypt.  */
-  gcry_mpi_t y;                        /* Result.  */
+  gpg_err_code_t rc;
+  struct pk_encoding_ctx ctx;
+  gcry_sexp_t l1 = NULL;
+  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;
+
+  _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT,
+                                   rsa_get_nbits (keyparms));
+
+  /* Extract the data.  */
+  rc = _gcry_pk_util_preparse_encval (s_data, rsa_names, &l1, &ctx);
+  if (rc)
+    goto leave;
+  rc = sexp_extract_param (l1, NULL, "a", &data, NULL);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    log_printmpi ("rsa_decrypt data", data);
+  if (mpi_is_opaque (data))
+    {
+      rc = GPG_ERR_INV_DATA;
+      goto leave;
+    }
 
-  (void)algo;
+  /* Extract the key.  */
+  rc = sexp_extract_param (keyparms, NULL, "nedp?q?u?",
+                           &sk.n, &sk.e, &sk.d, &sk.p, &sk.q, &sk.u,
+                           NULL);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    {
+      log_printmpi ("rsa_decrypt    n", sk.n);
+      log_printmpi ("rsa_decrypt    e", sk.e);
+      if (!fips_mode ())
+        {
+          log_printmpi ("rsa_decrypt    d", sk.d);
+          log_printmpi ("rsa_decrypt    p", sk.p);
+          log_printmpi ("rsa_decrypt    q", sk.q);
+          log_printmpi ("rsa_decrypt    u", sk.u);
+        }
+    }
 
-  /* Extract private key.  */
-  sk.n = skey[0];
-  sk.e = skey[1];
-  sk.d = skey[2];
-  sk.p = skey[3]; /* Optional. */
-  sk.q = skey[4]; /* Optional. */
-  sk.u = skey[5]; /* Optional. */
+  /* Better make sure that there are no superfluous leading zeroes in
+     the input and it has not been "padded" using multiples of N.
+     This mitigates side-channel attacks (CVE-2013-4576).  */
+  mpi_normalize (data);
+  mpi_fdiv_r (data, data, sk.n);
 
-  y = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
+  /* Allocate MPI for the plaintext.  */
+  plain = mpi_snew (ctx.nbits);
 
   /* 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 (! (flags & PUBKEY_FLAG_NO_BLINDING))
+  if (!(ctx.flags & PUBKEY_FLAG_NO_BLINDING))
     {
-      /* Initialize 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 = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
-      ri = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
+      r  = mpi_snew (ctx.nbits);
+      ri = mpi_snew (ctx.nbits);
+      bldata = mpi_snew (ctx.nbits);
 
-      gcry_mpi_randomize (r, gcry_mpi_get_nbits (sk.n), GCRY_WEAK_RANDOM);
-      gcry_mpi_mod (r, r, sk.n);
+      do
+        {
+          _gcry_mpi_randomize (r, ctx.nbits, GCRY_WEAK_RANDOM);
+          mpi_mod (r, r, sk.n);
+        }
+      while (!mpi_invm (ri, r, sk.n));
 
-      /* Calculate inverse of r.  It practically impossible that the
-         following test fails, thus we do not add code to release
-         allocated resources.  */
-      if (!gcry_mpi_invm (ri, r, sk.n))
-       return GPG_ERR_INTERNAL;
-    }
+      /* 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);
 
-  if (! (flags & PUBKEY_FLAG_NO_BLINDING))
-    x = rsa_blind (data[0], r, sk.e, sk.n);
+      _gcry_mpi_release (r); r = NULL;
+      _gcry_mpi_release (ri); ri = NULL;
+    }
   else
-    x = data[0];
+    secret (plain, data, &sk);
 
-  /* Do the encryption.  */
-  secret (y, x, &sk);
+  if (DBG_CIPHER)
+    log_printmpi ("rsa_decrypt  res", plain);
 
-  if (! (flags & PUBKEY_FLAG_NO_BLINDING))
+  /* Reverse the encoding and build the s-expression.  */
+  switch (ctx.encoding)
     {
-      /* Undo blinding.  */
-      gcry_mpi_t a = gcry_mpi_copy (y);
-
-      gcry_mpi_release (y);
-      y = rsa_unblind (a, ri, sk.n);
+    case PUBKEY_ENC_PKCS1:
+      rc = _gcry_rsa_pkcs1_decode_for_enc (&unpad, &unpadlen, ctx.nbits, plain);
+      mpi_free (plain);
+      plain = NULL;
+      if (!rc)
+        rc = sexp_build (r_plain, NULL, "(value %b)", (int)unpadlen, unpad);
+      break;
 
-      gcry_mpi_release (a);
-    }
+    case PUBKEY_ENC_OAEP:
+      rc = _gcry_rsa_oaep_decode (&unpad, &unpadlen,
+                                  ctx.nbits, ctx.hash_algo,
+                                  plain, ctx.label, ctx.labellen);
+      mpi_free (plain);
+      plain = NULL;
+      if (!rc)
+        rc = sexp_build (r_plain, NULL, "(value %b)", (int)unpadlen, unpad);
+      break;
 
-  if (! (flags & PUBKEY_FLAG_NO_BLINDING))
-    {
-      /* Deallocate resources needed for blinding.  */
-      gcry_mpi_release (x);
-      gcry_mpi_release (r);
-      gcry_mpi_release (ri);
+    default:
+      /* Raw format.  For backward compatibility we need to assume a
+         signed mpi by using the sexp format string "%m".  */
+      rc = sexp_build (r_plain, NULL,
+                       (ctx.flags & PUBKEY_FLAG_LEGACYRESULT)
+                       ? "%m":"(value %m)", plain);
+      break;
     }
 
-  /* Copy out result.  */
-  *result = y;
-
-  return GPG_ERR_NO_ERROR;
+ leave:
+  xfree (unpad);
+  _gcry_mpi_release (plain);
+  _gcry_mpi_release (sk.n);
+  _gcry_mpi_release (sk.e);
+  _gcry_mpi_release (sk.d);
+  _gcry_mpi_release (sk.p);
+  _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)
+    log_debug ("rsa_decrypt    => %s\n", gpg_strerror (rc));
+  return rc;
 }
 
 
 static gcry_err_code_t
-rsa_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey)
+rsa_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
 {
-  RSA_secret_key sk;
+  gpg_err_code_t rc;
+  struct pk_encoding_ctx ctx;
+  gcry_mpi_t data = NULL;
+  RSA_secret_key sk = {NULL, NULL, NULL, NULL, NULL, NULL};
+  gcry_mpi_t sig = NULL;
+
+  _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_SIGN,
+                                   rsa_get_nbits (keyparms));
+
+  /* Extract the data.  */
+  rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    log_printmpi ("rsa_sign   data", data);
+  if (mpi_is_opaque (data))
+    {
+      rc = GPG_ERR_INV_DATA;
+      goto leave;
+    }
+
+  /* Extract the key.  */
+  rc = sexp_extract_param (keyparms, NULL, "nedp?q?u?",
+                           &sk.n, &sk.e, &sk.d, &sk.p, &sk.q, &sk.u,
+                           NULL);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    {
+      log_printmpi ("rsa_sign      n", sk.n);
+      log_printmpi ("rsa_sign      e", sk.e);
+      if (!fips_mode ())
+        {
+          log_printmpi ("rsa_sign      d", sk.d);
+          log_printmpi ("rsa_sign      p", sk.p);
+          log_printmpi ("rsa_sign      q", sk.q);
+          log_printmpi ("rsa_sign      u", sk.u);
+        }
+    }
 
-  (void)algo;
+  /* Do RSA computation and build the result.  */
+  sig = mpi_new (0);
+  secret (sig, data, &sk);
+  if (DBG_CIPHER)
+    log_printmpi ("rsa_sign    res", sig);
+  if ((ctx.flags & PUBKEY_FLAG_FIXEDLEN))
+    {
+      /* We need to make sure to return the correct length to avoid
+         problems with missing leading zeroes.  */
+      unsigned char *em;
+      size_t emlen = (mpi_get_nbits (sk.n)+7)/8;
+
+      rc = _gcry_mpi_to_octet_string (&em, NULL, sig, emlen);
+      if (!rc)
+        {
+          rc = sexp_build (r_sig, NULL, "(sig-val(rsa(s%b)))", (int)emlen, em);
+          xfree (em);
+        }
+    }
+  else
+    rc = sexp_build (r_sig, NULL, "(sig-val(rsa(s%M)))", sig);
 
-  sk.n = skey[0];
-  sk.e = skey[1];
-  sk.d = skey[2];
-  sk.p = skey[3];
-  sk.q = skey[4];
-  sk.u = skey[5];
-  resarr[0] = mpi_alloc( mpi_get_nlimbs (sk.n));
-  secret (resarr[0], data, &sk);
 
-  return GPG_ERR_NO_ERROR;
+ leave:
+  _gcry_mpi_release (sig);
+  _gcry_mpi_release (sk.n);
+  _gcry_mpi_release (sk.e);
+  _gcry_mpi_release (sk.d);
+  _gcry_mpi_release (sk.p);
+  _gcry_mpi_release (sk.q);
+  _gcry_mpi_release (sk.u);
+  _gcry_mpi_release (data);
+  _gcry_pk_util_free_encoding_ctx (&ctx);
+  if (DBG_CIPHER)
+    log_debug ("rsa_sign      => %s\n", gpg_strerror (rc));
+  return rc;
 }
 
 
 static gcry_err_code_t
-rsa_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
-                 int (*cmp) (void *opaque, gcry_mpi_t tmp),
-                 void *opaquev)
+rsa_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms)
 {
-  RSA_public_key pk;
-  gcry_mpi_t result;
   gcry_err_code_t rc;
+  struct pk_encoding_ctx ctx;
+  gcry_sexp_t l1 = NULL;
+  gcry_mpi_t sig = NULL;
+  gcry_mpi_t data = NULL;
+  RSA_public_key pk = { NULL, NULL };
+  gcry_mpi_t result = NULL;
+
+  _gcry_pk_util_init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY,
+                                   rsa_get_nbits (keyparms));
+
+  /* Extract the data.  */
+  rc = _gcry_pk_util_data_to_mpi (s_data, &data, &ctx);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    log_printmpi ("rsa_verify data", data);
+  if (mpi_is_opaque (data))
+    {
+      rc = GPG_ERR_INV_DATA;
+      goto leave;
+    }
 
-  (void)algo;
-  (void)cmp;
-  (void)opaquev;
+  /* Extract the signature value.  */
+  rc = _gcry_pk_util_preparse_sigval (s_sig, rsa_names, &l1, NULL);
+  if (rc)
+    goto leave;
+  rc = sexp_extract_param (l1, NULL, "s", &sig, NULL);
+  if (rc)
+    goto leave;
+  if (DBG_CIPHER)
+    log_printmpi ("rsa_verify  sig", sig);
 
-  pk.n = pkey[0];
-  pk.e = pkey[1];
-  result = gcry_mpi_new ( 160 );
-  public( result, data[0], &pk );
-#ifdef IS_DEVELOPMENT_VERSION
+  /* Extract the key.  */
+  rc = sexp_extract_param (keyparms, NULL, "ne", &pk.n, &pk.e, NULL);
+  if (rc)
+    goto leave;
   if (DBG_CIPHER)
     {
-      log_mpidump ("rsa verify result:", result );
-      log_mpidump ("             hash:", hash );
+      log_printmpi ("rsa_verify    n", pk.n);
+      log_printmpi ("rsa_verify    e", pk.e);
     }
-#endif /*IS_DEVELOPMENT_VERSION*/
-  if (cmp)
-    rc = (*cmp) (opaquev, result);
+
+  /* Do RSA computation and compare.  */
+  result = mpi_new (0);
+  public (result, sig, &pk);
+  if (DBG_CIPHER)
+    log_printmpi ("rsa_verify  cmp", result);
+  if (ctx.verify_cmp)
+    rc = ctx.verify_cmp (&ctx, result);
   else
-    rc = mpi_cmp (result, hash) ? GPG_ERR_BAD_SIGNATURE : GPG_ERR_NO_ERROR;
-  gcry_mpi_release (result);
+    rc = mpi_cmp (result, data) ? GPG_ERR_BAD_SIGNATURE : 0;
 
+ leave:
+  _gcry_mpi_release (result);
+  _gcry_mpi_release (pk.n);
+  _gcry_mpi_release (pk.e);
+  _gcry_mpi_release (data);
+  _gcry_mpi_release (sig);
+  sexp_release (l1);
+  _gcry_pk_util_free_encoding_ctx (&ctx);
+  if (DBG_CIPHER)
+    log_debug ("rsa_verify    => %s\n", rc?gpg_strerror (rc):"Good");
   return rc;
 }
 
 
+
+/* Return the number of bits for the key described by PARMS.  On error
+ * 0 is returned.  The format of PARMS starts with the algorithm name;
+ * for example:
+ *
+ *   (rsa
+ *     (n <mpi>)
+ *     (e <mpi>))
+ *
+ * More parameters may be given but we only need N here.
+ */
 static unsigned int
-rsa_get_nbits (int algo, gcry_mpi_t *pkey)
+rsa_get_nbits (gcry_sexp_t parms)
 {
-  (void)algo;
+  gcry_sexp_t l1;
+  gcry_mpi_t n;
+  unsigned int nbits;
+
+  l1 = sexp_find_token (parms, "n", 1);
+  if (!l1)
+    return 0; /* Parameter N not found.  */
 
-  return mpi_get_nbits (pkey[0]);
+  n = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+  sexp_release (l1);
+  nbits = n? mpi_get_nbits (n) : 0;
+  _gcry_mpi_release (n);
+  return nbits;
 }
 
 
@@ -1075,19 +1307,19 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
   const char *data;
   size_t datalen;
 
-  l1 = gcry_sexp_find_token (keyparam, "n", 1);
+  l1 = sexp_find_token (keyparam, "n", 1);
   if (!l1)
     return GPG_ERR_NO_OBJ;
 
-  data = gcry_sexp_nth_data (l1, 1, &datalen);
+  data = sexp_nth_data (l1, 1, &datalen);
   if (!data)
     {
-      gcry_sexp_release (l1);
+      sexp_release (l1);
       return GPG_ERR_NO_OBJ;
     }
 
-  gcry_md_write (md, data, datalen);
-  gcry_sexp_release (l1);
+  _gcry_md_write (md, data, datalen);
+  sexp_release (l1);
 
   return 0;
 }
@@ -1115,30 +1347,29 @@ selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
   gcry_sexp_t data_bad = NULL;
   gcry_sexp_t sig = NULL;
 
-  err = gcry_sexp_sscan (&data, NULL,
-                         sample_data, strlen (sample_data));
+  err = sexp_sscan (&data, NULL, sample_data, strlen (sample_data));
   if (!err)
-    err = gcry_sexp_sscan (&data_bad, NULL,
-                           sample_data_bad, strlen (sample_data_bad));
+    err = sexp_sscan (&data_bad, NULL,
+                      sample_data_bad, strlen (sample_data_bad));
   if (err)
     {
       errtxt = "converting data failed";
       goto leave;
     }
 
-  err = gcry_pk_sign (&sig, data, skey);
+  err = _gcry_pk_sign (&sig, data, skey);
   if (err)
     {
       errtxt = "signing failed";
       goto leave;
     }
-  err = gcry_pk_verify (sig, data, pkey);
+  err = _gcry_pk_verify (sig, data, pkey);
   if (err)
     {
       errtxt = "verify failed";
       goto leave;
     }
-  err = gcry_pk_verify (sig, data_bad, pkey);
+  err = _gcry_pk_verify (sig, data_bad, pkey);
   if (gcry_err_code (err) != GPG_ERR_BAD_SIGNATURE)
     {
       errtxt = "bad signature not detected";
@@ -1147,9 +1378,9 @@ selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
 
 
  leave:
-  gcry_sexp_release (sig);
-  gcry_sexp_release (data_bad);
-  gcry_sexp_release (data);
+  sexp_release (sig);
+  sexp_release (data_bad);
+  sexp_release (data);
   return errtxt;
 }
 
@@ -1169,19 +1400,19 @@ extract_a_from_sexp (gcry_sexp_t encr_data)
   gcry_sexp_t l1, l2, l3;
   gcry_mpi_t a_value;
 
-  l1 = gcry_sexp_find_token (encr_data, "enc-val", 0);
+  l1 = sexp_find_token (encr_data, "enc-val", 0);
   if (!l1)
     return NULL;
-  l2 = gcry_sexp_find_token (l1, "rsa", 0);
-  gcry_sexp_release (l1);
+  l2 = sexp_find_token (l1, "rsa", 0);
+  sexp_release (l1);
   if (!l2)
     return NULL;
-  l3 = gcry_sexp_find_token (l2, "a", 0);
-  gcry_sexp_release (l2);
+  l3 = sexp_find_token (l2, "a", 0);
+  sexp_release (l2);
   if (!l3)
     return NULL;
-  a_value = gcry_sexp_nth_mpi (l3, 1, 0);
-  gcry_sexp_release (l3);
+  a_value = sexp_nth_mpi (l3, 1, 0);
+  sexp_release (l3);
 
   return a_value;
 }
@@ -1202,12 +1433,11 @@ selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
   gcry_sexp_t tmplist = NULL;
 
   /* Create plaintext.  The plaintext is actually a big integer number.  */
-  plaintext = gcry_mpi_new (nbits);
-  gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
+  plaintext = mpi_new (nbits);
+  _gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
 
   /* Put the plaintext into an S-expression.  */
-  err = gcry_sexp_build (&plain, NULL,
-                         "(data (flags raw) (value %m))", plaintext);
+  err = sexp_build (&plain, NULL, "(data (flags raw) (value %m))", plaintext);
   if (err)
     {
       errtxt = "converting data failed";
@@ -1215,7 +1445,7 @@ selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
     }
 
   /* Encrypt.  */
-  err = gcry_pk_encrypt (&encr, plain, pkey);
+  err = _gcry_pk_encrypt (&encr, plain, pkey);
   if (err)
     {
       errtxt = "encrypt failed";
@@ -1223,7 +1453,7 @@ selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
     }
 
   /* Extraxt the ciphertext from the returned S-expression.  */
-  /*gcry_sexp_dump (encr);*/
+  /*sexp_dump (encr);*/
   ciphertext = extract_a_from_sexp (encr);
   if (!ciphertext)
     {
@@ -1232,16 +1462,16 @@ selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
     }
 
   /* Check that the ciphertext does no match the plaintext.  */
-  /* _gcry_log_mpidump ("plaintext", plaintext); */
-  /* _gcry_log_mpidump ("ciphertxt", ciphertext); */
-  if (!gcry_mpi_cmp (plaintext, ciphertext))
+  /* _gcry_log_printmpi ("plaintext", plaintext); */
+  /* _gcry_log_printmpi ("ciphertxt", ciphertext); */
+  if (!mpi_cmp (plaintext, ciphertext))
     {
       errtxt = "ciphertext matches plaintext";
       goto leave;
     }
 
   /* Decrypt.  */
-  err = gcry_pk_decrypt (&decr, encr, skey);
+  err = _gcry_pk_decrypt (&decr, encr, skey);
   if (err)
     {
       errtxt = "decrypt failed";
@@ -1254,11 +1484,11 @@ selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
      gcry_pk_encrypt directly to gcry_pk_decrypt, such a flag value
      won't be there as of today.  To be prepared for future changes we
      take care of it anyway.  */
-  tmplist = gcry_sexp_find_token (decr, "value", 0);
+  tmplist = sexp_find_token (decr, "value", 0);
   if (tmplist)
-    decr_plaintext = gcry_sexp_nth_mpi (tmplist, 1, GCRYMPI_FMT_USG);
+    decr_plaintext = sexp_nth_mpi (tmplist, 1, GCRYMPI_FMT_USG);
   else
-    decr_plaintext = gcry_sexp_nth_mpi (decr, 0, GCRYMPI_FMT_USG);
+    decr_plaintext = sexp_nth_mpi (decr, 0, GCRYMPI_FMT_USG);
   if (!decr_plaintext)
     {
       errtxt = "decrypt returned no plaintext";
@@ -1266,20 +1496,20 @@ selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
     }
 
   /* Check that the decrypted plaintext matches the original  plaintext.  */
-  if (gcry_mpi_cmp (plaintext, decr_plaintext))
+  if (mpi_cmp (plaintext, decr_plaintext))
     {
       errtxt = "mismatch";
       goto leave;
     }
 
  leave:
-  gcry_sexp_release (tmplist);
-  gcry_mpi_release (decr_plaintext);
-  gcry_sexp_release (decr);
-  gcry_mpi_release (ciphertext);
-  gcry_sexp_release (encr);
-  gcry_sexp_release (plain);
-  gcry_mpi_release (plaintext);
+  sexp_release (tmplist);
+  _gcry_mpi_release (decr_plaintext);
+  sexp_release (decr);
+  _gcry_mpi_release (ciphertext);
+  sexp_release (encr);
+  sexp_release (plain);
+  _gcry_mpi_release (plaintext);
   return errtxt;
 }
 
@@ -1295,22 +1525,21 @@ selftests_rsa (selftest_report_func_t report)
 
   /* Convert the S-expressions into the internal representation.  */
   what = "convert";
-  err = gcry_sexp_sscan (&skey, NULL,
-                         sample_secret_key, strlen (sample_secret_key));
+  err = sexp_sscan (&skey, NULL, sample_secret_key, strlen (sample_secret_key));
   if (!err)
-    err = gcry_sexp_sscan (&pkey, NULL,
-                           sample_public_key, strlen (sample_public_key));
+    err = sexp_sscan (&pkey, NULL,
+                      sample_public_key, strlen (sample_public_key));
   if (err)
     {
-      errtxt = gcry_strerror (err);
+      errtxt = _gcry_strerror (err);
       goto failed;
     }
 
   what = "key consistency";
-  err = gcry_pk_testkey (skey);
+  err = _gcry_pk_testkey (skey);
   if (err)
     {
-      errtxt = gcry_strerror (err);
+      errtxt = _gcry_strerror (err);
       goto failed;
     }
 
@@ -1324,13 +1553,13 @@ selftests_rsa (selftest_report_func_t report)
   if (errtxt)
     goto failed;
 
-  gcry_sexp_release (pkey);
-  gcry_sexp_release (skey);
+  sexp_release (pkey);
+  sexp_release (skey);
   return 0; /* Succeeded. */
 
  failed:
-  gcry_sexp_release (pkey);
-  gcry_sexp_release (skey);
+  sexp_release (pkey);
+  sexp_release (skey);
   if (report)
     report ("pubkey", GCRY_PK_RSA, what, errtxt);
   return GPG_ERR_SELFTEST_FAILED;
@@ -1361,19 +1590,12 @@ run_selftests (int algo, int extended, selftest_report_func_t report)
 
 
 \f
-static const char *rsa_names[] =
-  {
-    "rsa",
-    "openpgp-rsa",
-    "oid.1.2.840.113549.1.1.1",
-    NULL,
-  };
-
 gcry_pk_spec_t _gcry_pubkey_spec_rsa =
   {
+    GCRY_PK_RSA, { 0, 1 },
+    (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR),
     "RSA", rsa_names,
     "ne", "nedpqu", "a", "s", "n",
-    GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR,
     rsa_generate,
     rsa_check_secret_key,
     rsa_encrypt,
@@ -1381,10 +1603,6 @@ gcry_pk_spec_t _gcry_pubkey_spec_rsa =
     rsa_sign,
     rsa_verify,
     rsa_get_nbits,
-  };
-pk_extra_spec_t _gcry_pubkey_extraspec_rsa =
-  {
     run_selftests,
-    rsa_generate_ext,
     compute_keygrip
   };
diff --git a/cipher/salsa20-amd64.S b/cipher/salsa20-amd64.S
new file mode 100644 (file)
index 0000000..e79da4e
--- /dev/null
@@ -0,0 +1,924 @@
+/* salsa20-amd64.S  -  AMD64 implementation of Salsa20
+ *
+ * Copyright © 2013 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 D. J. Bernstein at
+ *  http://cr.yp.to/snuffle.html
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && defined(USE_SALSA20)
+
+.text
+
+.align 8
+.globl _gcry_salsa20_amd64_keysetup
+.type  _gcry_salsa20_amd64_keysetup,@function;
+_gcry_salsa20_amd64_keysetup:
+       movl   0(%rsi),%r8d
+       movl   4(%rsi),%r9d
+       movl   8(%rsi),%eax
+       movl   12(%rsi),%r10d
+       movl   %r8d,20(%rdi)
+       movl   %r9d,40(%rdi)
+       movl   %eax,60(%rdi)
+       movl   %r10d,48(%rdi)
+       cmp  $256,%rdx
+       jb .L_kbits128
+.L_kbits256:
+       movl   16(%rsi),%edx
+       movl   20(%rsi),%ecx
+       movl   24(%rsi),%r8d
+       movl   28(%rsi),%esi
+       movl   %edx,28(%rdi)
+       movl   %ecx,16(%rdi)
+       movl   %r8d,36(%rdi)
+       movl   %esi,56(%rdi)
+       mov  $1634760805,%rsi
+       mov  $857760878,%rdx
+       mov  $2036477234,%rcx
+       mov  $1797285236,%r8
+       movl   %esi,0(%rdi)
+       movl   %edx,4(%rdi)
+       movl   %ecx,8(%rdi)
+       movl   %r8d,12(%rdi)
+       jmp .L_keysetupdone
+.L_kbits128:
+       movl   0(%rsi),%edx
+       movl   4(%rsi),%ecx
+       movl   8(%rsi),%r8d
+       movl   12(%rsi),%esi
+       movl   %edx,28(%rdi)
+       movl   %ecx,16(%rdi)
+       movl   %r8d,36(%rdi)
+       movl   %esi,56(%rdi)
+       mov  $1634760805,%rsi
+       mov  $824206446,%rdx
+       mov  $2036477238,%rcx
+       mov  $1797285236,%r8
+       movl   %esi,0(%rdi)
+       movl   %edx,4(%rdi)
+       movl   %ecx,8(%rdi)
+       movl   %r8d,12(%rdi)
+.L_keysetupdone:
+       ret
+
+.align 8
+.globl _gcry_salsa20_amd64_ivsetup
+.type  _gcry_salsa20_amd64_ivsetup,@function;
+_gcry_salsa20_amd64_ivsetup:
+       movl   0(%rsi),%r8d
+       movl   4(%rsi),%esi
+       mov  $0,%r9
+       mov  $0,%rax
+       movl   %r8d,24(%rdi)
+       movl   %esi,44(%rdi)
+       movl   %r9d,32(%rdi)
+       movl   %eax,52(%rdi)
+       ret
+
+.align 8
+.globl _gcry_salsa20_amd64_encrypt_blocks
+.type  _gcry_salsa20_amd64_encrypt_blocks,@function;
+_gcry_salsa20_amd64_encrypt_blocks:
+       /*
+        * Modifications to original implementation:
+        *  - Number of rounds passing in register %r8 (for Salsa20/12).
+        *  - Length is input as number of blocks, so don't handle tail bytes
+        *    (this is done in salsa20.c).
+        */
+       push %rbx
+       shlq $6, %rcx /* blocks to bytes */
+       mov %r8, %rbx
+       mov %rsp,%r11
+       and $31,%r11
+       add $384,%r11
+       sub %r11,%rsp
+       mov  %rdi,%r8
+       mov  %rsi,%rsi
+       mov  %rdx,%rdi
+       mov  %rcx,%rdx
+       cmp  $0,%rdx
+       jbe .L_done
+.L_start:
+       cmp  $256,%rdx
+       jb .L_bytes_are_64_128_or_192
+       movdqa 0(%r8),%xmm0
+       pshufd $0x55,%xmm0,%xmm1
+       pshufd $0xaa,%xmm0,%xmm2
+       pshufd $0xff,%xmm0,%xmm3
+       pshufd $0x00,%xmm0,%xmm0
+       movdqa %xmm1,0(%rsp)
+       movdqa %xmm2,16(%rsp)
+       movdqa %xmm3,32(%rsp)
+       movdqa %xmm0,48(%rsp)
+       movdqa 16(%r8),%xmm0
+       pshufd $0xaa,%xmm0,%xmm1
+       pshufd $0xff,%xmm0,%xmm2
+       pshufd $0x00,%xmm0,%xmm3
+       pshufd $0x55,%xmm0,%xmm0
+       movdqa %xmm1,64(%rsp)
+       movdqa %xmm2,80(%rsp)
+       movdqa %xmm3,96(%rsp)
+       movdqa %xmm0,112(%rsp)
+       movdqa 32(%r8),%xmm0
+       pshufd $0xff,%xmm0,%xmm1
+       pshufd $0x55,%xmm0,%xmm2
+       pshufd $0xaa,%xmm0,%xmm0
+       movdqa %xmm1,128(%rsp)
+       movdqa %xmm2,144(%rsp)
+       movdqa %xmm0,160(%rsp)
+       movdqa 48(%r8),%xmm0
+       pshufd $0x00,%xmm0,%xmm1
+       pshufd $0xaa,%xmm0,%xmm2
+       pshufd $0xff,%xmm0,%xmm0
+       movdqa %xmm1,176(%rsp)
+       movdqa %xmm2,192(%rsp)
+       movdqa %xmm0,208(%rsp)
+.L_bytesatleast256:
+       movl   32(%r8),%ecx
+       movl   52(%r8),%r9d
+       movl %ecx,224(%rsp)
+       movl %r9d,240(%rsp)
+       add  $1,%ecx
+       adc  $0,%r9d
+       movl %ecx,4+224(%rsp)
+       movl %r9d,4+240(%rsp)
+       add  $1,%ecx
+       adc  $0,%r9d
+       movl %ecx,8+224(%rsp)
+       movl %r9d,8+240(%rsp)
+       add  $1,%ecx
+       adc  $0,%r9d
+       movl %ecx,12+224(%rsp)
+       movl %r9d,12+240(%rsp)
+       add  $1,%ecx
+       adc  $0,%r9d
+       movl   %ecx,32(%r8)
+       movl   %r9d,52(%r8)
+       movq %rdx,288(%rsp)
+       mov  %rbx,%rdx
+       movdqa 0(%rsp),%xmm0
+       movdqa 16(%rsp),%xmm1
+       movdqa 32(%rsp),%xmm2
+       movdqa 192(%rsp),%xmm3
+       movdqa 208(%rsp),%xmm4
+       movdqa 64(%rsp),%xmm5
+       movdqa 80(%rsp),%xmm6
+       movdqa 112(%rsp),%xmm7
+       movdqa 128(%rsp),%xmm8
+       movdqa 144(%rsp),%xmm9
+       movdqa 160(%rsp),%xmm10
+       movdqa 240(%rsp),%xmm11
+       movdqa 48(%rsp),%xmm12
+       movdqa 96(%rsp),%xmm13
+       movdqa 176(%rsp),%xmm14
+       movdqa 224(%rsp),%xmm15
+.L_mainloop1:
+       movdqa %xmm1,256(%rsp)
+       movdqa %xmm2,272(%rsp)
+       movdqa %xmm13,%xmm1
+       paddd %xmm12,%xmm1
+       movdqa %xmm1,%xmm2
+       pslld $7,%xmm1
+       pxor  %xmm1,%xmm14
+       psrld $25,%xmm2
+       pxor  %xmm2,%xmm14
+       movdqa %xmm7,%xmm1
+       paddd %xmm0,%xmm1
+       movdqa %xmm1,%xmm2
+       pslld $7,%xmm1
+       pxor  %xmm1,%xmm11
+       psrld $25,%xmm2
+       pxor  %xmm2,%xmm11
+       movdqa %xmm12,%xmm1
+       paddd %xmm14,%xmm1
+       movdqa %xmm1,%xmm2
+       pslld $9,%xmm1
+       pxor  %xmm1,%xmm15
+       psrld $23,%xmm2
+       pxor  %xmm2,%xmm15
+       movdqa %xmm0,%xmm1
+       paddd %xmm11,%xmm1
+       movdqa %xmm1,%xmm2
+       pslld $9,%xmm1
+       pxor  %xmm1,%xmm9
+       psrld $23,%xmm2
+       pxor  %xmm2,%xmm9
+       movdqa %xmm14,%xmm1
+       paddd %xmm15,%xmm1
+       movdqa %xmm1,%xmm2
+       pslld $13,%xmm1
+       pxor  %xmm1,%xmm13
+       psrld $19,%xmm2
+       pxor  %xmm2,%xmm13
+       movdqa %xmm11,%xmm1
+       paddd %xmm9,%xmm1
+       movdqa %xmm1,%xmm2
+       pslld $13,%xmm1
+       pxor  %xmm1,%xmm7
+       psrld $19,%xmm2
+       pxor  %xmm2,%xmm7
+       movdqa %xmm15,%xmm1
+       paddd %xmm13,%xmm1
+       movdqa %xmm1,%xmm2
+       pslld $18,%xmm1
+       pxor  %xmm1,%xmm12
+       psrld $14,%xmm2
+       pxor  %xmm2,%xmm12
+       movdqa 256(%rsp),%xmm1
+       movdqa %xmm12,256(%rsp)
+       movdqa %xmm9,%xmm2
+       paddd %xmm7,%xmm2
+       movdqa %xmm2,%xmm12
+       pslld $18,%xmm2
+       pxor  %xmm2,%xmm0
+       psrld $14,%xmm12
+       pxor  %xmm12,%xmm0
+       movdqa %xmm5,%xmm2
+       paddd %xmm1,%xmm2
+       movdqa %xmm2,%xmm12
+       pslld $7,%xmm2
+       pxor  %xmm2,%xmm3
+       psrld $25,%xmm12
+       pxor  %xmm12,%xmm3
+       movdqa 272(%rsp),%xmm2
+       movdqa %xmm0,272(%rsp)
+       movdqa %xmm6,%xmm0
+       paddd %xmm2,%xmm0
+       movdqa %xmm0,%xmm12
+       pslld $7,%xmm0
+       pxor  %xmm0,%xmm4
+       psrld $25,%xmm12
+       pxor  %xmm12,%xmm4
+       movdqa %xmm1,%xmm0
+       paddd %xmm3,%xmm0
+       movdqa %xmm0,%xmm12
+       pslld $9,%xmm0
+       pxor  %xmm0,%xmm10
+       psrld $23,%xmm12
+       pxor  %xmm12,%xmm10
+       movdqa %xmm2,%xmm0
+       paddd %xmm4,%xmm0
+       movdqa %xmm0,%xmm12
+       pslld $9,%xmm0
+       pxor  %xmm0,%xmm8
+       psrld $23,%xmm12
+       pxor  %xmm12,%xmm8
+       movdqa %xmm3,%xmm0
+       paddd %xmm10,%xmm0
+       movdqa %xmm0,%xmm12
+       pslld $13,%xmm0
+       pxor  %xmm0,%xmm5
+       psrld $19,%xmm12
+       pxor  %xmm12,%xmm5
+       movdqa %xmm4,%xmm0
+       paddd %xmm8,%xmm0
+       movdqa %xmm0,%xmm12
+       pslld $13,%xmm0
+       pxor  %xmm0,%xmm6
+       psrld $19,%xmm12
+       pxor  %xmm12,%xmm6
+       movdqa %xmm10,%xmm0
+       paddd %xmm5,%xmm0
+       movdqa %xmm0,%xmm12
+       pslld $18,%xmm0
+       pxor  %xmm0,%xmm1
+       psrld $14,%xmm12
+       pxor  %xmm12,%xmm1
+       movdqa 256(%rsp),%xmm0
+       movdqa %xmm1,256(%rsp)
+       movdqa %xmm4,%xmm1
+       paddd %xmm0,%xmm1
+       movdqa %xmm1,%xmm12
+       pslld $7,%xmm1
+       pxor  %xmm1,%xmm7
+       psrld $25,%xmm12
+       pxor  %xmm12,%xmm7
+       movdqa %xmm8,%xmm1
+       paddd %xmm6,%xmm1
+       movdqa %xmm1,%xmm12
+       pslld $18,%xmm1
+       pxor  %xmm1,%xmm2
+       psrld $14,%xmm12
+       pxor  %xmm12,%xmm2
+       movdqa 272(%rsp),%xmm12
+       movdqa %xmm2,272(%rsp)
+       movdqa %xmm14,%xmm1
+       paddd %xmm12,%xmm1
+       movdqa %xmm1,%xmm2
+       pslld $7,%xmm1
+       pxor  %xmm1,%xmm5
+       psrld $25,%xmm2
+       pxor  %xmm2,%xmm5
+       movdqa %xmm0,%xmm1
+       paddd %xmm7,%xmm1
+       movdqa %xmm1,%xmm2
+       pslld $9,%xmm1
+       pxor  %xmm1,%xmm10
+       psrld $23,%xmm2
+       pxor  %xmm2,%xmm10
+       movdqa %xmm12,%xmm1
+       paddd %xmm5,%xmm1
+       movdqa %xmm1,%xmm2
+       pslld $9,%xmm1
+       pxor  %xmm1,%xmm8
+       psrld $23,%xmm2
+       pxor  %xmm2,%xmm8
+       movdqa %xmm7,%xmm1
+       paddd %xmm10,%xmm1
+       movdqa %xmm1,%xmm2
+       pslld $13,%xmm1
+       pxor  %xmm1,%xmm4
+       psrld $19,%xmm2
+       pxor  %xmm2,%xmm4
+       movdqa %xmm5,%xmm1
+       paddd %xmm8,%xmm1
+       movdqa %xmm1,%xmm2
+       pslld $13,%xmm1
+       pxor  %xmm1,%xmm14
+       psrld $19,%xmm2
+       pxor  %xmm2,%xmm14
+       movdqa %xmm10,%xmm1
+       paddd %xmm4,%xmm1
+       movdqa %xmm1,%xmm2
+       pslld $18,%xmm1
+       pxor  %xmm1,%xmm0
+       psrld $14,%xmm2
+       pxor  %xmm2,%xmm0
+       movdqa 256(%rsp),%xmm1
+       movdqa %xmm0,256(%rsp)
+       movdqa %xmm8,%xmm0
+       paddd %xmm14,%xmm0
+       movdqa %xmm0,%xmm2
+       pslld $18,%xmm0
+       pxor  %xmm0,%xmm12
+       psrld $14,%xmm2
+       pxor  %xmm2,%xmm12
+       movdqa %xmm11,%xmm0
+       paddd %xmm1,%xmm0
+       movdqa %xmm0,%xmm2
+       pslld $7,%xmm0
+       pxor  %xmm0,%xmm6
+       psrld $25,%xmm2
+       pxor  %xmm2,%xmm6
+       movdqa 272(%rsp),%xmm2
+       movdqa %xmm12,272(%rsp)
+       movdqa %xmm3,%xmm0
+       paddd %xmm2,%xmm0
+       movdqa %xmm0,%xmm12
+       pslld $7,%xmm0
+       pxor  %xmm0,%xmm13
+       psrld $25,%xmm12
+       pxor  %xmm12,%xmm13
+       movdqa %xmm1,%xmm0
+       paddd %xmm6,%xmm0
+       movdqa %xmm0,%xmm12
+       pslld $9,%xmm0
+       pxor  %xmm0,%xmm15
+       psrld $23,%xmm12
+       pxor  %xmm12,%xmm15
+       movdqa %xmm2,%xmm0
+       paddd %xmm13,%xmm0
+       movdqa %xmm0,%xmm12
+       pslld $9,%xmm0
+       pxor  %xmm0,%xmm9
+       psrld $23,%xmm12
+       pxor  %xmm12,%xmm9
+       movdqa %xmm6,%xmm0
+       paddd %xmm15,%xmm0
+       movdqa %xmm0,%xmm12
+       pslld $13,%xmm0
+       pxor  %xmm0,%xmm11
+       psrld $19,%xmm12
+       pxor  %xmm12,%xmm11
+       movdqa %xmm13,%xmm0
+       paddd %xmm9,%xmm0
+       movdqa %xmm0,%xmm12
+       pslld $13,%xmm0
+       pxor  %xmm0,%xmm3
+       psrld $19,%xmm12
+       pxor  %xmm12,%xmm3
+       movdqa %xmm15,%xmm0
+       paddd %xmm11,%xmm0
+       movdqa %xmm0,%xmm12
+       pslld $18,%xmm0
+       pxor  %xmm0,%xmm1
+       psrld $14,%xmm12
+       pxor  %xmm12,%xmm1
+       movdqa %xmm9,%xmm0
+       paddd %xmm3,%xmm0
+       movdqa %xmm0,%xmm12
+       pslld $18,%xmm0
+       pxor  %xmm0,%xmm2
+       psrld $14,%xmm12
+       pxor  %xmm12,%xmm2
+       movdqa 256(%rsp),%xmm12
+       movdqa 272(%rsp),%xmm0
+       sub  $2,%rdx
+       ja .L_mainloop1
+       paddd 48(%rsp),%xmm12
+       paddd 112(%rsp),%xmm7
+       paddd 160(%rsp),%xmm10
+       paddd 208(%rsp),%xmm4
+       movd   %xmm12,%rdx
+       movd   %xmm7,%rcx
+       movd   %xmm10,%r9
+       movd   %xmm4,%rax
+       pshufd $0x39,%xmm12,%xmm12
+       pshufd $0x39,%xmm7,%xmm7
+       pshufd $0x39,%xmm10,%xmm10
+       pshufd $0x39,%xmm4,%xmm4
+       xorl 0(%rsi),%edx
+       xorl 4(%rsi),%ecx
+       xorl 8(%rsi),%r9d
+       xorl 12(%rsi),%eax
+       movl   %edx,0(%rdi)
+       movl   %ecx,4(%rdi)
+       movl   %r9d,8(%rdi)
+       movl   %eax,12(%rdi)
+       movd   %xmm12,%rdx
+       movd   %xmm7,%rcx
+       movd   %xmm10,%r9
+       movd   %xmm4,%rax
+       pshufd $0x39,%xmm12,%xmm12
+       pshufd $0x39,%xmm7,%xmm7
+       pshufd $0x39,%xmm10,%xmm10
+       pshufd $0x39,%xmm4,%xmm4
+       xorl 64(%rsi),%edx
+       xorl 68(%rsi),%ecx
+       xorl 72(%rsi),%r9d
+       xorl 76(%rsi),%eax
+       movl   %edx,64(%rdi)
+       movl   %ecx,68(%rdi)
+       movl   %r9d,72(%rdi)
+       movl   %eax,76(%rdi)
+       movd   %xmm12,%rdx
+       movd   %xmm7,%rcx
+       movd   %xmm10,%r9
+       movd   %xmm4,%rax
+       pshufd $0x39,%xmm12,%xmm12
+       pshufd $0x39,%xmm7,%xmm7
+       pshufd $0x39,%xmm10,%xmm10
+       pshufd $0x39,%xmm4,%xmm4
+       xorl 128(%rsi),%edx
+       xorl 132(%rsi),%ecx
+       xorl 136(%rsi),%r9d
+       xorl 140(%rsi),%eax
+       movl   %edx,128(%rdi)
+       movl   %ecx,132(%rdi)
+       movl   %r9d,136(%rdi)
+       movl   %eax,140(%rdi)
+       movd   %xmm12,%rdx
+       movd   %xmm7,%rcx
+       movd   %xmm10,%r9
+       movd   %xmm4,%rax
+       xorl 192(%rsi),%edx
+       xorl 196(%rsi),%ecx
+       xorl 200(%rsi),%r9d
+       xorl 204(%rsi),%eax
+       movl   %edx,192(%rdi)
+       movl   %ecx,196(%rdi)
+       movl   %r9d,200(%rdi)
+       movl   %eax,204(%rdi)
+       paddd 176(%rsp),%xmm14
+       paddd 0(%rsp),%xmm0
+       paddd 64(%rsp),%xmm5
+       paddd 128(%rsp),%xmm8
+       movd   %xmm14,%rdx
+       movd   %xmm0,%rcx
+       movd   %xmm5,%r9
+       movd   %xmm8,%rax
+       pshufd $0x39,%xmm14,%xmm14
+       pshufd $0x39,%xmm0,%xmm0
+       pshufd $0x39,%xmm5,%xmm5
+       pshufd $0x39,%xmm8,%xmm8
+       xorl 16(%rsi),%edx
+       xorl 20(%rsi),%ecx
+       xorl 24(%rsi),%r9d
+       xorl 28(%rsi),%eax
+       movl   %edx,16(%rdi)
+       movl   %ecx,20(%rdi)
+       movl   %r9d,24(%rdi)
+       movl   %eax,28(%rdi)
+       movd   %xmm14,%rdx
+       movd   %xmm0,%rcx
+       movd   %xmm5,%r9
+       movd   %xmm8,%rax
+       pshufd $0x39,%xmm14,%xmm14
+       pshufd $0x39,%xmm0,%xmm0
+       pshufd $0x39,%xmm5,%xmm5
+       pshufd $0x39,%xmm8,%xmm8
+       xorl 80(%rsi),%edx
+       xorl 84(%rsi),%ecx
+       xorl 88(%rsi),%r9d
+       xorl 92(%rsi),%eax
+       movl   %edx,80(%rdi)
+       movl   %ecx,84(%rdi)
+       movl   %r9d,88(%rdi)
+       movl   %eax,92(%rdi)
+       movd   %xmm14,%rdx
+       movd   %xmm0,%rcx
+       movd   %xmm5,%r9
+       movd   %xmm8,%rax
+       pshufd $0x39,%xmm14,%xmm14
+       pshufd $0x39,%xmm0,%xmm0
+       pshufd $0x39,%xmm5,%xmm5
+       pshufd $0x39,%xmm8,%xmm8
+       xorl 144(%rsi),%edx
+       xorl 148(%rsi),%ecx
+       xorl 152(%rsi),%r9d
+       xorl 156(%rsi),%eax
+       movl   %edx,144(%rdi)
+       movl   %ecx,148(%rdi)
+       movl   %r9d,152(%rdi)
+       movl   %eax,156(%rdi)
+       movd   %xmm14,%rdx
+       movd   %xmm0,%rcx
+       movd   %xmm5,%r9
+       movd   %xmm8,%rax
+       xorl 208(%rsi),%edx
+       xorl 212(%rsi),%ecx
+       xorl 216(%rsi),%r9d
+       xorl 220(%rsi),%eax
+       movl   %edx,208(%rdi)
+       movl   %ecx,212(%rdi)
+       movl   %r9d,216(%rdi)
+       movl   %eax,220(%rdi)
+       paddd 224(%rsp),%xmm15
+       paddd 240(%rsp),%xmm11
+       paddd 16(%rsp),%xmm1
+       paddd 80(%rsp),%xmm6
+       movd   %xmm15,%rdx
+       movd   %xmm11,%rcx
+       movd   %xmm1,%r9
+       movd   %xmm6,%rax
+       pshufd $0x39,%xmm15,%xmm15
+       pshufd $0x39,%xmm11,%xmm11
+       pshufd $0x39,%xmm1,%xmm1
+       pshufd $0x39,%xmm6,%xmm6
+       xorl 32(%rsi),%edx
+       xorl 36(%rsi),%ecx
+       xorl 40(%rsi),%r9d
+       xorl 44(%rsi),%eax
+       movl   %edx,32(%rdi)
+       movl   %ecx,36(%rdi)
+       movl   %r9d,40(%rdi)
+       movl   %eax,44(%rdi)
+       movd   %xmm15,%rdx
+       movd   %xmm11,%rcx
+       movd   %xmm1,%r9
+       movd   %xmm6,%rax
+       pshufd $0x39,%xmm15,%xmm15
+       pshufd $0x39,%xmm11,%xmm11
+       pshufd $0x39,%xmm1,%xmm1
+       pshufd $0x39,%xmm6,%xmm6
+       xorl 96(%rsi),%edx
+       xorl 100(%rsi),%ecx
+       xorl 104(%rsi),%r9d
+       xorl 108(%rsi),%eax
+       movl   %edx,96(%rdi)
+       movl   %ecx,100(%rdi)
+       movl   %r9d,104(%rdi)
+       movl   %eax,108(%rdi)
+       movd   %xmm15,%rdx
+       movd   %xmm11,%rcx
+       movd   %xmm1,%r9
+       movd   %xmm6,%rax
+       pshufd $0x39,%xmm15,%xmm15
+       pshufd $0x39,%xmm11,%xmm11
+       pshufd $0x39,%xmm1,%xmm1
+       pshufd $0x39,%xmm6,%xmm6
+       xorl 160(%rsi),%edx
+       xorl 164(%rsi),%ecx
+       xorl 168(%rsi),%r9d
+       xorl 172(%rsi),%eax
+       movl   %edx,160(%rdi)
+       movl   %ecx,164(%rdi)
+       movl   %r9d,168(%rdi)
+       movl   %eax,172(%rdi)
+       movd   %xmm15,%rdx
+       movd   %xmm11,%rcx
+       movd   %xmm1,%r9
+       movd   %xmm6,%rax
+       xorl 224(%rsi),%edx
+       xorl 228(%rsi),%ecx
+       xorl 232(%rsi),%r9d
+       xorl 236(%rsi),%eax
+       movl   %edx,224(%rdi)
+       movl   %ecx,228(%rdi)
+       movl   %r9d,232(%rdi)
+       movl   %eax,236(%rdi)
+       paddd 96(%rsp),%xmm13
+       paddd 144(%rsp),%xmm9
+       paddd 192(%rsp),%xmm3
+       paddd 32(%rsp),%xmm2
+       movd   %xmm13,%rdx
+       movd   %xmm9,%rcx
+       movd   %xmm3,%r9
+       movd   %xmm2,%rax
+       pshufd $0x39,%xmm13,%xmm13
+       pshufd $0x39,%xmm9,%xmm9
+       pshufd $0x39,%xmm3,%xmm3
+       pshufd $0x39,%xmm2,%xmm2
+       xorl 48(%rsi),%edx
+       xorl 52(%rsi),%ecx
+       xorl 56(%rsi),%r9d
+       xorl 60(%rsi),%eax
+       movl   %edx,48(%rdi)
+       movl   %ecx,52(%rdi)
+       movl   %r9d,56(%rdi)
+       movl   %eax,60(%rdi)
+       movd   %xmm13,%rdx
+       movd   %xmm9,%rcx
+       movd   %xmm3,%r9
+       movd   %xmm2,%rax
+       pshufd $0x39,%xmm13,%xmm13
+       pshufd $0x39,%xmm9,%xmm9
+       pshufd $0x39,%xmm3,%xmm3
+       pshufd $0x39,%xmm2,%xmm2
+       xorl 112(%rsi),%edx
+       xorl 116(%rsi),%ecx
+       xorl 120(%rsi),%r9d
+       xorl 124(%rsi),%eax
+       movl   %edx,112(%rdi)
+       movl   %ecx,116(%rdi)
+       movl   %r9d,120(%rdi)
+       movl   %eax,124(%rdi)
+       movd   %xmm13,%rdx
+       movd   %xmm9,%rcx
+       movd   %xmm3,%r9
+       movd   %xmm2,%rax
+       pshufd $0x39,%xmm13,%xmm13
+       pshufd $0x39,%xmm9,%xmm9
+       pshufd $0x39,%xmm3,%xmm3
+       pshufd $0x39,%xmm2,%xmm2
+       xorl 176(%rsi),%edx
+       xorl 180(%rsi),%ecx
+       xorl 184(%rsi),%r9d
+       xorl 188(%rsi),%eax
+       movl   %edx,176(%rdi)
+       movl   %ecx,180(%rdi)
+       movl   %r9d,184(%rdi)
+       movl   %eax,188(%rdi)
+       movd   %xmm13,%rdx
+       movd   %xmm9,%rcx
+       movd   %xmm3,%r9
+       movd   %xmm2,%rax
+       xorl 240(%rsi),%edx
+       xorl 244(%rsi),%ecx
+       xorl 248(%rsi),%r9d
+       xorl 252(%rsi),%eax
+       movl   %edx,240(%rdi)
+       movl   %ecx,244(%rdi)
+       movl   %r9d,248(%rdi)
+       movl   %eax,252(%rdi)
+       movq 288(%rsp),%rdx
+       sub  $256,%rdx
+       add  $256,%rsi
+       add  $256,%rdi
+       cmp  $256,%rdx
+       jae .L_bytesatleast256
+       cmp  $0,%rdx
+       jbe .L_done
+.L_bytes_are_64_128_or_192:
+       movq %rdx,288(%rsp)
+       movdqa 0(%r8),%xmm0
+       movdqa 16(%r8),%xmm1
+       movdqa 32(%r8),%xmm2
+       movdqa 48(%r8),%xmm3
+       movdqa %xmm1,%xmm4
+       mov  %rbx,%rdx
+.L_mainloop2:
+       paddd %xmm0,%xmm4
+       movdqa %xmm0,%xmm5
+       movdqa %xmm4,%xmm6
+       pslld $7,%xmm4
+       psrld $25,%xmm6
+       pxor  %xmm4,%xmm3
+       pxor  %xmm6,%xmm3
+       paddd %xmm3,%xmm5
+       movdqa %xmm3,%xmm4
+       movdqa %xmm5,%xmm6
+       pslld $9,%xmm5
+       psrld $23,%xmm6
+       pxor  %xmm5,%xmm2
+       pshufd $0x93,%xmm3,%xmm3
+       pxor  %xmm6,%xmm2
+       paddd %xmm2,%xmm4
+       movdqa %xmm2,%xmm5
+       movdqa %xmm4,%xmm6
+       pslld $13,%xmm4
+       psrld $19,%xmm6
+       pxor  %xmm4,%xmm1
+       pshufd $0x4e,%xmm2,%xmm2
+       pxor  %xmm6,%xmm1
+       paddd %xmm1,%xmm5
+       movdqa %xmm3,%xmm4
+       movdqa %xmm5,%xmm6
+       pslld $18,%xmm5
+       psrld $14,%xmm6
+       pxor  %xmm5,%xmm0
+       pshufd $0x39,%xmm1,%xmm1
+       pxor  %xmm6,%xmm0
+       paddd %xmm0,%xmm4
+       movdqa %xmm0,%xmm5
+       movdqa %xmm4,%xmm6
+       pslld $7,%xmm4
+       psrld $25,%xmm6
+       pxor  %xmm4,%xmm1
+       pxor  %xmm6,%xmm1
+       paddd %xmm1,%xmm5
+       movdqa %xmm1,%xmm4
+       movdqa %xmm5,%xmm6
+       pslld $9,%xmm5
+       psrld $23,%xmm6
+       pxor  %xmm5,%xmm2
+       pshufd $0x93,%xmm1,%xmm1
+       pxor  %xmm6,%xmm2
+       paddd %xmm2,%xmm4
+       movdqa %xmm2,%xmm5
+       movdqa %xmm4,%xmm6
+       pslld $13,%xmm4
+       psrld $19,%xmm6
+       pxor  %xmm4,%xmm3
+       pshufd $0x4e,%xmm2,%xmm2
+       pxor  %xmm6,%xmm3
+       paddd %xmm3,%xmm5
+       movdqa %xmm1,%xmm4
+       movdqa %xmm5,%xmm6
+       pslld $18,%xmm5
+       psrld $14,%xmm6
+       pxor  %xmm5,%xmm0
+       pshufd $0x39,%xmm3,%xmm3
+       pxor  %xmm6,%xmm0
+       paddd %xmm0,%xmm4
+       movdqa %xmm0,%xmm5
+       movdqa %xmm4,%xmm6
+       pslld $7,%xmm4
+       psrld $25,%xmm6
+       pxor  %xmm4,%xmm3
+       pxor  %xmm6,%xmm3
+       paddd %xmm3,%xmm5
+       movdqa %xmm3,%xmm4
+       movdqa %xmm5,%xmm6
+       pslld $9,%xmm5
+       psrld $23,%xmm6
+       pxor  %xmm5,%xmm2
+       pshufd $0x93,%xmm3,%xmm3
+       pxor  %xmm6,%xmm2
+       paddd %xmm2,%xmm4
+       movdqa %xmm2,%xmm5
+       movdqa %xmm4,%xmm6
+       pslld $13,%xmm4
+       psrld $19,%xmm6
+       pxor  %xmm4,%xmm1
+       pshufd $0x4e,%xmm2,%xmm2
+       pxor  %xmm6,%xmm1
+       paddd %xmm1,%xmm5
+       movdqa %xmm3,%xmm4
+       movdqa %xmm5,%xmm6
+       pslld $18,%xmm5
+       psrld $14,%xmm6
+       pxor  %xmm5,%xmm0
+       pshufd $0x39,%xmm1,%xmm1
+       pxor  %xmm6,%xmm0
+       paddd %xmm0,%xmm4
+       movdqa %xmm0,%xmm5
+       movdqa %xmm4,%xmm6
+       pslld $7,%xmm4
+       psrld $25,%xmm6
+       pxor  %xmm4,%xmm1
+       pxor  %xmm6,%xmm1
+       paddd %xmm1,%xmm5
+       movdqa %xmm1,%xmm4
+       movdqa %xmm5,%xmm6
+       pslld $9,%xmm5
+       psrld $23,%xmm6
+       pxor  %xmm5,%xmm2
+       pshufd $0x93,%xmm1,%xmm1
+       pxor  %xmm6,%xmm2
+       paddd %xmm2,%xmm4
+       movdqa %xmm2,%xmm5
+       movdqa %xmm4,%xmm6
+       pslld $13,%xmm4
+       psrld $19,%xmm6
+       pxor  %xmm4,%xmm3
+       pshufd $0x4e,%xmm2,%xmm2
+       pxor  %xmm6,%xmm3
+       sub  $4,%rdx
+       paddd %xmm3,%xmm5
+       movdqa %xmm1,%xmm4
+       movdqa %xmm5,%xmm6
+       pslld $18,%xmm5
+       pxor   %xmm7,%xmm7
+       psrld $14,%xmm6
+       pxor  %xmm5,%xmm0
+       pshufd $0x39,%xmm3,%xmm3
+       pxor  %xmm6,%xmm0
+       ja .L_mainloop2
+       paddd 0(%r8),%xmm0
+       paddd 16(%r8),%xmm1
+       paddd 32(%r8),%xmm2
+       paddd 48(%r8),%xmm3
+       movd   %xmm0,%rdx
+       movd   %xmm1,%rcx
+       movd   %xmm2,%rax
+       movd   %xmm3,%r10
+       pshufd $0x39,%xmm0,%xmm0
+       pshufd $0x39,%xmm1,%xmm1
+       pshufd $0x39,%xmm2,%xmm2
+       pshufd $0x39,%xmm3,%xmm3
+       xorl 0(%rsi),%edx
+       xorl 48(%rsi),%ecx
+       xorl 32(%rsi),%eax
+       xorl 16(%rsi),%r10d
+       movl   %edx,0(%rdi)
+       movl   %ecx,48(%rdi)
+       movl   %eax,32(%rdi)
+       movl   %r10d,16(%rdi)
+       movd   %xmm0,%rdx
+       movd   %xmm1,%rcx
+       movd   %xmm2,%rax
+       movd   %xmm3,%r10
+       pshufd $0x39,%xmm0,%xmm0
+       pshufd $0x39,%xmm1,%xmm1
+       pshufd $0x39,%xmm2,%xmm2
+       pshufd $0x39,%xmm3,%xmm3
+       xorl 20(%rsi),%edx
+       xorl 4(%rsi),%ecx
+       xorl 52(%rsi),%eax
+       xorl 36(%rsi),%r10d
+       movl   %edx,20(%rdi)
+       movl   %ecx,4(%rdi)
+       movl   %eax,52(%rdi)
+       movl   %r10d,36(%rdi)
+       movd   %xmm0,%rdx
+       movd   %xmm1,%rcx
+       movd   %xmm2,%rax
+       movd   %xmm3,%r10
+       pshufd $0x39,%xmm0,%xmm0
+       pshufd $0x39,%xmm1,%xmm1
+       pshufd $0x39,%xmm2,%xmm2
+       pshufd $0x39,%xmm3,%xmm3
+       xorl 40(%rsi),%edx
+       xorl 24(%rsi),%ecx
+       xorl 8(%rsi),%eax
+       xorl 56(%rsi),%r10d
+       movl   %edx,40(%rdi)
+       movl   %ecx,24(%rdi)
+       movl   %eax,8(%rdi)
+       movl   %r10d,56(%rdi)
+       movd   %xmm0,%rdx
+       movd   %xmm1,%rcx
+       movd   %xmm2,%rax
+       movd   %xmm3,%r10
+       xorl 60(%rsi),%edx
+       xorl 44(%rsi),%ecx
+       xorl 28(%rsi),%eax
+       xorl 12(%rsi),%r10d
+       movl   %edx,60(%rdi)
+       movl   %ecx,44(%rdi)
+       movl   %eax,28(%rdi)
+       movl   %r10d,12(%rdi)
+       movq 288(%rsp),%rdx
+       movl   32(%r8),%ecx
+       movl   52(%r8),%eax
+       add  $1,%ecx
+       adc  $0,%eax
+       movl   %ecx,32(%r8)
+       movl   %eax,52(%r8)
+       cmp  $64,%rdx
+       ja .L_bytes_are_128_or_192
+.L_done:
+       add %r11,%rsp
+       mov %r11,%rax
+       pop %rbx
+       ret
+.L_bytes_are_128_or_192:
+       sub  $64,%rdx
+       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;
+
+#endif /*defined(USE_SALSA20)*/
+#endif /*__x86_64*/
diff --git a/cipher/salsa20-armv7-neon.S b/cipher/salsa20-armv7-neon.S
new file mode 100644 (file)
index 0000000..8a9d9c4
--- /dev/null
@@ -0,0 +1,899 @@
+/* salsa-armv7-neon.S  -  ARM NEON implementation of Salsa20 cipher
+ *
+ * Copyright © 2013 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) && defined(USE_SALSA20)
+
+/*
+ * Based on public domain implementation from SUPERCOP benchmarking framework
+ * by Peter Schwabe and D. J. Bernstein. Paper about the implementation at:
+ *   http://cryptojedi.org/papers/#neoncrypto
+ */
+
+.syntax unified
+.arm
+.fpu neon
+.text
+
+.align 2
+.globl _gcry_arm_neon_salsa20_encrypt
+.type  _gcry_arm_neon_salsa20_encrypt,%function;
+_gcry_arm_neon_salsa20_encrypt:
+       /* Modifications:
+        *  - arguments changed to (void *c, const void *m, unsigned int nblks,
+         *    void *ctx, unsigned int rounds) from (void *c, const void *m,
+         *    unsigned long long mlen, const void *n, const void *k)
+        *  - nonce and key read from 'ctx' as well as sigma and counter.
+        *  - read in counter from 'ctx' at the start.
+         *  - update counter in 'ctx' at the end.
+        *  - length is input as number of blocks, so don't handle tail bytes
+        *    (this is done in salsa20.c).
+        */
+       lsl r2,r2,#6
+       vpush {q4,q5,q6,q7}
+       mov r12,sp
+       sub sp,sp,#352
+       and sp,sp,#0xffffffe0
+       strd r4,[sp,#0]
+       strd r6,[sp,#8]
+       strd r8,[sp,#16]
+       strd r10,[sp,#24]
+       str r14,[sp,#224]
+       str r12,[sp,#228]
+       str r0,[sp,#232]
+       str r1,[sp,#236]
+       str r2,[sp,#240]
+       ldr r4,[r12,#64]
+       str r4,[sp,#244]
+       mov r2,r3
+       add r3,r2,#48
+       vld1.8 {q3},[r2]
+       add r0,r2,#32
+       add r14,r2,#40
+       vmov.i64 q3,#0xff
+       str r14,[sp,#160]
+       ldrd r8,[r2,#4]
+       vld1.8 {d0},[r0]
+       ldrd r4,[r2,#20]
+       vld1.8 {d8-d9},[r2]!
+       ldrd r6,[r0,#0]
+       vmov d4,d9
+       ldr r0,[r14]
+       vrev64.i32 d0,d0
+       ldr r1,[r14,#4]
+       vld1.8 {d10-d11},[r2]
+       strd r6,[sp,#32]
+       sub r2,r2,#16
+       strd r0,[sp,#40]
+       vmov d5,d11
+       strd r8,[sp,#48]
+       vext.32 d1,d0,d10,#1
+       strd r4,[sp,#56]
+       ldr r1,[r2,#0]
+       vshr.u32 q3,q3,#7
+       ldr r4,[r2,#12]
+       vext.32 d3,d11,d9,#1
+       ldr r11,[r2,#16]
+       vext.32 d2,d8,d0,#1
+       ldr r8,[r2,#28]
+       vext.32 d0,d10,d8,#1
+       ldr r0,[r3,#0]
+       add r2,r2,#44
+       vmov q4,q3
+       vld1.8 {d6-d7},[r14]
+       vadd.i64 q3,q3,q4
+       ldr r5,[r3,#4]
+       add r12,sp,#256
+       vst1.8 {d4-d5},[r12,: 128]
+       ldr r10,[r3,#8]
+       add r14,sp,#272
+       vst1.8 {d2-d3},[r14,: 128]
+       ldr r9,[r3,#12]
+       vld1.8 {d2-d3},[r3]
+       strd r0,[sp,#64]
+       ldr r0,[sp,#240]
+       strd r4,[sp,#72]
+       strd r10,[sp,#80]
+       strd r8,[sp,#88]
+       nop
+       cmp r0,#192
+       blo .L_mlenlowbelow192
+.L_mlenatleast192:
+       ldrd r2,[sp,#48]
+       vext.32 d7,d6,d6,#1
+       vmov q8,q1
+       ldrd r6,[sp,#32]
+       vld1.8 {d18-d19},[r12,: 128]
+       vmov q10,q0
+       str r0,[sp,#240]
+       vext.32 d4,d7,d19,#1
+       vmov q11,q8
+       vext.32 d10,d18,d7,#1
+       vadd.i64 q3,q3,q4
+       ldrd r0,[sp,#64]
+       vld1.8 {d24-d25},[r14,: 128]
+       vmov d5,d24
+       add r8,sp,#288
+       ldrd r4,[sp,#72]
+       vmov d11,d25
+       add r9,sp,#304
+       ldrd r10,[sp,#80]
+       vst1.8 {d4-d5},[r8,: 128]
+       strd r2,[sp,#96]
+       vext.32 d7,d6,d6,#1
+       vmov q13,q10
+       strd r6,[sp,#104]
+       vmov d13,d24
+       vst1.8 {d10-d11},[r9,: 128]
+       add r2,sp,#320
+       vext.32 d12,d7,d19,#1
+       vmov d15,d25
+       add r6,sp,#336
+       ldr r12,[sp,#244]
+       vext.32 d14,d18,d7,#1
+       vadd.i64 q3,q3,q4
+       ldrd r8,[sp,#88]
+       vst1.8 {d12-d13},[r2,: 128]
+       ldrd r2,[sp,#56]
+       vst1.8 {d14-d15},[r6,: 128]
+       ldrd r6,[sp,#40]
+.L_mainloop2:
+       str r12,[sp,#248]
+       vadd.i32 q4,q10,q8
+       vadd.i32 q9,q13,q11
+       add r12,r0,r2
+       add r14,r5,r1
+       vshl.i32 q12,q4,#7
+       vshl.i32 q14,q9,#7
+       vshr.u32 q4,q4,#25
+       vshr.u32 q9,q9,#25
+       eor r4,r4,r12,ROR #25
+       eor r7,r7,r14,ROR #25
+       add r12,r4,r0
+       add r14,r7,r5
+       veor q5,q5,q12
+       veor q7,q7,q14
+       veor q4,q5,q4
+       veor q5,q7,q9
+       eor r6,r6,r12,ROR #23
+       eor r3,r3,r14,ROR #23
+       add r12,r6,r4
+       str r7,[sp,#116]
+       add r7,r3,r7
+       ldr r14,[sp,#108]
+       vadd.i32 q7,q8,q4
+       vadd.i32 q9,q11,q5
+       vshl.i32 q12,q7,#9
+       vshl.i32 q14,q9,#9
+       vshr.u32 q7,q7,#23
+       vshr.u32 q9,q9,#23
+       veor q2,q2,q12
+       veor q6,q6,q14
+       veor q2,q2,q7
+       veor q6,q6,q9
+       eor r2,r2,r12,ROR #19
+       str r2,[sp,#120]
+       eor r1,r1,r7,ROR #19
+       ldr r7,[sp,#96]
+       add r2,r2,r6
+       str r6,[sp,#112]
+       add r6,r1,r3
+       ldr r12,[sp,#104]
+       vadd.i32 q7,q4,q2
+       vext.32 q4,q4,q4,#3
+       vadd.i32 q9,q5,q6
+       vshl.i32 q12,q7,#13
+       vext.32 q5,q5,q5,#3
+       vshl.i32 q14,q9,#13
+       eor r0,r0,r2,ROR #14
+       eor r2,r5,r6,ROR #14
+       str r3,[sp,#124]
+       add r3,r10,r12
+       ldr r5,[sp,#100]
+       add r6,r9,r11
+       vshr.u32 q7,q7,#19
+       vshr.u32 q9,q9,#19
+       veor q10,q10,q12
+       veor q12,q13,q14
+       eor r8,r8,r3,ROR #25
+       eor r3,r5,r6,ROR #25
+       add r5,r8,r10
+       add r6,r3,r9
+       veor q7,q10,q7
+       veor q9,q12,q9
+       eor r5,r7,r5,ROR #23
+       eor r6,r14,r6,ROR #23
+       add r7,r5,r8
+       add r14,r6,r3
+       vadd.i32 q10,q2,q7
+       vswp d4,d5
+       vadd.i32 q12,q6,q9
+       vshl.i32 q13,q10,#18
+       vswp d12,d13
+       vshl.i32 q14,q12,#18
+       eor r7,r12,r7,ROR #19
+       eor r11,r11,r14,ROR #19
+       add r12,r7,r5
+       add r14,r11,r6
+       vshr.u32 q10,q10,#14
+       vext.32 q7,q7,q7,#1
+       vshr.u32 q12,q12,#14
+       veor q8,q8,q13
+       vext.32 q9,q9,q9,#1
+       veor q11,q11,q14
+       eor r10,r10,r12,ROR #14
+       eor r9,r9,r14,ROR #14
+       add r12,r0,r3
+       add r14,r2,r4
+       veor q8,q8,q10
+       veor q10,q11,q12
+       eor r1,r1,r12,ROR #25
+       eor r7,r7,r14,ROR #25
+       add r12,r1,r0
+       add r14,r7,r2
+       vadd.i32 q11,q4,q8
+       vadd.i32 q12,q5,q10
+       vshl.i32 q13,q11,#7
+       vshl.i32 q14,q12,#7
+       eor r5,r5,r12,ROR #23
+       eor r6,r6,r14,ROR #23
+       vshr.u32 q11,q11,#25
+       vshr.u32 q12,q12,#25
+       add r12,r5,r1
+       add r14,r6,r7
+       veor q7,q7,q13
+       veor q9,q9,q14
+       veor q7,q7,q11
+       veor q9,q9,q12
+       vadd.i32 q11,q8,q7
+       vadd.i32 q12,q10,q9
+       vshl.i32 q13,q11,#9
+       vshl.i32 q14,q12,#9
+       eor r3,r3,r12,ROR #19
+       str r7,[sp,#104]
+       eor r4,r4,r14,ROR #19
+       ldr r7,[sp,#112]
+       add r12,r3,r5
+       str r6,[sp,#108]
+       add r6,r4,r6
+       ldr r14,[sp,#116]
+       eor r0,r0,r12,ROR #14
+       str r5,[sp,#96]
+       eor r5,r2,r6,ROR #14
+       ldr r2,[sp,#120]
+       vshr.u32 q11,q11,#23
+       vshr.u32 q12,q12,#23
+       veor q2,q2,q13
+       veor q6,q6,q14
+       veor q2,q2,q11
+       veor q6,q6,q12
+       add r6,r10,r14
+       add r12,r9,r8
+       vadd.i32 q11,q7,q2
+       vext.32 q7,q7,q7,#3
+       vadd.i32 q12,q9,q6
+       vshl.i32 q13,q11,#13
+       vext.32 q9,q9,q9,#3
+       vshl.i32 q14,q12,#13
+       vshr.u32 q11,q11,#19
+       vshr.u32 q12,q12,#19
+       eor r11,r11,r6,ROR #25
+       eor r2,r2,r12,ROR #25
+       add r6,r11,r10
+       str r3,[sp,#100]
+       add r3,r2,r9
+       ldr r12,[sp,#124]
+       veor q4,q4,q13
+       veor q5,q5,q14
+       veor q4,q4,q11
+       veor q5,q5,q12
+       eor r6,r7,r6,ROR #23
+       eor r3,r12,r3,ROR #23
+       add r7,r6,r11
+       add r12,r3,r2
+       vadd.i32 q11,q2,q4
+       vswp d4,d5
+       vadd.i32 q12,q6,q5
+       vshl.i32 q13,q11,#18
+       vswp d12,d13
+       vshl.i32 q14,q12,#18
+       eor r7,r14,r7,ROR #19
+       eor r8,r8,r12,ROR #19
+       add r12,r7,r6
+       add r14,r8,r3
+       vshr.u32 q11,q11,#14
+       vext.32 q4,q4,q4,#1
+       vshr.u32 q12,q12,#14
+       veor q8,q8,q13
+       vext.32 q5,q5,q5,#1
+       veor q10,q10,q14
+       eor r10,r10,r12,ROR #14
+       veor q8,q8,q11
+       eor r9,r9,r14,ROR #14
+       veor q10,q10,q12
+       vadd.i32 q11,q7,q8
+       vadd.i32 q12,q9,q10
+       add r12,r0,r2
+       add r14,r5,r1
+       vshl.i32 q13,q11,#7
+       vshl.i32 q14,q12,#7
+       vshr.u32 q11,q11,#25
+       vshr.u32 q12,q12,#25
+       eor r4,r4,r12,ROR #25
+       eor r7,r7,r14,ROR #25
+       add r12,r4,r0
+       add r14,r7,r5
+       veor q4,q4,q13
+       veor q5,q5,q14
+       veor q4,q4,q11
+       veor q5,q5,q12
+       eor r6,r6,r12,ROR #23
+       eor r3,r3,r14,ROR #23
+       add r12,r6,r4
+       str r7,[sp,#116]
+       add r7,r3,r7
+       ldr r14,[sp,#108]
+       vadd.i32 q11,q8,q4
+       vadd.i32 q12,q10,q5
+       vshl.i32 q13,q11,#9
+       vshl.i32 q14,q12,#9
+       vshr.u32 q11,q11,#23
+       vshr.u32 q12,q12,#23
+       veor q2,q2,q13
+       veor q6,q6,q14
+       veor q2,q2,q11
+       veor q6,q6,q12
+       eor r2,r2,r12,ROR #19
+       str r2,[sp,#120]
+       eor r1,r1,r7,ROR #19
+       ldr r7,[sp,#96]
+       add r2,r2,r6
+       str r6,[sp,#112]
+       add r6,r1,r3
+       ldr r12,[sp,#104]
+       vadd.i32 q11,q4,q2
+       vext.32 q4,q4,q4,#3
+       vadd.i32 q12,q5,q6
+       vshl.i32 q13,q11,#13
+       vext.32 q5,q5,q5,#3
+       vshl.i32 q14,q12,#13
+       eor r0,r0,r2,ROR #14
+       eor r2,r5,r6,ROR #14
+       str r3,[sp,#124]
+       add r3,r10,r12
+       ldr r5,[sp,#100]
+       add r6,r9,r11
+       vshr.u32 q11,q11,#19
+       vshr.u32 q12,q12,#19
+       veor q7,q7,q13
+       veor q9,q9,q14
+       eor r8,r8,r3,ROR #25
+       eor r3,r5,r6,ROR #25
+       add r5,r8,r10
+       add r6,r3,r9
+       veor q7,q7,q11
+       veor q9,q9,q12
+       eor r5,r7,r5,ROR #23
+       eor r6,r14,r6,ROR #23
+       add r7,r5,r8
+       add r14,r6,r3
+       vadd.i32 q11,q2,q7
+       vswp d4,d5
+       vadd.i32 q12,q6,q9
+       vshl.i32 q13,q11,#18
+       vswp d12,d13
+       vshl.i32 q14,q12,#18
+       eor r7,r12,r7,ROR #19
+       eor r11,r11,r14,ROR #19
+       add r12,r7,r5
+       add r14,r11,r6
+       vshr.u32 q11,q11,#14
+       vext.32 q7,q7,q7,#1
+       vshr.u32 q12,q12,#14
+       veor q8,q8,q13
+       vext.32 q9,q9,q9,#1
+       veor q10,q10,q14
+       eor r10,r10,r12,ROR #14
+       eor r9,r9,r14,ROR #14
+       add r12,r0,r3
+       add r14,r2,r4
+       veor q8,q8,q11
+       veor q11,q10,q12
+       eor r1,r1,r12,ROR #25
+       eor r7,r7,r14,ROR #25
+       add r12,r1,r0
+       add r14,r7,r2
+       vadd.i32 q10,q4,q8
+       vadd.i32 q12,q5,q11
+       vshl.i32 q13,q10,#7
+       vshl.i32 q14,q12,#7
+       eor r5,r5,r12,ROR #23
+       eor r6,r6,r14,ROR #23
+       vshr.u32 q10,q10,#25
+       vshr.u32 q12,q12,#25
+       add r12,r5,r1
+       add r14,r6,r7
+       veor q7,q7,q13
+       veor q9,q9,q14
+       veor q7,q7,q10
+       veor q9,q9,q12
+       vadd.i32 q10,q8,q7
+       vadd.i32 q12,q11,q9
+       vshl.i32 q13,q10,#9
+       vshl.i32 q14,q12,#9
+       eor r3,r3,r12,ROR #19
+       str r7,[sp,#104]
+       eor r4,r4,r14,ROR #19
+       ldr r7,[sp,#112]
+       add r12,r3,r5
+       str r6,[sp,#108]
+       add r6,r4,r6
+       ldr r14,[sp,#116]
+       eor r0,r0,r12,ROR #14
+       str r5,[sp,#96]
+       eor r5,r2,r6,ROR #14
+       ldr r2,[sp,#120]
+       vshr.u32 q10,q10,#23
+       vshr.u32 q12,q12,#23
+       veor q2,q2,q13
+       veor q6,q6,q14
+       veor q2,q2,q10
+       veor q6,q6,q12
+       add r6,r10,r14
+       add r12,r9,r8
+       vadd.i32 q12,q7,q2
+       vext.32 q10,q7,q7,#3
+       vadd.i32 q7,q9,q6
+       vshl.i32 q14,q12,#13
+       vext.32 q13,q9,q9,#3
+       vshl.i32 q9,q7,#13
+       vshr.u32 q12,q12,#19
+       vshr.u32 q7,q7,#19
+       eor r11,r11,r6,ROR #25
+       eor r2,r2,r12,ROR #25
+       add r6,r11,r10
+       str r3,[sp,#100]
+       add r3,r2,r9
+       ldr r12,[sp,#124]
+       veor q4,q4,q14
+       veor q5,q5,q9
+       veor q4,q4,q12
+       veor q7,q5,q7
+       eor r6,r7,r6,ROR #23
+       eor r3,r12,r3,ROR #23
+       add r7,r6,r11
+       add r12,r3,r2
+       vadd.i32 q5,q2,q4
+       vswp d4,d5
+       vadd.i32 q9,q6,q7
+       vshl.i32 q12,q5,#18
+       vswp d12,d13
+       vshl.i32 q14,q9,#18
+       eor r7,r14,r7,ROR #19
+       eor r8,r8,r12,ROR #19
+       add r12,r7,r6
+       add r14,r8,r3
+       vshr.u32 q15,q5,#14
+       vext.32 q5,q4,q4,#1
+       vshr.u32 q4,q9,#14
+       veor q8,q8,q12
+       vext.32 q7,q7,q7,#1
+       veor q9,q11,q14
+       eor r10,r10,r12,ROR #14
+       ldr r12,[sp,#248]
+       veor q8,q8,q15
+       eor r9,r9,r14,ROR #14
+       veor q11,q9,q4
+       subs r12,r12,#4
+       bhi .L_mainloop2
+       strd r8,[sp,#112]
+       ldrd r8,[sp,#64]
+       strd r2,[sp,#120]
+       ldrd r2,[sp,#96]
+       add r0,r0,r8
+       strd r10,[sp,#96]
+       add r1,r1,r9
+       ldrd r10,[sp,#48]
+       ldrd r8,[sp,#72]
+       add r2,r2,r10
+       strd r6,[sp,#128]
+       add r3,r3,r11
+       ldrd r6,[sp,#104]
+       ldrd r10,[sp,#32]
+       ldr r12,[sp,#236]
+       add r4,r4,r8
+       add r5,r5,r9
+       add r6,r6,r10
+       add r7,r7,r11
+       cmp r12,#0
+       beq .L_nomessage1
+       ldr r8,[r12,#0]
+       ldr r9,[r12,#4]
+       ldr r10,[r12,#8]
+       ldr r11,[r12,#12]
+       eor r0,r0,r8
+       ldr r8,[r12,#16]
+       eor r1,r1,r9
+       ldr r9,[r12,#20]
+       eor r2,r2,r10
+       ldr r10,[r12,#24]
+       eor r3,r3,r11
+       ldr r11,[r12,#28]
+       eor r4,r4,r8
+       eor r5,r5,r9
+       eor r6,r6,r10
+       eor r7,r7,r11
+.L_nomessage1:
+       ldr r14,[sp,#232]
+       vadd.i32 q4,q8,q1
+       str r0,[r14,#0]
+       add r0,sp,#304
+       str r1,[r14,#4]
+       vld1.8 {d16-d17},[r0,: 128]
+       str r2,[r14,#8]
+       vadd.i32 q5,q8,q5
+       str r3,[r14,#12]
+       add r0,sp,#288
+       str r4,[r14,#16]
+       vld1.8 {d16-d17},[r0,: 128]
+       str r5,[r14,#20]
+       vadd.i32 q9,q10,q0
+       str r6,[r14,#24]
+       vadd.i32 q2,q8,q2
+       str r7,[r14,#28]
+       vmov.i64 q8,#0xffffffff
+       ldrd r6,[sp,#128]
+       vext.32 d20,d8,d10,#1
+       ldrd r0,[sp,#40]
+       vext.32 d25,d9,d11,#1
+       ldrd r2,[sp,#120]
+       vbif q4,q9,q8
+       ldrd r4,[sp,#56]
+       vext.32 d21,d5,d19,#1
+       add r6,r6,r0
+       vext.32 d24,d4,d18,#1
+       add r7,r7,r1
+       vbif q2,q5,q8
+       add r2,r2,r4
+       vrev64.i32 q5,q10
+       add r3,r3,r5
+       vrev64.i32 q9,q12
+       adds r0,r0,#3
+       vswp d5,d9
+       adc r1,r1,#0
+       strd r0,[sp,#40]
+       ldrd r8,[sp,#112]
+       ldrd r0,[sp,#88]
+       ldrd r10,[sp,#96]
+       ldrd r4,[sp,#80]
+       add r0,r8,r0
+       add r1,r9,r1
+       add r4,r10,r4
+       add r5,r11,r5
+       add r8,r14,#64
+       cmp r12,#0
+       beq .L_nomessage2
+       ldr r9,[r12,#32]
+       ldr r10,[r12,#36]
+       ldr r11,[r12,#40]
+       ldr r14,[r12,#44]
+       eor r6,r6,r9
+       ldr r9,[r12,#48]
+       eor r7,r7,r10
+       ldr r10,[r12,#52]
+       eor r4,r4,r11
+       ldr r11,[r12,#56]
+       eor r5,r5,r14
+       ldr r14,[r12,#60]
+       add r12,r12,#64
+       eor r2,r2,r9
+       vld1.8 {d20-d21},[r12]!
+       veor q4,q4,q10
+       eor r3,r3,r10
+       vld1.8 {d20-d21},[r12]!
+       veor q5,q5,q10
+       eor r0,r0,r11
+       vld1.8 {d20-d21},[r12]!
+       veor q2,q2,q10
+       eor r1,r1,r14
+       vld1.8 {d20-d21},[r12]!
+       veor q9,q9,q10
+.L_nomessage2:
+       vst1.8 {d8-d9},[r8]!
+       vst1.8 {d10-d11},[r8]!
+       vmov.i64 q4,#0xff
+       vst1.8 {d4-d5},[r8]!
+       vst1.8 {d18-d19},[r8]!
+       str r6,[r8,#-96]
+       add r6,sp,#336
+       str r7,[r8,#-92]
+       add r7,sp,#320
+       str r4,[r8,#-88]
+       vadd.i32 q2,q11,q1
+       vld1.8 {d10-d11},[r6,: 128]
+       vadd.i32 q5,q5,q7
+       vld1.8 {d14-d15},[r7,: 128]
+       vadd.i32 q9,q13,q0
+       vadd.i32 q6,q7,q6
+       str r5,[r8,#-84]
+       vext.32 d14,d4,d10,#1
+       str r2,[r8,#-80]
+       vext.32 d21,d5,d11,#1
+       str r3,[r8,#-76]
+       vbif q2,q9,q8
+       str r0,[r8,#-72]
+       vext.32 d15,d13,d19,#1
+       vshr.u32 q4,q4,#7
+       str r1,[r8,#-68]
+       vext.32 d20,d12,d18,#1
+       vbif q6,q5,q8
+       ldr r0,[sp,#240]
+       vrev64.i32 q5,q7
+       vrev64.i32 q7,q10
+       vswp d13,d5
+       vadd.i64 q3,q3,q4
+       sub r0,r0,#192
+       cmp r12,#0
+       beq .L_nomessage21
+       vld1.8 {d16-d17},[r12]!
+       veor q2,q2,q8
+       vld1.8 {d16-d17},[r12]!
+       veor q5,q5,q8
+       vld1.8 {d16-d17},[r12]!
+       veor q6,q6,q8
+       vld1.8 {d16-d17},[r12]!
+       veor q7,q7,q8
+.L_nomessage21:
+       vst1.8 {d4-d5},[r8]!
+       vst1.8 {d10-d11},[r8]!
+       vst1.8 {d12-d13},[r8]!
+       vst1.8 {d14-d15},[r8]!
+       str r12,[sp,#236]
+       add r14,sp,#272
+       add r12,sp,#256
+       str r8,[sp,#232]
+       cmp r0,#192
+       bhs .L_mlenatleast192
+.L_mlenlowbelow192:
+       cmp r0,#0
+       beq .L_done
+       b .L_mlenatleast1
+.L_nextblock:
+       sub r0,r0,#64
+.L_mlenatleast1:
+.L_handleblock:
+       str r0,[sp,#248]
+       ldrd r2,[sp,#48]
+       ldrd r6,[sp,#32]
+       ldrd r0,[sp,#64]
+       ldrd r4,[sp,#72]
+       ldrd r10,[sp,#80]
+       ldrd r8,[sp,#88]
+       strd r2,[sp,#96]
+       strd r6,[sp,#104]
+       ldrd r2,[sp,#56]
+       ldrd r6,[sp,#40]
+       ldr r12,[sp,#244]
+.L_mainloop1:
+       str r12,[sp,#252]
+       add r12,r0,r2
+       add r14,r5,r1
+       eor r4,r4,r12,ROR #25
+       eor r7,r7,r14,ROR #25
+       add r12,r4,r0
+       add r14,r7,r5
+       eor r6,r6,r12,ROR #23
+       eor r3,r3,r14,ROR #23
+       add r12,r6,r4
+       str r7,[sp,#132]
+       add r7,r3,r7
+       ldr r14,[sp,#104]
+       eor r2,r2,r12,ROR #19
+       str r6,[sp,#128]
+       eor r1,r1,r7,ROR #19
+       ldr r7,[sp,#100]
+       add r6,r2,r6
+       str r2,[sp,#120]
+       add r2,r1,r3
+       ldr r12,[sp,#96]
+       eor r0,r0,r6,ROR #14
+       str r3,[sp,#124]
+       eor r2,r5,r2,ROR #14
+       ldr r3,[sp,#108]
+       add r5,r10,r14
+       add r6,r9,r11
+       eor r8,r8,r5,ROR #25
+       eor r5,r7,r6,ROR #25
+       add r6,r8,r10
+       add r7,r5,r9
+       eor r6,r12,r6,ROR #23
+       eor r3,r3,r7,ROR #23
+       add r7,r6,r8
+       add r12,r3,r5
+       eor r7,r14,r7,ROR #19
+       eor r11,r11,r12,ROR #19
+       add r12,r7,r6
+       add r14,r11,r3
+       eor r10,r10,r12,ROR #14
+       eor r9,r9,r14,ROR #14
+       add r12,r0,r5
+       add r14,r2,r4
+       eor r1,r1,r12,ROR #25
+       eor r7,r7,r14,ROR #25
+       add r12,r1,r0
+       add r14,r7,r2
+       eor r6,r6,r12,ROR #23
+       eor r3,r3,r14,ROR #23
+       add r12,r6,r1
+       str r7,[sp,#104]
+       add r7,r3,r7
+       ldr r14,[sp,#128]
+       eor r5,r5,r12,ROR #19
+       str r3,[sp,#108]
+       eor r4,r4,r7,ROR #19
+       ldr r7,[sp,#132]
+       add r12,r5,r6
+       str r6,[sp,#96]
+       add r3,r4,r3
+       ldr r6,[sp,#120]
+       eor r0,r0,r12,ROR #14
+       str r5,[sp,#100]
+       eor r5,r2,r3,ROR #14
+       ldr r3,[sp,#124]
+       add r2,r10,r7
+       add r12,r9,r8
+       eor r11,r11,r2,ROR #25
+       eor r2,r6,r12,ROR #25
+       add r6,r11,r10
+       add r12,r2,r9
+       eor r6,r14,r6,ROR #23
+       eor r3,r3,r12,ROR #23
+       add r12,r6,r11
+       add r14,r3,r2
+       eor r7,r7,r12,ROR #19
+       eor r8,r8,r14,ROR #19
+       add r12,r7,r6
+       add r14,r8,r3
+       eor r10,r10,r12,ROR #14
+       eor r9,r9,r14,ROR #14
+       ldr r12,[sp,#252]
+       subs r12,r12,#2
+       bhi .L_mainloop1
+       strd r6,[sp,#128]
+       strd r2,[sp,#120]
+       strd r10,[sp,#112]
+       strd r8,[sp,#136]
+       ldrd r2,[sp,#96]
+       ldrd r6,[sp,#104]
+       ldrd r8,[sp,#64]
+       ldrd r10,[sp,#48]
+       add r0,r0,r8
+       add r1,r1,r9
+       add r2,r2,r10
+       add r3,r3,r11
+       ldrd r8,[sp,#72]
+       ldrd r10,[sp,#32]
+       add r4,r4,r8
+       add r5,r5,r9
+       add r6,r6,r10
+       add r7,r7,r11
+       ldr r12,[sp,#236]
+       cmp r12,#0
+       beq .L_nomessage10
+       ldr r8,[r12,#0]
+       ldr r9,[r12,#4]
+       ldr r10,[r12,#8]
+       ldr r11,[r12,#12]
+       eor r0,r0,r8
+       ldr r8,[r12,#16]
+       eor r1,r1,r9
+       ldr r9,[r12,#20]
+       eor r2,r2,r10
+       ldr r10,[r12,#24]
+       eor r3,r3,r11
+       ldr r11,[r12,#28]
+       eor r4,r4,r8
+       eor r5,r5,r9
+       eor r6,r6,r10
+       eor r7,r7,r11
+.L_nomessage10:
+       ldr r14,[sp,#232]
+       str r0,[r14,#0]
+       str r1,[r14,#4]
+       str r2,[r14,#8]
+       str r3,[r14,#12]
+       str r4,[r14,#16]
+       str r5,[r14,#20]
+       str r6,[r14,#24]
+       str r7,[r14,#28]
+       ldrd r6,[sp,#128]
+       ldrd r10,[sp,#112]
+       ldrd r0,[sp,#40]
+       ldrd r4,[sp,#80]
+       add r6,r6,r0
+       add r7,r7,r1
+       add r10,r10,r4
+       add r11,r11,r5
+       adds r0,r0,#1
+       adc r1,r1,#0
+       strd r0,[sp,#40]
+       ldrd r2,[sp,#120]
+       ldrd r8,[sp,#136]
+       ldrd r4,[sp,#56]
+       ldrd r0,[sp,#88]
+       add r2,r2,r4
+       add r3,r3,r5
+       add r0,r8,r0
+       add r1,r9,r1
+       cmp r12,#0
+       beq .L_nomessage11
+       ldr r4,[r12,#32]
+       ldr r5,[r12,#36]
+       ldr r8,[r12,#40]
+       ldr r9,[r12,#44]
+       eor r6,r6,r4
+       ldr r4,[r12,#48]
+       eor r7,r7,r5
+       ldr r5,[r12,#52]
+       eor r10,r10,r8
+       ldr r8,[r12,#56]
+       eor r11,r11,r9
+       ldr r9,[r12,#60]
+       eor r2,r2,r4
+       eor r3,r3,r5
+       eor r0,r0,r8
+       eor r1,r1,r9
+       add r4,r12,#64
+       str r4,[sp,#236]
+.L_nomessage11:
+       str r6,[r14,#32]
+       str r7,[r14,#36]
+       str r10,[r14,#40]
+       str r11,[r14,#44]
+       str r2,[r14,#48]
+       str r3,[r14,#52]
+       str r0,[r14,#56]
+       str r1,[r14,#60]
+       add r0,r14,#64
+       str r0,[sp,#232]
+       ldr r0,[sp,#248]
+       cmp r0,#64
+       bhi .L_nextblock
+.L_done:
+       ldr r2,[sp,#160]
+       ldrd r4,[sp,#0]
+       ldrd r6,[sp,#8]
+       ldrd r8,[sp,#16]
+       ldrd r10,[sp,#24]
+       ldr r12,[sp,#228]
+       ldr r14,[sp,#224]
+       ldrd r0,[sp,#40]
+       strd r0,[r2]
+       sub r0,r12,sp
+       mov sp,r12
+       vpop {q4,q5,q6,q7}
+       add r0,r0,#64
+       bx lr
+.size _gcry_arm_neon_salsa20_encrypt,.-_gcry_arm_neon_salsa20_encrypt;
+
+#endif
diff --git a/cipher/salsa20.c b/cipher/salsa20.c
new file mode 100644 (file)
index 0000000..72b28b0
--- /dev/null
@@ -0,0 +1,576 @@
+/* salsa20.c  -  Bernstein's Salsa20 cipher
+ * Copyright (C) 2012 Simon Josefsson, Niels Möller
+ * Copyright (C) 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/>.
+ *
+ * For a description of the algorithm, see:
+ *   http://cr.yp.to/snuffle/spec.pdf
+ *   http://cr.yp.to/snuffle/design.pdf
+ */
+
+/* The code is based on the code in Nettle
+   (git commit id 9d2d8ddaee35b91a4e1a32ae77cba04bea3480e7)
+   which in turn is based on
+   salsa20-ref.c version 20051118
+   D. J. Bernstein
+   Public domain.
+*/
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "types.h"
+#include "g10lib.h"
+#include "cipher.h"
+#include "bufhelp.h"
+
+
+/* USE_AMD64 indicates whether to compile with AMD64 code. */
+#undef USE_AMD64
+#if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS)
+# define USE_AMD64 1
+#endif
+
+/* USE_ARM_NEON_ASM indicates whether to enable ARM NEON assembly code. */
+#undef USE_ARM_NEON_ASM
+#if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__)
+# if defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+     defined(HAVE_GCC_INLINE_ASM_NEON)
+#  define USE_ARM_NEON_ASM 1
+# endif
+#endif
+
+
+#define SALSA20_MIN_KEY_SIZE 16  /* Bytes.  */
+#define SALSA20_MAX_KEY_SIZE 32  /* Bytes.  */
+#define SALSA20_BLOCK_SIZE   64  /* Bytes.  */
+#define SALSA20_IV_SIZE       8  /* Bytes.  */
+#define SALSA20_INPUT_LENGTH 16  /* Bytes.  */
+
+/* Number of rounds.  The standard uses 20 rounds.  In any case the
+   number of rounds must be even.  */
+#define SALSA20_ROUNDS       20
+#define SALSA20R12_ROUNDS    12
+
+
+struct SALSA20_context_s;
+
+typedef unsigned int (*salsa20_core_t) (u32 *dst, struct SALSA20_context_s *ctx,
+                                        unsigned int rounds);
+typedef void (* salsa20_keysetup_t)(struct SALSA20_context_s *ctx,
+                                    const byte *key, int keylen);
+typedef void (* salsa20_ivsetup_t)(struct SALSA20_context_s *ctx,
+                                   const byte *iv);
+
+typedef struct SALSA20_context_s
+{
+  /* Indices 1-4 and 11-14 holds the key (two identical copies for the
+     shorter key size), indices 0, 5, 10, 15 are constant, indices 6, 7
+     are the IV, and indices 8, 9 are the block counter:
+
+     C K K K
+     K C I I
+     B B C K
+     K K K C
+  */
+  u32 input[SALSA20_INPUT_LENGTH];
+  u32 pad[SALSA20_INPUT_LENGTH];
+  unsigned int unused; /* bytes in the pad.  */
+#ifdef USE_ARM_NEON_ASM
+  int use_neon;
+#endif
+  salsa20_keysetup_t keysetup;
+  salsa20_ivsetup_t ivsetup;
+  salsa20_core_t core;
+} SALSA20_context_t;
+
+
+/* The masking of the right shift is needed to allow n == 0 (using
+   just 32 - n and 64 - n results in undefined behaviour). Most uses
+   of these macros use a constant and non-zero rotation count. */
+#define ROTL32(n,x) (((x)<<(n)) | ((x)>>((-(n)&31))))
+
+
+#define LE_SWAP32(v) le_bswap32(v)
+
+#define LE_READ_UINT32(p) buf_get_le32(p)
+
+
+static void salsa20_setiv (void *context, const byte *iv, size_t ivlen);
+static const char *selftest (void);
+
+
+#ifdef USE_AMD64
+/* 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);
+unsigned int
+_gcry_salsa20_amd64_encrypt_blocks(u32 *ctxinput, const void *src, void *dst,
+                                   size_t len, int rounds);
+
+static void
+salsa20_keysetup(SALSA20_context_t *ctx, const byte *key, int keylen)
+{
+  _gcry_salsa20_amd64_keysetup(ctx->input, key, keylen * 8);
+}
+
+static void
+salsa20_ivsetup(SALSA20_context_t *ctx, const byte *iv)
+{
+  _gcry_salsa20_amd64_ivsetup(ctx->input, iv);
+}
+
+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);
+}
+
+#else /* USE_AMD64 */
+
+\f
+
+#if 0
+# define SALSA20_CORE_DEBUG(i) do {            \
+    unsigned debug_j;                          \
+    for (debug_j = 0; debug_j < 16; debug_j++) \
+      {                                                \
+       if (debug_j == 0)                       \
+         fprintf(stderr, "%2d:", (i));         \
+       else if (debug_j % 4 == 0)              \
+         fprintf(stderr, "\n   ");             \
+       fprintf(stderr, " %8x", pad[debug_j]);  \
+      }                                                \
+    fprintf(stderr, "\n");                     \
+  } while (0)
+#else
+# define SALSA20_CORE_DEBUG(i)
+#endif
+
+#define QROUND(x0, x1, x2, x3)      \
+  do {                              \
+    x1 ^= ROTL32 ( 7, x0 + x3);            \
+    x2 ^= ROTL32 ( 9, x1 + x0);            \
+    x3 ^= ROTL32 (13, x2 + x1);            \
+    x0 ^= ROTL32 (18, x3 + x2);            \
+  } while(0)
+
+static unsigned int
+salsa20_core (u32 *dst, SALSA20_context_t *ctx, unsigned rounds)
+{
+  u32 pad[SALSA20_INPUT_LENGTH], *src = ctx->input;
+  unsigned int i;
+
+  memcpy (pad, src, sizeof(pad));
+  for (i = 0; i < rounds; i += 2)
+    {
+      SALSA20_CORE_DEBUG (i);
+      QROUND (pad[0],  pad[4],  pad[8],  pad[12]);
+      QROUND (pad[5],  pad[9],  pad[13], pad[1] );
+      QROUND (pad[10], pad[14], pad[2],  pad[6] );
+      QROUND (pad[15], pad[3],  pad[7],  pad[11]);
+
+      SALSA20_CORE_DEBUG (i+1);
+      QROUND (pad[0],  pad[1],  pad[2],  pad[3] );
+      QROUND (pad[5],  pad[6],  pad[7],  pad[4] );
+      QROUND (pad[10], pad[11], pad[8],  pad[9] );
+      QROUND (pad[15], pad[12], pad[13], pad[14]);
+    }
+  SALSA20_CORE_DEBUG (i);
+
+  for (i = 0; i < SALSA20_INPUT_LENGTH; i++)
+    {
+      u32 t = pad[i] + src[i];
+      dst[i] = LE_SWAP32 (t);
+    }
+
+  /* Update counter. */
+  if (!++src[8])
+    src[9]++;
+
+  /* burn_stack */
+  return ( 3*sizeof (void*) \
+         + 2*sizeof (void*) \
+         + 64 \
+         + sizeof (unsigned int) \
+         + sizeof (u32) );
+}
+#undef QROUND
+#undef SALSA20_CORE_DEBUG
+
+static void
+salsa20_keysetup(SALSA20_context_t *ctx, const byte *key, 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[5]  = 0x3320646e; /* "3 dn"  */
+  ctx->input[10] = 0x79622d32; /* "yb-2"  */
+  ctx->input[15] = 0x6b206574; /* "k et"  */
+
+  ctx->input[1] = LE_READ_UINT32(key + 0);
+  ctx->input[2] = LE_READ_UINT32(key + 4);
+  ctx->input[3] = LE_READ_UINT32(key + 8);
+  ctx->input[4] = LE_READ_UINT32(key + 12);
+  if (keylen == SALSA20_MAX_KEY_SIZE) /* 256 bits */
+    {
+      ctx->input[11] = LE_READ_UINT32(key + 16);
+      ctx->input[12] = LE_READ_UINT32(key + 20);
+      ctx->input[13] = LE_READ_UINT32(key + 24);
+      ctx->input[14] = LE_READ_UINT32(key + 28);
+    }
+  else  /* 128 bits */
+    {
+      ctx->input[11] = ctx->input[1];
+      ctx->input[12] = ctx->input[2];
+      ctx->input[13] = ctx->input[3];
+      ctx->input[14] = ctx->input[4];
+
+      ctx->input[5]  -= 0x02000000; /* Change to "1 dn".  */
+      ctx->input[10] += 0x00000004; /* Change to "yb-6".  */
+    }
+}
+
+static void salsa20_ivsetup(SALSA20_context_t *ctx, const byte *iv)
+{
+  ctx->input[6] = LE_READ_UINT32(iv + 0);
+  ctx->input[7] = LE_READ_UINT32(iv + 4);
+  /* Reset the block counter.  */
+  ctx->input[8] = 0;
+  ctx->input[9] = 0;
+}
+
+#endif /*!USE_AMD64*/
+
+#ifdef USE_ARM_NEON_ASM
+
+/* ARM NEON implementation of Salsa20. */
+unsigned int
+_gcry_arm_neon_salsa20_encrypt(void *c, const void *m, unsigned int nblks,
+                               void *k, unsigned int rounds);
+
+static unsigned int
+salsa20_core_neon (u32 *dst, SALSA20_context_t *ctx, unsigned int rounds)
+{
+  return _gcry_arm_neon_salsa20_encrypt(dst, NULL, 1, ctx->input, rounds);
+}
+
+static void salsa20_ivsetup_neon(SALSA20_context_t *ctx, const byte *iv)
+{
+  memcpy(ctx->input + 8, iv, 8);
+  /* Reset the block counter.  */
+  memset(ctx->input + 10, 0, 8);
+}
+
+static void
+salsa20_keysetup_neon(SALSA20_context_t *ctx, const byte *key, int klen)
+{
+  static const unsigned char sigma32[16] = "expand 32-byte k";
+  static const unsigned char sigma16[16] = "expand 16-byte k";
+
+  if (klen == 16)
+    {
+      memcpy (ctx->input, key, 16);
+      memcpy (ctx->input + 4, key, 16); /* Duplicate 128-bit key. */
+      memcpy (ctx->input + 12, sigma16, 16);
+    }
+  else
+    {
+      /* 32-byte key */
+      memcpy (ctx->input, key, 32);
+      memcpy (ctx->input + 12, sigma32, 16);
+    }
+}
+
+#endif /*USE_ARM_NEON_ASM*/
+
+
+static gcry_err_code_t
+salsa20_do_setkey (SALSA20_context_t *ctx,
+                   const byte *key, unsigned int keylen)
+{
+  static int initialized;
+  static const char *selftest_failed;
+
+  if (!initialized )
+    {
+      initialized = 1;
+      selftest_failed = selftest ();
+      if (selftest_failed)
+        log_error ("SALSA20 selftest failed (%s)\n", selftest_failed );
+    }
+  if (selftest_failed)
+    return GPG_ERR_SELFTEST_FAILED;
+
+  if (keylen != SALSA20_MIN_KEY_SIZE
+      && keylen != SALSA20_MAX_KEY_SIZE)
+    return GPG_ERR_INV_KEYLEN;
+
+  /* Default ops. */
+  ctx->keysetup = salsa20_keysetup;
+  ctx->ivsetup = salsa20_ivsetup;
+  ctx->core = salsa20_core;
+
+#ifdef USE_ARM_NEON_ASM
+  ctx->use_neon = (_gcry_get_hw_features () & HWF_ARM_NEON) != 0;
+  if (ctx->use_neon)
+    {
+      /* Use ARM NEON ops instead. */
+      ctx->keysetup = salsa20_keysetup_neon;
+      ctx->ivsetup = salsa20_ivsetup_neon;
+      ctx->core = salsa20_core_neon;
+    }
+#endif
+
+  ctx->keysetup (ctx, key, keylen);
+
+  /* We default to a zero nonce.  */
+  salsa20_setiv (ctx, NULL, 0);
+
+  return 0;
+}
+
+
+static gcry_err_code_t
+salsa20_setkey (void *context, const byte *key, unsigned int keylen)
+{
+  SALSA20_context_t *ctx = (SALSA20_context_t *)context;
+  gcry_err_code_t rc = salsa20_do_setkey (ctx, key, keylen);
+  _gcry_burn_stack (4 + sizeof (void *) + 4 * sizeof (void *));
+  return rc;
+}
+
+
+static void
+salsa20_setiv (void *context, const byte *iv, size_t ivlen)
+{
+  SALSA20_context_t *ctx = (SALSA20_context_t *)context;
+  byte tmp[SALSA20_IV_SIZE];
+
+  if (iv && ivlen != SALSA20_IV_SIZE)
+    log_info ("WARNING: salsa20_setiv: bad ivlen=%u\n", (u32)ivlen);
+
+  if (!iv || ivlen != SALSA20_IV_SIZE)
+    memset (tmp, 0, sizeof(tmp));
+  else
+    memcpy (tmp, iv, SALSA20_IV_SIZE);
+
+  ctx->ivsetup (ctx, tmp);
+
+  /* Reset the unused pad bytes counter.  */
+  ctx->unused = 0;
+
+  wipememory (tmp, sizeof(tmp));
+}
+
+
+\f
+/* Note: This function requires LENGTH > 0.  */
+static void
+salsa20_do_encrypt_stream (SALSA20_context_t *ctx,
+                           byte *outbuf, const byte *inbuf,
+                           size_t length, unsigned rounds)
+{
+  unsigned int nburn, burn = 0;
+
+  if (ctx->unused)
+    {
+      unsigned char *p = (void*)ctx->pad;
+      size_t n;
+
+      gcry_assert (ctx->unused < SALSA20_BLOCK_SIZE);
+
+      n = ctx->unused;
+      if (n > length)
+        n = length;
+      buf_xor (outbuf, inbuf, p + SALSA20_BLOCK_SIZE - ctx->unused, n);
+      length -= n;
+      outbuf += n;
+      inbuf  += n;
+      ctx->unused -= n;
+      if (!length)
+        return;
+      gcry_assert (!ctx->unused);
+    }
+
+#ifdef USE_AMD64
+  if (length >= SALSA20_BLOCK_SIZE)
+    {
+      size_t nblocks = length / SALSA20_BLOCK_SIZE;
+      burn = _gcry_salsa20_amd64_encrypt_blocks(ctx->input, inbuf, outbuf,
+                                                nblocks, rounds);
+      length -= SALSA20_BLOCK_SIZE * nblocks;
+      outbuf += SALSA20_BLOCK_SIZE * nblocks;
+      inbuf  += SALSA20_BLOCK_SIZE * nblocks;
+    }
+#endif
+
+#ifdef USE_ARM_NEON_ASM
+  if (ctx->use_neon && length >= SALSA20_BLOCK_SIZE)
+    {
+      unsigned int nblocks = length / SALSA20_BLOCK_SIZE;
+      _gcry_arm_neon_salsa20_encrypt (outbuf, inbuf, nblocks, ctx->input,
+                                      rounds);
+      length -= SALSA20_BLOCK_SIZE * nblocks;
+      outbuf += SALSA20_BLOCK_SIZE * nblocks;
+      inbuf  += SALSA20_BLOCK_SIZE * nblocks;
+    }
+#endif
+
+  while (length > 0)
+    {
+      /* Create the next pad and bump the block counter.  Note that it
+         is the user's duty to change to another nonce not later than
+         after 2^70 processed bytes.  */
+      nburn = ctx->core (ctx->pad, ctx, rounds);
+      burn = nburn > burn ? nburn : burn;
+
+      if (length <= SALSA20_BLOCK_SIZE)
+       {
+         buf_xor (outbuf, inbuf, ctx->pad, length);
+          ctx->unused = SALSA20_BLOCK_SIZE - length;
+         break;
+       }
+      buf_xor (outbuf, inbuf, ctx->pad, SALSA20_BLOCK_SIZE);
+      length -= SALSA20_BLOCK_SIZE;
+      outbuf += SALSA20_BLOCK_SIZE;
+      inbuf  += SALSA20_BLOCK_SIZE;
+    }
+
+  _gcry_burn_stack (burn);
+}
+
+
+static void
+salsa20_encrypt_stream (void *context,
+                        byte *outbuf, const byte *inbuf, size_t length)
+{
+  SALSA20_context_t *ctx = (SALSA20_context_t *)context;
+
+  if (length)
+    salsa20_do_encrypt_stream (ctx, outbuf, inbuf, length, SALSA20_ROUNDS);
+}
+
+
+static void
+salsa20r12_encrypt_stream (void *context,
+                           byte *outbuf, const byte *inbuf, size_t length)
+{
+  SALSA20_context_t *ctx = (SALSA20_context_t *)context;
+
+  if (length)
+    salsa20_do_encrypt_stream (ctx, outbuf, inbuf, length, SALSA20R12_ROUNDS);
+}
+
+
+static const char*
+selftest (void)
+{
+  SALSA20_context_t ctx;
+  byte scratch[8+1];
+  byte buf[256+64+4];
+  int i;
+
+  static byte key_1[] =
+    { 0x80, 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 nonce_1[] =
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+  static const byte plaintext_1[] =
+    { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+  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);
+  scratch[8] = 0;
+  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);
+  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);
+  /*encrypt*/
+  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);
+  for (i = 0; i < sizeof buf; i++)
+    if (buf[i] != (byte)i)
+      return "Salsa20 encryption test 2 failed.";
+
+  return NULL;
+}
+
+
+gcry_cipher_spec_t _gcry_cipher_spec_salsa20 =
+  {
+    GCRY_CIPHER_SALSA20,
+    {0, 0},     /* flags */
+    "SALSA20",  /* name */
+    NULL,       /* aliases */
+    NULL,       /* oids */
+    1,          /* blocksize in bytes. */
+    SALSA20_MAX_KEY_SIZE*8,  /* standard key length in bits. */
+    sizeof (SALSA20_context_t),
+    salsa20_setkey,
+    NULL,
+    NULL,
+    salsa20_encrypt_stream,
+    salsa20_encrypt_stream,
+    NULL,
+    NULL,
+    salsa20_setiv
+  };
+
+gcry_cipher_spec_t _gcry_cipher_spec_salsa20r12 =
+  {
+    GCRY_CIPHER_SALSA20R12,
+    {0, 0},     /* flags */
+    "SALSA20R12",  /* name */
+    NULL,       /* aliases */
+    NULL,       /* oids */
+    1,          /* blocksize in bytes. */
+    SALSA20_MAX_KEY_SIZE*8,  /* standard key length in bits. */
+    sizeof (SALSA20_context_t),
+    salsa20_setkey,
+    NULL,
+    NULL,
+    salsa20r12_encrypt_stream,
+    salsa20r12_encrypt_stream,
+    NULL,
+    NULL,
+    salsa20_setiv
+  };
diff --git a/cipher/scrypt.c b/cipher/scrypt.c
new file mode 100644 (file)
index 0000000..404943d
--- /dev/null
@@ -0,0 +1,324 @@
+/* scrypt.c - Scrypt password-based key derivation function.
+ * Copyright (C) 2012 Simon Josefsson
+ * Copyright (C) 2013 Christian Grothoff
+ * Copyright (C) 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/>.
+ */
+
+/* Adapted from the nettle, low-level cryptographics library for
+ * libgcrypt by Christian Grothoff; original license:
+ *
+ * Copyright (C) 2012 Simon Josefsson
+ *
+ * The nettle 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.
+ *
+ * The nettle 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 the nettle library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02111-1301, USA.
+ */
+
+#include <config.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "kdf-internal.h"
+#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))))
+
+
+/* Reads a 64-bit integer, in network, big-endian, byte order */
+#define READ_UINT64(p) buf_get_be64(p)
+
+
+/* And the other, little-endian, byteorder */
+#define LE_READ_UINT64(p) buf_get_le64(p)
+
+#define LE_SWAP32(v) le_bswap32(v)
+
+
+#define QROUND(x0, x1, x2, x3) do { \
+  x1 ^= ROTL32(7, x0 + x3);        \
+  x2 ^= ROTL32(9, x1 + x0);        \
+  x3 ^= ROTL32(13, x2 + x1);       \
+  x0 ^= ROTL32(18, x3 + x2);       \
+  } while(0)
+
+
+static void
+_salsa20_core(u32 *dst, const u32 *src, unsigned rounds)
+{
+  u32 x[SALSA20_INPUT_LENGTH];
+  unsigned i;
+
+  assert ( (rounds & 1) == 0);
+
+  for (i = 0; i < SALSA20_INPUT_LENGTH; i++)
+    x[i] = LE_SWAP32(src[i]);
+
+  for (i = 0; i < rounds;i += 2)
+    {
+      QROUND(x[0], x[4], x[8], x[12]);
+      QROUND(x[5], x[9], x[13], x[1]);
+      QROUND(x[10], x[14], x[2], x[6]);
+      QROUND(x[15], x[3], x[7], x[11]);
+
+      QROUND(x[0], x[1], x[2], x[3]);
+      QROUND(x[5], x[6], x[7], x[4]);
+      QROUND(x[10], x[11], x[8], x[9]);
+      QROUND(x[15], x[12], x[13], x[14]);
+    }
+
+  for (i = 0; i < SALSA20_INPUT_LENGTH; i++)
+    {
+      u32 t = x[i] + LE_SWAP32(src[i]);
+      dst[i] = LE_SWAP32(t);
+    }
+}
+
+
+static void
+_scryptBlockMix (u32 r, unsigned char *B, unsigned char *tmp2)
+{
+  u64 i;
+  unsigned char *X = tmp2;
+  unsigned char *Y = tmp2 + 64;
+
+#if 0
+  if (r == 1)
+    {
+      for (i = 0; i < 2 * r; i++)
+        {
+          size_t j;
+          printf ("B[%d] = ", (int)i);
+          for (j = 0; j < 64; j++)
+            {
+              if (j && !(j % 16))
+                printf ("\n       ");
+              printf (" %02x", B[i * 64 + j]);
+            }
+          putchar ('\n');
+        }
+    }
+#endif
+
+  /* X = B[2 * r - 1] */
+  memcpy (X, &B[(2 * r - 1) * 64], 64);
+
+  /* for i = 0 to 2 * r - 1 do */
+  for (i = 0; i <= 2 * r - 1; i++)
+    {
+      /* T = X xor B[i] */
+      buf_xor(X, X, &B[i * 64], 64);
+
+      /* X = Salsa (T) */
+      _salsa20_core ((u32*)X, (u32*)X, 8);
+
+      /* Y[i] = X */
+      memcpy (&Y[i * 64], X, 64);
+    }
+
+  for (i = 0; i < r; i++)
+    {
+      memcpy (&B[i * 64], &Y[2 * i * 64], 64);
+      memcpy (&B[(r + i) * 64], &Y[(2 * i + 1) * 64], 64);
+    }
+
+#if 0
+  if (r==1)
+    {
+      for (i = 0; i < 2 * r; i++)
+        {
+          size_t j;
+          printf ("B'[%d] =", (int)i);
+          for (j = 0; j < 64; j++)
+            {
+              if (j && !(j % 16))
+                printf ("\n       ");
+              printf (" %02x", B[i * 64 + j]);
+            }
+          putchar ('\n');
+        }
+    }
+#endif
+}
+
+static void
+_scryptROMix (u32 r, unsigned char *B, u64 N,
+             unsigned char *tmp1, unsigned char *tmp2)
+{
+  unsigned char *X = B, *T = B;
+  u64 i;
+
+#if 0
+  if (r == 1)
+    {
+      printf ("B = ");
+      for (i = 0; i < 128 * r; i++)
+        {
+          if (i && !(i % 16))
+            printf ("\n    ");
+          printf (" %02x", B[i]);
+        }
+      putchar ('\n');
+    }
+#endif
+
+  /* for i = 0 to N - 1 do */
+  for (i = 0; i <= N - 1; i++)
+    {
+      /* V[i] = X */
+      memcpy (&tmp1[i * 128 * r], X, 128 * r);
+
+      /* X =  ScryptBlockMix (X) */
+      _scryptBlockMix (r, X, tmp2);
+    }
+
+  /* for i = 0 to N - 1 do */
+  for (i = 0; i <= N - 1; i++)
+    {
+      u64 j;
+
+      /* j = Integerify (X) mod N */
+      j = LE_READ_UINT64 (&X[128 * r - 64]) % N;
+
+      /* T = X xor V[j] */
+      buf_xor (T, T, &tmp1[j * 128 * r], 128 * r);
+
+      /* X = scryptBlockMix (T) */
+      _scryptBlockMix (r, T, tmp2);
+    }
+
+#if 0
+  if (r == 1)
+    {
+      printf ("B' =");
+      for (i = 0; i < 128 * r; i++)
+        {
+          if (i && !(i % 16))
+            printf ("\n    ");
+          printf (" %02x", B[i]);
+        }
+      putchar ('\n');
+    }
+#endif
+}
+
+/**
+ */
+gcry_err_code_t
+_gcry_kdf_scrypt (const unsigned char *passwd, size_t passwdlen,
+                  int algo, int subalgo,
+                  const unsigned char *salt, size_t saltlen,
+                  unsigned long iterations,
+                  size_t dkLen, unsigned char *DK)
+{
+  u64 N = subalgo;    /* CPU/memory cost paramter.  */
+  u32 r;              /* Block size.  */
+  u32 p = iterations; /* Parallelization parameter.  */
+
+  gpg_err_code_t ec;
+  u32 i;
+  unsigned char *B = NULL;
+  unsigned char *tmp1 = NULL;
+  unsigned char *tmp2 = NULL;
+  size_t r128;
+  size_t nbytes;
+
+  if (subalgo < 1 || !iterations)
+    return GPG_ERR_INV_VALUE;
+
+  if (algo == GCRY_KDF_SCRYPT)
+    r = 8;
+  else if (algo == 41) /* Hack to allow the use of all test vectors.  */
+    r = 1;
+  else
+    return GPG_ERR_UNKNOWN_ALGORITHM;
+
+  r128 = r * 128;
+  if (r128 / 128 != r)
+    return GPG_ERR_ENOMEM;
+
+  nbytes = p * r128;
+  if (r128 && nbytes / r128 != p)
+    return GPG_ERR_ENOMEM;
+
+  nbytes = N * r128;
+  if (r128 && nbytes / r128 != N)
+    return GPG_ERR_ENOMEM;
+
+  nbytes = 64 + r128;
+  if (nbytes < r128)
+    return GPG_ERR_ENOMEM;
+
+  B = xtrymalloc (p * r128);
+  if (!B)
+    {
+      ec = gpg_err_code_from_syserror ();
+      goto leave;
+    }
+
+  tmp1 = xtrymalloc (N * r128);
+  if (!tmp1)
+    {
+      ec = gpg_err_code_from_syserror ();
+      goto leave;
+    }
+
+  tmp2 = xtrymalloc (64 + r128);
+  if (!tmp2)
+    {
+      ec = gpg_err_code_from_syserror ();
+      goto leave;
+    }
+
+  ec = _gcry_kdf_pkdf2 (passwd, passwdlen, GCRY_MD_SHA256, salt, saltlen,
+                        1 /* iterations */, p * r128, B);
+
+  for (i = 0; !ec && i < p; i++)
+    _scryptROMix (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,
+                          1 /* iterations */, dkLen, DK);
+
+ leave:
+  xfree (tmp2);
+  xfree (tmp1);
+  xfree (B);
+
+  return ec;
+}
+
+
+#endif /* HAVE_U64_TYPEDEF */
index ae26e67..9f87c05 100644 (file)
 #include "types.h"  /* for byte and u32 typedefs */
 #include "g10lib.h"
 #include "cipher.h"
+#include "bufhelp.h"
 
 #define NUMKC  16
 
-#define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ \
-                   ((u32)(pt)[2] <<  8) ^ ((u32)(pt)[3]))
-#define PUTU32(ct, st) { (ct)[0] = (byte)((st) >> 24); \
-                        (ct)[1] = (byte)((st) >> 16); \
-                        (ct)[2] = (byte)((st) >>  8); \
-                        (ct)[3] = (byte)(st); }
+#define GETU32(pt) buf_get_be32(pt)
+#define PUTU32(ct, st) buf_put_be32(ct, st)
 
 union wordbuf
 {
@@ -371,13 +368,13 @@ do_encrypt (const SEED_context *ctx, byte *outbuf, const byte *inbuf)
   PUTU32 (outbuf+12, x2);
 }
 
-static void
+static unsigned int
 seed_encrypt (void *context, byte *outbuf, const byte *inbuf)
 {
   SEED_context *ctx = context;
 
   do_encrypt (ctx, outbuf, inbuf);
-  _gcry_burn_stack (4*6);
+  return /*burn_stack*/ (4*6);
 }
 
 
@@ -417,13 +414,13 @@ do_decrypt (SEED_context *ctx, byte *outbuf, const byte *inbuf)
   PUTU32 (outbuf+12, x2);
 }
 
-static void
+static unsigned int
 seed_decrypt (void *context, byte *outbuf, const byte *inbuf)
 {
   SEED_context *ctx = context;
 
   do_decrypt (ctx, outbuf, inbuf);
-  _gcry_burn_stack (4*6);
+  return /*burn_stack*/ (4*6);
 }
 
 \f
@@ -473,6 +470,7 @@ static gcry_cipher_oid_spec_t seed_oids[] =
 
 gcry_cipher_spec_t _gcry_cipher_spec_seed =
   {
+    GCRY_CIPHER_SEED, {0, 0},
     "SEED", NULL, seed_oids, 16, 128, sizeof (SEED_context),
     seed_setkey, seed_encrypt, seed_decrypt,
   };
diff --git a/cipher/serpent-armv7-neon.S b/cipher/serpent-armv7-neon.S
new file mode 100644 (file)
index 0000000..92e95a0
--- /dev/null
@@ -0,0 +1,869 @@
+/* serpent-armv7-neon.S  -  ARM/NEON assembly implementation of Serpent cipher
+ *
+ * Copyright © 2013 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)
+
+.text
+
+.syntax unified
+.fpu neon
+.arm
+
+/* ARM registers */
+#define RROUND r0
+
+/* NEON vector registers */
+#define RA0 q0
+#define RA1 q1
+#define RA2 q2
+#define RA3 q3
+#define RA4 q4
+#define RB0 q5
+#define RB1 q6
+#define RB2 q7
+#define RB3 q8
+#define RB4 q9
+
+#define RT0 q10
+#define RT1 q11
+#define RT2 q12
+#define RT3 q13
+
+#define RA0d0 d0
+#define RA0d1 d1
+#define RA1d0 d2
+#define RA1d1 d3
+#define RA2d0 d4
+#define RA2d1 d5
+#define RA3d0 d6
+#define RA3d1 d7
+#define RA4d0 d8
+#define RA4d1 d9
+#define RB0d0 d10
+#define RB0d1 d11
+#define RB1d0 d12
+#define RB1d1 d13
+#define RB2d0 d14
+#define RB2d1 d15
+#define RB3d0 d16
+#define RB3d1 d17
+#define RB4d0 d18
+#define RB4d1 d19
+#define RT0d0 d20
+#define RT0d1 d21
+#define RT1d0 d22
+#define RT1d1 d23
+#define RT2d0 d24
+#define RT2d1 d25
+
+/**********************************************************************
+  helper macros
+ **********************************************************************/
+
+#define transpose_4x4(_q0, _q1, _q2, _q3) \
+       vtrn.32 _q0, _q1;       \
+       vtrn.32 _q2, _q3;       \
+       vswp _q0##d1, _q2##d0;  \
+       vswp _q1##d1, _q3##d0;
+
+/**********************************************************************
+  8-way serpent
+ **********************************************************************/
+
+/*
+ * These are the S-Boxes of Serpent from following research paper.
+ *
+ *  D. A. Osvik, “Speeding up Serpent,” in Third AES Candidate Conference,
+ *   (New York, New York, USA), p. 317–329, National Institute of Standards and
+ *   Technology, 2000.
+ *
+ * Paper is also available at: http://www.ii.uib.no/~osvik/pub/aes3.pdf
+ *
+ */
+#define SBOX0(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       veor    a3, a3, a0;     veor    b3, b3, b0;     vmov    a4, a1;         vmov    b4, b1;         \
+       vand    a1, a1, a3;     vand    b1, b1, b3;     veor    a4, a4, a2;     veor    b4, b4, b2;     \
+       veor    a1, a1, a0;     veor    b1, b1, b0;     vorr    a0, a0, a3;     vorr    b0, b0, b3;     \
+       veor    a0, a0, a4;     veor    b0, b0, b4;     veor    a4, a4, a3;     veor    b4, b4, b3;     \
+       veor    a3, a3, a2;     veor    b3, b3, b2;     vorr    a2, a2, a1;     vorr    b2, b2, b1;     \
+       veor    a2, a2, a4;     veor    b2, b2, b4;     vmvn    a4, a4;         vmvn    b4, b4;         \
+       vorr    a4, a4, a1;     vorr    b4, b4, b1;     veor    a1, a1, a3;     veor    b1, b1, b3;     \
+       veor    a1, a1, a4;     veor    b1, b1, b4;     vorr    a3, a3, a0;     vorr    b3, b3, b0;     \
+       veor    a1, a1, a3;     veor    b1, b1, b3;     veor    a4, a3;         veor    b4, b3;
+
+#define SBOX0_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       vmvn    a2, a2;         vmvn    b2, b2;         vmov    a4, a1;         vmov    b4, b1;         \
+       vorr    a1, a1, a0;     vorr    b1, b1, b0;     vmvn    a4, a4;         vmvn    b4, b4;         \
+       veor    a1, a1, a2;     veor    b1, b1, b2;     vorr    a2, a2, a4;     vorr    b2, b2, b4;     \
+       veor    a1, a1, a3;     veor    b1, b1, b3;     veor    a0, a0, a4;     veor    b0, b0, b4;     \
+       veor    a2, a2, a0;     veor    b2, b2, b0;     vand    a0, a0, a3;     vand    b0, b0, b3;     \
+       veor    a4, a4, a0;     veor    b4, b4, b0;     vorr    a0, a0, a1;     vorr    b0, b0, b1;     \
+       veor    a0, a0, a2;     veor    b0, b0, b2;     veor    a3, a3, a4;     veor    b3, b3, b4;     \
+       veor    a2, a2, a1;     veor    b2, b2, b1;     veor    a3, a3, a0;     veor    b3, b3, b0;     \
+       veor    a3, a3, a1;     veor    b3, b3, b1;\
+       vand    a2, a2, a3;     vand    b2, b2, b3;\
+       veor    a4, a2; veor    b4, b2;
+
+#define SBOX1(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       vmvn    a0, a0;         vmvn    b0, b0;         vmvn    a2, a2;         vmvn    b2, b2;         \
+       vmov    a4, a0;         vmov    b4, b0;         vand    a0, a0, a1;     vand    b0, b0, b1;     \
+       veor    a2, a2, a0;     veor    b2, b2, b0;     vorr    a0, a0, a3;     vorr    b0, b0, b3;     \
+       veor    a3, a3, a2;     veor    b3, b3, b2;     veor    a1, a1, a0;     veor    b1, b1, b0;     \
+       veor    a0, a0, a4;     veor    b0, b0, b4;     vorr    a4, a4, a1;     vorr    b4, b4, b1;     \
+       veor    a1, a1, a3;     veor    b1, b1, b3;     vorr    a2, a2, a0;     vorr    b2, b2, b0;     \
+       vand    a2, a2, a4;     vand    b2, b2, b4;     veor    a0, a0, a1;     veor    b0, b0, b1;     \
+       vand    a1, a1, a2;     vand    b1, b1, b2;\
+       veor    a1, a1, a0;     veor    b1, b1, b0;     vand    a0, a0, a2;     vand    b0, b0, b2;     \
+       veor    a0, a4;         veor    b0, b4;
+
+#define SBOX1_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       vmov    a4, a1;         vmov    b4, b1;         veor    a1, a1, a3;     veor    b1, b1, b3;     \
+       vand    a3, a3, a1;     vand    b3, b3, b1;     veor    a4, a4, a2;     veor    b4, b4, b2;     \
+       veor    a3, a3, a0;     veor    b3, b3, b0;     vorr    a0, a0, a1;     vorr    b0, b0, b1;     \
+       veor    a2, a2, a3;     veor    b2, b2, b3;     veor    a0, a0, a4;     veor    b0, b0, b4;     \
+       vorr    a0, a0, a2;     vorr    b0, b0, b2;     veor    a1, a1, a3;     veor    b1, b1, b3;     \
+       veor    a0, a0, a1;     veor    b0, b0, b1;     vorr    a1, a1, a3;     vorr    b1, b1, b3;     \
+       veor    a1, a1, a0;     veor    b1, b1, b0;     vmvn    a4, a4;         vmvn    b4, b4;         \
+       veor    a4, a4, a1;     veor    b4, b4, b1;     vorr    a1, a1, a0;     vorr    b1, b1, b0;     \
+       veor    a1, a1, a0;     veor    b1, b1, b0;\
+       vorr    a1, a1, a4;     vorr    b1, b1, b4;\
+       veor    a3, a1;         veor    b3, b1;
+
+#define SBOX2(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       vmov    a4, a0;         vmov    b4, b0;         vand    a0, a0, a2;     vand    b0, b0, b2;     \
+       veor    a0, a0, a3;     veor    b0, b0, b3;     veor    a2, a2, a1;     veor    b2, b2, b1;     \
+       veor    a2, a2, a0;     veor    b2, b2, b0;     vorr    a3, a3, a4;     vorr    b3, b3, b4;     \
+       veor    a3, a3, a1;     veor    b3, b3, b1;     veor    a4, a4, a2;     veor    b4, b4, b2;     \
+       vmov    a1, a3;         vmov    b1, b3;         vorr    a3, a3, a4;     vorr    b3, b3, b4;     \
+       veor    a3, a3, a0;     veor    b3, b3, b0;     vand    a0, a0, a1;     vand    b0, b0, b1;     \
+       veor    a4, a4, a0;     veor    b4, b4, b0;     veor    a1, a1, a3;     veor    b1, b1, b3;     \
+       veor    a1, a1, a4;     veor    b1, b1, b4;     vmvn    a4, a4;         vmvn    b4, b4;
+
+#define SBOX2_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       veor    a2, a2, a3;     veor    b2, b2, b3;     veor    a3, a3, a0;     veor    b3, b3, b0;     \
+       vmov    a4, a3;         vmov    b4, b3;         vand    a3, a3, a2;     vand    b3, b3, b2;     \
+       veor    a3, a3, a1;     veor    b3, b3, b1;     vorr    a1, a1, a2;     vorr    b1, b1, b2;     \
+       veor    a1, a1, a4;     veor    b1, b1, b4;     vand    a4, a4, a3;     vand    b4, b4, b3;     \
+       veor    a2, a2, a3;     veor    b2, b2, b3;     vand    a4, a4, a0;     vand    b4, b4, b0;     \
+       veor    a4, a4, a2;     veor    b4, b4, b2;     vand    a2, a2, a1;     vand    b2, b2, b1;     \
+       vorr    a2, a2, a0;     vorr    b2, b2, b0;     vmvn    a3, a3;         vmvn    b3, b3;         \
+       veor    a2, a2, a3;     veor    b2, b2, b3;     veor    a0, a0, a3;     veor    b0, b0, b3;     \
+       vand    a0, a0, a1;     vand    b0, b0, b1;     veor    a3, a3, a4;     veor    b3, b3, b4;     \
+       veor    a3, a0;         veor    b3, b0;
+
+#define SBOX3(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       vmov    a4, a0;         vmov    b4, b0;         vorr    a0, a0, a3;     vorr    b0, b0, b3;     \
+       veor    a3, a3, a1;     veor    b3, b3, b1;     vand    a1, a1, a4;     vand    b1, b1, b4;     \
+       veor    a4, a4, a2;     veor    b4, b4, b2;     veor    a2, a2, a3;     veor    b2, b2, b3;     \
+       vand    a3, a3, a0;     vand    b3, b3, b0;     vorr    a4, a4, a1;     vorr    b4, b4, b1;     \
+       veor    a3, a3, a4;     veor    b3, b3, b4;     veor    a0, a0, a1;     veor    b0, b0, b1;     \
+       vand    a4, a4, a0;     vand    b4, b4, b0;     veor    a1, a1, a3;     veor    b1, b1, b3;     \
+       veor    a4, a4, a2;     veor    b4, b4, b2;     vorr    a1, a1, a0;     vorr    b1, b1, b0;     \
+       veor    a1, a1, a2;     veor    b1, b1, b2;     veor    a0, a0, a3;     veor    b0, b0, b3;     \
+       vmov    a2, a1;         vmov    b2, b1;         vorr    a1, a1, a3;     vorr    b1, b1, b3;     \
+       veor    a1, a0;         veor    b1, b0;
+
+#define SBOX3_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       vmov    a4, a2;         vmov    b4, b2;         veor    a2, a2, a1;     veor    b2, b2, b1;     \
+       veor    a0, a0, a2;     veor    b0, b0, b2;     vand    a4, a4, a2;     vand    b4, b4, b2;     \
+       veor    a4, a4, a0;     veor    b4, b4, b0;     vand    a0, a0, a1;     vand    b0, b0, b1;     \
+       veor    a1, a1, a3;     veor    b1, b1, b3;     vorr    a3, a3, a4;     vorr    b3, b3, b4;     \
+       veor    a2, a2, a3;     veor    b2, b2, b3;     veor    a0, a0, a3;     veor    b0, b0, b3;     \
+       veor    a1, a1, a4;     veor    b1, b1, b4;     vand    a3, a3, a2;     vand    b3, b3, b2;     \
+       veor    a3, a3, a1;     veor    b3, b3, b1;     veor    a1, a1, a0;     veor    b1, b1, b0;     \
+       vorr    a1, a1, a2;     vorr    b1, b1, b2;     veor    a0, a0, a3;     veor    b0, b0, b3;     \
+       veor    a1, a1, a4;     veor    b1, b1, b4;\
+       veor    a0, a1;         veor    b0, b1;
+
+#define SBOX4(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       veor    a1, a1, a3;     veor    b1, b1, b3;     vmvn    a3, a3;         vmvn    b3, b3;         \
+       veor    a2, a2, a3;     veor    b2, b2, b3;     veor    a3, a3, a0;     veor    b3, b3, b0;     \
+       vmov    a4, a1;         vmov    b4, b1;         vand    a1, a1, a3;     vand    b1, b1, b3;     \
+       veor    a1, a1, a2;     veor    b1, b1, b2;     veor    a4, a4, a3;     veor    b4, b4, b3;     \
+       veor    a0, a0, a4;     veor    b0, b0, b4;     vand    a2, a2, a4;     vand    b2, b2, b4;     \
+       veor    a2, a2, a0;     veor    b2, b2, b0;     vand    a0, a0, a1;     vand    b0, b0, b1;     \
+       veor    a3, a3, a0;     veor    b3, b3, b0;     vorr    a4, a4, a1;     vorr    b4, b4, b1;     \
+       veor    a4, a4, a0;     veor    b4, b4, b0;     vorr    a0, a0, a3;     vorr    b0, b0, b3;     \
+       veor    a0, a0, a2;     veor    b0, b0, b2;     vand    a2, a2, a3;     vand    b2, b2, b3;     \
+       vmvn    a0, a0;         vmvn    b0, b0;         veor    a4, a2;         veor    b4, b2;
+
+#define SBOX4_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       vmov    a4, a2;         vmov    b4, b2;         vand    a2, a2, a3;     vand    b2, b2, b3;     \
+       veor    a2, a2, a1;     veor    b2, b2, b1;     vorr    a1, a1, a3;     vorr    b1, b1, b3;     \
+       vand    a1, a1, a0;     vand    b1, b1, b0;     veor    a4, a4, a2;     veor    b4, b4, b2;     \
+       veor    a4, a4, a1;     veor    b4, b4, b1;     vand    a1, a1, a2;     vand    b1, b1, b2;     \
+       vmvn    a0, a0;         vmvn    b0, b0;         veor    a3, a3, a4;     veor    b3, b3, b4;     \
+       veor    a1, a1, a3;     veor    b1, b1, b3;     vand    a3, a3, a0;     vand    b3, b3, b0;     \
+       veor    a3, a3, a2;     veor    b3, b3, b2;     veor    a0, a0, a1;     veor    b0, b0, b1;     \
+       vand    a2, a2, a0;     vand    b2, b2, b0;     veor    a3, a3, a0;     veor    b3, b3, b0;     \
+       veor    a2, a2, a4;     veor    b2, b2, b4;\
+       vorr    a2, a2, a3;     vorr    b2, b2, b3;     veor    a3, a3, a0;     veor    b3, b3, b0;     \
+       veor    a2, a1;         veor    b2, b1;
+
+#define SBOX5(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       veor    a0, a0, a1;     veor    b0, b0, b1;     veor    a1, a1, a3;     veor    b1, b1, b3;     \
+       vmvn    a3, a3;         vmvn    b3, b3;         vmov    a4, a1;         vmov    b4, b1;         \
+       vand    a1, a1, a0;     vand    b1, b1, b0;     veor    a2, a2, a3;     veor    b2, b2, b3;     \
+       veor    a1, a1, a2;     veor    b1, b1, b2;     vorr    a2, a2, a4;     vorr    b2, b2, b4;     \
+       veor    a4, a4, a3;     veor    b4, b4, b3;     vand    a3, a3, a1;     vand    b3, b3, b1;     \
+       veor    a3, a3, a0;     veor    b3, b3, b0;     veor    a4, a4, a1;     veor    b4, b4, b1;     \
+       veor    a4, a4, a2;     veor    b4, b4, b2;     veor    a2, a2, a0;     veor    b2, b2, b0;     \
+       vand    a0, a0, a3;     vand    b0, b0, b3;     vmvn    a2, a2;         vmvn    b2, b2;         \
+       veor    a0, a0, a4;     veor    b0, b0, b4;     vorr    a4, a4, a3;     vorr    b4, b4, b3;     \
+       veor    a2, a4;         veor    b2, b4;
+
+#define SBOX5_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       vmvn    a1, a1;         vmvn    b1, b1;         vmov    a4, a3;         vmov    b4, b3;         \
+       veor    a2, a2, a1;     veor    b2, b2, b1;     vorr    a3, a3, a0;     vorr    b3, b3, b0;     \
+       veor    a3, a3, a2;     veor    b3, b3, b2;     vorr    a2, a2, a1;     vorr    b2, b2, b1;     \
+       vand    a2, a2, a0;     vand    b2, b2, b0;     veor    a4, a4, a3;     veor    b4, b4, b3;     \
+       veor    a2, a2, a4;     veor    b2, b2, b4;     vorr    a4, a4, a0;     vorr    b4, b4, b0;     \
+       veor    a4, a4, a1;     veor    b4, b4, b1;     vand    a1, a1, a2;     vand    b1, b1, b2;     \
+       veor    a1, a1, a3;     veor    b1, b1, b3;     veor    a4, a4, a2;     veor    b4, b4, b2;     \
+       vand    a3, a3, a4;     vand    b3, b3, b4;     veor    a4, a4, a1;     veor    b4, b4, b1;     \
+       veor    a3, a3, a4;     veor    b3, b3, b4;     vmvn    a4, a4;         vmvn    b4, b4;         \
+       veor    a3, a0;         veor    b3, b0;
+
+#define SBOX6(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       vmvn    a2, a2;         vmvn    b2, b2;         vmov    a4, a3;         vmov    b4, b3;         \
+       vand    a3, a3, a0;     vand    b3, b3, b0;     veor    a0, a0, a4;     veor    b0, b0, b4;     \
+       veor    a3, a3, a2;     veor    b3, b3, b2;     vorr    a2, a2, a4;     vorr    b2, b2, b4;     \
+       veor    a1, a1, a3;     veor    b1, b1, b3;     veor    a2, a2, a0;     veor    b2, b2, b0;     \
+       vorr    a0, a0, a1;     vorr    b0, b0, b1;     veor    a2, a2, a1;     veor    b2, b2, b1;     \
+       veor    a4, a4, a0;     veor    b4, b4, b0;     vorr    a0, a0, a3;     vorr    b0, b0, b3;     \
+       veor    a0, a0, a2;     veor    b0, b0, b2;     veor    a4, a4, a3;     veor    b4, b4, b3;     \
+       veor    a4, a4, a0;     veor    b4, b4, b0;     vmvn    a3, a3;         vmvn    b3, b3;         \
+       vand    a2, a2, a4;     vand    b2, b2, b4;\
+       veor    a2, a3;         veor    b2, b3;
+
+#define SBOX6_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       veor    a0, a0, a2;     veor    b0, b0, b2;     vmov    a4, a2;         vmov    b4, b2;         \
+       vand    a2, a2, a0;     vand    b2, b2, b0;     veor    a4, a4, a3;     veor    b4, b4, b3;     \
+       vmvn    a2, a2;         vmvn    b2, b2;         veor    a3, a3, a1;     veor    b3, b3, b1;     \
+       veor    a2, a2, a3;     veor    b2, b2, b3;     vorr    a4, a4, a0;     vorr    b4, b4, b0;     \
+       veor    a0, a0, a2;     veor    b0, b0, b2;     veor    a3, a3, a4;     veor    b3, b3, b4;     \
+       veor    a4, a4, a1;     veor    b4, b4, b1;     vand    a1, a1, a3;     vand    b1, b1, b3;     \
+       veor    a1, a1, a0;     veor    b1, b1, b0;     veor    a0, a0, a3;     veor    b0, b0, b3;     \
+       vorr    a0, a0, a2;     vorr    b0, b0, b2;     veor    a3, a3, a1;     veor    b3, b3, b1;     \
+       veor    a4, a0;         veor    b4, b0;
+
+#define SBOX7(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       vmov    a4, a1;         vmov    b4, b1;         vorr    a1, a1, a2;     vorr    b1, b1, b2;     \
+       veor    a1, a1, a3;     veor    b1, b1, b3;     veor    a4, a4, a2;     veor    b4, b4, b2;     \
+       veor    a2, a2, a1;     veor    b2, b2, b1;     vorr    a3, a3, a4;     vorr    b3, b3, b4;     \
+       vand    a3, a3, a0;     vand    b3, b3, b0;     veor    a4, a4, a2;     veor    b4, b4, b2;     \
+       veor    a3, a3, a1;     veor    b3, b3, b1;     vorr    a1, a1, a4;     vorr    b1, b1, b4;     \
+       veor    a1, a1, a0;     veor    b1, b1, b0;     vorr    a0, a0, a4;     vorr    b0, b0, b4;     \
+       veor    a0, a0, a2;     veor    b0, b0, b2;     veor    a1, a1, a4;     veor    b1, b1, b4;     \
+       veor    a2, a2, a1;     veor    b2, b2, b1;     vand    a1, a1, a0;     vand    b1, b1, b0;     \
+       veor    a1, a1, a4;     veor    b1, b1, b4;     vmvn    a2, a2;         vmvn    b2, b2;         \
+       vorr    a2, a2, a0;     vorr    b2, b2, b0;\
+       veor    a4, a2;         veor    b4, b2;
+
+#define SBOX7_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       vmov    a4, a2;         vmov    b4, b2;         veor    a2, a2, a0;     veor    b2, b2, b0;     \
+       vand    a0, a0, a3;     vand    b0, b0, b3;     vorr    a4, a4, a3;     vorr    b4, b4, b3;     \
+       vmvn    a2, a2;         vmvn    b2, b2;         veor    a3, a3, a1;     veor    b3, b3, b1;     \
+       vorr    a1, a1, a0;     vorr    b1, b1, b0;     veor    a0, a0, a2;     veor    b0, b0, b2;     \
+       vand    a2, a2, a4;     vand    b2, b2, b4;     vand    a3, a3, a4;     vand    b3, b3, b4;     \
+       veor    a1, a1, a2;     veor    b1, b1, b2;     veor    a2, a2, a0;     veor    b2, b2, b0;     \
+       vorr    a0, a0, a2;     vorr    b0, b0, b2;     veor    a4, a4, a1;     veor    b4, b4, b1;     \
+       veor    a0, a0, a3;     veor    b0, b0, b3;     veor    a3, a3, a4;     veor    b3, b3, b4;     \
+       vorr    a4, a4, a0;     vorr    b4, b4, b0;     veor    a3, a3, a2;     veor    b3, b3, b2;     \
+       veor    a4, a2;         veor    b4, b2;
+
+/* Apply SBOX number WHICH to to the block.  */
+#define SBOX(which, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       SBOX##which (a0, a1, a2, a3, a4, b0, b1, b2, b3, b4)
+
+/* Apply inverse SBOX number WHICH to to the block.  */
+#define SBOX_INVERSE(which, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       SBOX##which##_INVERSE (a0, a1, a2, a3, a4, b0, b1, b2, b3, b4)
+
+/* XOR round key into block state in a0,a1,a2,a3. a4 used as temporary.  */
+#define BLOCK_XOR_KEY(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       vdup.32 RT3, RT0d0[0]; \
+       vdup.32 RT1, RT0d0[1]; \
+       vdup.32 RT2, RT0d1[0]; \
+       vdup.32 RT0, RT0d1[1]; \
+       veor a0, a0, RT3;       veor b0, b0, RT3; \
+       veor a1, a1, RT1;       veor b1, b1, RT1; \
+       veor a2, a2, RT2;       veor b2, b2, RT2; \
+       veor a3, a3, RT0;       veor b3, b3, RT0;
+
+#define BLOCK_LOAD_KEY_ENC() \
+       vld1.8 {RT0d0, RT0d1}, [RROUND]!;
+
+#define BLOCK_LOAD_KEY_DEC() \
+       vld1.8 {RT0d0, RT0d1}, [RROUND]; \
+       sub RROUND, RROUND, #16
+
+/* Apply the linear transformation to BLOCK.  */
+#define LINEAR_TRANSFORMATION(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       vshl.u32        a4, a0, #13;            vshl.u32        b4, b0, #13;            \
+       vshr.u32        a0, a0, #(32-13);       vshr.u32        b0, b0, #(32-13);       \
+       veor            a0, a0, a4;             veor            b0, b0, b4;             \
+       vshl.u32        a4, a2, #3;             vshl.u32        b4, b2, #3;             \
+       vshr.u32        a2, a2, #(32-3);        vshr.u32        b2, b2, #(32-3);        \
+       veor            a2, a2, a4;             veor            b2, b2, b4;             \
+       veor            a1, a0, a1;             veor            b1, b0, b1;             \
+       veor            a1, a2, a1;             veor            b1, b2, b1;             \
+       vshl.u32        a4, a0, #3;             vshl.u32        b4, b0, #3;             \
+       veor            a3, a2, a3;             veor            b3, b2, b3;             \
+       veor            a3, a4, a3;             veor            b3, b4, b3;             \
+       vshl.u32        a4, a1, #1;             vshl.u32        b4, b1, #1;             \
+       vshr.u32        a1, a1, #(32-1);        vshr.u32        b1, b1, #(32-1);        \
+       veor            a1, a1, a4;             veor            b1, b1, b4;             \
+       vshl.u32        a4, a3, #7;             vshl.u32        b4, b3, #7;             \
+       vshr.u32        a3, a3, #(32-7);        vshr.u32        b3, b3, #(32-7);        \
+       veor            a3, a3, a4;             veor            b3, b3, b4;             \
+       veor            a0, a1, a0;             veor            b0, b1, b0;             \
+       veor            a0, a3, a0;             veor            b0, b3, b0;             \
+       vshl.u32        a4, a1, #7;             vshl.u32        b4, b1, #7;             \
+       veor            a2, a3, a2;             veor            b2, b3, b2;             \
+       veor            a2, a4, a2;             veor            b2, b4, b2;             \
+       vshl.u32        a4, a0, #5;             vshl.u32        b4, b0, #5;             \
+       vshr.u32        a0, a0, #(32-5);        vshr.u32        b0, b0, #(32-5);        \
+       veor            a0, a0, a4;             veor            b0, b0, b4;             \
+       vshl.u32        a4, a2, #22;            vshl.u32        b4, b2, #22;            \
+       vshr.u32        a2, a2, #(32-22);       vshr.u32        b2, b2, #(32-22);       \
+       veor            a2, a2, a4;             veor            b2, b2, b4;
+
+/* Apply the inverse linear transformation to BLOCK.  */
+#define LINEAR_TRANSFORMATION_INVERSE(a0, a1, a2, a3, a4, b0, b1, b2, b3, b4) \
+       vshr.u32        a4, a2, #22;            vshr.u32        b4, b2, #22;            \
+       vshl.u32        a2, a2, #(32-22);       vshl.u32        b2, b2, #(32-22);       \
+       veor            a2, a2, a4;             veor            b2, b2, b4;             \
+       vshr.u32        a4, a0, #5;             vshr.u32        b4, b0, #5;             \
+       vshl.u32        a0, a0, #(32-5);        vshl.u32        b0, b0, #(32-5);        \
+       veor            a0, a0, a4;             veor            b0, b0, b4;             \
+       vshl.u32        a4, a1, #7;             vshl.u32        b4, b1, #7;             \
+       veor            a2, a3, a2;             veor            b2, b3, b2;             \
+       veor            a2, a4, a2;             veor            b2, b4, b2;             \
+       veor            a0, a1, a0;             veor            b0, b1, b0;             \
+       veor            a0, a3, a0;             veor            b0, b3, b0;             \
+       vshr.u32        a4, a3, #7;             vshr.u32        b4, b3, #7;             \
+       vshl.u32        a3, a3, #(32-7);        vshl.u32        b3, b3, #(32-7);        \
+       veor            a3, a3, a4;             veor            b3, b3, b4;             \
+       vshr.u32        a4, a1, #1;             vshr.u32        b4, b1, #1;             \
+       vshl.u32        a1, a1, #(32-1);        vshl.u32        b1, b1, #(32-1);        \
+       veor            a1, a1, a4;             veor            b1, b1, b4;             \
+       vshl.u32        a4, a0, #3;             vshl.u32        b4, b0, #3;             \
+       veor            a3, a2, a3;             veor            b3, b2, b3;             \
+       veor            a3, a4, a3;             veor            b3, b4, b3;             \
+       veor            a1, a0, a1;             veor            b1, b0, b1;             \
+       veor            a1, a2, a1;             veor            b1, b2, b1;             \
+       vshr.u32        a4, a2, #3;             vshr.u32        b4, b2, #3;             \
+       vshl.u32        a2, a2, #(32-3);        vshl.u32        b2, b2, #(32-3);        \
+       veor            a2, a2, a4;             veor            b2, b2, b4;             \
+       vshr.u32        a4, a0, #13;            vshr.u32        b4, b0, #13;            \
+       vshl.u32        a0, a0, #(32-13);       vshl.u32        b0, b0, #(32-13);       \
+       veor            a0, a0, a4;             veor            b0, b0, b4;
+
+/* Apply a Serpent round to eight parallel blocks.  This macro increments
+   `round'.  */
+#define ROUND(round, which, a0, a1, a2, a3, a4, na0, na1, na2, na3, na4, \
+                           b0, b1, b2, b3, b4, nb0, nb1, nb2, nb3, nb4) \
+       BLOCK_XOR_KEY (a0, a1, a2, a3, a4, b0, b1, b2, b3, b4);         \
+       BLOCK_LOAD_KEY_ENC ();                                          \
+       SBOX (which, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4);           \
+       LINEAR_TRANSFORMATION (na0, na1, na2, na3, na4, nb0, nb1, nb2, nb3, nb4);
+
+/* Apply the last Serpent round to eight parallel blocks.  This macro increments
+   `round'.  */
+#define ROUND_LAST(round, which, a0, a1, a2, a3, a4, na0, na1, na2, na3, na4, \
+                                b0, b1, b2, b3, b4, nb0, nb1, nb2, nb3, nb4) \
+       BLOCK_XOR_KEY (a0, a1, a2, a3, a4, b0, b1, b2, b3, b4);         \
+       BLOCK_LOAD_KEY_ENC ();                                          \
+       SBOX (which, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4);           \
+       BLOCK_XOR_KEY (na0, na1, na2, na3, na4, nb0, nb1, nb2, nb3, nb4);
+
+/* Apply an inverse Serpent round to eight parallel blocks.  This macro
+   increments `round'.  */
+#define ROUND_INVERSE(round, which, a0, a1, a2, a3, a4, \
+                                   na0, na1, na2, na3, na4, \
+                                   b0, b1, b2, b3, b4, \
+                                   nb0, nb1, nb2, nb3, nb4) \
+       LINEAR_TRANSFORMATION_INVERSE (a0, a1, a2, a3, a4, b0, b1, b2, b3, b4); \
+       SBOX_INVERSE (which, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4);           \
+       BLOCK_XOR_KEY (na0, na1, na2, na3, na4, nb0, nb1, nb2, nb3, nb4);       \
+       BLOCK_LOAD_KEY_DEC ();
+
+/* Apply the first inverse Serpent round to eight parallel blocks.  This macro
+   increments `round'.  */
+#define ROUND_FIRST_INVERSE(round, which, a0, a1, a2, a3, a4, \
+                                         na0, na1, na2, na3, na4, \
+                                         b0, b1, b2, b3, b4, \
+                                         nb0, nb1, nb2, nb3, nb4) \
+       BLOCK_XOR_KEY (a0, a1, a2, a3, a4, b0, b1, b2, b3, b4);                 \
+       BLOCK_LOAD_KEY_DEC ();                                                  \
+       SBOX_INVERSE (which, a0, a1, a2, a3, a4, b0, b1, b2, b3, b4);           \
+       BLOCK_XOR_KEY (na0, na1, na2, na3, na4, nb0, nb1, nb2, nb3, nb4);       \
+       BLOCK_LOAD_KEY_DEC ();
+
+.align 3
+.type __serpent_enc_blk8,%function;
+__serpent_enc_blk8:
+       /* input:
+        *      r0: round key pointer
+        *      RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel plaintext
+        *                                              blocks
+        * output:
+        *      RA4, RA1, RA2, RA0, RB4, RB1, RB2, RB0: eight parallel
+        *                                              ciphertext blocks
+        */
+
+       transpose_4x4(RA0, RA1, RA2, RA3);
+       BLOCK_LOAD_KEY_ENC ();
+       transpose_4x4(RB0, RB1, RB2, RB3);
+
+       ROUND (0, 0, RA0, RA1, RA2, RA3, RA4, RA1, RA4, RA2, RA0, RA3,
+                    RB0, RB1, RB2, RB3, RB4, RB1, RB4, RB2, RB0, RB3);
+       ROUND (1, 1, RA1, RA4, RA2, RA0, RA3, RA2, RA1, RA0, RA4, RA3,
+                    RB1, RB4, RB2, RB0, RB3, RB2, RB1, RB0, RB4, RB3);
+       ROUND (2, 2, RA2, RA1, RA0, RA4, RA3, RA0, RA4, RA1, RA3, RA2,
+                    RB2, RB1, RB0, RB4, RB3, RB0, RB4, RB1, RB3, RB2);
+       ROUND (3, 3, RA0, RA4, RA1, RA3, RA2, RA4, RA1, RA3, RA2, RA0,
+                    RB0, RB4, RB1, RB3, RB2, RB4, RB1, RB3, RB2, RB0);
+       ROUND (4, 4, RA4, RA1, RA3, RA2, RA0, RA1, RA0, RA4, RA2, RA3,
+                    RB4, RB1, RB3, RB2, RB0, RB1, RB0, RB4, RB2, RB3);
+       ROUND (5, 5, RA1, RA0, RA4, RA2, RA3, RA0, RA2, RA1, RA4, RA3,
+                    RB1, RB0, RB4, RB2, RB3, RB0, RB2, RB1, RB4, RB3);
+       ROUND (6, 6, RA0, RA2, RA1, RA4, RA3, RA0, RA2, RA3, RA1, RA4,
+                    RB0, RB2, RB1, RB4, RB3, RB0, RB2, RB3, RB1, RB4);
+       ROUND (7, 7, RA0, RA2, RA3, RA1, RA4, RA4, RA1, RA2, RA0, RA3,
+                    RB0, RB2, RB3, RB1, RB4, RB4, RB1, RB2, RB0, RB3);
+       ROUND (8, 0, RA4, RA1, RA2, RA0, RA3, RA1, RA3, RA2, RA4, RA0,
+                    RB4, RB1, RB2, RB0, RB3, RB1, RB3, RB2, RB4, RB0);
+       ROUND (9, 1, RA1, RA3, RA2, RA4, RA0, RA2, RA1, RA4, RA3, RA0,
+                    RB1, RB3, RB2, RB4, RB0, RB2, RB1, RB4, RB3, RB0);
+       ROUND (10, 2, RA2, RA1, RA4, RA3, RA0, RA4, RA3, RA1, RA0, RA2,
+                     RB2, RB1, RB4, RB3, RB0, RB4, RB3, RB1, RB0, RB2);
+       ROUND (11, 3, RA4, RA3, RA1, RA0, RA2, RA3, RA1, RA0, RA2, RA4,
+                     RB4, RB3, RB1, RB0, RB2, RB3, RB1, RB0, RB2, RB4);
+       ROUND (12, 4, RA3, RA1, RA0, RA2, RA4, RA1, RA4, RA3, RA2, RA0,
+                     RB3, RB1, RB0, RB2, RB4, RB1, RB4, RB3, RB2, RB0);
+       ROUND (13, 5, RA1, RA4, RA3, RA2, RA0, RA4, RA2, RA1, RA3, RA0,
+                     RB1, RB4, RB3, RB2, RB0, RB4, RB2, RB1, RB3, RB0);
+       ROUND (14, 6, RA4, RA2, RA1, RA3, RA0, RA4, RA2, RA0, RA1, RA3,
+                     RB4, RB2, RB1, RB3, RB0, RB4, RB2, RB0, RB1, RB3);
+       ROUND (15, 7, RA4, RA2, RA0, RA1, RA3, RA3, RA1, RA2, RA4, RA0,
+                     RB4, RB2, RB0, RB1, RB3, RB3, RB1, RB2, RB4, RB0);
+       ROUND (16, 0, RA3, RA1, RA2, RA4, RA0, RA1, RA0, RA2, RA3, RA4,
+                     RB3, RB1, RB2, RB4, RB0, RB1, RB0, RB2, RB3, RB4);
+       ROUND (17, 1, RA1, RA0, RA2, RA3, RA4, RA2, RA1, RA3, RA0, RA4,
+                     RB1, RB0, RB2, RB3, RB4, RB2, RB1, RB3, RB0, RB4);
+       ROUND (18, 2, RA2, RA1, RA3, RA0, RA4, RA3, RA0, RA1, RA4, RA2,
+                     RB2, RB1, RB3, RB0, RB4, RB3, RB0, RB1, RB4, RB2);
+       ROUND (19, 3, RA3, RA0, RA1, RA4, RA2, RA0, RA1, RA4, RA2, RA3,
+                     RB3, RB0, RB1, RB4, RB2, RB0, RB1, RB4, RB2, RB3);
+       ROUND (20, 4, RA0, RA1, RA4, RA2, RA3, RA1, RA3, RA0, RA2, RA4,
+                     RB0, RB1, RB4, RB2, RB3, RB1, RB3, RB0, RB2, RB4);
+       ROUND (21, 5, RA1, RA3, RA0, RA2, RA4, RA3, RA2, RA1, RA0, RA4,
+                     RB1, RB3, RB0, RB2, RB4, RB3, RB2, RB1, RB0, RB4);
+       ROUND (22, 6, RA3, RA2, RA1, RA0, RA4, RA3, RA2, RA4, RA1, RA0,
+                     RB3, RB2, RB1, RB0, RB4, RB3, RB2, RB4, RB1, RB0);
+       ROUND (23, 7, RA3, RA2, RA4, RA1, RA0, RA0, RA1, RA2, RA3, RA4,
+                     RB3, RB2, RB4, RB1, RB0, RB0, RB1, RB2, RB3, RB4);
+       ROUND (24, 0, RA0, RA1, RA2, RA3, RA4, RA1, RA4, RA2, RA0, RA3,
+                     RB0, RB1, RB2, RB3, RB4, RB1, RB4, RB2, RB0, RB3);
+       ROUND (25, 1, RA1, RA4, RA2, RA0, RA3, RA2, RA1, RA0, RA4, RA3,
+                     RB1, RB4, RB2, RB0, RB3, RB2, RB1, RB0, RB4, RB3);
+       ROUND (26, 2, RA2, RA1, RA0, RA4, RA3, RA0, RA4, RA1, RA3, RA2,
+                     RB2, RB1, RB0, RB4, RB3, RB0, RB4, RB1, RB3, RB2);
+       ROUND (27, 3, RA0, RA4, RA1, RA3, RA2, RA4, RA1, RA3, RA2, RA0,
+                     RB0, RB4, RB1, RB3, RB2, RB4, RB1, RB3, RB2, RB0);
+       ROUND (28, 4, RA4, RA1, RA3, RA2, RA0, RA1, RA0, RA4, RA2, RA3,
+                     RB4, RB1, RB3, RB2, RB0, RB1, RB0, RB4, RB2, RB3);
+       ROUND (29, 5, RA1, RA0, RA4, RA2, RA3, RA0, RA2, RA1, RA4, RA3,
+                     RB1, RB0, RB4, RB2, RB3, RB0, RB2, RB1, RB4, RB3);
+       ROUND (30, 6, RA0, RA2, RA1, RA4, RA3, RA0, RA2, RA3, RA1, RA4,
+                     RB0, RB2, RB1, RB4, RB3, RB0, RB2, RB3, RB1, RB4);
+       ROUND_LAST (31, 7, RA0, RA2, RA3, RA1, RA4, RA4, RA1, RA2, RA0, RA3,
+                          RB0, RB2, RB3, RB1, RB4, RB4, RB1, RB2, RB0, RB3);
+
+       transpose_4x4(RA4, RA1, RA2, RA0);
+       transpose_4x4(RB4, RB1, RB2, RB0);
+
+       bx lr;
+.size __serpent_enc_blk8,.-__serpent_enc_blk8;
+
+.align 3
+.type   __serpent_dec_blk8,%function;
+__serpent_dec_blk8:
+       /* input:
+        *      r0: round key pointer
+        *      RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel
+        *                                              ciphertext blocks
+        * output:
+        *      RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel plaintext
+        *                                              blocks
+        */
+
+       add RROUND, RROUND, #(32*16);
+
+       transpose_4x4(RA0, RA1, RA2, RA3);
+       BLOCK_LOAD_KEY_DEC ();
+       transpose_4x4(RB0, RB1, RB2, RB3);
+
+       ROUND_FIRST_INVERSE (31, 7, RA0, RA1, RA2, RA3, RA4,
+                                   RA3, RA0, RA1, RA4, RA2,
+                                   RB0, RB1, RB2, RB3, RB4,
+                                   RB3, RB0, RB1, RB4, RB2);
+       ROUND_INVERSE (30, 6, RA3, RA0, RA1, RA4, RA2, RA0, RA1, RA2, RA4, RA3,
+                             RB3, RB0, RB1, RB4, RB2, RB0, RB1, RB2, RB4, RB3);
+       ROUND_INVERSE (29, 5, RA0, RA1, RA2, RA4, RA3, RA1, RA3, RA4, RA2, RA0,
+                             RB0, RB1, RB2, RB4, RB3, RB1, RB3, RB4, RB2, RB0);
+       ROUND_INVERSE (28, 4, RA1, RA3, RA4, RA2, RA0, RA1, RA2, RA4, RA0, RA3,
+                             RB1, RB3, RB4, RB2, RB0, RB1, RB2, RB4, RB0, RB3);
+       ROUND_INVERSE (27, 3, RA1, RA2, RA4, RA0, RA3, RA4, RA2, RA0, RA1, RA3,
+                             RB1, RB2, RB4, RB0, RB3, RB4, RB2, RB0, RB1, RB3);
+       ROUND_INVERSE (26, 2, RA4, RA2, RA0, RA1, RA3, RA2, RA3, RA0, RA1, RA4,
+                             RB4, RB2, RB0, RB1, RB3, RB2, RB3, RB0, RB1, RB4);
+       ROUND_INVERSE (25, 1, RA2, RA3, RA0, RA1, RA4, RA4, RA2, RA1, RA0, RA3,
+                             RB2, RB3, RB0, RB1, RB4, RB4, RB2, RB1, RB0, RB3);
+       ROUND_INVERSE (24, 0, RA4, RA2, RA1, RA0, RA3, RA4, RA3, RA2, RA0, RA1,
+                             RB4, RB2, RB1, RB0, RB3, RB4, RB3, RB2, RB0, RB1);
+       ROUND_INVERSE (23, 7, RA4, RA3, RA2, RA0, RA1, RA0, RA4, RA3, RA1, RA2,
+                             RB4, RB3, RB2, RB0, RB1, RB0, RB4, RB3, RB1, RB2);
+       ROUND_INVERSE (22, 6, RA0, RA4, RA3, RA1, RA2, RA4, RA3, RA2, RA1, RA0,
+                             RB0, RB4, RB3, RB1, RB2, RB4, RB3, RB2, RB1, RB0);
+       ROUND_INVERSE (21, 5, RA4, RA3, RA2, RA1, RA0, RA3, RA0, RA1, RA2, RA4,
+                             RB4, RB3, RB2, RB1, RB0, RB3, RB0, RB1, RB2, RB4);
+       ROUND_INVERSE (20, 4, RA3, RA0, RA1, RA2, RA4, RA3, RA2, RA1, RA4, RA0,
+                             RB3, RB0, RB1, RB2, RB4, RB3, RB2, RB1, RB4, RB0);
+       ROUND_INVERSE (19, 3, RA3, RA2, RA1, RA4, RA0, RA1, RA2, RA4, RA3, RA0,
+                             RB3, RB2, RB1, RB4, RB0, RB1, RB2, RB4, RB3, RB0);
+       ROUND_INVERSE (18, 2, RA1, RA2, RA4, RA3, RA0, RA2, RA0, RA4, RA3, RA1,
+                             RB1, RB2, RB4, RB3, RB0, RB2, RB0, RB4, RB3, RB1);
+       ROUND_INVERSE (17, 1, RA2, RA0, RA4, RA3, RA1, RA1, RA2, RA3, RA4, RA0,
+                             RB2, RB0, RB4, RB3, RB1, RB1, RB2, RB3, RB4, RB0);
+       ROUND_INVERSE (16, 0, RA1, RA2, RA3, RA4, RA0, RA1, RA0, RA2, RA4, RA3,
+                             RB1, RB2, RB3, RB4, RB0, RB1, RB0, RB2, RB4, RB3);
+       ROUND_INVERSE (15, 7, RA1, RA0, RA2, RA4, RA3, RA4, RA1, RA0, RA3, RA2,
+                             RB1, RB0, RB2, RB4, RB3, RB4, RB1, RB0, RB3, RB2);
+       ROUND_INVERSE (14, 6, RA4, RA1, RA0, RA3, RA2, RA1, RA0, RA2, RA3, RA4,
+                             RB4, RB1, RB0, RB3, RB2, RB1, RB0, RB2, RB3, RB4);
+       ROUND_INVERSE (13, 5, RA1, RA0, RA2, RA3, RA4, RA0, RA4, RA3, RA2, RA1,
+                             RB1, RB0, RB2, RB3, RB4, RB0, RB4, RB3, RB2, RB1);
+       ROUND_INVERSE (12, 4, RA0, RA4, RA3, RA2, RA1, RA0, RA2, RA3, RA1, RA4,
+                             RB0, RB4, RB3, RB2, RB1, RB0, RB2, RB3, RB1, RB4);
+       ROUND_INVERSE (11, 3, RA0, RA2, RA3, RA1, RA4, RA3, RA2, RA1, RA0, RA4,
+                             RB0, RB2, RB3, RB1, RB4, RB3, RB2, RB1, RB0, RB4);
+       ROUND_INVERSE (10, 2, RA3, RA2, RA1, RA0, RA4, RA2, RA4, RA1, RA0, RA3,
+                             RB3, RB2, RB1, RB0, RB4, RB2, RB4, RB1, RB0, RB3);
+       ROUND_INVERSE (9, 1, RA2, RA4, RA1, RA0, RA3, RA3, RA2, RA0, RA1, RA4,
+                            RB2, RB4, RB1, RB0, RB3, RB3, RB2, RB0, RB1, RB4);
+       ROUND_INVERSE (8, 0, RA3, RA2, RA0, RA1, RA4, RA3, RA4, RA2, RA1, RA0,
+                            RB3, RB2, RB0, RB1, RB4, RB3, RB4, RB2, RB1, RB0);
+       ROUND_INVERSE (7, 7, RA3, RA4, RA2, RA1, RA0, RA1, RA3, RA4, RA0, RA2,
+                            RB3, RB4, RB2, RB1, RB0, RB1, RB3, RB4, RB0, RB2);
+       ROUND_INVERSE (6, 6, RA1, RA3, RA4, RA0, RA2, RA3, RA4, RA2, RA0, RA1,
+                            RB1, RB3, RB4, RB0, RB2, RB3, RB4, RB2, RB0, RB1);
+       ROUND_INVERSE (5, 5, RA3, RA4, RA2, RA0, RA1, RA4, RA1, RA0, RA2, RA3,
+                            RB3, RB4, RB2, RB0, RB1, RB4, RB1, RB0, RB2, RB3);
+       ROUND_INVERSE (4, 4, RA4, RA1, RA0, RA2, RA3, RA4, RA2, RA0, RA3, RA1,
+                            RB4, RB1, RB0, RB2, RB3, RB4, RB2, RB0, RB3, RB1);
+       ROUND_INVERSE (3, 3, RA4, RA2, RA0, RA3, RA1, RA0, RA2, RA3, RA4, RA1,
+                            RB4, RB2, RB0, RB3, RB1, RB0, RB2, RB3, RB4, RB1);
+       ROUND_INVERSE (2, 2, RA0, RA2, RA3, RA4, RA1, RA2, RA1, RA3, RA4, RA0,
+                            RB0, RB2, RB3, RB4, RB1, RB2, RB1, RB3, RB4, RB0);
+       ROUND_INVERSE (1, 1, RA2, RA1, RA3, RA4, RA0, RA0, RA2, RA4, RA3, RA1,
+                            RB2, RB1, RB3, RB4, RB0, RB0, RB2, RB4, RB3, RB1);
+       ROUND_INVERSE (0, 0, RA0, RA2, RA4, RA3, RA1, RA0, RA1, RA2, RA3, RA4,
+                            RB0, RB2, RB4, RB3, RB1, RB0, RB1, RB2, RB3, RB4);
+
+       transpose_4x4(RA0, RA1, RA2, RA3);
+       transpose_4x4(RB0, RB1, RB2, RB3);
+
+       bx lr;
+.size __serpent_dec_blk8,.-__serpent_dec_blk8;
+
+.align 3
+.globl _gcry_serpent_neon_ctr_enc
+.type _gcry_serpent_neon_ctr_enc,%function;
+_gcry_serpent_neon_ctr_enc:
+       /* input:
+        *      r0: ctx, CTX
+        *      r1: dst (8 blocks)
+        *      r2: src (8 blocks)
+        *      r3: iv
+        */
+
+       vmov.u8 RT1d0, #0xff; /* u64: -1 */
+       push {r4,lr};
+       vadd.u64 RT2d0, RT1d0, RT1d0; /* u64: -2 */
+       vpush {RA4-RB2};
+
+       /* load IV and byteswap */
+       vld1.8 {RA0}, [r3];
+       vrev64.u8 RT0, RA0; /* be => le */
+       ldr r4, [r3, #8];
+
+       /* construct IVs */
+       vsub.u64 RA2d1, RT0d1, RT2d0; /* +2 */
+       vsub.u64 RA1d1, RT0d1, RT1d0; /* +1 */
+       cmp r4, #-1;
+
+       vsub.u64 RB0d1, RA2d1, RT2d0; /* +4 */
+       vsub.u64 RA3d1, RA2d1, RT1d0; /* +3 */
+       ldr r4, [r3, #12];
+
+       vsub.u64 RB2d1, RB0d1, RT2d0; /* +6 */
+       vsub.u64 RB1d1, RB0d1, RT1d0; /* +5 */
+
+       vsub.u64 RT2d1, RB2d1, RT2d0; /* +8 */
+       vsub.u64 RB3d1, RB2d1, RT1d0; /* +7 */
+
+       vmov RA1d0, RT0d0;
+       vmov RA2d0, RT0d0;
+       vmov RA3d0, RT0d0;
+       vmov RB0d0, RT0d0;
+       rev r4, r4;
+       vmov RB1d0, RT0d0;
+       vmov RB2d0, RT0d0;
+       vmov RB3d0, RT0d0;
+       vmov RT2d0, RT0d0;
+
+       /* check need for handling 64-bit overflow and carry */
+       beq .Ldo_ctr_carry;
+
+.Lctr_carry_done:
+       /* le => be */
+       vrev64.u8 RA1, RA1;
+       vrev64.u8 RA2, RA2;
+       vrev64.u8 RA3, RA3;
+       vrev64.u8 RB0, RB0;
+       vrev64.u8 RT2, RT2;
+       vrev64.u8 RB1, RB1;
+       vrev64.u8 RB2, RB2;
+       vrev64.u8 RB3, RB3;
+       /* store new IV */
+       vst1.8 {RT2}, [r3];
+
+       bl __serpent_enc_blk8;
+
+       vld1.8 {RT0, RT1}, [r2]!;
+       vld1.8 {RT2, RT3}, [r2]!;
+       veor RA4, RA4, RT0;
+       veor RA1, RA1, RT1;
+       vld1.8 {RT0, RT1}, [r2]!;
+       veor RA2, RA2, RT2;
+       veor RA0, RA0, RT3;
+       vld1.8 {RT2, RT3}, [r2]!;
+       veor RB4, RB4, RT0;
+       veor RT0, RT0;
+       veor RB1, RB1, RT1;
+       veor RT1, RT1;
+       veor RB2, RB2, RT2;
+       veor RT2, RT2;
+       veor RB0, RB0, RT3;
+       veor RT3, RT3;
+
+       vst1.8 {RA4}, [r1]!;
+       vst1.8 {RA1}, [r1]!;
+       veor RA1, RA1;
+       vst1.8 {RA2}, [r1]!;
+       veor RA2, RA2;
+       vst1.8 {RA0}, [r1]!;
+       veor RA0, RA0;
+       vst1.8 {RB4}, [r1]!;
+       veor RB4, RB4;
+       vst1.8 {RB1}, [r1]!;
+       vst1.8 {RB2}, [r1]!;
+       vst1.8 {RB0}, [r1]!;
+
+       vpop {RA4-RB2};
+
+       /* clear the used registers */
+       veor RA3, RA3;
+       veor RB3, RB3;
+
+       pop {r4,pc};
+
+.Ldo_ctr_carry:
+       cmp r4, #-8;
+       blo .Lctr_carry_done;
+       beq .Lcarry_RT2;
+
+       cmp r4, #-6;
+       blo .Lcarry_RB3;
+       beq .Lcarry_RB2;
+
+       cmp r4, #-4;
+       blo .Lcarry_RB1;
+       beq .Lcarry_RB0;
+
+       cmp r4, #-2;
+       blo .Lcarry_RA3;
+       beq .Lcarry_RA2;
+
+       vsub.u64 RA1d0, RT1d0;
+.Lcarry_RA2:
+       vsub.u64 RA2d0, RT1d0;
+.Lcarry_RA3:
+       vsub.u64 RA3d0, RT1d0;
+.Lcarry_RB0:
+       vsub.u64 RB0d0, RT1d0;
+.Lcarry_RB1:
+       vsub.u64 RB1d0, RT1d0;
+.Lcarry_RB2:
+       vsub.u64 RB2d0, RT1d0;
+.Lcarry_RB3:
+       vsub.u64 RB3d0, RT1d0;
+.Lcarry_RT2:
+       vsub.u64 RT2d0, RT1d0;
+
+       b .Lctr_carry_done;
+.size _gcry_serpent_neon_ctr_enc,.-_gcry_serpent_neon_ctr_enc;
+
+.align 3
+.globl _gcry_serpent_neon_cfb_dec
+.type _gcry_serpent_neon_cfb_dec,%function;
+_gcry_serpent_neon_cfb_dec:
+       /* input:
+        *      r0: ctx, CTX
+        *      r1: dst (8 blocks)
+        *      r2: src (8 blocks)
+        *      r3: iv
+        */
+
+       push {lr};
+       vpush {RA4-RB2};
+
+       /* Load input */
+       vld1.8 {RA0}, [r3];
+       vld1.8 {RA1, RA2}, [r2]!;
+       vld1.8 {RA3}, [r2]!;
+       vld1.8 {RB0}, [r2]!;
+       vld1.8 {RB1, RB2}, [r2]!;
+       vld1.8 {RB3}, [r2]!;
+
+       /* Update IV */
+       vld1.8 {RT0}, [r2]!;
+       vst1.8 {RT0}, [r3];
+       mov r3, lr;
+       sub r2, r2, #(8*16);
+
+       bl __serpent_enc_blk8;
+
+       vld1.8 {RT0, RT1}, [r2]!;
+       vld1.8 {RT2, RT3}, [r2]!;
+       veor RA4, RA4, RT0;
+       veor RA1, RA1, RT1;
+       vld1.8 {RT0, RT1}, [r2]!;
+       veor RA2, RA2, RT2;
+       veor RA0, RA0, RT3;
+       vld1.8 {RT2, RT3}, [r2]!;
+       veor RB4, RB4, RT0;
+       veor RT0, RT0;
+       veor RB1, RB1, RT1;
+       veor RT1, RT1;
+       veor RB2, RB2, RT2;
+       veor RT2, RT2;
+       veor RB0, RB0, RT3;
+       veor RT3, RT3;
+
+       vst1.8 {RA4}, [r1]!;
+       vst1.8 {RA1}, [r1]!;
+       veor RA1, RA1;
+       vst1.8 {RA2}, [r1]!;
+       veor RA2, RA2;
+       vst1.8 {RA0}, [r1]!;
+       veor RA0, RA0;
+       vst1.8 {RB4}, [r1]!;
+       veor RB4, RB4;
+       vst1.8 {RB1}, [r1]!;
+       vst1.8 {RB2}, [r1]!;
+       vst1.8 {RB0}, [r1]!;
+
+       vpop {RA4-RB2};
+
+       /* clear the used registers */
+       veor RA3, RA3;
+       veor RB3, RB3;
+
+       pop {pc};
+.size _gcry_serpent_neon_cfb_dec,.-_gcry_serpent_neon_cfb_dec;
+
+.align 3
+.globl _gcry_serpent_neon_cbc_dec
+.type _gcry_serpent_neon_cbc_dec,%function;
+_gcry_serpent_neon_cbc_dec:
+       /* input:
+        *      r0: ctx, CTX
+        *      r1: dst (8 blocks)
+        *      r2: src (8 blocks)
+        *      r3: iv
+        */
+
+       push {lr};
+       vpush {RA4-RB2};
+
+       vld1.8 {RA0, RA1}, [r2]!;
+       vld1.8 {RA2, RA3}, [r2]!;
+       vld1.8 {RB0, RB1}, [r2]!;
+       vld1.8 {RB2, RB3}, [r2]!;
+       sub r2, r2, #(8*16);
+
+       bl __serpent_dec_blk8;
+
+       vld1.8 {RB4}, [r3];
+       vld1.8 {RT0, RT1}, [r2]!;
+       vld1.8 {RT2, RT3}, [r2]!;
+       veor RA0, RA0, RB4;
+       veor RA1, RA1, RT0;
+       veor RA2, RA2, RT1;
+       vld1.8 {RT0, RT1}, [r2]!;
+       veor RA3, RA3, RT2;
+       veor RB0, RB0, RT3;
+       vld1.8 {RT2, RT3}, [r2]!;
+       veor RB1, RB1, RT0;
+       veor RT0, RT0;
+       veor RB2, RB2, RT1;
+       veor RT1, RT1;
+       veor RB3, RB3, RT2;
+       veor RT2, RT2;
+       vst1.8 {RT3}, [r3]; /* store new IV */
+       veor RT3, RT3;
+
+       vst1.8 {RA0, RA1}, [r1]!;
+       veor RA0, RA0;
+       veor RA1, RA1;
+       vst1.8 {RA2, RA3}, [r1]!;
+       veor RA2, RA2;
+       vst1.8 {RB0, RB1}, [r1]!;
+       veor RA3, RA3;
+       vst1.8 {RB2, RB3}, [r1]!;
+       veor RB3, RB3;
+
+       vpop {RA4-RB2};
+
+       /* clear the used registers */
+       veor RB4, RB4;
+
+       pop {pc};
+.size _gcry_serpent_neon_cbc_dec,.-_gcry_serpent_neon_cbc_dec;
+
+#endif
diff --git a/cipher/serpent-avx2-amd64.S b/cipher/serpent-avx2-amd64.S
new file mode 100644 (file)
index 0000000..3177574
--- /dev/null
@@ -0,0 +1,812 @@
+/* serpent-avx2-amd64.S  -  AVX2 implementation of Serpent cipher
+ *
+ * Copyright © 2013 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(USE_SERPENT) && \
+    defined(ENABLE_AVX2_SUPPORT)
+
+#ifdef __PIC__
+#  define RIP (%rip)
+#else
+#  define RIP
+#endif
+
+/* struct serpent_context: */
+#define ctx_keys 0
+
+/* register macros */
+#define CTX %rdi
+
+/* vector registers */
+#define RA0 %ymm0
+#define RA1 %ymm1
+#define RA2 %ymm2
+#define RA3 %ymm3
+#define RA4 %ymm4
+
+#define RB0 %ymm5
+#define RB1 %ymm6
+#define RB2 %ymm7
+#define RB3 %ymm8
+#define RB4 %ymm9
+
+#define RNOT %ymm10
+#define RTMP0 %ymm11
+#define RTMP1 %ymm12
+#define RTMP2 %ymm13
+#define RTMP3 %ymm14
+#define RTMP4 %ymm15
+
+#define RNOTx %xmm10
+#define RTMP0x %xmm11
+#define RTMP1x %xmm12
+#define RTMP2x %xmm13
+#define RTMP3x %xmm14
+#define RTMP4x %xmm15
+
+/**********************************************************************
+  helper macros
+ **********************************************************************/
+
+/* vector 32-bit rotation to left */
+#define vec_rol(reg, nleft, tmp) \
+       vpslld $(nleft), reg, tmp;              \
+       vpsrld $(32 - (nleft)), reg, reg;       \
+       vpor tmp, reg, reg;
+
+/* vector 32-bit rotation to right */
+#define vec_ror(reg, nright, tmp) \
+       vec_rol(reg, 32 - nright, tmp)
+
+/* 4x4 32-bit integer matrix transpose */
+#define transpose_4x4(x0, x1, x2, x3, t1, t2, t3) \
+       vpunpckhdq x1, x0, t2; \
+       vpunpckldq x1, x0, x0; \
+       \
+       vpunpckldq x3, x2, t1; \
+       vpunpckhdq x3, x2, x2; \
+       \
+       vpunpckhqdq t1, x0, x1; \
+       vpunpcklqdq t1, x0, x0; \
+       \
+       vpunpckhqdq x2, t2, x3; \
+       vpunpcklqdq x2, t2, x2;
+
+/**********************************************************************
+  16-way serpent
+ **********************************************************************/
+
+/*
+ * These are the S-Boxes of Serpent from following research paper.
+ *
+ *  D. A. Osvik, “Speeding up Serpent,” in Third AES Candidate Conference,
+ *   (New York, New York, USA), p. 317–329, National Institute of Standards and
+ *   Technology, 2000.
+ *
+ * Paper is also available at: http://www.ii.uib.no/~osvik/pub/aes3.pdf
+ *
+ */
+#define SBOX0(r0, r1, r2, r3, r4) \
+       vpxor   r0, r3, r3;             vmovdqa r1, r4;                 \
+       vpand   r3, r1, r1;             vpxor   r2, r4, r4;             \
+       vpxor   r0, r1, r1;             vpor    r3, r0, r0;             \
+       vpxor   r4, r0, r0;             vpxor   r3, r4, r4;             \
+       vpxor   r2, r3, r3;             vpor    r1, r2, r2;             \
+       vpxor   r4, r2, r2;             vpxor   RNOT, r4, r4;           \
+       vpor    r1, r4, r4;             vpxor   r3, r1, r1;             \
+       vpxor   r4, r1, r1;             vpor    r0, r3, r3;             \
+       vpxor   r3, r1, r1;             vpxor   r3, r4, r4;
+
+#define SBOX0_INVERSE(r0, r1, r2, r3, r4) \
+       vpxor   RNOT, r2, r2;           vmovdqa r1, r4;                 \
+       vpor    r0, r1, r1;             vpxor   RNOT, r4, r4;           \
+       vpxor   r2, r1, r1;             vpor    r4, r2, r2;             \
+       vpxor   r3, r1, r1;             vpxor   r4, r0, r0;             \
+       vpxor   r0, r2, r2;             vpand   r3, r0, r0;             \
+       vpxor   r0, r4, r4;             vpor    r1, r0, r0;             \
+       vpxor   r2, r0, r0;             vpxor   r4, r3, r3;             \
+       vpxor   r1, r2, r2;             vpxor   r0, r3, r3;             \
+       vpxor   r1, r3, r3;     \
+       vpand   r3, r2, r2;     \
+       vpxor   r2, r4, r4;
+
+#define SBOX1(r0, r1, r2, r3, r4) \
+       vpxor   RNOT, r0, r0;           vpxor   RNOT, r2, r2;           \
+       vmovdqa r0, r4;                 vpand   r1, r0, r0;             \
+       vpxor   r0, r2, r2;             vpor    r3, r0, r0;             \
+       vpxor   r2, r3, r3;             vpxor   r0, r1, r1;             \
+       vpxor   r4, r0, r0;             vpor    r1, r4, r4;             \
+       vpxor   r3, r1, r1;             vpor    r0, r2, r2;             \
+       vpand   r4, r2, r2;             vpxor   r1, r0, r0;             \
+       vpand   r2, r1, r1;     \
+       vpxor   r0, r1, r1;             vpand   r2, r0, r0;             \
+       vpxor   r4, r0, r0;
+
+#define SBOX1_INVERSE(r0, r1, r2, r3, r4) \
+       vmovdqa r1, r4;                 vpxor   r3, r1, r1;             \
+       vpand   r1, r3, r3;             vpxor   r2, r4, r4;             \
+       vpxor   r0, r3, r3;             vpor    r1, r0, r0;             \
+       vpxor   r3, r2, r2;             vpxor   r4, r0, r0;             \
+       vpor    r2, r0, r0;             vpxor   r3, r1, r1;             \
+       vpxor   r1, r0, r0;             vpor    r3, r1, r1;             \
+       vpxor   r0, r1, r1;             vpxor   RNOT, r4, r4;           \
+       vpxor   r1, r4, r4;             vpor    r0, r1, r1;             \
+       vpxor   r0, r1, r1;     \
+       vpor    r4, r1, r1;     \
+       vpxor   r1, r3, r3;
+
+#define SBOX2(r0, r1, r2, r3, r4) \
+       vmovdqa r0, r4;                 vpand   r2, r0, r0;             \
+       vpxor   r3, r0, r0;             vpxor   r1, r2, r2;             \
+       vpxor   r0, r2, r2;             vpor    r4, r3, r3;             \
+       vpxor   r1, r3, r3;             vpxor   r2, r4, r4;             \
+       vmovdqa r3, r1;                 vpor    r4, r3, r3;             \
+       vpxor   r0, r3, r3;             vpand   r1, r0, r0;             \
+       vpxor   r0, r4, r4;             vpxor   r3, r1, r1;             \
+       vpxor   r4, r1, r1;             vpxor   RNOT, r4, r4;
+
+#define SBOX2_INVERSE(r0, r1, r2, r3, r4) \
+       vpxor   r3, r2, r2;             vpxor   r0, r3, r3;             \
+       vmovdqa r3, r4;                 vpand   r2, r3, r3;             \
+       vpxor   r1, r3, r3;             vpor    r2, r1, r1;             \
+       vpxor   r4, r1, r1;             vpand   r3, r4, r4;             \
+       vpxor   r3, r2, r2;             vpand   r0, r4, r4;             \
+       vpxor   r2, r4, r4;             vpand   r1, r2, r2;             \
+       vpor    r0, r2, r2;             vpxor   RNOT, r3, r3;           \
+       vpxor   r3, r2, r2;             vpxor   r3, r0, r0;             \
+       vpand   r1, r0, r0;             vpxor   r4, r3, r3;             \
+       vpxor   r0, r3, r3;
+
+#define SBOX3(r0, r1, r2, r3, r4) \
+       vmovdqa r0, r4;                 vpor    r3, r0, r0;             \
+       vpxor   r1, r3, r3;             vpand   r4, r1, r1;             \
+       vpxor   r2, r4, r4;             vpxor   r3, r2, r2;             \
+       vpand   r0, r3, r3;             vpor    r1, r4, r4;             \
+       vpxor   r4, r3, r3;             vpxor   r1, r0, r0;             \
+       vpand   r0, r4, r4;             vpxor   r3, r1, r1;             \
+       vpxor   r2, r4, r4;             vpor    r0, r1, r1;             \
+       vpxor   r2, r1, r1;             vpxor   r3, r0, r0;             \
+       vmovdqa r1, r2;                 vpor    r3, r1, r1;             \
+       vpxor   r0, r1, r1;
+
+#define SBOX3_INVERSE(r0, r1, r2, r3, r4) \
+       vmovdqa r2, r4;                 vpxor   r1, r2, r2;             \
+       vpxor   r2, r0, r0;             vpand   r2, r4, r4;             \
+       vpxor   r0, r4, r4;             vpand   r1, r0, r0;             \
+       vpxor   r3, r1, r1;             vpor    r4, r3, r3;             \
+       vpxor   r3, r2, r2;             vpxor   r3, r0, r0;             \
+       vpxor   r4, r1, r1;             vpand   r2, r3, r3;             \
+       vpxor   r1, r3, r3;             vpxor   r0, r1, r1;             \
+       vpor    r2, r1, r1;             vpxor   r3, r0, r0;             \
+       vpxor   r4, r1, r1;     \
+       vpxor   r1, r0, r0;
+
+#define SBOX4(r0, r1, r2, r3, r4) \
+       vpxor   r3, r1, r1;             vpxor   RNOT, r3, r3;           \
+       vpxor   r3, r2, r2;             vpxor   r0, r3, r3;             \
+       vmovdqa r1, r4;                 vpand   r3, r1, r1;             \
+       vpxor   r2, r1, r1;             vpxor   r3, r4, r4;             \
+       vpxor   r4, r0, r0;             vpand   r4, r2, r2;             \
+       vpxor   r0, r2, r2;             vpand   r1, r0, r0;             \
+       vpxor   r0, r3, r3;             vpor    r1, r4, r4;             \
+       vpxor   r0, r4, r4;             vpor    r3, r0, r0;             \
+       vpxor   r2, r0, r0;             vpand   r3, r2, r2;             \
+       vpxor   RNOT, r0, r0;           vpxor   r2, r4, r4;
+
+#define SBOX4_INVERSE(r0, r1, r2, r3, r4) \
+       vmovdqa r2, r4;                 vpand   r3, r2, r2;             \
+       vpxor   r1, r2, r2;             vpor    r3, r1, r1;             \
+       vpand   r0, r1, r1;             vpxor   r2, r4, r4;             \
+       vpxor   r1, r4, r4;             vpand   r2, r1, r1;             \
+       vpxor   RNOT, r0, r0;           vpxor   r4, r3, r3;             \
+       vpxor   r3, r1, r1;             vpand   r0, r3, r3;             \
+       vpxor   r2, r3, r3;             vpxor   r1, r0, r0;             \
+       vpand   r0, r2, r2;             vpxor   r0, r3, r3;             \
+       vpxor   r4, r2, r2;     \
+       vpor    r3, r2, r2;             vpxor   r0, r3, r3;             \
+       vpxor   r1, r2, r2;
+
+#define SBOX5(r0, r1, r2, r3, r4) \
+       vpxor   r1, r0, r0;             vpxor   r3, r1, r1;             \
+       vpxor   RNOT, r3, r3;           vmovdqa r1, r4;                 \
+       vpand   r0, r1, r1;             vpxor   r3, r2, r2;             \
+       vpxor   r2, r1, r1;             vpor    r4, r2, r2;             \
+       vpxor   r3, r4, r4;             vpand   r1, r3, r3;             \
+       vpxor   r0, r3, r3;             vpxor   r1, r4, r4;             \
+       vpxor   r2, r4, r4;             vpxor   r0, r2, r2;             \
+       vpand   r3, r0, r0;             vpxor   RNOT, r2, r2;           \
+       vpxor   r4, r0, r0;             vpor    r3, r4, r4;             \
+       vpxor   r4, r2, r2;
+
+#define SBOX5_INVERSE(r0, r1, r2, r3, r4) \
+       vpxor   RNOT, r1, r1;           vmovdqa r3, r4;                 \
+       vpxor   r1, r2, r2;             vpor    r0, r3, r3;             \
+       vpxor   r2, r3, r3;             vpor    r1, r2, r2;             \
+       vpand   r0, r2, r2;             vpxor   r3, r4, r4;             \
+       vpxor   r4, r2, r2;             vpor    r0, r4, r4;             \
+       vpxor   r1, r4, r4;             vpand   r2, r1, r1;             \
+       vpxor   r3, r1, r1;             vpxor   r2, r4, r4;             \
+       vpand   r4, r3, r3;             vpxor   r1, r4, r4;             \
+       vpxor   r4, r3, r3;             vpxor   RNOT, r4, r4;           \
+       vpxor   r0, r3, r3;
+
+#define SBOX6(r0, r1, r2, r3, r4) \
+       vpxor   RNOT, r2, r2;           vmovdqa r3, r4;                 \
+       vpand   r0, r3, r3;             vpxor   r4, r0, r0;             \
+       vpxor   r2, r3, r3;             vpor    r4, r2, r2;             \
+       vpxor   r3, r1, r1;             vpxor   r0, r2, r2;             \
+       vpor    r1, r0, r0;             vpxor   r1, r2, r2;             \
+       vpxor   r0, r4, r4;             vpor    r3, r0, r0;             \
+       vpxor   r2, r0, r0;             vpxor   r3, r4, r4;             \
+       vpxor   r0, r4, r4;             vpxor   RNOT, r3, r3;           \
+       vpand   r4, r2, r2;     \
+       vpxor   r3, r2, r2;
+
+#define SBOX6_INVERSE(r0, r1, r2, r3, r4) \
+       vpxor   r2, r0, r0;             vmovdqa r2, r4;                 \
+       vpand   r0, r2, r2;             vpxor   r3, r4, r4;             \
+       vpxor   RNOT, r2, r2;           vpxor   r1, r3, r3;             \
+       vpxor   r3, r2, r2;             vpor    r0, r4, r4;             \
+       vpxor   r2, r0, r0;             vpxor   r4, r3, r3;             \
+       vpxor   r1, r4, r4;             vpand   r3, r1, r1;             \
+       vpxor   r0, r1, r1;             vpxor   r3, r0, r0;             \
+       vpor    r2, r0, r0;             vpxor   r1, r3, r3;             \
+       vpxor   r0, r4, r4;
+
+#define SBOX7(r0, r1, r2, r3, r4) \
+       vmovdqa r1, r4;                 vpor    r2, r1, r1;             \
+       vpxor   r3, r1, r1;             vpxor   r2, r4, r4;             \
+       vpxor   r1, r2, r2;             vpor    r4, r3, r3;             \
+       vpand   r0, r3, r3;             vpxor   r2, r4, r4;             \
+       vpxor   r1, r3, r3;             vpor    r4, r1, r1;             \
+       vpxor   r0, r1, r1;             vpor    r4, r0, r0;             \
+       vpxor   r2, r0, r0;             vpxor   r4, r1, r1;             \
+       vpxor   r1, r2, r2;             vpand   r0, r1, r1;             \
+       vpxor   r4, r1, r1;             vpxor   RNOT, r2, r2;           \
+       vpor    r0, r2, r2;     \
+       vpxor   r2, r4, r4;
+
+#define SBOX7_INVERSE(r0, r1, r2, r3, r4) \
+       vmovdqa r2, r4;                 vpxor   r0, r2, r2;             \
+       vpand   r3, r0, r0;             vpor    r3, r4, r4;             \
+       vpxor   RNOT, r2, r2;           vpxor   r1, r3, r3;             \
+       vpor    r0, r1, r1;             vpxor   r2, r0, r0;             \
+       vpand   r4, r2, r2;             vpand   r4, r3, r3;             \
+       vpxor   r2, r1, r1;             vpxor   r0, r2, r2;             \
+       vpor    r2, r0, r0;             vpxor   r1, r4, r4;             \
+       vpxor   r3, r0, r0;             vpxor   r4, r3, r3;             \
+       vpor    r0, r4, r4;             vpxor   r2, r3, r3;             \
+       vpxor   r2, r4, r4;
+
+/* Apply SBOX number WHICH to to the block.  */
+#define SBOX(which, r0, r1, r2, r3, r4) \
+       SBOX##which (r0, r1, r2, r3, r4)
+
+/* Apply inverse SBOX number WHICH to to the block.  */
+#define SBOX_INVERSE(which, r0, r1, r2, r3, r4) \
+       SBOX##which##_INVERSE (r0, r1, r2, r3, r4)
+
+/* XOR round key into block state in r0,r1,r2,r3. r4 used as temporary.  */
+#define BLOCK_XOR_KEY(r0, r1, r2, r3, r4, round) \
+       vpbroadcastd (ctx_keys + (round) * 16 + 0 * 4)(CTX), r4; \
+       vpxor r4, r0, r0; \
+       vpbroadcastd (ctx_keys + (round) * 16 + 1 * 4)(CTX), r4; \
+       vpxor r4, r1, r1; \
+       vpbroadcastd (ctx_keys + (round) * 16 + 2 * 4)(CTX), r4; \
+       vpxor r4, r2, r2; \
+       vpbroadcastd (ctx_keys + (round) * 16 + 3 * 4)(CTX), r4; \
+       vpxor r4, r3, r3;
+
+/* Apply the linear transformation to BLOCK.  */
+#define LINEAR_TRANSFORMATION(r0, r1, r2, r3, r4) \
+       vec_rol(r0, 13, r4);    \
+       vec_rol(r2, 3, r4);     \
+       vpxor r0, r1, r1;       \
+       vpxor r2, r1, r1;       \
+       vpslld $3, r0, r4;      \
+       vpxor r2, r3, r3;       \
+       vpxor r4, r3, r3;       \
+       vec_rol(r1, 1, r4);     \
+       vec_rol(r3, 7, r4);     \
+       vpxor r1, r0, r0;       \
+       vpxor r3, r0, r0;       \
+       vpslld $7, r1, r4;      \
+       vpxor r3, r2, r2;       \
+       vpxor r4, r2, r2;       \
+       vec_rol(r0, 5, r4);     \
+       vec_rol(r2, 22, r4);
+
+/* Apply the inverse linear transformation to BLOCK.  */
+#define LINEAR_TRANSFORMATION_INVERSE(r0, r1, r2, r3, r4) \
+       vec_ror(r2, 22, r4);    \
+       vec_ror(r0, 5, r4);     \
+       vpslld $7, r1, r4;      \
+       vpxor r3, r2, r2;       \
+       vpxor r4, r2, r2;       \
+       vpxor r1, r0, r0;       \
+       vpxor r3, r0, r0;       \
+       vec_ror(r3, 7, r4);     \
+       vec_ror(r1, 1, r4);     \
+       vpslld $3, r0, r4;      \
+       vpxor r2, r3, r3;       \
+       vpxor r4, r3, r3;       \
+       vpxor r0, r1, r1;       \
+       vpxor r2, r1, r1;       \
+       vec_ror(r2, 3, r4);     \
+       vec_ror(r0, 13, r4);
+
+/* Apply a Serpent round to sixteen parallel blocks.  This macro increments
+   `round'.  */
+#define ROUND(round, which, a0, a1, a2, a3, a4, na0, na1, na2, na3, na4, \
+                           b0, b1, b2, b3, b4, nb0, nb1, nb2, nb3, nb4) \
+       BLOCK_XOR_KEY (a0, a1, a2, a3, a4, round);              \
+       SBOX (which, a0, a1, a2, a3, a4);                       \
+               BLOCK_XOR_KEY (b0, b1, b2, b3, b4, round);              \
+               SBOX (which, b0, b1, b2, b3, b4);                       \
+       LINEAR_TRANSFORMATION (na0, na1, na2, na3, na4);        \
+               LINEAR_TRANSFORMATION (nb0, nb1, nb2, nb3, nb4);
+
+/* Apply the last Serpent round to sixteen parallel blocks.  This macro
+   increments `round'.  */
+#define ROUND_LAST(round, which, a0, a1, a2, a3, a4, na0, na1, na2, na3, na4, \
+                                b0, b1, b2, b3, b4, nb0, nb1, nb2, nb3, nb4) \
+       BLOCK_XOR_KEY (a0, a1, a2, a3, a4, round);              \
+       SBOX (which, a0, a1, a2, a3, a4);                       \
+               BLOCK_XOR_KEY (b0, b1, b2, b3, b4, round);              \
+               SBOX (which, b0, b1, b2, b3, b4);                       \
+       BLOCK_XOR_KEY (na0, na1, na2, na3, na4, ((round) + 1));         \
+               BLOCK_XOR_KEY (nb0, nb1, nb2, nb3, nb4, ((round) + 1));
+
+/* Apply an inverse Serpent round to sixteen parallel blocks.  This macro
+   increments `round'.  */
+#define ROUND_INVERSE(round, which, a0, a1, a2, a3, a4, \
+                                   na0, na1, na2, na3, na4, \
+                                   b0, b1, b2, b3, b4, \
+                                   nb0, nb1, nb2, nb3, nb4) \
+       LINEAR_TRANSFORMATION_INVERSE (a0, a1, a2, a3, a4);     \
+               LINEAR_TRANSFORMATION_INVERSE (b0, b1, b2, b3, b4);     \
+       SBOX_INVERSE (which, a0, a1, a2, a3, a4);               \
+       BLOCK_XOR_KEY (na0, na1, na2, na3, na4, round);         \
+               SBOX_INVERSE (which, b0, b1, b2, b3, b4);               \
+               BLOCK_XOR_KEY (nb0, nb1, nb2, nb3, nb4, round);
+
+/* Apply the first inverse Serpent round to sixteen parallel blocks.  This macro
+   increments `round'.  */
+#define ROUND_FIRST_INVERSE(round, which, a0, a1, a2, a3, a4, \
+                                         na0, na1, na2, na3, na4, \
+                                         b0, b1, b2, b3, b4, \
+                                         nb0, nb1, nb2, nb3, nb4) \
+       BLOCK_XOR_KEY (a0, a1, a2, a3, a4, ((round) + 1));      \
+               BLOCK_XOR_KEY (b0, b1, b2, b3, b4, ((round) + 1));      \
+       SBOX_INVERSE (which, a0, a1, a2, a3, a4);       \
+       BLOCK_XOR_KEY (na0, na1, na2, na3, na4, round); \
+               SBOX_INVERSE (which, b0, b1, b2, b3, b4);       \
+               BLOCK_XOR_KEY (nb0, nb1, nb2, nb3, nb4, round);
+
+.text
+
+.align 8
+.type   __serpent_enc_blk16,@function;
+__serpent_enc_blk16:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: sixteen parallel
+        *                                              plaintext blocks
+        * output:
+        *      RA4, RA1, RA2, RA0, RB4, RB1, RB2, RB0: sixteen parallel
+        *                                              ciphertext blocks
+        */
+
+       vpcmpeqd RNOT, RNOT, RNOT;
+
+       transpose_4x4(RA0, RA1, RA2, RA3, RA4, RTMP0, RTMP1);
+       transpose_4x4(RB0, RB1, RB2, RB3, RB4, RTMP0, RTMP1);
+
+       ROUND (0, 0, RA0, RA1, RA2, RA3, RA4, RA1, RA4, RA2, RA0, RA3,
+                    RB0, RB1, RB2, RB3, RB4, RB1, RB4, RB2, RB0, RB3);
+       ROUND (1, 1, RA1, RA4, RA2, RA0, RA3, RA2, RA1, RA0, RA4, RA3,
+                    RB1, RB4, RB2, RB0, RB3, RB2, RB1, RB0, RB4, RB3);
+       ROUND (2, 2, RA2, RA1, RA0, RA4, RA3, RA0, RA4, RA1, RA3, RA2,
+                    RB2, RB1, RB0, RB4, RB3, RB0, RB4, RB1, RB3, RB2);
+       ROUND (3, 3, RA0, RA4, RA1, RA3, RA2, RA4, RA1, RA3, RA2, RA0,
+                    RB0, RB4, RB1, RB3, RB2, RB4, RB1, RB3, RB2, RB0);
+       ROUND (4, 4, RA4, RA1, RA3, RA2, RA0, RA1, RA0, RA4, RA2, RA3,
+                    RB4, RB1, RB3, RB2, RB0, RB1, RB0, RB4, RB2, RB3);
+       ROUND (5, 5, RA1, RA0, RA4, RA2, RA3, RA0, RA2, RA1, RA4, RA3,
+                    RB1, RB0, RB4, RB2, RB3, RB0, RB2, RB1, RB4, RB3);
+       ROUND (6, 6, RA0, RA2, RA1, RA4, RA3, RA0, RA2, RA3, RA1, RA4,
+                    RB0, RB2, RB1, RB4, RB3, RB0, RB2, RB3, RB1, RB4);
+       ROUND (7, 7, RA0, RA2, RA3, RA1, RA4, RA4, RA1, RA2, RA0, RA3,
+                    RB0, RB2, RB3, RB1, RB4, RB4, RB1, RB2, RB0, RB3);
+       ROUND (8, 0, RA4, RA1, RA2, RA0, RA3, RA1, RA3, RA2, RA4, RA0,
+                    RB4, RB1, RB2, RB0, RB3, RB1, RB3, RB2, RB4, RB0);
+       ROUND (9, 1, RA1, RA3, RA2, RA4, RA0, RA2, RA1, RA4, RA3, RA0,
+                    RB1, RB3, RB2, RB4, RB0, RB2, RB1, RB4, RB3, RB0);
+       ROUND (10, 2, RA2, RA1, RA4, RA3, RA0, RA4, RA3, RA1, RA0, RA2,
+                     RB2, RB1, RB4, RB3, RB0, RB4, RB3, RB1, RB0, RB2);
+       ROUND (11, 3, RA4, RA3, RA1, RA0, RA2, RA3, RA1, RA0, RA2, RA4,
+                     RB4, RB3, RB1, RB0, RB2, RB3, RB1, RB0, RB2, RB4);
+       ROUND (12, 4, RA3, RA1, RA0, RA2, RA4, RA1, RA4, RA3, RA2, RA0,
+                     RB3, RB1, RB0, RB2, RB4, RB1, RB4, RB3, RB2, RB0);
+       ROUND (13, 5, RA1, RA4, RA3, RA2, RA0, RA4, RA2, RA1, RA3, RA0,
+                     RB1, RB4, RB3, RB2, RB0, RB4, RB2, RB1, RB3, RB0);
+       ROUND (14, 6, RA4, RA2, RA1, RA3, RA0, RA4, RA2, RA0, RA1, RA3,
+                     RB4, RB2, RB1, RB3, RB0, RB4, RB2, RB0, RB1, RB3);
+       ROUND (15, 7, RA4, RA2, RA0, RA1, RA3, RA3, RA1, RA2, RA4, RA0,
+                     RB4, RB2, RB0, RB1, RB3, RB3, RB1, RB2, RB4, RB0);
+       ROUND (16, 0, RA3, RA1, RA2, RA4, RA0, RA1, RA0, RA2, RA3, RA4,
+                     RB3, RB1, RB2, RB4, RB0, RB1, RB0, RB2, RB3, RB4);
+       ROUND (17, 1, RA1, RA0, RA2, RA3, RA4, RA2, RA1, RA3, RA0, RA4,
+                     RB1, RB0, RB2, RB3, RB4, RB2, RB1, RB3, RB0, RB4);
+       ROUND (18, 2, RA2, RA1, RA3, RA0, RA4, RA3, RA0, RA1, RA4, RA2,
+                     RB2, RB1, RB3, RB0, RB4, RB3, RB0, RB1, RB4, RB2);
+       ROUND (19, 3, RA3, RA0, RA1, RA4, RA2, RA0, RA1, RA4, RA2, RA3,
+                     RB3, RB0, RB1, RB4, RB2, RB0, RB1, RB4, RB2, RB3);
+       ROUND (20, 4, RA0, RA1, RA4, RA2, RA3, RA1, RA3, RA0, RA2, RA4,
+                     RB0, RB1, RB4, RB2, RB3, RB1, RB3, RB0, RB2, RB4);
+       ROUND (21, 5, RA1, RA3, RA0, RA2, RA4, RA3, RA2, RA1, RA0, RA4,
+                     RB1, RB3, RB0, RB2, RB4, RB3, RB2, RB1, RB0, RB4);
+       ROUND (22, 6, RA3, RA2, RA1, RA0, RA4, RA3, RA2, RA4, RA1, RA0,
+                     RB3, RB2, RB1, RB0, RB4, RB3, RB2, RB4, RB1, RB0);
+       ROUND (23, 7, RA3, RA2, RA4, RA1, RA0, RA0, RA1, RA2, RA3, RA4,
+                     RB3, RB2, RB4, RB1, RB0, RB0, RB1, RB2, RB3, RB4);
+       ROUND (24, 0, RA0, RA1, RA2, RA3, RA4, RA1, RA4, RA2, RA0, RA3,
+                     RB0, RB1, RB2, RB3, RB4, RB1, RB4, RB2, RB0, RB3);
+       ROUND (25, 1, RA1, RA4, RA2, RA0, RA3, RA2, RA1, RA0, RA4, RA3,
+                     RB1, RB4, RB2, RB0, RB3, RB2, RB1, RB0, RB4, RB3);
+       ROUND (26, 2, RA2, RA1, RA0, RA4, RA3, RA0, RA4, RA1, RA3, RA2,
+                     RB2, RB1, RB0, RB4, RB3, RB0, RB4, RB1, RB3, RB2);
+       ROUND (27, 3, RA0, RA4, RA1, RA3, RA2, RA4, RA1, RA3, RA2, RA0,
+                     RB0, RB4, RB1, RB3, RB2, RB4, RB1, RB3, RB2, RB0);
+       ROUND (28, 4, RA4, RA1, RA3, RA2, RA0, RA1, RA0, RA4, RA2, RA3,
+                     RB4, RB1, RB3, RB2, RB0, RB1, RB0, RB4, RB2, RB3);
+       ROUND (29, 5, RA1, RA0, RA4, RA2, RA3, RA0, RA2, RA1, RA4, RA3,
+                     RB1, RB0, RB4, RB2, RB3, RB0, RB2, RB1, RB4, RB3);
+       ROUND (30, 6, RA0, RA2, RA1, RA4, RA3, RA0, RA2, RA3, RA1, RA4,
+                     RB0, RB2, RB1, RB4, RB3, RB0, RB2, RB3, RB1, RB4);
+       ROUND_LAST (31, 7, RA0, RA2, RA3, RA1, RA4, RA4, RA1, RA2, RA0, RA3,
+                          RB0, RB2, RB3, RB1, RB4, RB4, RB1, RB2, RB0, RB3);
+
+       transpose_4x4(RA4, RA1, RA2, RA0, RA3, RTMP0, RTMP1);
+       transpose_4x4(RB4, RB1, RB2, RB0, RB3, RTMP0, RTMP1);
+
+       ret;
+.size __serpent_enc_blk16,.-__serpent_enc_blk16;
+
+.align 8
+.type   __serpent_dec_blk16,@function;
+__serpent_dec_blk16:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: sixteen parallel
+        *                                              ciphertext blocks
+        * output:
+        *      RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: sixteen parallel
+        *                                              plaintext blocks
+        */
+
+       vpcmpeqd RNOT, RNOT, RNOT;
+
+       transpose_4x4(RA0, RA1, RA2, RA3, RA4, RTMP0, RTMP1);
+       transpose_4x4(RB0, RB1, RB2, RB3, RB4, RTMP0, RTMP1);
+
+       ROUND_FIRST_INVERSE (31, 7, RA0, RA1, RA2, RA3, RA4,
+                                   RA3, RA0, RA1, RA4, RA2,
+                                   RB0, RB1, RB2, RB3, RB4,
+                                   RB3, RB0, RB1, RB4, RB2);
+       ROUND_INVERSE (30, 6, RA3, RA0, RA1, RA4, RA2, RA0, RA1, RA2, RA4, RA3,
+                             RB3, RB0, RB1, RB4, RB2, RB0, RB1, RB2, RB4, RB3);
+       ROUND_INVERSE (29, 5, RA0, RA1, RA2, RA4, RA3, RA1, RA3, RA4, RA2, RA0,
+                             RB0, RB1, RB2, RB4, RB3, RB1, RB3, RB4, RB2, RB0);
+       ROUND_INVERSE (28, 4, RA1, RA3, RA4, RA2, RA0, RA1, RA2, RA4, RA0, RA3,
+                             RB1, RB3, RB4, RB2, RB0, RB1, RB2, RB4, RB0, RB3);
+       ROUND_INVERSE (27, 3, RA1, RA2, RA4, RA0, RA3, RA4, RA2, RA0, RA1, RA3,
+                             RB1, RB2, RB4, RB0, RB3, RB4, RB2, RB0, RB1, RB3);
+       ROUND_INVERSE (26, 2, RA4, RA2, RA0, RA1, RA3, RA2, RA3, RA0, RA1, RA4,
+                             RB4, RB2, RB0, RB1, RB3, RB2, RB3, RB0, RB1, RB4);
+       ROUND_INVERSE (25, 1, RA2, RA3, RA0, RA1, RA4, RA4, RA2, RA1, RA0, RA3,
+                             RB2, RB3, RB0, RB1, RB4, RB4, RB2, RB1, RB0, RB3);
+       ROUND_INVERSE (24, 0, RA4, RA2, RA1, RA0, RA3, RA4, RA3, RA2, RA0, RA1,
+                             RB4, RB2, RB1, RB0, RB3, RB4, RB3, RB2, RB0, RB1);
+       ROUND_INVERSE (23, 7, RA4, RA3, RA2, RA0, RA1, RA0, RA4, RA3, RA1, RA2,
+                             RB4, RB3, RB2, RB0, RB1, RB0, RB4, RB3, RB1, RB2);
+       ROUND_INVERSE (22, 6, RA0, RA4, RA3, RA1, RA2, RA4, RA3, RA2, RA1, RA0,
+                             RB0, RB4, RB3, RB1, RB2, RB4, RB3, RB2, RB1, RB0);
+       ROUND_INVERSE (21, 5, RA4, RA3, RA2, RA1, RA0, RA3, RA0, RA1, RA2, RA4,
+                             RB4, RB3, RB2, RB1, RB0, RB3, RB0, RB1, RB2, RB4);
+       ROUND_INVERSE (20, 4, RA3, RA0, RA1, RA2, RA4, RA3, RA2, RA1, RA4, RA0,
+                             RB3, RB0, RB1, RB2, RB4, RB3, RB2, RB1, RB4, RB0);
+       ROUND_INVERSE (19, 3, RA3, RA2, RA1, RA4, RA0, RA1, RA2, RA4, RA3, RA0,
+                             RB3, RB2, RB1, RB4, RB0, RB1, RB2, RB4, RB3, RB0);
+       ROUND_INVERSE (18, 2, RA1, RA2, RA4, RA3, RA0, RA2, RA0, RA4, RA3, RA1,
+                             RB1, RB2, RB4, RB3, RB0, RB2, RB0, RB4, RB3, RB1);
+       ROUND_INVERSE (17, 1, RA2, RA0, RA4, RA3, RA1, RA1, RA2, RA3, RA4, RA0,
+                             RB2, RB0, RB4, RB3, RB1, RB1, RB2, RB3, RB4, RB0);
+       ROUND_INVERSE (16, 0, RA1, RA2, RA3, RA4, RA0, RA1, RA0, RA2, RA4, RA3,
+                             RB1, RB2, RB3, RB4, RB0, RB1, RB0, RB2, RB4, RB3);
+       ROUND_INVERSE (15, 7, RA1, RA0, RA2, RA4, RA3, RA4, RA1, RA0, RA3, RA2,
+                             RB1, RB0, RB2, RB4, RB3, RB4, RB1, RB0, RB3, RB2);
+       ROUND_INVERSE (14, 6, RA4, RA1, RA0, RA3, RA2, RA1, RA0, RA2, RA3, RA4,
+                             RB4, RB1, RB0, RB3, RB2, RB1, RB0, RB2, RB3, RB4);
+       ROUND_INVERSE (13, 5, RA1, RA0, RA2, RA3, RA4, RA0, RA4, RA3, RA2, RA1,
+                             RB1, RB0, RB2, RB3, RB4, RB0, RB4, RB3, RB2, RB1);
+       ROUND_INVERSE (12, 4, RA0, RA4, RA3, RA2, RA1, RA0, RA2, RA3, RA1, RA4,
+                             RB0, RB4, RB3, RB2, RB1, RB0, RB2, RB3, RB1, RB4);
+       ROUND_INVERSE (11, 3, RA0, RA2, RA3, RA1, RA4, RA3, RA2, RA1, RA0, RA4,
+                             RB0, RB2, RB3, RB1, RB4, RB3, RB2, RB1, RB0, RB4);
+       ROUND_INVERSE (10, 2, RA3, RA2, RA1, RA0, RA4, RA2, RA4, RA1, RA0, RA3,
+                             RB3, RB2, RB1, RB0, RB4, RB2, RB4, RB1, RB0, RB3);
+       ROUND_INVERSE (9, 1, RA2, RA4, RA1, RA0, RA3, RA3, RA2, RA0, RA1, RA4,
+                            RB2, RB4, RB1, RB0, RB3, RB3, RB2, RB0, RB1, RB4);
+       ROUND_INVERSE (8, 0, RA3, RA2, RA0, RA1, RA4, RA3, RA4, RA2, RA1, RA0,
+                            RB3, RB2, RB0, RB1, RB4, RB3, RB4, RB2, RB1, RB0);
+       ROUND_INVERSE (7, 7, RA3, RA4, RA2, RA1, RA0, RA1, RA3, RA4, RA0, RA2,
+                            RB3, RB4, RB2, RB1, RB0, RB1, RB3, RB4, RB0, RB2);
+       ROUND_INVERSE (6, 6, RA1, RA3, RA4, RA0, RA2, RA3, RA4, RA2, RA0, RA1,
+                            RB1, RB3, RB4, RB0, RB2, RB3, RB4, RB2, RB0, RB1);
+       ROUND_INVERSE (5, 5, RA3, RA4, RA2, RA0, RA1, RA4, RA1, RA0, RA2, RA3,
+                            RB3, RB4, RB2, RB0, RB1, RB4, RB1, RB0, RB2, RB3);
+       ROUND_INVERSE (4, 4, RA4, RA1, RA0, RA2, RA3, RA4, RA2, RA0, RA3, RA1,
+                            RB4, RB1, RB0, RB2, RB3, RB4, RB2, RB0, RB3, RB1);
+       ROUND_INVERSE (3, 3, RA4, RA2, RA0, RA3, RA1, RA0, RA2, RA3, RA4, RA1,
+                            RB4, RB2, RB0, RB3, RB1, RB0, RB2, RB3, RB4, RB1);
+       ROUND_INVERSE (2, 2, RA0, RA2, RA3, RA4, RA1, RA2, RA1, RA3, RA4, RA0,
+                            RB0, RB2, RB3, RB4, RB1, RB2, RB1, RB3, RB4, RB0);
+       ROUND_INVERSE (1, 1, RA2, RA1, RA3, RA4, RA0, RA0, RA2, RA4, RA3, RA1,
+                            RB2, RB1, RB3, RB4, RB0, RB0, RB2, RB4, RB3, RB1);
+       ROUND_INVERSE (0, 0, RA0, RA2, RA4, RA3, RA1, RA0, RA1, RA2, RA3, RA4,
+                            RB0, RB2, RB4, RB3, RB1, RB0, RB1, RB2, RB3, RB4);
+
+       transpose_4x4(RA0, RA1, RA2, RA3, RA4, RTMP0, RTMP1);
+       transpose_4x4(RB0, RB1, RB2, RB3, RB4, RTMP0, RTMP1);
+
+       ret;
+.size __serpent_dec_blk16,.-__serpent_dec_blk16;
+
+#define inc_le128(x, minus_one, tmp) \
+       vpcmpeqq minus_one, x, tmp; \
+       vpsubq minus_one, x, x; \
+       vpslldq $8, tmp, tmp; \
+       vpsubq tmp, x, x;
+
+.align 8
+.globl _gcry_serpent_avx2_ctr_enc
+.type   _gcry_serpent_avx2_ctr_enc,@function;
+_gcry_serpent_avx2_ctr_enc:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (16 blocks)
+        *      %rdx: src (16 blocks)
+        *      %rcx: iv (big endian, 128bit)
+        */
+
+       movq 8(%rcx), %rax;
+       bswapq %rax;
+
+       vzeroupper;
+
+       vbroadcasti128 .Lbswap128_mask RIP, RTMP3;
+       vpcmpeqd RNOT, RNOT, RNOT;
+       vpsrldq $8, RNOT, RNOT;   /* ab: -1:0 ; cd: -1:0 */
+       vpaddq RNOT, RNOT, RTMP2; /* ab: -2:0 ; cd: -2:0 */
+
+       /* load IV and byteswap */
+       vmovdqu (%rcx), RTMP4x;
+       vpshufb RTMP3x, RTMP4x, RTMP4x;
+       vmovdqa RTMP4x, RTMP0x;
+       inc_le128(RTMP4x, RNOTx, RTMP1x);
+       vinserti128 $1, RTMP4x, RTMP0, RTMP0;
+       vpshufb RTMP3, RTMP0, RA0; /* +1 ; +0 */
+
+       /* check need for handling 64-bit overflow and carry */
+       cmpq $(0xffffffffffffffff - 16), %rax;
+       ja .Lhandle_ctr_carry;
+
+       /* construct IVs */
+       vpsubq RTMP2, RTMP0, RTMP0; /* +3 ; +2 */
+       vpshufb RTMP3, RTMP0, RA1;
+       vpsubq RTMP2, RTMP0, RTMP0; /* +5 ; +4 */
+       vpshufb RTMP3, RTMP0, RA2;
+       vpsubq RTMP2, RTMP0, RTMP0; /* +7 ; +6 */
+       vpshufb RTMP3, RTMP0, RA3;
+       vpsubq RTMP2, RTMP0, RTMP0; /* +9 ; +8 */
+       vpshufb RTMP3, RTMP0, RB0;
+       vpsubq RTMP2, RTMP0, RTMP0; /* +11 ; +10 */
+       vpshufb RTMP3, RTMP0, RB1;
+       vpsubq RTMP2, RTMP0, RTMP0; /* +13 ; +12 */
+       vpshufb RTMP3, RTMP0, RB2;
+       vpsubq RTMP2, RTMP0, RTMP0; /* +15 ; +14 */
+       vpshufb RTMP3, RTMP0, RB3;
+       vpsubq RTMP2, RTMP0, RTMP0; /* +16 */
+       vpshufb RTMP3x, RTMP0x, RTMP0x;
+
+       jmp .Lctr_carry_done;
+
+.Lhandle_ctr_carry:
+       /* construct IVs */
+       inc_le128(RTMP0, RNOT, RTMP1);
+       inc_le128(RTMP0, RNOT, RTMP1);
+       vpshufb RTMP3, RTMP0, RA1; /* +3 ; +2 */
+       inc_le128(RTMP0, RNOT, RTMP1);
+       inc_le128(RTMP0, RNOT, RTMP1);
+       vpshufb RTMP3, RTMP0, RA2; /* +5 ; +4 */
+       inc_le128(RTMP0, RNOT, RTMP1);
+       inc_le128(RTMP0, RNOT, RTMP1);
+       vpshufb RTMP3, RTMP0, RA3; /* +7 ; +6 */
+       inc_le128(RTMP0, RNOT, RTMP1);
+       inc_le128(RTMP0, RNOT, RTMP1);
+       vpshufb RTMP3, RTMP0, RB0; /* +9 ; +8 */
+       inc_le128(RTMP0, RNOT, RTMP1);
+       inc_le128(RTMP0, RNOT, RTMP1);
+       vpshufb RTMP3, RTMP0, RB1; /* +11 ; +10 */
+       inc_le128(RTMP0, RNOT, RTMP1);
+       inc_le128(RTMP0, RNOT, RTMP1);
+       vpshufb RTMP3, RTMP0, RB2; /* +13 ; +12 */
+       inc_le128(RTMP0, RNOT, RTMP1);
+       inc_le128(RTMP0, RNOT, RTMP1);
+       vpshufb RTMP3, RTMP0, RB3; /* +15 ; +14 */
+       inc_le128(RTMP0, RNOT, RTMP1);
+       vextracti128 $1, RTMP0, RTMP0x;
+       vpshufb RTMP3x, RTMP0x, RTMP0x; /* +16 */
+
+.align 4
+.Lctr_carry_done:
+       /* store new IV */
+       vmovdqu RTMP0x, (%rcx);
+
+       call __serpent_enc_blk16;
+
+       vpxor (0 * 32)(%rdx), RA4, RA4;
+       vpxor (1 * 32)(%rdx), RA1, RA1;
+       vpxor (2 * 32)(%rdx), RA2, RA2;
+       vpxor (3 * 32)(%rdx), RA0, RA0;
+       vpxor (4 * 32)(%rdx), RB4, RB4;
+       vpxor (5 * 32)(%rdx), RB1, RB1;
+       vpxor (6 * 32)(%rdx), RB2, RB2;
+       vpxor (7 * 32)(%rdx), 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
+.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;
+_gcry_serpent_avx2_cbc_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (16 blocks)
+        *      %rdx: src (16 blocks)
+        *      %rcx: iv
+        */
+
+       vzeroupper;
+
+       vmovdqu (0 * 32)(%rdx), RA0;
+       vmovdqu (1 * 32)(%rdx), RA1;
+       vmovdqu (2 * 32)(%rdx), RA2;
+       vmovdqu (3 * 32)(%rdx), RA3;
+       vmovdqu (4 * 32)(%rdx), RB0;
+       vmovdqu (5 * 32)(%rdx), RB1;
+       vmovdqu (6 * 32)(%rdx), RB2;
+       vmovdqu (7 * 32)(%rdx), RB3;
+
+       call __serpent_dec_blk16;
+
+       vmovdqu (%rcx), RNOTx;
+       vinserti128 $1, (%rdx), RNOT, RNOT;
+       vpxor RNOT, RA0, RA0;
+       vpxor (0 * 32 + 16)(%rdx), RA1, RA1;
+       vpxor (1 * 32 + 16)(%rdx), RA2, RA2;
+       vpxor (2 * 32 + 16)(%rdx), RA3, RA3;
+       vpxor (3 * 32 + 16)(%rdx), RB0, RB0;
+       vpxor (4 * 32 + 16)(%rdx), RB1, RB1;
+       vpxor (5 * 32 + 16)(%rdx), RB2, RB2;
+       vpxor (6 * 32 + 16)(%rdx), RB3, RB3;
+       vmovdqu (7 * 32 + 16)(%rdx), RNOTx;
+       vmovdqu RNOTx, (%rcx); /* store new IV */
+
+       vmovdqu RA0, (0 * 32)(%rsi);
+       vmovdqu RA1, (1 * 32)(%rsi);
+       vmovdqu RA2, (2 * 32)(%rsi);
+       vmovdqu RA3, (3 * 32)(%rsi);
+       vmovdqu RB0, (4 * 32)(%rsi);
+       vmovdqu RB1, (5 * 32)(%rsi);
+       vmovdqu RB2, (6 * 32)(%rsi);
+       vmovdqu RB3, (7 * 32)(%rsi);
+
+       vzeroall;
+
+       ret
+.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;
+_gcry_serpent_avx2_cfb_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (16 blocks)
+        *      %rdx: src (16 blocks)
+        *      %rcx: iv
+        */
+
+       vzeroupper;
+
+       /* Load input */
+       vmovdqu (%rcx), RNOTx;
+       vinserti128 $1, (%rdx), RNOT, RA0;
+       vmovdqu (0 * 32 + 16)(%rdx), RA1;
+       vmovdqu (1 * 32 + 16)(%rdx), RA2;
+       vmovdqu (2 * 32 + 16)(%rdx), RA3;
+       vmovdqu (3 * 32 + 16)(%rdx), RB0;
+       vmovdqu (4 * 32 + 16)(%rdx), RB1;
+       vmovdqu (5 * 32 + 16)(%rdx), RB2;
+       vmovdqu (6 * 32 + 16)(%rdx), RB3;
+
+       /* Update IV */
+       vmovdqu (7 * 32 + 16)(%rdx), RNOTx;
+       vmovdqu RNOTx, (%rcx);
+
+       call __serpent_enc_blk16;
+
+       vpxor (0 * 32)(%rdx), RA4, RA4;
+       vpxor (1 * 32)(%rdx), RA1, RA1;
+       vpxor (2 * 32)(%rdx), RA2, RA2;
+       vpxor (3 * 32)(%rdx), RA0, RA0;
+       vpxor (4 * 32)(%rdx), RB4, RB4;
+       vpxor (5 * 32)(%rdx), RB1, RB1;
+       vpxor (6 * 32)(%rdx), RB2, RB2;
+       vpxor (7 * 32)(%rdx), 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
+.size _gcry_serpent_avx2_cfb_dec,.-_gcry_serpent_avx2_cfb_dec;
+
+.data
+.align 16
+
+/* For CTR-mode IV byteswap */
+.Lbswap128_mask:
+       .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
+
+#endif /*defined(USE_SERPENT) && defined(ENABLE_AVX2_SUPPORT)*/
+#endif /*__x86_64*/
diff --git a/cipher/serpent-sse2-amd64.S b/cipher/serpent-sse2-amd64.S
new file mode 100644 (file)
index 0000000..f2be236
--- /dev/null
@@ -0,0 +1,863 @@
+/* serpent-sse2-amd64.S  -  SSE2 implementation of Serpent cipher
+ *
+ * Copyright © 2013 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(USE_SERPENT)
+
+#ifdef __PIC__
+#  define RIP (%rip)
+#else
+#  define RIP
+#endif
+
+/* struct serpent_context: */
+#define ctx_keys 0
+
+/* register macros */
+#define CTX %rdi
+
+/* vector registers */
+#define RA0 %xmm0
+#define RA1 %xmm1
+#define RA2 %xmm2
+#define RA3 %xmm3
+#define RA4 %xmm4
+
+#define RB0 %xmm5
+#define RB1 %xmm6
+#define RB2 %xmm7
+#define RB3 %xmm8
+#define RB4 %xmm9
+
+#define RNOT %xmm10
+#define RTMP0 %xmm11
+#define RTMP1 %xmm12
+#define RTMP2 %xmm13
+
+/**********************************************************************
+  helper macros
+ **********************************************************************/
+
+/* vector 32-bit rotation to left */
+#define vec_rol(reg, nleft, tmp) \
+       movdqa reg, tmp;                \
+       pslld $(nleft), tmp;            \
+       psrld $(32 - (nleft)), reg;     \
+       por tmp, reg;
+
+/* vector 32-bit rotation to right */
+#define vec_ror(reg, nright, tmp) \
+       vec_rol(reg, 32 - nright, tmp)
+
+/* 4x4 32-bit integer matrix transpose */
+#define transpose_4x4(x0, x1, x2, x3, t1, t2, t3) \
+       movdqa    x0, t2; \
+       punpckhdq x1, t2; \
+       punpckldq x1, x0; \
+       \
+       movdqa    x2, t1; \
+       punpckldq x3, t1; \
+       punpckhdq x3, x2; \
+       \
+       movdqa     x0, x1; \
+       punpckhqdq t1, x1; \
+       punpcklqdq t1, x0; \
+       \
+       movdqa     t2, x3; \
+       punpckhqdq x2, x3; \
+       punpcklqdq x2, t2; \
+       movdqa     t2, x2;
+
+/* fill xmm register with 32-bit value from memory */
+#define pbroadcastd(mem32, xreg) \
+       movd mem32, xreg; \
+       pshufd $0, xreg, xreg;
+
+/* xor with unaligned memory operand */
+#define pxor_u(umem128, xreg, t) \
+       movdqu umem128, t; \
+       pxor t, xreg;
+
+/* 128-bit wide byte swap */
+#define pbswap(xreg, t0) \
+       /* reorder 32-bit words, [a,b,c,d] => [d,c,b,a] */ \
+       pshufd $0x1b, xreg, xreg; \
+       /* reorder high&low 16-bit words, [d0,d1,c0,c1] => [d1,d0,c1,c0] */ \
+       pshuflw $0xb1, xreg, xreg; \
+       pshufhw $0xb1, xreg, xreg; \
+       /* reorder bytes in 16-bit words */ \
+       movdqa xreg, t0; \
+       psrlw $8, t0; \
+       psllw $8, xreg; \
+       por t0, xreg;
+
+/**********************************************************************
+  8-way serpent
+ **********************************************************************/
+
+/*
+ * These are the S-Boxes of Serpent from following research paper.
+ *
+ *  D. A. Osvik, “Speeding up Serpent,” in Third AES Candidate Conference,
+ *   (New York, New York, USA), p. 317–329, National Institute of Standards and
+ *   Technology, 2000.
+ *
+ * Paper is also available at: http://www.ii.uib.no/~osvik/pub/aes3.pdf
+ *
+ */
+#define SBOX0(r0, r1, r2, r3, r4) \
+       pxor    r0, r3;         movdqa  r1, r4;         \
+       pand    r3, r1;         pxor    r2, r4;         \
+       pxor    r0, r1;         por     r3, r0;         \
+       pxor    r4, r0;         pxor    r3, r4;         \
+       pxor    r2, r3;         por     r1, r2;         \
+       pxor    r4, r2;         pxor    RNOT, r4;       \
+       por     r1, r4;         pxor    r3, r1;         \
+       pxor    r4, r1;         por     r0, r3;         \
+       pxor    r3, r1;         pxor    r3, r4;
+
+#define SBOX0_INVERSE(r0, r1, r2, r3, r4) \
+       pxor    RNOT, r2;       movdqa  r1, r4;         \
+       por     r0, r1;         pxor    RNOT, r4;       \
+       pxor    r2, r1;         por     r4, r2;         \
+       pxor    r3, r1;         pxor    r4, r0;         \
+       pxor    r0, r2;         pand    r3, r0;         \
+       pxor    r0, r4;         por     r1, r0;         \
+       pxor    r2, r0;         pxor    r4, r3;         \
+       pxor    r1, r2;         pxor    r0, r3;         \
+       pxor    r1, r3; \
+       pand    r3, r2; \
+       pxor    r2, r4;
+
+#define SBOX1(r0, r1, r2, r3, r4) \
+       pxor    RNOT, r0;       pxor    RNOT, r2;       \
+       movdqa  r0, r4;         pand    r1, r0;         \
+       pxor    r0, r2;         por     r3, r0;         \
+       pxor    r2, r3;         pxor    r0, r1;         \
+       pxor    r4, r0;         por     r1, r4;         \
+       pxor    r3, r1;         por     r0, r2;         \
+       pand    r4, r2;         pxor    r1, r0;         \
+       pand    r2, r1; \
+       pxor    r0, r1;         pand    r2, r0;         \
+       pxor    r4, r0;
+
+#define SBOX1_INVERSE(r0, r1, r2, r3, r4) \
+       movdqa  r1, r4;         pxor    r3, r1;         \
+       pand    r1, r3;         pxor    r2, r4;         \
+       pxor    r0, r3;         por     r1, r0;         \
+       pxor    r3, r2;         pxor    r4, r0;         \
+       por     r2, r0;         pxor    r3, r1;         \
+       pxor    r1, r0;         por     r3, r1;         \
+       pxor    r0, r1;         pxor    RNOT, r4;       \
+       pxor    r1, r4;         por     r0, r1;         \
+       pxor    r0, r1; \
+       por     r4, r1; \
+       pxor    r1, r3;
+
+#define SBOX2(r0, r1, r2, r3, r4) \
+       movdqa  r0, r4;         pand    r2, r0;         \
+       pxor    r3, r0;         pxor    r1, r2;         \
+       pxor    r0, r2;         por     r4, r3;         \
+       pxor    r1, r3;         pxor    r2, r4;         \
+       movdqa  r3, r1;         por     r4, r3;         \
+       pxor    r0, r3;         pand    r1, r0;         \
+       pxor    r0, r4;         pxor    r3, r1;         \
+       pxor    r4, r1;         pxor    RNOT, r4;
+
+#define SBOX2_INVERSE(r0, r1, r2, r3, r4) \
+       pxor    r3, r2;         pxor    r0, r3;         \
+       movdqa  r3, r4;         pand    r2, r3;         \
+       pxor    r1, r3;         por     r2, r1;         \
+       pxor    r4, r1;         pand    r3, r4;         \
+       pxor    r3, r2;         pand    r0, r4;         \
+       pxor    r2, r4;         pand    r1, r2;         \
+       por     r0, r2;         pxor    RNOT, r3;       \
+       pxor    r3, r2;         pxor    r3, r0;         \
+       pand    r1, r0;         pxor    r4, r3;         \
+       pxor    r0, r3;
+
+#define SBOX3(r0, r1, r2, r3, r4) \
+       movdqa  r0, r4;         por     r3, r0;         \
+       pxor    r1, r3;         pand    r4, r1;         \
+       pxor    r2, r4;         pxor    r3, r2;         \
+       pand    r0, r3;         por     r1, r4;         \
+       pxor    r4, r3;         pxor    r1, r0;         \
+       pand    r0, r4;         pxor    r3, r1;         \
+       pxor    r2, r4;         por     r0, r1;         \
+       pxor    r2, r1;         pxor    r3, r0;         \
+       movdqa  r1, r2;         por     r3, r1;         \
+       pxor    r0, r1;
+
+#define SBOX3_INVERSE(r0, r1, r2, r3, r4) \
+       movdqa  r2, r4;         pxor    r1, r2;         \
+       pxor    r2, r0;         pand    r2, r4;         \
+       pxor    r0, r4;         pand    r1, r0;         \
+       pxor    r3, r1;         por     r4, r3;         \
+       pxor    r3, r2;         pxor    r3, r0;         \
+       pxor    r4, r1;         pand    r2, r3;         \
+       pxor    r1, r3;         pxor    r0, r1;         \
+       por     r2, r1;         pxor    r3, r0;         \
+       pxor    r4, r1; \
+       pxor    r1, r0;
+
+#define SBOX4(r0, r1, r2, r3, r4) \
+       pxor    r3, r1;         pxor    RNOT, r3;       \
+       pxor    r3, r2;         pxor    r0, r3;         \
+       movdqa  r1, r4;         pand    r3, r1;         \
+       pxor    r2, r1;         pxor    r3, r4;         \
+       pxor    r4, r0;         pand    r4, r2;         \
+       pxor    r0, r2;         pand    r1, r0;         \
+       pxor    r0, r3;         por     r1, r4;         \
+       pxor    r0, r4;         por     r3, r0;         \
+       pxor    r2, r0;         pand    r3, r2;         \
+       pxor    RNOT, r0;       pxor    r2, r4;
+
+#define SBOX4_INVERSE(r0, r1, r2, r3, r4) \
+       movdqa  r2, r4;         pand    r3, r2;         \
+       pxor    r1, r2;         por     r3, r1;         \
+       pand    r0, r1;         pxor    r2, r4;         \
+       pxor    r1, r4;         pand    r2, r1;         \
+       pxor    RNOT, r0;       pxor    r4, r3;         \
+       pxor    r3, r1;         pand    r0, r3;         \
+       pxor    r2, r3;         pxor    r1, r0;         \
+       pand    r0, r2;         pxor    r0, r3;         \
+       pxor    r4, r2; \
+       por     r3, r2;         pxor    r0, r3;         \
+       pxor    r1, r2;
+
+#define SBOX5(r0, r1, r2, r3, r4) \
+       pxor    r1, r0;         pxor    r3, r1;         \
+       pxor    RNOT, r3;       movdqa  r1, r4;         \
+       pand    r0, r1;         pxor    r3, r2;         \
+       pxor    r2, r1;         por     r4, r2;         \
+       pxor    r3, r4;         pand    r1, r3;         \
+       pxor    r0, r3;         pxor    r1, r4;         \
+       pxor    r2, r4;         pxor    r0, r2;         \
+       pand    r3, r0;         pxor    RNOT, r2;       \
+       pxor    r4, r0;         por     r3, r4;         \
+       pxor    r4, r2;
+
+#define SBOX5_INVERSE(r0, r1, r2, r3, r4) \
+       pxor    RNOT, r1;       movdqa  r3, r4;         \
+       pxor    r1, r2;         por     r0, r3;         \
+       pxor    r2, r3;         por     r1, r2;         \
+       pand    r0, r2;         pxor    r3, r4;         \
+       pxor    r4, r2;         por     r0, r4;         \
+       pxor    r1, r4;         pand    r2, r1;         \
+       pxor    r3, r1;         pxor    r2, r4;         \
+       pand    r4, r3;         pxor    r1, r4;         \
+       pxor    r4, r3;         pxor    RNOT, r4;       \
+       pxor    r0, r3;
+
+#define SBOX6(r0, r1, r2, r3, r4) \
+       pxor    RNOT, r2;       movdqa  r3, r4;         \
+       pand    r0, r3;         pxor    r4, r0;         \
+       pxor    r2, r3;         por     r4, r2;         \
+       pxor    r3, r1;         pxor    r0, r2;         \
+       por     r1, r0;         pxor    r1, r2;         \
+       pxor    r0, r4;         por     r3, r0;         \
+       pxor    r2, r0;         pxor    r3, r4;         \
+       pxor    r0, r4;         pxor    RNOT, r3;       \
+       pand    r4, r2; \
+       pxor    r3, r2;
+
+#define SBOX6_INVERSE(r0, r1, r2, r3, r4) \
+       pxor    r2, r0;         movdqa  r2, r4;         \
+       pand    r0, r2;         pxor    r3, r4;         \
+       pxor    RNOT, r2;       pxor    r1, r3;         \
+       pxor    r3, r2;         por     r0, r4;         \
+       pxor    r2, r0;         pxor    r4, r3;         \
+       pxor    r1, r4;         pand    r3, r1;         \
+       pxor    r0, r1;         pxor    r3, r0;         \
+       por     r2, r0;         pxor    r1, r3;         \
+       pxor    r0, r4;
+
+#define SBOX7(r0, r1, r2, r3, r4) \
+       movdqa  r1, r4;         por     r2, r1;         \
+       pxor    r3, r1;         pxor    r2, r4;         \
+       pxor    r1, r2;         por     r4, r3;         \
+       pand    r0, r3;         pxor    r2, r4;         \
+       pxor    r1, r3;         por     r4, r1;         \
+       pxor    r0, r1;         por     r4, r0;         \
+       pxor    r2, r0;         pxor    r4, r1;         \
+       pxor    r1, r2;         pand    r0, r1;         \
+       pxor    r4, r1;         pxor    RNOT, r2;       \
+       por     r0, r2; \
+       pxor    r2, r4;
+
+#define SBOX7_INVERSE(r0, r1, r2, r3, r4) \
+       movdqa  r2, r4;         pxor    r0, r2;         \
+       pand    r3, r0;         por     r3, r4;         \
+       pxor    RNOT, r2;       pxor    r1, r3;         \
+       por     r0, r1;         pxor    r2, r0;         \
+       pand    r4, r2;         pand    r4, r3;         \
+       pxor    r2, r1;         pxor    r0, r2;         \
+       por     r2, r0;         pxor    r1, r4;         \
+       pxor    r3, r0;         pxor    r4, r3;         \
+       por     r0, r4;         pxor    r2, r3;         \
+       pxor    r2, r4;
+
+/* Apply SBOX number WHICH to to the block.  */
+#define SBOX(which, r0, r1, r2, r3, r4) \
+       SBOX##which (r0, r1, r2, r3, r4)
+
+/* Apply inverse SBOX number WHICH to to the block.  */
+#define SBOX_INVERSE(which, r0, r1, r2, r3, r4) \
+       SBOX##which##_INVERSE (r0, r1, r2, r3, r4)
+
+/* XOR round key into block state in r0,r1,r2,r3. r4 used as temporary.  */
+#define BLOCK_XOR_KEY(r0, r1, r2, r3, r4, round) \
+       pbroadcastd ((ctx_keys + (round) * 16 + 0 * 4)(CTX), r4); \
+       pxor r4, r0; \
+       pbroadcastd ((ctx_keys + (round) * 16 + 1 * 4)(CTX), r4); \
+       pxor r4, r1; \
+       pbroadcastd ((ctx_keys + (round) * 16 + 2 * 4)(CTX), r4); \
+       pxor r4, r2; \
+       pbroadcastd ((ctx_keys + (round) * 16 + 3 * 4)(CTX), r4); \
+       pxor r4, r3;
+
+/* Apply the linear transformation to BLOCK.  */
+#define LINEAR_TRANSFORMATION(r0, r1, r2, r3, r4) \
+       vec_rol(r0, 13, r4);    \
+       vec_rol(r2, 3, r4);     \
+       pxor r0, r1;            \
+       pxor r2, r1;            \
+       movdqa r0, r4;          \
+       pslld $3, r4;           \
+       pxor r2, r3;            \
+       pxor r4, r3;            \
+       vec_rol(r1, 1, r4);     \
+       vec_rol(r3, 7, r4);     \
+       pxor r1, r0;            \
+       pxor r3, r0;            \
+       movdqa r1, r4;          \
+       pslld $7, r4;           \
+       pxor r3, r2;            \
+       pxor r4, r2;            \
+       vec_rol(r0, 5, r4);     \
+       vec_rol(r2, 22, r4);
+
+/* Apply the inverse linear transformation to BLOCK.  */
+#define LINEAR_TRANSFORMATION_INVERSE(r0, r1, r2, r3, r4) \
+       vec_ror(r2, 22, r4);    \
+       vec_ror(r0, 5, r4);     \
+       movdqa r1, r4;          \
+       pslld $7, r4;           \
+       pxor r3, r2;            \
+       pxor r4, r2;            \
+       pxor r1, r0;            \
+       pxor r3, r0;            \
+       vec_ror(r3, 7, r4);     \
+       vec_ror(r1, 1, r4);     \
+       movdqa r0, r4;          \
+       pslld $3, r4;           \
+       pxor r2, r3;            \
+       pxor r4, r3;            \
+       pxor r0, r1;            \
+       pxor r2, r1;            \
+       vec_ror(r2, 3, r4);     \
+       vec_ror(r0, 13, r4);
+
+/* Apply a Serpent round to eight parallel blocks.  This macro increments
+   `round'.  */
+#define ROUND(round, which, a0, a1, a2, a3, a4, na0, na1, na2, na3, na4, \
+                           b0, b1, b2, b3, b4, nb0, nb1, nb2, nb3, nb4) \
+       BLOCK_XOR_KEY (a0, a1, a2, a3, a4, round);              \
+       SBOX (which, a0, a1, a2, a3, a4);                       \
+               BLOCK_XOR_KEY (b0, b1, b2, b3, b4, round);              \
+               SBOX (which, b0, b1, b2, b3, b4);                       \
+       LINEAR_TRANSFORMATION (na0, na1, na2, na3, na4);        \
+               LINEAR_TRANSFORMATION (nb0, nb1, nb2, nb3, nb4);
+
+/* Apply the last Serpent round to eight parallel blocks.  This macro increments
+   `round'.  */
+#define ROUND_LAST(round, which, a0, a1, a2, a3, a4, na0, na1, na2, na3, na4, \
+                                b0, b1, b2, b3, b4, nb0, nb1, nb2, nb3, nb4) \
+       BLOCK_XOR_KEY (a0, a1, a2, a3, a4, round);              \
+       SBOX (which, a0, a1, a2, a3, a4);                       \
+               BLOCK_XOR_KEY (b0, b1, b2, b3, b4, round);              \
+               SBOX (which, b0, b1, b2, b3, b4);                       \
+       BLOCK_XOR_KEY (na0, na1, na2, na3, na4, ((round) + 1));         \
+               BLOCK_XOR_KEY (nb0, nb1, nb2, nb3, nb4, ((round) + 1));
+
+/* Apply an inverse Serpent round to eight parallel blocks.  This macro
+   increments `round'.  */
+#define ROUND_INVERSE(round, which, a0, a1, a2, a3, a4, \
+                                   na0, na1, na2, na3, na4, \
+                                   b0, b1, b2, b3, b4, \
+                                   nb0, nb1, nb2, nb3, nb4) \
+       LINEAR_TRANSFORMATION_INVERSE (a0, a1, a2, a3, a4);     \
+               LINEAR_TRANSFORMATION_INVERSE (b0, b1, b2, b3, b4);     \
+       SBOX_INVERSE (which, a0, a1, a2, a3, a4);               \
+       BLOCK_XOR_KEY (na0, na1, na2, na3, na4, round);         \
+               SBOX_INVERSE (which, b0, b1, b2, b3, b4);               \
+               BLOCK_XOR_KEY (nb0, nb1, nb2, nb3, nb4, round);
+
+/* Apply the first inverse Serpent round to eight parallel blocks.  This macro
+   increments `round'.  */
+#define ROUND_FIRST_INVERSE(round, which, a0, a1, a2, a3, a4, \
+                                         na0, na1, na2, na3, na4, \
+                                         b0, b1, b2, b3, b4, \
+                                         nb0, nb1, nb2, nb3, nb4) \
+       BLOCK_XOR_KEY (a0, a1, a2, a3, a4, ((round) + 1));      \
+               BLOCK_XOR_KEY (b0, b1, b2, b3, b4, ((round) + 1));      \
+       SBOX_INVERSE (which, a0, a1, a2, a3, a4);       \
+       BLOCK_XOR_KEY (na0, na1, na2, na3, na4, round); \
+               SBOX_INVERSE (which, b0, b1, b2, b3, b4);       \
+               BLOCK_XOR_KEY (nb0, nb1, nb2, nb3, nb4, round);
+
+.text
+
+.align 8
+.type   __serpent_enc_blk8,@function;
+__serpent_enc_blk8:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel plaintext
+        *                                              blocks
+        * output:
+        *      RA4, RA1, RA2, RA0, RB4, RB1, RB2, RB0: eight parallel
+        *                                              ciphertext blocks
+        */
+
+       pcmpeqd RNOT, RNOT;
+
+       transpose_4x4(RA0, RA1, RA2, RA3, RA4, RTMP0, RTMP1);
+       transpose_4x4(RB0, RB1, RB2, RB3, RB4, RTMP0, RTMP1);
+
+       ROUND (0, 0, RA0, RA1, RA2, RA3, RA4, RA1, RA4, RA2, RA0, RA3,
+                    RB0, RB1, RB2, RB3, RB4, RB1, RB4, RB2, RB0, RB3);
+       ROUND (1, 1, RA1, RA4, RA2, RA0, RA3, RA2, RA1, RA0, RA4, RA3,
+                    RB1, RB4, RB2, RB0, RB3, RB2, RB1, RB0, RB4, RB3);
+       ROUND (2, 2, RA2, RA1, RA0, RA4, RA3, RA0, RA4, RA1, RA3, RA2,
+                    RB2, RB1, RB0, RB4, RB3, RB0, RB4, RB1, RB3, RB2);
+       ROUND (3, 3, RA0, RA4, RA1, RA3, RA2, RA4, RA1, RA3, RA2, RA0,
+                    RB0, RB4, RB1, RB3, RB2, RB4, RB1, RB3, RB2, RB0);
+       ROUND (4, 4, RA4, RA1, RA3, RA2, RA0, RA1, RA0, RA4, RA2, RA3,
+                    RB4, RB1, RB3, RB2, RB0, RB1, RB0, RB4, RB2, RB3);
+       ROUND (5, 5, RA1, RA0, RA4, RA2, RA3, RA0, RA2, RA1, RA4, RA3,
+                    RB1, RB0, RB4, RB2, RB3, RB0, RB2, RB1, RB4, RB3);
+       ROUND (6, 6, RA0, RA2, RA1, RA4, RA3, RA0, RA2, RA3, RA1, RA4,
+                    RB0, RB2, RB1, RB4, RB3, RB0, RB2, RB3, RB1, RB4);
+       ROUND (7, 7, RA0, RA2, RA3, RA1, RA4, RA4, RA1, RA2, RA0, RA3,
+                    RB0, RB2, RB3, RB1, RB4, RB4, RB1, RB2, RB0, RB3);
+       ROUND (8, 0, RA4, RA1, RA2, RA0, RA3, RA1, RA3, RA2, RA4, RA0,
+                    RB4, RB1, RB2, RB0, RB3, RB1, RB3, RB2, RB4, RB0);
+       ROUND (9, 1, RA1, RA3, RA2, RA4, RA0, RA2, RA1, RA4, RA3, RA0,
+                    RB1, RB3, RB2, RB4, RB0, RB2, RB1, RB4, RB3, RB0);
+       ROUND (10, 2, RA2, RA1, RA4, RA3, RA0, RA4, RA3, RA1, RA0, RA2,
+                     RB2, RB1, RB4, RB3, RB0, RB4, RB3, RB1, RB0, RB2);
+       ROUND (11, 3, RA4, RA3, RA1, RA0, RA2, RA3, RA1, RA0, RA2, RA4,
+                     RB4, RB3, RB1, RB0, RB2, RB3, RB1, RB0, RB2, RB4);
+       ROUND (12, 4, RA3, RA1, RA0, RA2, RA4, RA1, RA4, RA3, RA2, RA0,
+                     RB3, RB1, RB0, RB2, RB4, RB1, RB4, RB3, RB2, RB0);
+       ROUND (13, 5, RA1, RA4, RA3, RA2, RA0, RA4, RA2, RA1, RA3, RA0,
+                     RB1, RB4, RB3, RB2, RB0, RB4, RB2, RB1, RB3, RB0);
+       ROUND (14, 6, RA4, RA2, RA1, RA3, RA0, RA4, RA2, RA0, RA1, RA3,
+                     RB4, RB2, RB1, RB3, RB0, RB4, RB2, RB0, RB1, RB3);
+       ROUND (15, 7, RA4, RA2, RA0, RA1, RA3, RA3, RA1, RA2, RA4, RA0,
+                     RB4, RB2, RB0, RB1, RB3, RB3, RB1, RB2, RB4, RB0);
+       ROUND (16, 0, RA3, RA1, RA2, RA4, RA0, RA1, RA0, RA2, RA3, RA4,
+                     RB3, RB1, RB2, RB4, RB0, RB1, RB0, RB2, RB3, RB4);
+       ROUND (17, 1, RA1, RA0, RA2, RA3, RA4, RA2, RA1, RA3, RA0, RA4,
+                     RB1, RB0, RB2, RB3, RB4, RB2, RB1, RB3, RB0, RB4);
+       ROUND (18, 2, RA2, RA1, RA3, RA0, RA4, RA3, RA0, RA1, RA4, RA2,
+                     RB2, RB1, RB3, RB0, RB4, RB3, RB0, RB1, RB4, RB2);
+       ROUND (19, 3, RA3, RA0, RA1, RA4, RA2, RA0, RA1, RA4, RA2, RA3,
+                     RB3, RB0, RB1, RB4, RB2, RB0, RB1, RB4, RB2, RB3);
+       ROUND (20, 4, RA0, RA1, RA4, RA2, RA3, RA1, RA3, RA0, RA2, RA4,
+                     RB0, RB1, RB4, RB2, RB3, RB1, RB3, RB0, RB2, RB4);
+       ROUND (21, 5, RA1, RA3, RA0, RA2, RA4, RA3, RA2, RA1, RA0, RA4,
+                     RB1, RB3, RB0, RB2, RB4, RB3, RB2, RB1, RB0, RB4);
+       ROUND (22, 6, RA3, RA2, RA1, RA0, RA4, RA3, RA2, RA4, RA1, RA0,
+                     RB3, RB2, RB1, RB0, RB4, RB3, RB2, RB4, RB1, RB0);
+       ROUND (23, 7, RA3, RA2, RA4, RA1, RA0, RA0, RA1, RA2, RA3, RA4,
+                     RB3, RB2, RB4, RB1, RB0, RB0, RB1, RB2, RB3, RB4);
+       ROUND (24, 0, RA0, RA1, RA2, RA3, RA4, RA1, RA4, RA2, RA0, RA3,
+                     RB0, RB1, RB2, RB3, RB4, RB1, RB4, RB2, RB0, RB3);
+       ROUND (25, 1, RA1, RA4, RA2, RA0, RA3, RA2, RA1, RA0, RA4, RA3,
+                     RB1, RB4, RB2, RB0, RB3, RB2, RB1, RB0, RB4, RB3);
+       ROUND (26, 2, RA2, RA1, RA0, RA4, RA3, RA0, RA4, RA1, RA3, RA2,
+                     RB2, RB1, RB0, RB4, RB3, RB0, RB4, RB1, RB3, RB2);
+       ROUND (27, 3, RA0, RA4, RA1, RA3, RA2, RA4, RA1, RA3, RA2, RA0,
+                     RB0, RB4, RB1, RB3, RB2, RB4, RB1, RB3, RB2, RB0);
+       ROUND (28, 4, RA4, RA1, RA3, RA2, RA0, RA1, RA0, RA4, RA2, RA3,
+                     RB4, RB1, RB3, RB2, RB0, RB1, RB0, RB4, RB2, RB3);
+       ROUND (29, 5, RA1, RA0, RA4, RA2, RA3, RA0, RA2, RA1, RA4, RA3,
+                     RB1, RB0, RB4, RB2, RB3, RB0, RB2, RB1, RB4, RB3);
+       ROUND (30, 6, RA0, RA2, RA1, RA4, RA3, RA0, RA2, RA3, RA1, RA4,
+                     RB0, RB2, RB1, RB4, RB3, RB0, RB2, RB3, RB1, RB4);
+       ROUND_LAST (31, 7, RA0, RA2, RA3, RA1, RA4, RA4, RA1, RA2, RA0, RA3,
+                          RB0, RB2, RB3, RB1, RB4, RB4, RB1, RB2, RB0, RB3);
+
+       transpose_4x4(RA4, RA1, RA2, RA0, RA3, RTMP0, RTMP1);
+       transpose_4x4(RB4, RB1, RB2, RB0, RB3, RTMP0, RTMP1);
+
+       ret;
+.size __serpent_enc_blk8,.-__serpent_enc_blk8;
+
+.align 8
+.type   __serpent_dec_blk8,@function;
+__serpent_dec_blk8:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel
+        *                                              ciphertext blocks
+        * output:
+        *      RA0, RA1, RA2, RA3, RB0, RB1, RB2, RB3: eight parallel plaintext
+        *                                              blocks
+        */
+
+       pcmpeqd RNOT, RNOT;
+
+       transpose_4x4(RA0, RA1, RA2, RA3, RA4, RTMP0, RTMP1);
+       transpose_4x4(RB0, RB1, RB2, RB3, RB4, RTMP0, RTMP1);
+
+       ROUND_FIRST_INVERSE (31, 7, RA0, RA1, RA2, RA3, RA4,
+                                   RA3, RA0, RA1, RA4, RA2,
+                                   RB0, RB1, RB2, RB3, RB4,
+                                   RB3, RB0, RB1, RB4, RB2);
+       ROUND_INVERSE (30, 6, RA3, RA0, RA1, RA4, RA2, RA0, RA1, RA2, RA4, RA3,
+                             RB3, RB0, RB1, RB4, RB2, RB0, RB1, RB2, RB4, RB3);
+       ROUND_INVERSE (29, 5, RA0, RA1, RA2, RA4, RA3, RA1, RA3, RA4, RA2, RA0,
+                             RB0, RB1, RB2, RB4, RB3, RB1, RB3, RB4, RB2, RB0);
+       ROUND_INVERSE (28, 4, RA1, RA3, RA4, RA2, RA0, RA1, RA2, RA4, RA0, RA3,
+                             RB1, RB3, RB4, RB2, RB0, RB1, RB2, RB4, RB0, RB3);
+       ROUND_INVERSE (27, 3, RA1, RA2, RA4, RA0, RA3, RA4, RA2, RA0, RA1, RA3,
+                             RB1, RB2, RB4, RB0, RB3, RB4, RB2, RB0, RB1, RB3);
+       ROUND_INVERSE (26, 2, RA4, RA2, RA0, RA1, RA3, RA2, RA3, RA0, RA1, RA4,
+                             RB4, RB2, RB0, RB1, RB3, RB2, RB3, RB0, RB1, RB4);
+       ROUND_INVERSE (25, 1, RA2, RA3, RA0, RA1, RA4, RA4, RA2, RA1, RA0, RA3,
+                             RB2, RB3, RB0, RB1, RB4, RB4, RB2, RB1, RB0, RB3);
+       ROUND_INVERSE (24, 0, RA4, RA2, RA1, RA0, RA3, RA4, RA3, RA2, RA0, RA1,
+                             RB4, RB2, RB1, RB0, RB3, RB4, RB3, RB2, RB0, RB1);
+       ROUND_INVERSE (23, 7, RA4, RA3, RA2, RA0, RA1, RA0, RA4, RA3, RA1, RA2,
+                             RB4, RB3, RB2, RB0, RB1, RB0, RB4, RB3, RB1, RB2);
+       ROUND_INVERSE (22, 6, RA0, RA4, RA3, RA1, RA2, RA4, RA3, RA2, RA1, RA0,
+                             RB0, RB4, RB3, RB1, RB2, RB4, RB3, RB2, RB1, RB0);
+       ROUND_INVERSE (21, 5, RA4, RA3, RA2, RA1, RA0, RA3, RA0, RA1, RA2, RA4,
+                             RB4, RB3, RB2, RB1, RB0, RB3, RB0, RB1, RB2, RB4);
+       ROUND_INVERSE (20, 4, RA3, RA0, RA1, RA2, RA4, RA3, RA2, RA1, RA4, RA0,
+                             RB3, RB0, RB1, RB2, RB4, RB3, RB2, RB1, RB4, RB0);
+       ROUND_INVERSE (19, 3, RA3, RA2, RA1, RA4, RA0, RA1, RA2, RA4, RA3, RA0,
+                             RB3, RB2, RB1, RB4, RB0, RB1, RB2, RB4, RB3, RB0);
+       ROUND_INVERSE (18, 2, RA1, RA2, RA4, RA3, RA0, RA2, RA0, RA4, RA3, RA1,
+                             RB1, RB2, RB4, RB3, RB0, RB2, RB0, RB4, RB3, RB1);
+       ROUND_INVERSE (17, 1, RA2, RA0, RA4, RA3, RA1, RA1, RA2, RA3, RA4, RA0,
+                             RB2, RB0, RB4, RB3, RB1, RB1, RB2, RB3, RB4, RB0);
+       ROUND_INVERSE (16, 0, RA1, RA2, RA3, RA4, RA0, RA1, RA0, RA2, RA4, RA3,
+                             RB1, RB2, RB3, RB4, RB0, RB1, RB0, RB2, RB4, RB3);
+       ROUND_INVERSE (15, 7, RA1, RA0, RA2, RA4, RA3, RA4, RA1, RA0, RA3, RA2,
+                             RB1, RB0, RB2, RB4, RB3, RB4, RB1, RB0, RB3, RB2);
+       ROUND_INVERSE (14, 6, RA4, RA1, RA0, RA3, RA2, RA1, RA0, RA2, RA3, RA4,
+                             RB4, RB1, RB0, RB3, RB2, RB1, RB0, RB2, RB3, RB4);
+       ROUND_INVERSE (13, 5, RA1, RA0, RA2, RA3, RA4, RA0, RA4, RA3, RA2, RA1,
+                             RB1, RB0, RB2, RB3, RB4, RB0, RB4, RB3, RB2, RB1);
+       ROUND_INVERSE (12, 4, RA0, RA4, RA3, RA2, RA1, RA0, RA2, RA3, RA1, RA4,
+                             RB0, RB4, RB3, RB2, RB1, RB0, RB2, RB3, RB1, RB4);
+       ROUND_INVERSE (11, 3, RA0, RA2, RA3, RA1, RA4, RA3, RA2, RA1, RA0, RA4,
+                             RB0, RB2, RB3, RB1, RB4, RB3, RB2, RB1, RB0, RB4);
+       ROUND_INVERSE (10, 2, RA3, RA2, RA1, RA0, RA4, RA2, RA4, RA1, RA0, RA3,
+                             RB3, RB2, RB1, RB0, RB4, RB2, RB4, RB1, RB0, RB3);
+       ROUND_INVERSE (9, 1, RA2, RA4, RA1, RA0, RA3, RA3, RA2, RA0, RA1, RA4,
+                            RB2, RB4, RB1, RB0, RB3, RB3, RB2, RB0, RB1, RB4);
+       ROUND_INVERSE (8, 0, RA3, RA2, RA0, RA1, RA4, RA3, RA4, RA2, RA1, RA0,
+                            RB3, RB2, RB0, RB1, RB4, RB3, RB4, RB2, RB1, RB0);
+       ROUND_INVERSE (7, 7, RA3, RA4, RA2, RA1, RA0, RA1, RA3, RA4, RA0, RA2,
+                            RB3, RB4, RB2, RB1, RB0, RB1, RB3, RB4, RB0, RB2);
+       ROUND_INVERSE (6, 6, RA1, RA3, RA4, RA0, RA2, RA3, RA4, RA2, RA0, RA1,
+                            RB1, RB3, RB4, RB0, RB2, RB3, RB4, RB2, RB0, RB1);
+       ROUND_INVERSE (5, 5, RA3, RA4, RA2, RA0, RA1, RA4, RA1, RA0, RA2, RA3,
+                            RB3, RB4, RB2, RB0, RB1, RB4, RB1, RB0, RB2, RB3);
+       ROUND_INVERSE (4, 4, RA4, RA1, RA0, RA2, RA3, RA4, RA2, RA0, RA3, RA1,
+                            RB4, RB1, RB0, RB2, RB3, RB4, RB2, RB0, RB3, RB1);
+       ROUND_INVERSE (3, 3, RA4, RA2, RA0, RA3, RA1, RA0, RA2, RA3, RA4, RA1,
+                            RB4, RB2, RB0, RB3, RB1, RB0, RB2, RB3, RB4, RB1);
+       ROUND_INVERSE (2, 2, RA0, RA2, RA3, RA4, RA1, RA2, RA1, RA3, RA4, RA0,
+                            RB0, RB2, RB3, RB4, RB1, RB2, RB1, RB3, RB4, RB0);
+       ROUND_INVERSE (1, 1, RA2, RA1, RA3, RA4, RA0, RA0, RA2, RA4, RA3, RA1,
+                            RB2, RB1, RB3, RB4, RB0, RB0, RB2, RB4, RB3, RB1);
+       ROUND_INVERSE (0, 0, RA0, RA2, RA4, RA3, RA1, RA0, RA1, RA2, RA3, RA4,
+                            RB0, RB2, RB4, RB3, RB1, RB0, RB1, RB2, RB3, RB4);
+
+       transpose_4x4(RA0, RA1, RA2, RA3, RA4, RTMP0, RTMP1);
+       transpose_4x4(RB0, RB1, RB2, RB3, RB4, RTMP0, RTMP1);
+
+       ret;
+.size __serpent_dec_blk8,.-__serpent_dec_blk8;
+
+.align 8
+.globl _gcry_serpent_sse2_ctr_enc
+.type   _gcry_serpent_sse2_ctr_enc,@function;
+_gcry_serpent_sse2_ctr_enc:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (8 blocks)
+        *      %rdx: src (8 blocks)
+        *      %rcx: iv (big endian, 128bit)
+        */
+
+       /* load IV and byteswap */
+       movdqu (%rcx), RA0;
+       movdqa RA0, RTMP0;
+       pbswap(RTMP0, RTMP1); /* be => le */
+
+       pcmpeqd RNOT, RNOT;
+       psrldq $8, RNOT; /* low: -1, high: 0 */
+       movdqa RNOT, RTMP2;
+       paddq RTMP2, RTMP2; /* low: -2, high: 0 */
+
+       /* construct IVs */
+       movdqa RTMP0, RTMP1;
+       psubq RNOT, RTMP0; /* +1 */
+       movdqa RTMP0, RA1;
+       psubq RTMP2, RTMP1; /* +2 */
+       movdqa RTMP1, RA2;
+       psubq RTMP2, RTMP0; /* +3 */
+       movdqa RTMP0, RA3;
+       psubq RTMP2, RTMP1; /* +4 */
+       movdqa RTMP1, RB0;
+       psubq RTMP2, RTMP0; /* +5 */
+       movdqa RTMP0, RB1;
+       psubq RTMP2, RTMP1; /* +6 */
+       movdqa RTMP1, RB2;
+       psubq RTMP2, RTMP0; /* +7 */
+       movdqa RTMP0, RB3;
+       psubq RTMP2, RTMP1; /* +8 */
+
+       /* check need for handling 64-bit overflow and carry */
+       cmpl $0xffffffff, 8(%rcx);
+       jne .Lno_ctr_carry;
+
+       movl 12(%rcx), %eax;
+       bswapl %eax;
+       cmpl $-8, %eax;
+       jb .Lno_ctr_carry;
+       pslldq $8, RNOT; /* low: 0, high: -1 */
+       je .Lcarry_RTMP0;
+
+       cmpl $-6, %eax;
+       jb .Lcarry_RB3;
+       je .Lcarry_RB2;
+
+       cmpl $-4, %eax;
+       jb .Lcarry_RB1;
+       je .Lcarry_RB0;
+
+       cmpl $-2, %eax;
+       jb .Lcarry_RA3;
+       je .Lcarry_RA2;
+
+       psubq RNOT, RA1;
+.Lcarry_RA2:
+       psubq RNOT, RA2;
+.Lcarry_RA3:
+       psubq RNOT, RA3;
+.Lcarry_RB0:
+       psubq RNOT, RB0;
+.Lcarry_RB1:
+       psubq RNOT, RB1;
+.Lcarry_RB2:
+       psubq RNOT, RB2;
+.Lcarry_RB3:
+       psubq RNOT, RB3;
+.Lcarry_RTMP0:
+       psubq RNOT, RTMP1;
+
+.Lno_ctr_carry:
+       /* le => be */
+       pbswap(RA1, RTMP0);
+       pbswap(RA2, RTMP0);
+       pbswap(RA3, RTMP0);
+       pbswap(RB0, RTMP0);
+       pbswap(RB1, RTMP0);
+       pbswap(RB2, RTMP0);
+       pbswap(RB3, RTMP0);
+       pbswap(RTMP1, RTMP0);
+       /* store new IV */
+       movdqu RTMP1, (%rcx);
+
+       call __serpent_enc_blk8;
+
+       pxor_u((0 * 16)(%rdx), RA4, RTMP0);
+       pxor_u((1 * 16)(%rdx), RA1, RTMP0);
+       pxor_u((2 * 16)(%rdx), RA2, RTMP0);
+       pxor_u((3 * 16)(%rdx), RA0, RTMP0);
+       pxor_u((4 * 16)(%rdx), RB4, RTMP0);
+       pxor_u((5 * 16)(%rdx), RB1, RTMP0);
+       pxor_u((6 * 16)(%rdx), RB2, RTMP0);
+       pxor_u((7 * 16)(%rdx), 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
+.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;
+_gcry_serpent_sse2_cbc_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (8 blocks)
+        *      %rdx: src (8 blocks)
+        *      %rcx: iv
+        */
+
+       movdqu (0 * 16)(%rdx), RA0;
+       movdqu (1 * 16)(%rdx), RA1;
+       movdqu (2 * 16)(%rdx), RA2;
+       movdqu (3 * 16)(%rdx), RA3;
+       movdqu (4 * 16)(%rdx), RB0;
+       movdqu (5 * 16)(%rdx), RB1;
+       movdqu (6 * 16)(%rdx), RB2;
+       movdqu (7 * 16)(%rdx), RB3;
+
+       call __serpent_dec_blk8;
+
+       movdqu (7 * 16)(%rdx), RNOT;
+       pxor_u((%rcx), RA0, RTMP0);
+       pxor_u((0 * 16)(%rdx), RA1, RTMP0);
+       pxor_u((1 * 16)(%rdx), RA2, RTMP0);
+       pxor_u((2 * 16)(%rdx), RA3, RTMP0);
+       pxor_u((3 * 16)(%rdx), RB0, RTMP0);
+       pxor_u((4 * 16)(%rdx), RB1, RTMP0);
+       pxor_u((5 * 16)(%rdx), RB2, RTMP0);
+       pxor_u((6 * 16)(%rdx), RB3, RTMP0);
+       movdqu RNOT, (%rcx); /* store new IV */
+
+       movdqu RA0, (0 * 16)(%rsi);
+       movdqu RA1, (1 * 16)(%rsi);
+       movdqu RA2, (2 * 16)(%rsi);
+       movdqu RA3, (3 * 16)(%rsi);
+       movdqu RB0, (4 * 16)(%rsi);
+       movdqu RB1, (5 * 16)(%rsi);
+       movdqu RB2, (6 * 16)(%rsi);
+       movdqu RB3, (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
+.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;
+_gcry_serpent_sse2_cfb_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (8 blocks)
+        *      %rdx: src (8 blocks)
+        *      %rcx: iv
+        */
+
+       /* Load input */
+       movdqu (%rcx), RA0;
+       movdqu 0 * 16(%rdx), RA1;
+       movdqu 1 * 16(%rdx), RA2;
+       movdqu 2 * 16(%rdx), RA3;
+       movdqu 3 * 16(%rdx), RB0;
+       movdqu 4 * 16(%rdx), RB1;
+       movdqu 5 * 16(%rdx), RB2;
+       movdqu 6 * 16(%rdx), RB3;
+
+       /* Update IV */
+       movdqu 7 * 16(%rdx), RNOT;
+       movdqu RNOT, (%rcx);
+
+       call __serpent_enc_blk8;
+
+       pxor_u((0 * 16)(%rdx), RA4, RTMP0);
+       pxor_u((1 * 16)(%rdx), RA1, RTMP0);
+       pxor_u((2 * 16)(%rdx), RA2, RTMP0);
+       pxor_u((3 * 16)(%rdx), RA0, RTMP0);
+       pxor_u((4 * 16)(%rdx), RB4, RTMP0);
+       pxor_u((5 * 16)(%rdx), RB1, RTMP0);
+       pxor_u((6 * 16)(%rdx), RB2, RTMP0);
+       pxor_u((7 * 16)(%rdx), 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
+.size _gcry_serpent_sse2_cfb_dec,.-_gcry_serpent_sse2_cfb_dec;
+
+#endif /*defined(USE_SERPENT)*/
+#endif /*__x86_64*/
index a78e018..8e647d4 100644 (file)
 #include "g10lib.h"
 #include "cipher.h"
 #include "bithelp.h"
+#include "bufhelp.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)
+# 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(ENABLE_AVX2_SUPPORT)
+#  define USE_AVX2 1
+# endif
+#endif
+
+/* USE_NEON indicates whether to enable ARM NEON assembly code. */
+#undef USE_NEON
+#if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__)
+# if defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+     defined(HAVE_GCC_INLINE_ASM_NEON)
+#  define USE_NEON 1
+# endif
+#endif
+
 
 /* Number of rounds per Serpent encrypt/decrypt operation.  */
 #define ROUNDS 32
@@ -49,415 +76,378 @@ typedef u32 serpent_subkeys_t[ROUNDS + 1][4];
 typedef struct serpent_context
 {
   serpent_subkeys_t keys;      /* Generated subkeys.  */
+
+#ifdef USE_AVX2
+  int use_avx2;
+#endif
+#ifdef USE_NEON
+  int use_neon;
+#endif
 } serpent_context_t;
 
 
-/* A prototype.  */
-static const char *serpent_test (void);
+#ifdef USE_SSE2
+/* Assembler implementations of Serpent using SSE2.  Process 8 block in
+   parallel.
+ */
+extern void _gcry_serpent_sse2_ctr_enc(serpent_context_t *ctx,
+                                      unsigned char *out,
+                                      const unsigned char *in,
+                                      unsigned char *ctr);
+
+extern void _gcry_serpent_sse2_cbc_dec(serpent_context_t *ctx,
+                                      unsigned char *out,
+                                      const unsigned char *in,
+                                      unsigned char *iv);
+
+extern void _gcry_serpent_sse2_cfb_dec(serpent_context_t *ctx,
+                                      unsigned char *out,
+                                      const unsigned char *in,
+                                      unsigned char *iv);
+#endif
 
+#ifdef USE_AVX2
+/* Assembler implementations of Serpent using SSE2.  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);
+
+extern void _gcry_serpent_avx2_cbc_dec(serpent_context_t *ctx,
+                                      unsigned char *out,
+                                      const unsigned char *in,
+                                      unsigned char *iv);
+
+extern void _gcry_serpent_avx2_cfb_dec(serpent_context_t *ctx,
+                                      unsigned char *out,
+                                      const unsigned char *in,
+                                      unsigned char *iv);
+#endif
 
-#define byte_swap_32(x) \
-  (0 \
-   | (((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) \
-   | (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
+#ifdef USE_NEON
+/* Assembler implementations of Serpent using ARM NEON.  Process 8 block in
+   parallel.
+ */
+extern void _gcry_serpent_neon_ctr_enc(serpent_context_t *ctx,
+                                      unsigned char *out,
+                                      const unsigned char *in,
+                                      unsigned char *ctr);
+
+extern void _gcry_serpent_neon_cbc_dec(serpent_context_t *ctx,
+                                      unsigned char *out,
+                                      const unsigned char *in,
+                                      unsigned char *iv);
+
+extern void _gcry_serpent_neon_cfb_dec(serpent_context_t *ctx,
+                                      unsigned char *out,
+                                      const unsigned char *in,
+                                      unsigned char *iv);
+#endif
 
-/* These are the S-Boxes of Serpent.  They are copied from Serpents
-   reference implementation (the optimized one, contained in
-   `floppy2') and are therefore:
 
-     Copyright (C) 1998 Ross Anderson, Eli Biham, Lars Knudsen.
+/* A prototype.  */
+static const char *serpent_test (void);
 
-  To quote the Serpent homepage
-  (http://www.cl.cam.ac.uk/~rja14/serpent.html):
 
-  "Serpent is now completely in the public domain, and we impose no
-   restrictions on its use.  This was announced on the 21st August at
-   the First AES Candidate Conference. The optimised implementations
-   in the submission package are now under the GNU PUBLIC LICENSE
-   (GPL), although some comments in the code still say otherwise. You
-   are welcome to use Serpent for any application."  */
+/*
+ * These are the S-Boxes of Serpent from following research paper.
+ *
+ *  D. A. Osvik, “Speeding up Serpent,” in Third AES Candidate Conference,
+ *   (New York, New York, USA), p. 317–329, National Institute of Standards and
+ *   Technology, 2000.
+ *
+ * Paper is also available at: http://www.ii.uib.no/~osvik/pub/aes3.pdf
+ *
+ */
 
-#define SBOX0(a, b, c, d, w, x, y, z) \
+#define SBOX0(r0, r1, r2, r3, w, x, y, z) \
   { \
-    u32 t02, t03, t05, t06, t07, t08, t09; \
-    u32 t11, t12, t13, t14, t15, t17, t01; \
-    t01 = b   ^ c  ; \
-    t02 = a   | d  ; \
-    t03 = a   ^ b  ; \
-    z   = t02 ^ t01; \
-    t05 = c   | z  ; \
-    t06 = a   ^ d  ; \
-    t07 = b   | c  ; \
-    t08 = d   & t05; \
-    t09 = t03 & t07; \
-    y   = t09 ^ t08; \
-    t11 = t09 & y  ; \
-    t12 = c   ^ d  ; \
-    t13 = t07 ^ t11; \
-    t14 = b   & t06; \
-    t15 = t06 ^ t13; \
-    w   =     ~ t15; \
-    t17 = w   ^ t14; \
-    x   = t12 ^ t17; \
+    u32 r4; \
+    \
+    r3 ^= r0; r4 =  r1; \
+    r1 &= r3; r4 ^= r2; \
+    r1 ^= r0; r0 |= r3; \
+    r0 ^= r4; r4 ^= r3; \
+    r3 ^= r2; r2 |= r1; \
+    r2 ^= r4; r4 = ~r4; \
+    r4 |= r1; r1 ^= r3; \
+    r1 ^= r4; r3 |= r0; \
+    r1 ^= r3; r4 ^= r3; \
+    \
+    w = r1; x = r4; y = r2; z = r0; \
   }
 
-#define SBOX0_INVERSE(a, b, c, d, w, x, y, z) \
+#define SBOX0_INVERSE(r0, r1, r2, r3, w, x, y, z) \
   { \
-    u32 t02, t03, t04, t05, t06, t08, t09, t10; \
-    u32 t12, t13, t14, t15, t17, t18, t01; \
-    t01 = c   ^ d  ; \
-    t02 = a   | b  ; \
-    t03 = b   | c  ; \
-    t04 = c   & t01; \
-    t05 = t02 ^ t01; \
-    t06 = a   | t04; \
-    y   =     ~ t05; \
-    t08 = b   ^ d  ; \
-    t09 = t03 & t08; \
-    t10 = d   | y  ; \
-    x   = t09 ^ t06; \
-    t12 = a   | t05; \
-    t13 = x   ^ t12; \
-    t14 = t03 ^ t10; \
-    t15 = a   ^ c  ; \
-    z   = t14 ^ t13; \
-    t17 = t05 & t13; \
-    t18 = t14 | t17; \
-    w   = t15 ^ t18; \
+    u32 r4; \
+    \
+    r2 = ~r2; r4 =  r1; \
+    r1 |= r0; r4 = ~r4; \
+    r1 ^= r2; r2 |= r4; \
+    r1 ^= r3; r0 ^= r4; \
+    r2 ^= r0; r0 &= r3; \
+    r4 ^= r0; r0 |= r1; \
+    r0 ^= r2; r3 ^= r4; \
+    r2 ^= r1; r3 ^= r0; \
+    r3 ^= r1; \
+    r2 &= r3; \
+    r4 ^= r2; \
+    \
+    w = r0; x = r4; y = r1; z = r3; \
   }
 
-#define SBOX1(a, b, c, d, w, x, y, z) \
+#define SBOX1(r0, r1, r2, r3, w, x, y, z) \
   { \
-    u32 t02, t03, t04, t05, t06, t07, t08; \
-    u32 t10, t11, t12, t13, t16, t17, t01; \
-    t01 = a   | d  ; \
-    t02 = c   ^ d  ; \
-    t03 =     ~ b  ; \
-    t04 = a   ^ c  ; \
-    t05 = a   | t03; \
-    t06 = d   & t04; \
-    t07 = t01 & t02; \
-    t08 = b   | t06; \
-    y   = t02 ^ t05; \
-    t10 = t07 ^ t08; \
-    t11 = t01 ^ t10; \
-    t12 = y   ^ t11; \
-    t13 = b   & d  ; \
-    z   =     ~ t10; \
-    x   = t13 ^ t12; \
-    t16 = t10 | x  ; \
-    t17 = t05 & t16; \
-    w   = c   ^ t17; \
+    u32 r4; \
+    \
+    r0 = ~r0; r2 = ~r2; \
+    r4 =  r0; r0 &= r1; \
+    r2 ^= r0; r0 |= r3; \
+    r3 ^= r2; r1 ^= r0; \
+    r0 ^= r4; r4 |= r1; \
+    r1 ^= r3; r2 |= r0; \
+    r2 &= r4; r0 ^= r1; \
+    r1 &= r2; \
+    r1 ^= r0; r0 &= r2; \
+    r0 ^= r4; \
+    \
+    w = r2; x = r0; y = r3; z = r1; \
   }
 
-#define SBOX1_INVERSE(a, b, c, d, w, x, y, z) \
+#define SBOX1_INVERSE(r0, r1, r2, r3, w, x, y, z) \
   { \
-    u32 t02, t03, t04, t05, t06, t07, t08; \
-    u32 t09, t10, t11, t14, t15, t17, t01; \
-    t01 = a   ^ b  ; \
-    t02 = b   | d  ; \
-    t03 = a   & c  ; \
-    t04 = c   ^ t02; \
-    t05 = a   | t04; \
-    t06 = t01 & t05; \
-    t07 = d   | t03; \
-    t08 = b   ^ t06; \
-    t09 = t07 ^ t06; \
-    t10 = t04 | t03; \
-    t11 = d   & t08; \
-    y   =     ~ t09; \
-    x   = t10 ^ t11; \
-    t14 = a   | y  ; \
-    t15 = t06 ^ x  ; \
-    z   = t01 ^ t04; \
-    t17 = c   ^ t15; \
-    w   = t14 ^ t17; \
+    u32 r4; \
+    \
+    r4 =  r1; r1 ^= r3; \
+    r3 &= r1; r4 ^= r2; \
+    r3 ^= r0; r0 |= r1; \
+    r2 ^= r3; r0 ^= r4; \
+    r0 |= r2; r1 ^= r3; \
+    r0 ^= r1; r1 |= r3; \
+    r1 ^= r0; r4 = ~r4; \
+    r4 ^= r1; r1 |= r0; \
+    r1 ^= r0; \
+    r1 |= r4; \
+    r3 ^= r1; \
+    \
+    w = r4; x = r0; y = r3; z = r2; \
   }
 
-#define SBOX2(a, b, c, d, w, x, y, z) \
+#define SBOX2(r0, r1, r2, r3, w, x, y, z) \
   { \
-    u32 t02, t03, t05, t06, t07, t08; \
-    u32 t09, t10, t12, t13, t14, t01; \
-    t01 = a   | c  ; \
-    t02 = a   ^ b  ; \
-    t03 = d   ^ t01; \
-    w   = t02 ^ t03; \
-    t05 = c   ^ w  ; \
-    t06 = b   ^ t05; \
-    t07 = b   | t05; \
-    t08 = t01 & t06; \
-    t09 = t03 ^ t07; \
-    t10 = t02 | t09; \
-    x   = t10 ^ t08; \
-    t12 = a   | d  ; \
-    t13 = t09 ^ x  ; \
-    t14 = b   ^ t13; \
-    z   =     ~ t09; \
-    y   = t12 ^ t14; \
+    u32 r4; \
+    \
+    r4 =  r0; r0 &= r2; \
+    r0 ^= r3; r2 ^= r1; \
+    r2 ^= r0; r3 |= r4; \
+    r3 ^= r1; r4 ^= r2; \
+    r1 =  r3; r3 |= r4; \
+    r3 ^= r0; r0 &= r1; \
+    r4 ^= r0; r1 ^= r3; \
+    r1 ^= r4; r4 = ~r4; \
+    \
+    w = r2; x = r3; y = r1; z = r4; \
   }
 
-#define SBOX2_INVERSE(a, b, c, d, w, x, y, z) \
+#define SBOX2_INVERSE(r0, r1, r2, r3, w, x, y, z) \
   { \
-    u32 t02, t03, t04, t06, t07, t08, t09; \
-    u32 t10, t11, t12, t15, t16, t17, t01; \
-    t01 = a   ^ d  ; \
-    t02 = c   ^ d  ; \
-    t03 = a   & c  ; \
-    t04 = b   | t02; \
-    w   = t01 ^ t04; \
-    t06 = a   | c  ; \
-    t07 = d   | w  ; \
-    t08 =     ~ d  ; \
-    t09 = b   & t06; \
-    t10 = t08 | t03; \
-    t11 = b   & t07; \
-    t12 = t06 & t02; \
-    z   = t09 ^ t10; \
-    x   = t12 ^ t11; \
-    t15 = c   & z  ; \
-    t16 = w   ^ x  ; \
-    t17 = t10 ^ t15; \
-    y   = t16 ^ t17; \
+    u32 r4; \
+    \
+    r2 ^= r3; r3 ^= r0; \
+    r4 =  r3; r3 &= r2; \
+    r3 ^= r1; r1 |= r2; \
+    r1 ^= r4; r4 &= r3; \
+    r2 ^= r3; r4 &= r0; \
+    r4 ^= r2; r2 &= r1; \
+    r2 |= r0; r3 = ~r3; \
+    r2 ^= r3; r0 ^= r3; \
+    r0 &= r1; r3 ^= r4; \
+    r3 ^= r0; \
+    \
+    w = r1; x = r4; y = r2; z = r3; \
   }
 
-#define SBOX3(a, b, c, d, w, x, y, z) \
+#define SBOX3(r0, r1, r2, r3, w, x, y, z) \
   { \
-    u32 t02, t03, t04, t05, t06, t07, t08; \
-    u32 t09, t10, t11, t13, t14, t15, t01; \
-    t01 = a   ^ c  ; \
-    t02 = a   | d  ; \
-    t03 = a   & d  ; \
-    t04 = t01 & t02; \
-    t05 = b   | t03; \
-    t06 = a   & b  ; \
-    t07 = d   ^ t04; \
-    t08 = c   | t06; \
-    t09 = b   ^ t07; \
-    t10 = d   & t05; \
-    t11 = t02 ^ t10; \
-    z   = t08 ^ t09; \
-    t13 = d   | z  ; \
-    t14 = a   | t07; \
-    t15 = b   & t13; \
-    y   = t08 ^ t11; \
-    w   = t14 ^ t15; \
-    x   = t05 ^ t04; \
+    u32 r4; \
+    \
+    r4 =  r0; r0 |= r3; \
+    r3 ^= r1; r1 &= r4; \
+    r4 ^= r2; r2 ^= r3; \
+    r3 &= r0; r4 |= r1; \
+    r3 ^= r4; r0 ^= r1; \
+    r4 &= r0; r1 ^= r3; \
+    r4 ^= r2; r1 |= r0; \
+    r1 ^= r2; r0 ^= r3; \
+    r2 =  r1; r1 |= r3; \
+    r1 ^= r0; \
+    \
+    w = r1; x = r2; y = r3; z = r4; \
   }
 
-#define SBOX3_INVERSE(a, b, c, d, w, x, y, z) \
+#define SBOX3_INVERSE(r0, r1, r2, r3, w, x, y, z) \
   { \
-    u32 t02, t03, t04, t05, t06, t07, t09; \
-    u32 t11, t12, t13, t14, t16, t01; \
-    t01 = c   | d  ; \
-    t02 = a   | d  ; \
-    t03 = c   ^ t02; \
-    t04 = b   ^ t02; \
-    t05 = a   ^ d  ; \
-    t06 = t04 & t03; \
-    t07 = b   & t01; \
-    y   = t05 ^ t06; \
-    t09 = a   ^ t03; \
-    w   = t07 ^ t03; \
-    t11 = w   | t05; \
-    t12 = t09 & t11; \
-    t13 = a   & y  ; \
-    t14 = t01 ^ t05; \
-    x   = b   ^ t12; \
-    t16 = b   | t13; \
-    z   = t14 ^ t16; \
+    u32 r4; \
+    \
+    r4 =  r2; r2 ^= r1; \
+    r0 ^= r2; r4 &= r2; \
+    r4 ^= r0; r0 &= r1; \
+    r1 ^= r3; r3 |= r4; \
+    r2 ^= r3; r0 ^= r3; \
+    r1 ^= r4; r3 &= r2; \
+    r3 ^= r1; r1 ^= r0; \
+    r1 |= r2; r0 ^= r3; \
+    r1 ^= r4; \
+    r0 ^= r1; \
+    \
+    w = r2; x = r1; y = r3; z = r0; \
   }
 
-#define SBOX4(a, b, c, d, w, x, y, z) \
+#define SBOX4(r0, r1, r2, r3, w, x, y, z) \
   { \
-    u32 t02, t03, t04, t05, t06, t08, t09; \
-    u32 t10, t11, t12, t13, t14, t15, t16, t01; \
-    t01 = a   | b  ; \
-    t02 = b   | c  ; \
-    t03 = a   ^ t02; \
-    t04 = b   ^ d  ; \
-    t05 = d   | t03; \
-    t06 = d   & t01; \
-    z   = t03 ^ t06; \
-    t08 = z   & t04; \
-    t09 = t04 & t05; \
-    t10 = c   ^ t06; \
-    t11 = b   & c  ; \
-    t12 = t04 ^ t08; \
-    t13 = t11 | t03; \
-    t14 = t10 ^ t09; \
-    t15 = a   & t05; \
-    t16 = t11 | t12; \
-    y   = t13 ^ t08; \
-    x   = t15 ^ t16; \
-    w   =     ~ t14; \
+    u32 r4; \
+    \
+    r1 ^= r3; r3 = ~r3; \
+    r2 ^= r3; r3 ^= r0; \
+    r4 =  r1; r1 &= r3; \
+    r1 ^= r2; r4 ^= r3; \
+    r0 ^= r4; r2 &= r4; \
+    r2 ^= r0; r0 &= r1; \
+    r3 ^= r0; r4 |= r1; \
+    r4 ^= r0; r0 |= r3; \
+    r0 ^= r2; r2 &= r3; \
+    r0 = ~r0; r4 ^= r2; \
+    \
+    w = r1; x = r4; y = r0; z = r3; \
   }
 
-#define SBOX4_INVERSE(a, b, c, d, w, x, y, z) \
+#define SBOX4_INVERSE(r0, r1, r2, r3, w, x, y, z) \
   { \
-    u32 t02, t03, t04, t05, t06, t07, t09; \
-    u32 t10, t11, t12, t13, t15, t01; \
-    t01 = b   | d  ; \
-    t02 = c   | d  ; \
-    t03 = a   & t01; \
-    t04 = b   ^ t02; \
-    t05 = c   ^ d  ; \
-    t06 =     ~ t03; \
-    t07 = a   & t04; \
-    x   = t05 ^ t07; \
-    t09 = x   | t06; \
-    t10 = a   ^ t07; \
-    t11 = t01 ^ t09; \
-    t12 = d   ^ t04; \
-    t13 = c   | t10; \
-    z   = t03 ^ t12; \
-    t15 = a   ^ t04; \
-    y   = t11 ^ t13; \
-    w   = t15 ^ t09; \
+    u32 r4; \
+    \
+    r4 =  r2; r2 &= r3; \
+    r2 ^= r1; r1 |= r3; \
+    r1 &= r0; r4 ^= r2; \
+    r4 ^= r1; r1 &= r2; \
+    r0 = ~r0; r3 ^= r4; \
+    r1 ^= r3; r3 &= r0; \
+    r3 ^= r2; r0 ^= r1; \
+    r2 &= r0; r3 ^= r0; \
+    r2 ^= r4; \
+    r2 |= r3; r3 ^= r0; \
+    r2 ^= r1; \
+    \
+    w = r0; x = r3; y = r2; z = r4; \
   }
 
-#define SBOX5(a, b, c, d, w, x, y, z) \
+#define SBOX5(r0, r1, r2, r3, w, x, y, z) \
   { \
-    u32 t02, t03, t04, t05, t07, t08, t09; \
-    u32 t10, t11, t12, t13, t14, t01; \
-    t01 = b   ^ d  ; \
-    t02 = b   | d  ; \
-    t03 = a   & t01; \
-    t04 = c   ^ t02; \
-    t05 = t03 ^ t04; \
-    w   =     ~ t05; \
-    t07 = a   ^ t01; \
-    t08 = d   | w  ; \
-    t09 = b   | t05; \
-    t10 = d   ^ t08; \
-    t11 = b   | t07; \
-    t12 = t03 | w  ; \
-    t13 = t07 | t10; \
-    t14 = t01 ^ t11; \
-    y   = t09 ^ t13; \
-    x   = t07 ^ t08; \
-    z   = t12 ^ t14; \
+    u32 r4; \
+    \
+    r0 ^= r1; r1 ^= r3; \
+    r3 = ~r3; r4 =  r1; \
+    r1 &= r0; r2 ^= r3; \
+    r1 ^= r2; r2 |= r4; \
+    r4 ^= r3; r3 &= r1; \
+    r3 ^= r0; r4 ^= r1; \
+    r4 ^= r2; r2 ^= r0; \
+    r0 &= r3; r2 = ~r2; \
+    r0 ^= r4; r4 |= r3; \
+    r2 ^= r4; \
+    \
+    w = r1; x = r3; y = r0; z = r2; \
   }
 
-#define SBOX5_INVERSE(a, b, c, d, w, x, y, z) \
+#define SBOX5_INVERSE(r0, r1, r2, r3, w, x, y, z) \
   { \
-    u32 t02, t03, t04, t05, t07, t08, t09; \
-    u32 t10, t12, t13, t15, t16, t01; \
-    t01 = a   & d  ; \
-    t02 = c   ^ t01; \
-    t03 = a   ^ d  ; \
-    t04 = b   & t02; \
-    t05 = a   & c  ; \
-    w   = t03 ^ t04; \
-    t07 = a   & w  ; \
-    t08 = t01 ^ w  ; \
-    t09 = b   | t05; \
-    t10 =     ~ b  ; \
-    x   = t08 ^ t09; \
-    t12 = t10 | t07; \
-    t13 = w   | x  ; \
-    z   = t02 ^ t12; \
-    t15 = t02 ^ t13; \
-    t16 = b   ^ d  ; \
-    y   = t16 ^ t15; \
+    u32 r4; \
+    \
+    r1 = ~r1; r4 =  r3; \
+    r2 ^= r1; r3 |= r0; \
+    r3 ^= r2; r2 |= r1; \
+    r2 &= r0; r4 ^= r3; \
+    r2 ^= r4; r4 |= r0; \
+    r4 ^= r1; r1 &= r2; \
+    r1 ^= r3; r4 ^= r2; \
+    r3 &= r4; r4 ^= r1; \
+    r3 ^= r4; r4 = ~r4; \
+    r3 ^= r0; \
+    \
+    w = r1; x = r4; y = r3; z = r2; \
   }
 
-#define SBOX6(a, b, c, d, w, x, y, z) \
+#define SBOX6(r0, r1, r2, r3, w, x, y, z) \
   { \
-    u32 t02, t03, t04, t05, t07, t08, t09, t10; \
-    u32 t11, t12, t13, t15, t17, t18, t01; \
-    t01 = a   & d  ; \
-    t02 = b   ^ c  ; \
-    t03 = a   ^ d  ; \
-    t04 = t01 ^ t02; \
-    t05 = b   | c  ; \
-    x   =     ~ t04; \
-    t07 = t03 & t05; \
-    t08 = b   & x  ; \
-    t09 = a   | c  ; \
-    t10 = t07 ^ t08; \
-    t11 = b   | d  ; \
-    t12 = c   ^ t11; \
-    t13 = t09 ^ t10; \
-    y   =     ~ t13; \
-    t15 = x   & t03; \
-    z   = t12 ^ t07; \
-    t17 = a   ^ b  ; \
-    t18 = y   ^ t15; \
-    w   = t17 ^ t18; \
+    u32 r4; \
+    \
+    r2 = ~r2; r4 =  r3; \
+    r3 &= r0; r0 ^= r4; \
+    r3 ^= r2; r2 |= r4; \
+    r1 ^= r3; r2 ^= r0; \
+    r0 |= r1; r2 ^= r1; \
+    r4 ^= r0; r0 |= r3; \
+    r0 ^= r2; r4 ^= r3; \
+    r4 ^= r0; r3 = ~r3; \
+    r2 &= r4; \
+    r2 ^= r3; \
+    \
+    w = r0; x = r1; y = r4; z = r2; \
   }
 
-#define SBOX6_INVERSE(a, b, c, d, w, x, y, z) \
+#define SBOX6_INVERSE(r0, r1, r2, r3, w, x, y, z) \
   { \
-    u32 t02, t03, t04, t05, t06, t07, t08, t09; \
-    u32 t12, t13, t14, t15, t16, t17, t01; \
-    t01 = a   ^ c  ; \
-    t02 =     ~ c  ; \
-    t03 = b   & t01; \
-    t04 = b   | t02; \
-    t05 = d   | t03; \
-    t06 = b   ^ d  ; \
-    t07 = a   & t04; \
-    t08 = a   | t02; \
-    t09 = t07 ^ t05; \
-    x   = t06 ^ t08; \
-    w   =     ~ t09; \
-    t12 = b   & w  ; \
-    t13 = t01 & t05; \
-    t14 = t01 ^ t12; \
-    t15 = t07 ^ t13; \
-    t16 = d   | t02; \
-    t17 = a   ^ x  ; \
-    z   = t17 ^ t15; \
-    y   = t16 ^ t14; \
+    u32 r4; \
+    \
+    r0 ^= r2; r4 =  r2; \
+    r2 &= r0; r4 ^= r3; \
+    r2 = ~r2; r3 ^= r1; \
+    r2 ^= r3; r4 |= r0; \
+    r0 ^= r2; r3 ^= r4; \
+    r4 ^= r1; r1 &= r3; \
+    r1 ^= r0; r0 ^= r3; \
+    r0 |= r2; r3 ^= r1; \
+    r4 ^= r0; \
+    \
+    w = r1; x = r2; y = r4; z = r3; \
   }
 
-#define SBOX7(a, b, c, d, w, x, y, z) \
+#define SBOX7(r0, r1, r2, r3, w, x, y, z) \
   { \
-    u32 t02, t03, t04, t05, t06, t08, t09, t10; \
-    u32 t11, t13, t14, t15, t16, t17, t01; \
-    t01 = a   & c  ; \
-    t02 =     ~ d  ; \
-    t03 = a   & t02; \
-    t04 = b   | t01; \
-    t05 = a   & b  ; \
-    t06 = c   ^ t04; \
-    z   = t03 ^ t06; \
-    t08 = c   | z  ; \
-    t09 = d   | t05; \
-    t10 = a   ^ t08; \
-    t11 = t04 & z  ; \
-    x   = t09 ^ t10; \
-    t13 = b   ^ x  ; \
-    t14 = t01 ^ x  ; \
-    t15 = c   ^ t05; \
-    t16 = t11 | t13; \
-    t17 = t02 | t14; \
-    w   = t15 ^ t17; \
-    y   = a   ^ t16; \
+    u32 r4; \
+    \
+    r4 =  r1; r1 |= r2; \
+    r1 ^= r3; r4 ^= r2; \
+    r2 ^= r1; r3 |= r4; \
+    r3 &= r0; r4 ^= r2; \
+    r3 ^= r1; r1 |= r4; \
+    r1 ^= r0; r0 |= r4; \
+    r0 ^= r2; r1 ^= r4; \
+    r2 ^= r1; r1 &= r0; \
+    r1 ^= r4; r2 = ~r2; \
+    r2 |= r0; \
+    r4 ^= r2; \
+    \
+    w = r4; x = r3; y = r1; z = r0; \
   }
 
-#define SBOX7_INVERSE(a, b, c, d, w, x, y, z) \
+#define SBOX7_INVERSE(r0, r1, r2, r3, w, x, y, z) \
   { \
-    u32 t02, t03, t04, t06, t07, t08, t09; \
-    u32 t10, t11, t13, t14, t15, t16, t01; \
-    t01 = a   & b  ; \
-    t02 = a   | b  ; \
-    t03 = c   | t01; \
-    t04 = d   & t02; \
-    z   = t03 ^ t04; \
-    t06 = b   ^ t04; \
-    t07 = d   ^ z  ; \
-    t08 =     ~ t07; \
-    t09 = t06 | t08; \
-    t10 = b   ^ d  ; \
-    t11 = a   | d  ; \
-    x   = a   ^ t09; \
-    t13 = c   ^ t06; \
-    t14 = c   & t11; \
-    t15 = d   | x  ; \
-    t16 = t01 | t10; \
-    w   = t13 ^ t15; \
-    y   = t14 ^ t16; \
+    u32 r4; \
+    \
+    r4 =  r2; r2 ^= r0; \
+    r0 &= r3; r4 |= r3; \
+    r2 = ~r2; r3 ^= r1; \
+    r1 |= r0; r0 ^= r2; \
+    r2 &= r4; r3 &= r4; \
+    r1 ^= r2; r2 ^= r0; \
+    r0 |= r2; r4 ^= r1; \
+    r0 ^= r3; r3 ^= r4; \
+    r4 |= r0; r3 ^= r2; \
+    r4 ^= r2; \
+    \
+    w = r3; x = r0; y = r1; z = r4; \
   }
 
 /* XOR BLOCK1 into BLOCK0.  */
@@ -478,23 +468,17 @@ static const char *serpent_test (void);
     block_dst[3] = block_src[3];         \
   }
 
-/* Apply SBOX number WHICH to to the block found in ARRAY0 at index
-   INDEX, writing the output to the block found in ARRAY1 at index
-   INDEX.  */
-#define SBOX(which, array0, array1, index)            \
-  SBOX##which (array0[index + 0], array0[index + 1],  \
-               array0[index + 2], array0[index + 3],  \
-               array1[index + 0], array1[index + 1],  \
-               array1[index + 2], array1[index + 3]);
-
-/* Apply inverse SBOX number WHICH to to the block found in ARRAY0 at
-   index INDEX, writing the output to the block found in ARRAY1 at
-   index INDEX.  */
-#define SBOX_INVERSE(which, array0, array1, index)              \
-  SBOX##which##_INVERSE (array0[index + 0], array0[index + 1],  \
-                         array0[index + 2], array0[index + 3],  \
-                         array1[index + 0], array1[index + 1],  \
-                         array1[index + 2], array1[index + 3]);
+/* Apply SBOX number WHICH to to the block found in ARRAY0, writing
+   the output to the block found in ARRAY1.  */
+#define SBOX(which, array0, array1)                         \
+  SBOX##which (array0[0], array0[1], array0[2], array0[3],  \
+               array1[0], array1[1], array1[2], array1[3]);
+
+/* Apply inverse SBOX number WHICH to to the block found in ARRAY0, writing
+   the output to the block found in ARRAY1.  */
+#define SBOX_INVERSE(which, array0, array1)                           \
+  SBOX##which##_INVERSE (array0[0], array0[1], array0[2], array0[3],  \
+                         array1[0], array1[1], array1[2], array1[3]);
 
 /* Apply the linear transformation to BLOCK.  */
 #define LINEAR_TRANSFORMATION(block)                  \
@@ -533,7 +517,7 @@ static const char *serpent_test (void);
   {                                             \
     BLOCK_XOR (block, subkeys[round]);          \
     round++;                                    \
-    SBOX (which, block, block_tmp, 0);          \
+    SBOX (which, block, block_tmp);             \
     LINEAR_TRANSFORMATION (block_tmp);          \
     BLOCK_COPY (block, block_tmp);              \
   }
@@ -546,7 +530,7 @@ static const char *serpent_test (void);
   {                                                  \
     BLOCK_XOR (block, subkeys[round]);               \
     round++;                                         \
-    SBOX (which, block, block_tmp, 0);               \
+    SBOX (which, block, block_tmp);                  \
     BLOCK_XOR (block_tmp, subkeys[round]);           \
     round++;                                         \
   }
@@ -557,7 +541,7 @@ static const char *serpent_test (void);
 #define ROUND_INVERSE(which, subkey, block, block_tmp) \
   {                                                    \
     LINEAR_TRANSFORMATION_INVERSE (block);             \
-    SBOX_INVERSE (which, block, block_tmp, 0);         \
+    SBOX_INVERSE (which, block, block_tmp);            \
     BLOCK_XOR (block_tmp, subkey[round]);              \
     round--;                                           \
     BLOCK_COPY (block, block_tmp);                     \
@@ -571,7 +555,7 @@ static const char *serpent_test (void);
   {                                                           \
     BLOCK_XOR (block, subkeys[round]);                        \
     round--;                                                  \
-    SBOX_INVERSE (which, block, block_tmp, 0);                \
+    SBOX_INVERSE (which, block, block_tmp);                   \
     BLOCK_XOR (block_tmp, subkeys[round]);                    \
     round--;                                                  \
   }
@@ -585,14 +569,9 @@ serpent_key_prepare (const byte *key, unsigned int key_length,
   int i;
 
   /* Copy key.  */
-  for (i = 0; i < key_length / 4; i++)
-    {
-#ifdef WORDS_BIGENDIAN
-      key_prepared[i] = byte_swap_32 (((u32 *) key)[i]);
-#else
-      key_prepared[i] = ((u32 *) key)[i];
-#endif
-    }
+  key_length /= 4;
+  for (i = 0; i < key_length; i++)
+    key_prepared[i] = buf_get_le32 (key + i * 4);
 
   if (i < 8)
     {
@@ -609,58 +588,57 @@ serpent_key_prepare (const byte *key, unsigned int key_length,
 static void
 serpent_subkeys_generate (serpent_key_t key, serpent_subkeys_t subkeys)
 {
-  u32 w_real[140];             /* The `prekey'.  */
-  u32 k[132];
-  u32 *w = &w_real[8];
-  int i, j;
+  u32 w[8];            /* The `prekey'.  */
+  u32 ws[4];
+  u32 wt[4];
 
   /* Initialize with key values.  */
-  for (i = 0; i < 8; i++)
-    w[i - 8] = key[i];
+  w[0] = key[0];
+  w[1] = key[1];
+  w[2] = key[2];
+  w[3] = key[3];
+  w[4] = key[4];
+  w[5] = key[5];
+  w[6] = key[6];
+  w[7] = key[7];
 
   /* Expand to intermediate key using the affine recurrence.  */
-  for (i = 0; i < 132; i++)
-    w[i] = rol (w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11);
+#define EXPAND_KEY4(wo, r)                                                     \
+  wo[0] = w[(r+0)%8] =                                                         \
+    rol (w[(r+0)%8] ^ w[(r+3)%8] ^ w[(r+5)%8] ^ w[(r+7)%8] ^ PHI ^ (r+0), 11); \
+  wo[1] = w[(r+1)%8] =                                                         \
+    rol (w[(r+1)%8] ^ w[(r+4)%8] ^ w[(r+6)%8] ^ w[(r+0)%8] ^ PHI ^ (r+1), 11); \
+  wo[2] = w[(r+2)%8] =                                                         \
+    rol (w[(r+2)%8] ^ w[(r+5)%8] ^ w[(r+7)%8] ^ w[(r+1)%8] ^ PHI ^ (r+2), 11); \
+  wo[3] = w[(r+3)%8] =                                                         \
+    rol (w[(r+3)%8] ^ w[(r+6)%8] ^ w[(r+0)%8] ^ w[(r+2)%8] ^ PHI ^ (r+3), 11);
+
+#define EXPAND_KEY(r)       \
+  EXPAND_KEY4(ws, (r));     \
+  EXPAND_KEY4(wt, (r + 4));
 
   /* Calculate subkeys via S-Boxes, in bitslice mode.  */
-  SBOX (3, w, k,   0);
-  SBOX (2, w, k,   4);
-  SBOX (1, w, k,   8);
-  SBOX (0, w, k,  12);
-  SBOX (7, w, k,  16);
-  SBOX (6, w, k,  20);
-  SBOX (5, w, k,  24);
-  SBOX (4, w, k,  28);
-  SBOX (3, w, k,  32);
-  SBOX (2, w, k,  36);
-  SBOX (1, w, k,  40);
-  SBOX (0, w, k,  44);
-  SBOX (7, w, k,  48);
-  SBOX (6, w, k,  52);
-  SBOX (5, w, k,  56);
-  SBOX (4, w, k,  60);
-  SBOX (3, w, k,  64);
-  SBOX (2, w, k,  68);
-  SBOX (1, w, k,  72);
-  SBOX (0, w, k,  76);
-  SBOX (7, w, k,  80);
-  SBOX (6, w, k,  84);
-  SBOX (5, w, k,  88);
-  SBOX (4, w, k,  92);
-  SBOX (3, w, k,  96);
-  SBOX (2, w, k, 100);
-  SBOX (1, w, k, 104);
-  SBOX (0, w, k, 108);
-  SBOX (7, w, k, 112);
-  SBOX (6, w, k, 116);
-  SBOX (5, w, k, 120);
-  SBOX (4, w, k, 124);
-  SBOX (3, w, k, 128);
-
-  /* Renumber subkeys.  */
-  for (i = 0; i < ROUNDS + 1; i++)
-    for (j = 0; j < 4; j++)
-      subkeys[i][j] = k[4 * i + j];
+  EXPAND_KEY (0); SBOX (3, ws, subkeys[0]); SBOX (2, wt, subkeys[1]);
+  EXPAND_KEY (8); SBOX (1, ws, subkeys[2]); SBOX (0, wt, subkeys[3]);
+  EXPAND_KEY (16); SBOX (7, ws, subkeys[4]); SBOX (6, wt, subkeys[5]);
+  EXPAND_KEY (24); SBOX (5, ws, subkeys[6]); SBOX (4, wt, subkeys[7]);
+  EXPAND_KEY (32); SBOX (3, ws, subkeys[8]); SBOX (2, wt, subkeys[9]);
+  EXPAND_KEY (40); SBOX (1, ws, subkeys[10]); SBOX (0, wt, subkeys[11]);
+  EXPAND_KEY (48); SBOX (7, ws, subkeys[12]); SBOX (6, wt, subkeys[13]);
+  EXPAND_KEY (56); SBOX (5, ws, subkeys[14]); SBOX (4, wt, subkeys[15]);
+  EXPAND_KEY (64); SBOX (3, ws, subkeys[16]); SBOX (2, wt, subkeys[17]);
+  EXPAND_KEY (72); SBOX (1, ws, subkeys[18]); SBOX (0, wt, subkeys[19]);
+  EXPAND_KEY (80); SBOX (7, ws, subkeys[20]); SBOX (6, wt, subkeys[21]);
+  EXPAND_KEY (88); SBOX (5, ws, subkeys[22]); SBOX (4, wt, subkeys[23]);
+  EXPAND_KEY (96); SBOX (3, ws, subkeys[24]); SBOX (2, wt, subkeys[25]);
+  EXPAND_KEY (104); SBOX (1, ws, subkeys[26]); SBOX (0, wt, subkeys[27]);
+  EXPAND_KEY (112); SBOX (7, ws, subkeys[28]); SBOX (6, wt, subkeys[29]);
+  EXPAND_KEY (120); SBOX (5, ws, subkeys[30]); SBOX (4, wt, subkeys[31]);
+  EXPAND_KEY4 (ws, 128); SBOX (3, ws, subkeys[32]);
+
+  wipememory (ws, sizeof (ws));
+  wipememory (wt, sizeof (wt));
+  wipememory (w, sizeof (w));
 }
 
 /* Initialize CONTEXT with the key KEY of KEY_LENGTH bits.  */
@@ -672,7 +650,24 @@ serpent_setkey_internal (serpent_context_t *context,
 
   serpent_key_prepare (key, key_length, key_prepared);
   serpent_subkeys_generate (key_prepared, context->keys);
-  _gcry_burn_stack (272 * sizeof (u32));
+
+#ifdef USE_AVX2
+  context->use_avx2 = 0;
+  if ((_gcry_get_hw_features () & HWF_INTEL_AVX2))
+    {
+      context->use_avx2 = 1;
+    }
+#endif
+
+#ifdef USE_NEON
+  context->use_neon = 0;
+  if ((_gcry_get_hw_features () & HWF_ARM_NEON))
+    {
+      context->use_neon = 1;
+    }
+#endif
+
+  wipememory (key_prepared, sizeof(key_prepared));
 }
 
 /* Initialize CTX with the key KEY of KEY_LENGTH bytes.  */
@@ -688,41 +683,31 @@ serpent_setkey (void *ctx,
   if (! serpent_init_done)
     {
       /* Execute a self-test the first time, Serpent is used.  */
+      serpent_init_done = 1;
       serpent_test_ret = serpent_test ();
       if (serpent_test_ret)
        log_error ("Serpent test failure: %s\n", serpent_test_ret);
-      serpent_init_done = 1;
     }
 
   if (serpent_test_ret)
     ret = GPG_ERR_SELFTEST_FAILED;
   else
-    {
-      serpent_setkey_internal (context, key, key_length);
-      _gcry_burn_stack (sizeof (serpent_key_t));
-    }
+    serpent_setkey_internal (context, key, key_length);
 
   return ret;
 }
 
 static void
 serpent_encrypt_internal (serpent_context_t *context,
-                         const serpent_block_t input, serpent_block_t output)
+                         const byte *input, byte *output)
 {
   serpent_block_t b, b_next;
   int round = 0;
 
-#ifdef WORDS_BIGENDIAN
-  b[0] = byte_swap_32 (input[0]);
-  b[1] = byte_swap_32 (input[1]);
-  b[2] = byte_swap_32 (input[2]);
-  b[3] = byte_swap_32 (input[3]);
-#else
-  b[0] = input[0];
-  b[1] = input[1];
-  b[2] = input[2];
-  b[3] = input[3];
-#endif
+  b[0] = buf_get_le32 (input + 0);
+  b[1] = buf_get_le32 (input + 4);
+  b[2] = buf_get_le32 (input + 8);
+  b[3] = buf_get_le32 (input + 12);
 
   ROUND (0, context->keys, b, b_next);
   ROUND (1, context->keys, b, b_next);
@@ -758,37 +743,23 @@ serpent_encrypt_internal (serpent_context_t *context,
 
   ROUND_LAST (7, context->keys, b, b_next);
 
-#ifdef WORDS_BIGENDIAN
-  output[0] = byte_swap_32 (b_next[0]);
-  output[1] = byte_swap_32 (b_next[1]);
-  output[2] = byte_swap_32 (b_next[2]);
-  output[3] = byte_swap_32 (b_next[3]);
-#else
-  output[0] = b_next[0];
-  output[1] = b_next[1];
-  output[2] = b_next[2];
-  output[3] = b_next[3];
-#endif
+  buf_put_le32 (output + 0, b_next[0]);
+  buf_put_le32 (output + 4, b_next[1]);
+  buf_put_le32 (output + 8, b_next[2]);
+  buf_put_le32 (output + 12, b_next[3]);
 }
 
 static void
 serpent_decrypt_internal (serpent_context_t *context,
-                         const serpent_block_t input, serpent_block_t output)
+                         const byte *input, byte *output)
 {
   serpent_block_t b, b_next;
   int round = ROUNDS;
 
-#ifdef WORDS_BIGENDIAN
-  b_next[0] = byte_swap_32 (input[0]);
-  b_next[1] = byte_swap_32 (input[1]);
-  b_next[2] = byte_swap_32 (input[2]);
-  b_next[3] = byte_swap_32 (input[3]);
-#else
-  b_next[0] = input[0];
-  b_next[1] = input[1];
-  b_next[2] = input[2];
-  b_next[3] = input[3];
-#endif
+  b_next[0] = buf_get_le32 (input + 0);
+  b_next[1] = buf_get_le32 (input + 4);
+  b_next[2] = buf_get_le32 (input + 8);
+  b_next[3] = buf_get_le32 (input + 12);
 
   ROUND_FIRST_INVERSE (7, context->keys, b_next, b);
 
@@ -824,43 +795,409 @@ serpent_decrypt_internal (serpent_context_t *context,
   ROUND_INVERSE (1, context->keys, b, b_next);
   ROUND_INVERSE (0, context->keys, b, b_next);
 
-
-#ifdef WORDS_BIGENDIAN
-  output[0] = byte_swap_32 (b_next[0]);
-  output[1] = byte_swap_32 (b_next[1]);
-  output[2] = byte_swap_32 (b_next[2]);
-  output[3] = byte_swap_32 (b_next[3]);
-#else
-  output[0] = b_next[0];
-  output[1] = b_next[1];
-  output[2] = b_next[2];
-  output[3] = b_next[3];
-#endif
+  buf_put_le32 (output + 0, b_next[0]);
+  buf_put_le32 (output + 4, b_next[1]);
+  buf_put_le32 (output + 8, b_next[2]);
+  buf_put_le32 (output + 12, b_next[3]);
 }
 
-static void
+static unsigned int
 serpent_encrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
 {
   serpent_context_t *context = ctx;
 
-  serpent_encrypt_internal (context,
-                           (const u32 *) buffer_in, (u32 *) buffer_out);
-  _gcry_burn_stack (2 * sizeof (serpent_block_t));
+  serpent_encrypt_internal (context, buffer_in, buffer_out);
+  return /*burn_stack*/ (2 * sizeof (serpent_block_t));
 }
 
-static void
+static unsigned int
 serpent_decrypt (void *ctx, byte *buffer_out, const byte *buffer_in)
 {
   serpent_context_t *context = ctx;
 
-  serpent_decrypt_internal (context,
-                           (const u32 *) buffer_in,
-                           (u32 *) buffer_out);
-  _gcry_burn_stack (2 * sizeof (serpent_block_t));
+  serpent_decrypt_internal (context, buffer_in, buffer_out);
+  return /*burn_stack*/ (2 * sizeof (serpent_block_t));
 }
 
 \f
 
+/* 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 sizeof(serpent_block_t). */
+void
+_gcry_serpent_ctr_enc(void *context, unsigned char *ctr,
+                      void *outbuf_arg, const void *inbuf_arg,
+                      size_t nblocks)
+{
+  serpent_context_t *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned char tmpbuf[sizeof(serpent_block_t)];
+  int burn_stack_depth = 2 * sizeof (serpent_block_t);
+  int i;
+
+#ifdef USE_AVX2
+  if (ctx->use_avx2)
+    {
+      int did_use_avx2 = 0;
+
+      /* Process data in 16 block chunks. */
+      while (nblocks >= 16)
+        {
+          _gcry_serpent_avx2_ctr_enc(ctx, outbuf, inbuf, ctr);
+
+          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/sse2 code to handle smaller chunks... */
+      /* TODO: use caching instead? */
+    }
+#endif
+
+#ifdef USE_SSE2
+  {
+    int did_use_sse2 = 0;
+
+    /* Process data in 8 block chunks. */
+    while (nblocks >= 8)
+      {
+        _gcry_serpent_sse2_ctr_enc(ctx, outbuf, inbuf, ctr);
+
+        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... */
+    /* TODO: use caching instead? */
+  }
+#endif
+
+#ifdef USE_NEON
+  if (ctx->use_neon)
+    {
+      int did_use_neon = 0;
+
+      /* Process data in 8 block chunks. */
+      while (nblocks >= 8)
+        {
+          _gcry_serpent_neon_ctr_enc(ctx, outbuf, inbuf, ctr);
+
+          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... */
+      /* TODO: use caching instead? */
+    }
+#endif
+
+  for ( ;nblocks; nblocks-- )
+    {
+      /* Encrypt the counter. */
+      serpent_encrypt_internal(ctx, ctr, tmpbuf);
+      /* XOR the input with the encrypted counter and store in output.  */
+      buf_xor(outbuf, tmpbuf, inbuf, sizeof(serpent_block_t));
+      outbuf += sizeof(serpent_block_t);
+      inbuf  += sizeof(serpent_block_t);
+      /* Increment the counter.  */
+      for (i = sizeof(serpent_block_t); 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_serpent_cbc_dec(void *context, unsigned char *iv,
+                      void *outbuf_arg, const void *inbuf_arg,
+                      size_t nblocks)
+{
+  serpent_context_t *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned char savebuf[sizeof(serpent_block_t)];
+  int burn_stack_depth = 2 * sizeof (serpent_block_t);
+
+#ifdef USE_AVX2
+  if (ctx->use_avx2)
+    {
+      int did_use_avx2 = 0;
+
+      /* Process data in 16 block chunks. */
+      while (nblocks >= 16)
+        {
+          _gcry_serpent_avx2_cbc_dec(ctx, outbuf, inbuf, iv);
+
+          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/sse2 code to handle smaller chunks... */
+    }
+#endif
+
+#ifdef USE_SSE2
+  {
+    int did_use_sse2 = 0;
+
+    /* Process data in 8 block chunks. */
+    while (nblocks >= 8)
+      {
+        _gcry_serpent_sse2_cbc_dec(ctx, outbuf, inbuf, iv);
+
+        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;
+
+      /* Process data in 8 block chunks. */
+      while (nblocks >= 8)
+        {
+          _gcry_serpent_neon_cbc_dec(ctx, outbuf, inbuf, iv);
+
+          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
+
+  for ( ;nblocks; nblocks-- )
+    {
+      /* INBUF is needed later and it may be identical to OUTBUF, so store
+         the intermediate result to SAVEBUF.  */
+      serpent_decrypt_internal (ctx, inbuf, savebuf);
+
+      buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, sizeof(serpent_block_t));
+      inbuf += sizeof(serpent_block_t);
+      outbuf += sizeof(serpent_block_t);
+    }
+
+  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_serpent_cfb_dec(void *context, unsigned char *iv,
+                      void *outbuf_arg, const void *inbuf_arg,
+                      size_t nblocks)
+{
+  serpent_context_t *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  int burn_stack_depth = 2 * sizeof (serpent_block_t);
+
+#ifdef USE_AVX2
+  if (ctx->use_avx2)
+    {
+      int did_use_avx2 = 0;
+
+      /* Process data in 16 block chunks. */
+      while (nblocks >= 16)
+        {
+          _gcry_serpent_avx2_cfb_dec(ctx, outbuf, inbuf, iv);
+
+          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/sse2 code to handle smaller chunks... */
+    }
+#endif
+
+#ifdef USE_SSE2
+  {
+    int did_use_sse2 = 0;
+
+    /* Process data in 8 block chunks. */
+    while (nblocks >= 8)
+      {
+        _gcry_serpent_sse2_cfb_dec(ctx, outbuf, inbuf, iv);
+
+        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;
+
+      /* Process data in 8 block chunks. */
+      while (nblocks >= 8)
+        {
+          _gcry_serpent_neon_cfb_dec(ctx, outbuf, inbuf, iv);
+
+          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
+
+  for ( ;nblocks; nblocks-- )
+    {
+      serpent_encrypt_internal(ctx, iv, iv);
+      buf_xor_n_copy(outbuf, iv, inbuf, sizeof(serpent_block_t));
+      outbuf += sizeof(serpent_block_t);
+      inbuf  += sizeof(serpent_block_t);
+    }
+
+  _gcry_burn_stack(burn_stack_depth);
+}
+
+\f
+
+/* Run the self-tests for SERPENT-CTR-128, tests IV increment of bulk CTR
+   encryption.  Returns NULL on success. */
+static const char*
+selftest_ctr_128 (void)
+{
+  const int nblocks = 16+8+1;
+  const int blocksize = sizeof(serpent_block_t);
+  const int context_size = sizeof(serpent_context_t);
+
+  return _gcry_selftest_helper_ctr("SERPENT", &serpent_setkey,
+           &serpent_encrypt, &_gcry_serpent_ctr_enc, nblocks, blocksize,
+          context_size);
+}
+
+
+/* Run the self-tests for SERPENT-CBC-128, tests bulk CBC decryption.
+   Returns NULL on success. */
+static const char*
+selftest_cbc_128 (void)
+{
+  const int nblocks = 16+8+2;
+  const int blocksize = sizeof(serpent_block_t);
+  const int context_size = sizeof(serpent_context_t);
+
+  return _gcry_selftest_helper_cbc("SERPENT", &serpent_setkey,
+           &serpent_encrypt, &_gcry_serpent_cbc_dec, nblocks, blocksize,
+          context_size);
+}
+
+
+/* Run the self-tests for SERPENT-CBC-128, tests bulk CBC decryption.
+   Returns NULL on success. */
+static const char*
+selftest_cfb_128 (void)
+{
+  const int nblocks = 16+8+2;
+  const int blocksize = sizeof(serpent_block_t);
+  const int context_size = sizeof(serpent_context_t);
+
+  return _gcry_selftest_helper_cfb("SERPENT", &serpent_setkey,
+           &serpent_encrypt, &_gcry_serpent_cfb_dec, nblocks, blocksize,
+          context_size);
+}
+
+
 /* Serpent test.  */
 
 static const char *
@@ -869,6 +1206,7 @@ serpent_test (void)
   serpent_context_t context;
   unsigned char scratch[16];
   unsigned int i;
+  const char *r;
 
   static struct test
   {
@@ -914,9 +1252,7 @@ serpent_test (void)
     {
       serpent_setkey_internal (&context, test_data[i].key,
                                test_data[i].key_length);
-      serpent_encrypt_internal (&context,
-                               (const u32 *) test_data[i].text_plain,
-                               (u32 *) scratch);
+      serpent_encrypt_internal (&context, test_data[i].text_plain, scratch);
 
       if (memcmp (scratch, test_data[i].text_cipher, sizeof (serpent_block_t)))
        switch (test_data[i].key_length)
@@ -929,9 +1265,7 @@ serpent_test (void)
            return "Serpent-256 test encryption failed.";
          }
 
-    serpent_decrypt_internal (&context,
-                             (const u32 *) test_data[i].text_cipher,
-                             (u32 *) scratch);
+    serpent_decrypt_internal (&context, test_data[i].text_cipher, scratch);
     if (memcmp (scratch, test_data[i].text_plain, sizeof (serpent_block_t)))
       switch (test_data[i].key_length)
        {
@@ -944,6 +1278,15 @@ serpent_test (void)
        }
     }
 
+  if ( (r = selftest_ctr_128 ()) )
+    return r;
+
+  if ( (r = selftest_cbc_128 ()) )
+    return r;
+
+  if ( (r = selftest_cfb_128 ()) )
+    return r;
+
   return NULL;
 }
 
@@ -958,6 +1301,7 @@ static const char *cipher_spec_serpent128_aliases[] =
 
 gcry_cipher_spec_t _gcry_cipher_spec_serpent128 =
   {
+    GCRY_CIPHER_SERPENT128, {0, 0},
     "SERPENT128", cipher_spec_serpent128_aliases, NULL, 16, 128,
     sizeof (serpent_context_t),
     serpent_setkey, serpent_encrypt, serpent_decrypt
@@ -965,6 +1309,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,
     sizeof (serpent_context_t),
     serpent_setkey, serpent_encrypt, serpent_decrypt
@@ -972,6 +1317,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,
     sizeof (serpent_context_t),
     serpent_setkey, serpent_encrypt, serpent_decrypt
diff --git a/cipher/sha1-ssse3-amd64.S b/cipher/sha1-ssse3-amd64.S
new file mode 100644 (file)
index 0000000..5e5716b
--- /dev/null
@@ -0,0 +1,377 @@
+/* sha1-ssse3-amd64.S - Intel SSSE3 accelerated SHA-1 transform function
+ * Copyright © 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_GCC_INLINE_ASM_SSSE3) && defined(USE_SHA1)
+
+#ifdef __PIC__
+#  define RIP (%rip)
+#else
+#  define RIP
+#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 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; \
+       roll $30, b; \
+       xorl d, RT0; \
+       leal (RT0,e), e; \
+       roll $5, RT1; \
+       addl RT1, e;
+
+#define R_F2(a,b,c,d,e,i) \
+       movl c, RT0; \
+       addl WK(i), e; \
+       xorl b, RT0; \
+       roll $30, b; \
+       xorl d, RT0; \
+       movl a, RT1; \
+       leal (RT0,e), e; \
+       roll $5, 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; \
+       roll $30, b; \
+       movl a, RT1; \
+       leal (RT0,e), e; \
+       roll $5, 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) \
+       movdqu (4*(i))(RDATA), tmp0;
+
+#define W_PRECALC_00_15_1(i, W, tmp0) \
+       pshufb BSWAP_REG, tmp0; \
+       movdqa tmp0, W;
+
+#define W_PRECALC_00_15_2(i, W, tmp0) \
+       paddd (.LK_XMM + ((i)/20)*16) RIP, tmp0;
+
+#define W_PRECALC_00_15_3(i, W, tmp0) \
+       movdqa tmp0, WK(i&~3);
+
+#define W_PRECALC_16_31_0(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+       movdqa W_m12, W; \
+       palignr $8, W_m16, W; \
+       movdqa W_m04, tmp0; \
+       psrldq $4, tmp0; \
+       pxor W_m08, W;
+
+#define W_PRECALC_16_31_1(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+       pxor W_m16, tmp0; \
+       pxor tmp0, W; \
+       movdqa W, tmp1; \
+       movdqa W, tmp0; \
+       pslldq $12, tmp1;
+
+#define W_PRECALC_16_31_2(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+       psrld $31, W; \
+       pslld $1, tmp0; \
+       por W, tmp0; \
+       movdqa tmp1, W; \
+       psrld $30, tmp1; \
+       pslld $2, W;
+
+#define W_PRECALC_16_31_3(i, W, W_m04, W_m08, W_m12, W_m16, tmp0, tmp1) \
+       pxor W, tmp0; \
+       pxor tmp1, tmp0; \
+       movdqa tmp0, W; \
+       paddd (.LK_XMM + ((i)/20)*16) RIP, tmp0; \
+       movdqa 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) \
+       movdqa W_m04, tmp0; \
+       pxor W_m28, W; \
+       palignr $8, W_m08, tmp0;
+
+#define W_PRECALC_32_79_1(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+       pxor W_m16, W; \
+       pxor tmp0, W; \
+       movdqa W, tmp0;
+
+#define W_PRECALC_32_79_2(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+       psrld $30, W; \
+       pslld $2, tmp0; \
+       por W, tmp0;
+
+#define W_PRECALC_32_79_3(i, W, W_m04, W_m08, W_m12, W_m16, W_m20, W_m24, W_m28, tmp0) \
+       movdqa tmp0, W; \
+       paddd (.LK_XMM + ((i)/20)*16) RIP, tmp0; \
+       movdqa tmp0, WK((i)&~3);
+
+#define CLEAR_REG(reg) pxor reg, reg;
+
+
+/*
+ * Transform 64 bytes (16 32-bit words) at DATA.
+ *
+ * unsigned int
+ * _gcry_sha1_transform_amd64_ssse3 (void *ctx, const unsigned char *data)
+ */
+.text
+.globl _gcry_sha1_transform_amd64_ssse3
+.type _gcry_sha1_transform_amd64_ssse3,@function
+.align 16
+_gcry_sha1_transform_amd64_ssse3:
+  /* input:
+   *   %rdi: ctx, CTX
+   *   %rsi: data (64 bytes)
+   *   %rdx: ...
+   */
+
+  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);
+
+  /* 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);
+
+  /* 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);
+  R( e, a, b, c, d, F4, 66 ); CLEAR_REG(Wtmp1);
+  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 );
+
+  /* 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_h4(RSTATE), e;
+
+  movl a, state_h0(RSTATE);
+  movl b, state_h1(RSTATE);
+  movl c, state_h2(RSTATE);
+  movl d, state_h3(RSTATE);
+  movl e, state_h4(RSTATE);
+
+  movq ROLDSTACK, %rsp;
+
+  popq %rbp;
+  popq %rbx;
+
+  /* burn_stack */
+  movl $(16*4 + 2*8 + 31), %eax;
+
+  ret;
+
+#endif
+#endif
index 4b784ac..2e0b030 100644 (file)
 
 #include "g10lib.h"
 #include "bithelp.h"
+#include "bufhelp.h"
 #include "cipher.h"
 #include "hash-common.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)
+# define USE_SSSE3 1
+#endif
+
+
 /* 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
    it does not exist in stdint.h.  */
 /* # define U32_ALIGNED_P(p) (!(((uintptr_t)p) % sizeof (u32))) */
 /* #endif */
 
-#define TRANSFORM(x,d,n) transform ((x), (d), (n))
-
-
 typedef struct
 {
+  gcry_md_block_ctx_t bctx;
   u32           h0,h1,h2,h3,h4;
-  u32           nblocks;
-  unsigned char buf[64];
-  int           count;
+#ifdef USE_SSSE3
+  unsigned int use_ssse3:1;
+#endif
 } SHA1_CONTEXT;
 
+static unsigned int
+transform (void *c, const unsigned char *data);
 
 
 static void
-sha1_init (void *context)
+sha1_init (void *context, unsigned int flags)
 {
   SHA1_CONTEXT *hd = context;
 
+  (void)flags;
+
   hd->h0 = 0x67452301;
   hd->h1 = 0xefcdab89;
   hd->h2 = 0x98badcfe;
   hd->h3 = 0x10325476;
   hd->h4 = 0xc3d2e1f0;
-  hd->nblocks = 0;
-  hd->count = 0;
+
+  hd->bctx.nblocks = 0;
+  hd->bctx.nblocks_high = 0;
+  hd->bctx.count = 0;
+  hd->bctx.blocksize = 64;
+  hd->bctx.bwrite = transform;
+
+#ifdef USE_SSSE3
+  hd->use_ssse3 = (_gcry_get_hw_features () & HWF_INTEL_SSSE3) != 0;
+#endif
 }
 
 
@@ -104,33 +123,17 @@ sha1_init (void *context)
 /*
  * Transform NBLOCKS of each 64 bytes (16 32-bit words) at DATA.
  */
-static void
-transform (SHA1_CONTEXT *hd, const unsigned char *data, size_t nblocks)
+static unsigned int
+_transform (void *ctx, const unsigned char *data)
 {
+  SHA1_CONTEXT *hd = ctx;
+  const u32 *idata = (const void *)data;
   register u32 a, b, c, d, e; /* Local copies of the chaining variables.  */
   register u32 tm;            /* Helper.  */
   u32 x[16];                  /* The array we work on. */
 
-  /* Loop over all blocks.  */
-  for ( ;nblocks; nblocks--)
-    {
-#ifdef WORDS_BIGENDIAN
-      memcpy (x, data, 64);
-      data += 64;
-#else
-      {
-        int i;
-        unsigned char *p;
-
-        for(i=0, p=(unsigned char*)x; i < 16; i++, p += 4 )
-          {
-            p[3] = *data++;
-            p[2] = *data++;
-            p[1] = *data++;
-            p[0] = *data++;
-          }
-      }
-#endif
+#define I(i) (x[i] = buf_get_be32(idata + i))
+
       /* Get the values of the chaining variables. */
       a = hd->h0;
       b = hd->h1;
@@ -139,22 +142,22 @@ transform (SHA1_CONTEXT *hd, const unsigned char *data, size_t nblocks)
       e = hd->h4;
 
       /* Transform. */
-      R( a, b, c, d, e, F1, K1, x[ 0] );
-      R( e, a, b, c, d, F1, K1, x[ 1] );
-      R( d, e, a, b, c, F1, K1, x[ 2] );
-      R( c, d, e, a, b, F1, K1, x[ 3] );
-      R( b, c, d, e, a, F1, K1, x[ 4] );
-      R( a, b, c, d, e, F1, K1, x[ 5] );
-      R( e, a, b, c, d, F1, K1, x[ 6] );
-      R( d, e, a, b, c, F1, K1, x[ 7] );
-      R( c, d, e, a, b, F1, K1, x[ 8] );
-      R( b, c, d, e, a, F1, K1, x[ 9] );
-      R( a, b, c, d, e, F1, K1, x[10] );
-      R( e, a, b, c, d, F1, K1, x[11] );
-      R( d, e, a, b, c, F1, K1, x[12] );
-      R( c, d, e, a, b, F1, K1, x[13] );
-      R( b, c, d, e, a, F1, K1, x[14] );
-      R( a, b, c, d, e, F1, K1, x[15] );
+      R( a, b, c, d, e, F1, K1, I( 0) );
+      R( e, a, b, c, d, F1, K1, I( 1) );
+      R( d, e, a, b, c, F1, K1, I( 2) );
+      R( c, d, e, a, b, F1, K1, I( 3) );
+      R( b, c, d, e, a, F1, K1, I( 4) );
+      R( a, b, c, d, e, F1, K1, I( 5) );
+      R( e, a, b, c, d, F1, K1, I( 6) );
+      R( d, e, a, b, c, F1, K1, I( 7) );
+      R( c, d, e, a, b, F1, K1, I( 8) );
+      R( b, c, d, e, a, F1, K1, I( 9) );
+      R( a, b, c, d, e, F1, K1, I(10) );
+      R( e, a, b, c, d, F1, K1, I(11) );
+      R( d, e, a, b, c, F1, K1, I(12) );
+      R( c, d, e, a, b, F1, K1, I(13) );
+      R( b, c, d, e, a, F1, K1, I(14) );
+      R( a, b, c, d, e, F1, K1, I(15) );
       R( e, a, b, c, d, F1, K1, M(16) );
       R( d, e, a, b, c, F1, K1, M(17) );
       R( c, d, e, a, b, F1, K1, M(18) );
@@ -226,53 +229,29 @@ transform (SHA1_CONTEXT *hd, const unsigned char *data, size_t nblocks)
       hd->h2 += c;
       hd->h3 += d;
       hd->h4 += e;
-    }
+
+  return /* burn_stack */ 88+4*sizeof(void*);
 }
 
 
-/* Update the message digest with the contents
- * of INBUF with length INLEN.
- */
-static void
-sha1_write( void *context, const void *inbuf_arg, size_t inlen)
-{
-  const unsigned char *inbuf = inbuf_arg;
-  SHA1_CONTEXT *hd = context;
-  size_t nblocks;
+#ifdef USE_SSSE3
+unsigned int
+_gcry_sha1_transform_amd64_ssse3 (void *state, const unsigned char *data);
+#endif
 
-  if (hd->count == 64)  /* Flush the buffer. */
-    {
-      TRANSFORM( hd, hd->buf, 1 );
-      _gcry_burn_stack (88+4*sizeof(void*));
-      hd->count = 0;
-      hd->nblocks++;
-    }
-  if (!inbuf)
-    return;
 
-  if (hd->count)
-    {
-      for (; inlen && hd->count < 64; inlen--)
-        hd->buf[hd->count++] = *inbuf++;
-      sha1_write (hd, NULL, 0);
-      if (!inlen)
-        return;
-    }
+static unsigned int
+transform (void *ctx, const unsigned char *data)
+{
+  SHA1_CONTEXT *hd = ctx;
 
-  nblocks = inlen / 64;
-  if (nblocks)
-    {
-      TRANSFORM (hd, inbuf, nblocks);
-      hd->count = 0;
-      hd->nblocks += nblocks;
-      inlen -= nblocks * 64;
-      inbuf += nblocks * 64;
-    }
-  _gcry_burn_stack (88+4*sizeof(void*));
+#ifdef USE_SSSE3
+  if (hd->use_ssse3)
+    return _gcry_sha1_transform_amd64_ssse3 (&hd->h0, data)
+           + 4 * sizeof(void*);
+#endif
 
-  /* Save remaining bytes.  */
-  for (; inlen && hd->count < 64; inlen--)
-    hd->buf[hd->count++] = *inbuf++;
+  return _transform (hd, data);
 }
 
 
@@ -287,19 +266,24 @@ static void
 sha1_final(void *context)
 {
   SHA1_CONTEXT *hd = context;
-
-  u32 t, msb, lsb;
+  u32 t, th, msb, lsb;
   unsigned char *p;
+  unsigned int burn;
+
+  _gcry_md_block_write (hd, NULL, 0); /* flush */;
 
-  sha1_write(hd, NULL, 0); /* flush */;
+  t = hd->bctx.nblocks;
+  if (sizeof t == sizeof hd->bctx.nblocks)
+    th = hd->bctx.nblocks_high;
+  else
+    th = hd->bctx.nblocks >> 32;
 
-  t = hd->nblocks;
   /* multiply by 64 to make a byte count */
   lsb = t << 6;
-  msb = t >> 26;
+  msb = (th << 6) | (t >> 26);
   /* add the count */
   t = lsb;
-  if( (lsb += hd->count) < t )
+  if( (lsb += hd->bctx.count) < t )
     msb++;
   /* multiply by 8 to make a bit count */
   t = lsb;
@@ -307,39 +291,28 @@ sha1_final(void *context)
   msb <<= 3;
   msb |= t >> 29;
 
-  if( hd->count < 56 )  /* enough room */
+  if( hd->bctx.count < 56 )  /* enough room */
     {
-      hd->buf[hd->count++] = 0x80; /* pad */
-      while( hd->count < 56 )
-        hd->buf[hd->count++] = 0;  /* pad */
+      hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
+      while( hd->bctx.count < 56 )
+        hd->bctx.buf[hd->bctx.count++] = 0;  /* pad */
     }
   else  /* need one extra block */
     {
-      hd->buf[hd->count++] = 0x80; /* pad character */
-      while( hd->count < 64 )
-        hd->buf[hd->count++] = 0;
-      sha1_write(hd, NULL, 0);  /* flush */;
-      memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+      hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
+      while( hd->bctx.count < 64 )
+        hd->bctx.buf[hd->bctx.count++] = 0;
+      _gcry_md_block_write(hd, NULL, 0);  /* flush */;
+      memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
     }
   /* append the 64 bit count */
-  hd->buf[56] = msb >> 24;
-  hd->buf[57] = msb >> 16;
-  hd->buf[58] = msb >>  8;
-  hd->buf[59] = msb       ;
-  hd->buf[60] = lsb >> 24;
-  hd->buf[61] = lsb >> 16;
-  hd->buf[62] = lsb >>  8;
-  hd->buf[63] = lsb       ;
-  TRANSFORM( hd, hd->buf, 1 );
-  _gcry_burn_stack (88+4*sizeof(void*));
-
-  p = hd->buf;
-#ifdef WORDS_BIGENDIAN
-#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
-#else /* little endian */
-#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;         \
-                  *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
-#endif
+  buf_put_be32(hd->bctx.buf + 56, msb);
+  buf_put_be32(hd->bctx.buf + 60, lsb);
+  burn = transform( hd, hd->bctx.buf );
+  _gcry_burn_stack (burn);
+
+  p = hd->bctx.buf;
+#define X(a) do { *(u32*)p = be_bswap32(hd->h##a) ; p += 4; } while(0)
   X(0);
   X(1);
   X(2);
@@ -354,7 +327,7 @@ sha1_read( void *context )
 {
   SHA1_CONTEXT *hd = context;
 
-  return hd->buf;
+  return hd->bctx.buf;
 }
 
 /****************
@@ -366,10 +339,25 @@ _gcry_sha1_hash_buffer (void *outbuf, const void *buffer, size_t length)
 {
   SHA1_CONTEXT hd;
 
-  sha1_init (&hd);
-  sha1_write (&hd, buffer, length);
+  sha1_init (&hd, 0);
+  _gcry_md_block_write (&hd, buffer, length);
   sha1_final (&hd);
-  memcpy (outbuf, hd.buf, 20);
+  memcpy (outbuf, hd.bctx.buf, 20);
+}
+
+
+/* Variant of the above shortcut function using a multiple buffers.  */
+void
+_gcry_sha1_hash_buffers (void *outbuf, const gcry_buffer_t *iov, int iovcnt)
+{
+  SHA1_CONTEXT hd;
+
+  sha1_init (&hd, 0);
+  for (;iovcnt > 0; iov++, iovcnt--)
+    _gcry_md_block_write (&hd,
+                          (const char*)iov[0].data + iov[0].off, iov[0].len);
+  sha1_final (&hd);
+  memcpy (outbuf, hd.bctx.buf, 20);
 }
 
 
@@ -467,11 +455,9 @@ static gcry_md_oid_spec_t oid_spec_sha1[] =
 
 gcry_md_spec_t _gcry_digest_spec_sha1 =
   {
+    GCRY_MD_SHA1, {0, 1},
     "SHA1", asn, DIM (asn), oid_spec_sha1, 20,
-    sha1_init, sha1_write, sha1_final, sha1_read,
-    sizeof (SHA1_CONTEXT)
-  };
-md_extra_spec_t _gcry_digest_extraspec_sha1 =
-  {
+    sha1_init, _gcry_md_block_write, sha1_final, sha1_read,
+    sizeof (SHA1_CONTEXT),
     run_selftests
   };
diff --git a/cipher/sha256-ssse3-amd64.S b/cipher/sha256-ssse3-amd64.S
new file mode 100644 (file)
index 0000000..9b27f8f
--- /dev/null
@@ -0,0 +1,540 @@
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; 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: original implementation was named as SHA256-SSE4. However, only SSSE3
+ *       is required.
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && \
+    defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+    defined(HAVE_GCC_INLINE_ASM_SSSE3) && defined(USE_SHA256)
+
+#ifdef __PIC__
+#  define ADD_RIP +rip
+#else
+#  define ADD_RIP
+#endif
+
+.intel_syntax noprefix
+
+#define        MOVDQ movdqu /* 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
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;*/
+
+/* 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
+       MOVDQ \p1, \p2
+       pshufb \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 */
+               movdqa  XTMP0, X3
+       mov     y0, e           /* y0 = e */
+       ror     y0, (25-11)     /* y0 = e >> (25-11) */
+       mov     y1, a           /* y1 = a */
+               palignr XTMP0, 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)) */
+               movdqa  XTMP1, X1
+       xor     y1, a           /* y1 = a ^ (a >> (22-13) */
+       xor     y2, g           /* y2 = f^g */
+               paddd   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 */
+               palignr XTMP1, 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 */
+               movdqa  XTMP2, XTMP1    /* XTMP2 = W[-15] */
+       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 */
+               movdqa  XTMP3, XTMP1    /* XTMP3 = W[-15] */
+       mov     y0, a           /* y0 = a */
+       add     h, y2           /* h = h + S1 + CH + k + w */
+       mov     y2, a           /* y2 = a */
+               pslld   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 */
+               psrld   XTMP2, 7
+       and     y0, b           /* y0 = (a|c)&b */
+       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 */
+
+ROTATE_ARGS
+               movdqa  XTMP2, XTMP3    /* XTMP2 = W[-15] */
+       mov     y0, e           /* y0 = e */
+       mov     y1, a           /* y1 = a */
+               movdqa  XTMP4, XTMP3    /* XTMP4 = W[-15] */
+       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) */
+               pslld   XTMP3, (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 */
+               psrld   XTMP2, 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) */
+               pxor    XTMP1, XTMP3
+       xor     y1, a           /* y1 = a ^ (a >> (13-2)) ^ (a >> (22-2)) */
+       xor     y2, g           /* y2 = CH = ((f^g)&e)^g */
+               psrld   XTMP4, 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) */
+               pxor    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 */
+               pxor    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 */
+               pshufd  XTMP2, X3, 0b11111010   /* XTMP2 = W[-2] {BBAA} */
+       and     y0, b           /* y0 = (a|c)&b */
+       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 */
+
+ROTATE_ARGS
+               movdqa  XTMP3, XTMP2    /* XTMP3 = W[-2] {BBAA} */
+       mov     y0, e           /* y0 = e */
+       mov     y1, a           /* y1 = a */
+       ror     y0, (25-11)     /* y0 = e >> (25-11) */
+               movdqa  XTMP4, XTMP2    /* XTMP4 = W[-2] {BBAA} */
+       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)) */
+               psrlq   XTMP2, 17       /* XTMP2 = W[-2] ror 17 {xBxA} */
+       xor     y2, g           /* y2 = f^g */
+               psrlq   XTMP3, 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 */
+               psrld   XTMP4, 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) */
+               pxor    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 */
+               pxor    XTMP4, XTMP2    /* XTMP4 = s1 {xBxA} */
+       mov     y0, a           /* y0 = a */
+       add     h, y2           /* h = h + S1 + CH + k + w */
+       mov     y2, a           /* y2 = a */
+               pshufb  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 */
+               paddd   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 */
+               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 */
+
+ROTATE_ARGS
+               movdqa  XTMP3, XTMP2    /* XTMP3 = W[-2] {DDCC} */
+       mov     y0, e           /* y0 = e */
+       ror     y0, (25-11)     /* y0 = e >> (25-11) */
+       mov     y1, a           /* y1 = a */
+               movdqa  X0,    XTMP2    /* X0    = W[-2] {DDCC} */
+       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)) */
+               psrlq   XTMP2, 17       /* XTMP2 = W[-2] ror 17 {xDxC} */
+       xor     y1, a           /* y1 = a ^ (a >> (22-13) */
+       xor     y2, g           /* y2 = f^g */
+               psrlq   XTMP3, 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)) */
+               psrld   X0,    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 */
+               pxor    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 */
+               pxor    X0, XTMP2       /* X0 = s1 {xDxC} */
+       mov     y0, a           /* y0 = a */
+       add     h, y2           /* h = h + S1 + CH + k + w */
+       mov     y2, a           /* y2 = a */
+               pshufb  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 */
+               paddd   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) */
+       add     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) */
+       add     h, y0           /* h = h + S1 + CH + k + w + S0 + MAJ */
+       ROTATE_ARGS
+.endm
+
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; void sha256_sse4(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_ssse3
+.type  _gcry_sha256_transform_amd64_ssse3,@function;
+.align 16
+_gcry_sha256_transform_amd64_ssse3:
+       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]
+
+       movdqa  BYTE_FLIP_MASK, [.LPSHUFFLE_BYTE_FLIP_MASK ADD_RIP]
+       movdqa  SHUF_00BA, [.L_SHUF_00BA ADD_RIP]
+       movdqa  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:
+       movdqa  XFER, [TBL + 0*16]
+       paddd   XFER, X0
+       movdqa  [rsp + _XFER], XFER
+       FOUR_ROUNDS_AND_SCHED
+
+       movdqa  XFER, [TBL + 1*16]
+       paddd   XFER, X0
+       movdqa  [rsp + _XFER], XFER
+       FOUR_ROUNDS_AND_SCHED
+
+       movdqa  XFER, [TBL + 2*16]
+       paddd   XFER, X0
+       movdqa  [rsp + _XFER], XFER
+       FOUR_ROUNDS_AND_SCHED
+
+       movdqa  XFER, [TBL + 3*16]
+       paddd   XFER, X0
+       movdqa  [rsp + _XFER], XFER
+       add     TBL, 4*16
+       FOUR_ROUNDS_AND_SCHED
+
+       sub     SRND, 1
+       jne     .Loop1
+
+       mov     SRND, 2
+.Loop2:
+       paddd   X0, [TBL + 0*16]
+       movdqa  [rsp + _XFER], X0
+       DO_ROUND        0
+       DO_ROUND        1
+       DO_ROUND        2
+       DO_ROUND        3
+       paddd   X1, [TBL + 1*16]
+       movdqa  [rsp + _XFER], X1
+       add     TBL, 2*16
+       DO_ROUND        0
+       DO_ROUND        1
+       DO_ROUND        2
+       DO_ROUND        3
+
+       movdqa  X0, X2
+       movdqa  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
+
+       pxor    xmm0, xmm0
+       pxor    xmm1, xmm1
+       pxor    xmm2, xmm2
+       pxor    xmm3, xmm3
+       pxor    xmm4, xmm4
+       pxor    xmm5, xmm5
+       pxor    xmm6, xmm6
+       pxor    xmm7, xmm7
+       pxor    xmm8, xmm8
+       pxor    xmm9, xmm9
+       pxor    xmm10, xmm10
+       pxor    xmm11, xmm11
+       pxor    xmm12, xmm12
+
+.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
index 309fa3b..d92303c 100644 (file)
 
 #include "g10lib.h"
 #include "bithelp.h"
+#include "bufhelp.h"
 #include "cipher.h"
 #include "hash-common.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) && \
+    defined(HAVE_INTEL_SYNTAX_PLATFORM_AS)
+# define USE_SSSE3 1
+#endif
+
+
 typedef struct {
+  gcry_md_block_ctx_t bctx;
   u32  h0,h1,h2,h3,h4,h5,h6,h7;
-  u32  nblocks;
-  byte buf[64];
-  int  count;
+#ifdef USE_SSSE3
+  unsigned int use_ssse3:1;
+#endif
 } SHA256_CONTEXT;
 
 
+static unsigned int
+transform (void *c, const unsigned char *data);
+
+
 static void
-sha256_init (void *context)
+sha256_init (void *context, unsigned int flags)
 {
   SHA256_CONTEXT *hd = context;
 
+  (void)flags;
+
   hd->h0 = 0x6a09e667;
   hd->h1 = 0xbb67ae85;
   hd->h2 = 0x3c6ef372;
@@ -67,16 +85,25 @@ sha256_init (void *context)
   hd->h6 = 0x1f83d9ab;
   hd->h7 = 0x5be0cd19;
 
-  hd->nblocks = 0;
-  hd->count = 0;
+  hd->bctx.nblocks = 0;
+  hd->bctx.nblocks_high = 0;
+  hd->bctx.count = 0;
+  hd->bctx.blocksize = 64;
+  hd->bctx.bwrite = transform;
+
+#ifdef USE_SSSE3
+  hd->use_ssse3 = (_gcry_get_hw_features () & HWF_INTEL_SSSE3) != 0;
+#endif
 }
 
 
 static void
-sha224_init (void *context)
+sha224_init (void *context, unsigned int flags)
 {
   SHA256_CONTEXT *hd = context;
 
+  (void)flags;
+
   hd->h0 = 0xc1059ed8;
   hd->h1 = 0x367cd507;
   hd->h2 = 0x3070dd17;
@@ -86,8 +113,15 @@ sha224_init (void *context)
   hd->h6 = 0x64f98fa7;
   hd->h7 = 0xbefa4fa4;
 
-  hd->nblocks = 0;
-  hd->count = 0;
+  hd->bctx.nblocks = 0;
+  hd->bctx.nblocks_high = 0;
+  hd->bctx.count = 0;
+  hd->bctx.blocksize = 64;
+  hd->bctx.bwrite = transform;
+
+#ifdef USE_SSSE3
+  hd->use_ssse3 = (_gcry_get_hw_features () & HWF_INTEL_SSSE3) != 0;
+#endif
 }
 
 
@@ -139,9 +173,10 @@ Sum1 (u32 x)
 }
 
 
-static void
-transform (SHA256_CONTEXT *hd, const unsigned char *data)
+static unsigned int
+_transform (void *ctx, const unsigned char *data)
 {
+  SHA256_CONTEXT *hd = ctx;
   static const u32 K[64] = {
     0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
     0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
@@ -162,7 +197,6 @@ transform (SHA256_CONTEXT *hd, const unsigned char *data)
   };
 
   u32 a,b,c,d,e,f,g,h,t1,t2;
-  u32 x[16];
   u32 w[64];
   int i;
 
@@ -175,24 +209,8 @@ transform (SHA256_CONTEXT *hd, const unsigned char *data)
   g = hd->h6;
   h = hd->h7;
 
-#ifdef WORDS_BIGENDIAN
-  memcpy (x, data, 64);
-#else
-  {
-    byte *p2;
-
-    for (i=0, p2=(byte*)x; i < 16; i++, p2 += 4 )
-      {
-        p2[3] = *data++;
-        p2[2] = *data++;
-        p2[1] = *data++;
-        p2[0] = *data++;
-      }
-  }
-#endif
-
   for (i=0; i < 16; i++)
-    w[i] = x[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];
 
@@ -254,49 +272,32 @@ transform (SHA256_CONTEXT *hd, const unsigned char *data)
   hd->h5 += f;
   hd->h6 += g;
   hd->h7 += h;
+
+  return /*burn_stack*/ 74*4+32;
 }
 #undef S0
 #undef S1
 #undef R
 
 
-/* Update the message digest with the contents of INBUF with length
-  INLEN.  */
-static void
-sha256_write (void *context, const void *inbuf_arg, size_t inlen)
+#ifdef USE_SSSE3
+unsigned int _gcry_sha256_transform_amd64_ssse3(const void *input_data,
+                                               u32 state[8], size_t num_blks);
+#endif
+
+
+static unsigned int
+transform (void *ctx, const unsigned char *data)
 {
-  const unsigned char *inbuf = inbuf_arg;
-  SHA256_CONTEXT *hd = context;
+  SHA256_CONTEXT *hd = ctx;
 
-  if (hd->count == 64)
-    { /* flush the buffer */
-      transform (hd, hd->buf);
-      _gcry_burn_stack (74*4+32);
-      hd->count = 0;
-      hd->nblocks++;
-    }
-  if (!inbuf)
-    return;
-  if (hd->count)
-    {
-      for (; inlen && hd->count < 64; inlen--)
-        hd->buf[hd->count++] = *inbuf++;
-      sha256_write (hd, NULL, 0);
-      if (!inlen)
-        return;
-    }
+#ifdef USE_SSSE3
+  if (hd->use_ssse3)
+    return _gcry_sha256_transform_amd64_ssse3 (data, &hd->h0, 1)
+           + 4 * sizeof(void*);
+#endif
 
-  while (inlen >= 64)
-    {
-      transform (hd, inbuf);
-      hd->count = 0;
-      hd->nblocks++;
-      inlen -= 64;
-      inbuf += 64;
-    }
-  _gcry_burn_stack (74*4+32);
-  for (; inlen && hd->count < 64; inlen--)
-    hd->buf[hd->count++] = *inbuf++;
+  return _transform (hd, data);
 }
 
 
@@ -309,18 +310,24 @@ static void
 sha256_final(void *context)
 {
   SHA256_CONTEXT *hd = context;
-  u32 t, msb, lsb;
+  u32 t, th, msb, lsb;
   byte *p;
+  unsigned int burn;
+
+  _gcry_md_block_write (hd, NULL, 0); /* flush */;
 
-  sha256_write (hd, NULL, 0); /* flush */;
+  t = hd->bctx.nblocks;
+  if (sizeof t == sizeof hd->bctx.nblocks)
+    th = hd->bctx.nblocks_high;
+  else
+    th = hd->bctx.nblocks >> 32;
 
-  t = hd->nblocks;
   /* multiply by 64 to make a byte count */
   lsb = t << 6;
-  msb = t >> 26;
+  msb = (th << 6) | (t >> 26);
   /* add the count */
   t = lsb;
-  if ((lsb += hd->count) < t)
+  if ((lsb += hd->bctx.count) < t)
     msb++;
   /* multiply by 8 to make a bit count */
   t = lsb;
@@ -328,39 +335,28 @@ sha256_final(void *context)
   msb <<= 3;
   msb |= t >> 29;
 
-  if (hd->count < 56)
+  if (hd->bctx.count < 56)
     { /* enough room */
-      hd->buf[hd->count++] = 0x80; /* pad */
-      while (hd->count < 56)
-        hd->buf[hd->count++] = 0;  /* pad */
+      hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad */
+      while (hd->bctx.count < 56)
+        hd->bctx.buf[hd->bctx.count++] = 0;  /* pad */
     }
   else
     { /* need one extra block */
-      hd->buf[hd->count++] = 0x80; /* pad character */
-      while (hd->count < 64)
-        hd->buf[hd->count++] = 0;
-      sha256_write (hd, NULL, 0);  /* flush */;
-      memset (hd->buf, 0, 56 ); /* fill next block with zeroes */
+      hd->bctx.buf[hd->bctx.count++] = 0x80; /* pad character */
+      while (hd->bctx.count < 64)
+        hd->bctx.buf[hd->bctx.count++] = 0;
+      _gcry_md_block_write (hd, NULL, 0);  /* flush */;
+      memset (hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
     }
   /* append the 64 bit count */
-  hd->buf[56] = msb >> 24;
-  hd->buf[57] = msb >> 16;
-  hd->buf[58] = msb >>  8;
-  hd->buf[59] = msb;
-  hd->buf[60] = lsb >> 24;
-  hd->buf[61] = lsb >> 16;
-  hd->buf[62] = lsb >>  8;
-  hd->buf[63] = lsb;
-  transform (hd, hd->buf);
-  _gcry_burn_stack (74*4+32);
-
-  p = hd->buf;
-#ifdef WORDS_BIGENDIAN
-#define X(a) do { *(u32*)p = hd->h##a ; p += 4; } while(0)
-#else /* little endian */
-#define X(a) do { *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;         \
-                 *p++ = hd->h##a >> 8; *p++ = hd->h##a; } while(0)
-#endif
+  buf_put_be32(hd->bctx.buf + 56, msb);
+  buf_put_be32(hd->bctx.buf + 60, lsb);
+  burn = transform (hd, hd->bctx.buf);
+  _gcry_burn_stack (burn);
+
+  p = hd->bctx.buf;
+#define X(a) do { *(u32*)p = be_bswap32(hd->h##a); p += 4; } while(0)
   X(0);
   X(1);
   X(2);
@@ -377,7 +373,7 @@ sha256_read (void *context)
 {
   SHA256_CONTEXT *hd = context;
 
-  return hd->buf;
+  return hd->bctx.buf;
 }
 
 
@@ -533,22 +529,18 @@ static gcry_md_oid_spec_t oid_spec_sha256[] =
 
 gcry_md_spec_t _gcry_digest_spec_sha224 =
   {
+    GCRY_MD_SHA224, {0, 1},
     "SHA224", asn224, DIM (asn224), oid_spec_sha224, 28,
-    sha224_init, sha256_write, sha256_final, sha256_read,
-    sizeof (SHA256_CONTEXT)
-  };
-md_extra_spec_t _gcry_digest_extraspec_sha224 =
-  {
+    sha224_init, _gcry_md_block_write, sha256_final, sha256_read,
+    sizeof (SHA256_CONTEXT),
     run_selftests
   };
 
 gcry_md_spec_t _gcry_digest_spec_sha256 =
   {
+    GCRY_MD_SHA256, {0, 1},
     "SHA256", asn256, DIM (asn256), oid_spec_sha256, 32,
-    sha256_init, sha256_write, sha256_final, sha256_read,
-    sizeof (SHA256_CONTEXT)
-  };
-md_extra_spec_t _gcry_digest_extraspec_sha256 =
-  {
+    sha256_init, _gcry_md_block_write, sha256_final, sha256_read,
+    sizeof (SHA256_CONTEXT),
     run_selftests
   };
diff --git a/cipher/sha512-armv7-neon.S b/cipher/sha512-armv7-neon.S
new file mode 100644 (file)
index 0000000..042b15a
--- /dev/null
@@ -0,0 +1,316 @@
+/* sha512-armv7-neon.S  -  ARM/NEON assembly implementation of SHA-512 transform
+ *
+ * Copyright © 2013 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)
+
+.text
+
+.syntax unified
+.fpu neon
+.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)
+
+/* register macros */
+#define RK %r2
+
+#define RA d0
+#define RB d1
+#define RC d2
+#define RD d3
+#define RE d4
+#define RF d5
+#define RG d6
+#define RH d7
+
+#define RT0 d8
+#define RT1 d9
+#define RT2 d10
+#define RT3 d11
+#define RT4 d12
+#define RT5 d13
+#define RT6 d14
+#define RT7 d15
+
+#define RW0 d16
+#define RW1 d17
+#define RW2 d18
+#define RW3 d19
+#define RW4 d20
+#define RW5 d21
+#define RW6 d22
+#define RW7 d23
+#define RW8 d24
+#define RW9 d25
+#define RW10 d26
+#define RW11 d27
+#define RW12 d28
+#define RW13 d29
+#define RW14 d30
+#define RW15 d31
+
+#define RW01q q8
+#define RW23q q9
+#define RW45q q10
+#define RW67q q11
+#define RW89q q12
+#define RW1011q q13
+#define RW1213q q14
+#define RW1415q q15
+
+/***********************************************************************
+ * ARM assembly implementation of sha512 transform
+ ***********************************************************************/
+#define round_0_63(ra, rb, rc, rd, re, rf, rg, rh, rw0, rw14, rw9, rw1) \
+       /* t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t]; */ \
+       vshr.u64 RT1, re, #14; \
+       vshl.u64 RT3, re, #64 - 14; \
+       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; \
+       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; \
+       \
+       vadd.u64 RT1, RT1, rh; \
+       veor.64 RT2, RT2, RT6; \
+       vshr.u64 rh, 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; \
+       \
+       /* 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; \
+       vadd.u64 rh, rh, RT0; \
+       vshl.u64 RT2, rw14, #64 - 19; \
+       \
+       /* 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; \
+
+#define round_64_79(ra, rb, rc, rd, re, rf, rg, rh, rw0) \
+       /* t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t]; */ \
+       vld1.64 {RT0}, [RK]!; \
+       vshr.u64 RT1, re, #14; \
+       vshl.u64 RT3, re, #64 - 14; \
+       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; \
+       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; \
+       \
+       vadd.u64 RT1, RT1, rh; \
+       veor.64 RT2, RT2, RT6; \
+       vadd.u64 RT1, RT1, RT0; \
+       vshr.u64 RT4, ra, #34; \
+       vshl.u64 RT5, ra, #64 - 34; \
+       \
+       /* 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; \
+       vadd.u64 rd, rd, RT1; /* d+=t1; */ \
+       vadd.u64 rh, RT7, RT1; /* h=t7+t1; */
+
+.align 3
+.globl _gcry_sha512_transform_armv7_neon
+.type  _gcry_sha512_transform_armv7_neon,%function;
+
+_gcry_sha512_transform_armv7_neon:
+       /* Input:
+        *      %r0: SHA512_CONTEXT
+        *      %r1: data
+        *      %r2: u64 k[] constants
+        */
+       mov %r3, #0;
+
+       /* Load context to d0-d7 */
+       vld1.64 {RA-RD}, [%r0]!;
+       vld1.64 {RE-RH}, [%r0];
+       sub %r0, #(4*8);
+
+       /* Load input to w[16], d16-d31 */
+       /* NOTE: Assumes that on ARMv7 unaligned accesses are always allowed. */
+       vld1.64 {RW0-RW3}, [%r1]!;
+       vld1.64 {RW4-RW7}, [%r1]!;
+       vld1.64 {RW8-RW11}, [%r1]!;
+       vld1.64 {RW12-RW15}, [%r1];
+#ifdef __ARMEL__
+       /* byteswap */
+       vrev64.8 RW01q, RW01q;
+       vrev64.8 RW23q, RW23q;
+       vrev64.8 RW45q, RW45q;
+       vrev64.8 RW67q, RW67q;
+       vrev64.8 RW89q, RW89q;
+       vrev64.8 RW1011q, RW1011q;
+       vrev64.8 RW1213q, RW1213q;
+       vrev64.8 RW1415q, RW1415q;
+#endif
+
+       /* EABI says that d8-d15 must be preserved by callee. */
+       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);
+
+       /* Load context to d16-d23 */
+       vld1.64 {RW0-RW3}, [%r0]!;
+       vld1.64 {RW4-RW7}, [%r0];
+       sub %r0, #(4*8);
+
+       vadd.u64 RA, RW0;
+       vadd.u64 RB, RW1;
+       vadd.u64 RC, RW2;
+       vadd.u64 RD, RW3;
+       vadd.u64 RE, RW4;
+       vadd.u64 RF, RW5;
+       vadd.u64 RG, RW6;
+       vadd.u64 RH, RW7;
+
+       /* Store the first half of context */
+       vst1.64 {RA-RD}, [%r0]!;
+
+       /* Clear used registers */
+       /* d16-d31 */
+       veor.u64 RW01q, RW01q;
+       veor.u64 RW23q, RW23q;
+       veor.u64 RW45q, RW45q;
+       veor.u64 RW67q, RW67q;
+       vst1.64 {RE-RH}, [%r0]; /* Store the last half of context */
+       veor.u64 RW89q, RW89q;
+       veor.u64 RW1011q, RW1011q;
+       veor.u64 RW1213q, RW1213q;
+       veor.u64 RW1415q, RW1415q;
+       /* d8-d15 */
+       vpop {RT0-RT7};
+       /* d0-d7 (q0-q3) */
+       veor.u64 %q0, %q0;
+       veor.u64 %q1, %q1;
+       veor.u64 %q2, %q2;
+       veor.u64 %q3, %q3;
+
+       bx %lr;
+.size _gcry_sha512_transform_armv7_neon,.-_gcry_sha512_transform_armv7_neon;
+
+#endif
diff --git a/cipher/sha512-avx-amd64.S b/cipher/sha512-avx-amd64.S
new file mode 100644 (file)
index 0000000..3449b87
--- /dev/null
@@ -0,0 +1,416 @@
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; 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.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+*/
+/*
+ * 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_INTEL_SYNTAX_PLATFORM_AS) && \
+    defined(HAVE_GCC_INLINE_ASM_AVX) && defined(USE_SHA512)
+
+#ifdef __PIC__
+#  define ADD_RIP +rip
+#else
+#  define ADD_RIP
+#endif
+
+.intel_syntax noprefix
+
+.text
+
+/* Virtual Registers */
+msg = rdi /* ARG1 */
+digest = rsi /* ARG2 */
+msglen = rdx /* ARG3 */
+T1 = rcx
+T2 = r8
+a_64 = r9
+b_64 = r10
+c_64 = r11
+d_64 = r12
+e_64 = r13
+f_64 = r14
+g_64 = r15
+h_64 = rbx
+tmp0 = rax
+
+/*
+; Local variables (stack frame)
+; Note: frame_size must be an odd multiple of 8 bytes to XMM align RSP
+*/
+frame_W      = 0 /* Message Schedule */
+frame_W_size = (80 * 8)
+frame_WK      = ((frame_W) + (frame_W_size)) /* W[t] + K[t] | W[t+1] + K[t+1] */
+frame_WK_size = (2 * 8)
+frame_GPRSAVE      = ((frame_WK) + (frame_WK_size))
+frame_GPRSAVE_size = (5 * 8)
+frame_size = ((frame_GPRSAVE) + (frame_GPRSAVE_size))
+
+
+/* Useful QWORD "arrays" for simpler memory references */
+#define MSG(i)    msg    + 8*(i)               /* Input message (arg1) */
+#define DIGEST(i) digest + 8*(i)               /* Output Digest (arg2) */
+#define K_t(i)    .LK512   + 8*(i) ADD_RIP     /* SHA Constants (static mem) */
+#define W_t(i)    rsp + frame_W  + 8*(i)       /* Message Schedule (stack frame) */
+#define WK_2(i)   rsp + frame_WK + 8*((i) % 2) /* W[t]+K[t] (stack frame) */
+/* MSG, DIGEST, K_t, W_t are arrays */
+/* WK_2(t) points to 1 of 2 qwords at frame.WK depdending on t being odd/even */
+
+.macro RotateState
+       /* Rotate symbles a..h right */
+       __TMP = h_64
+       h_64 =  g_64
+       g_64 =  f_64
+       f_64 =  e_64
+       e_64 =  d_64
+       d_64 =  c_64
+       c_64 =  b_64
+       b_64 =  a_64
+       a_64 =  __TMP
+.endm
+
+.macro RORQ p1 p2
+       /* shld is faster than ror on Intel Sandybridge */
+       shld    \p1, \p1, (64 - \p2)
+.endm
+
+.macro SHA512_Round t
+       /* Compute Round %%t */
+       mov     T1,   f_64        /* T1 = f */
+       mov     tmp0, e_64        /* tmp = e */
+       xor     T1,   g_64        /* T1 = f ^ g */
+       RORQ    tmp0, 23 /* 41     ; tmp = e ror 23 */
+       and     T1,   e_64        /* T1 = (f ^ g) & e */
+       xor     tmp0, e_64        /* tmp = (e ror 23) ^ e */
+       xor     T1,   g_64        /* T1 = ((f ^ g) & e) ^ g = CH(e,f,g) */
+       add     T1,   [WK_2(\t)] /* W[t] + K[t] from message scheduler */
+       RORQ    tmp0, 4 /* 18      ; tmp = ((e ror 23) ^ e) ror 4 */
+       xor     tmp0, e_64        /* tmp = (((e ror 23) ^ e) ror 4) ^ e */
+       mov     T2,   a_64        /* T2 = a */
+       add     T1,   h_64        /* T1 = CH(e,f,g) + W[t] + K[t] + h */
+       RORQ    tmp0, 14 /* 14     ; tmp = ((((e ror23)^e)ror4)^e)ror14 = S1(e) */
+       add     T1,   tmp0        /* T1 = CH(e,f,g) + W[t] + K[t] + S1(e) */
+       mov     tmp0, a_64        /* tmp = a */
+       xor     T2,   c_64        /* T2 = a ^ c */
+       and     tmp0, c_64        /* tmp = a & c */
+       and     T2,   b_64        /* T2 = (a ^ c) & b */
+       xor     T2,   tmp0        /* T2 = ((a ^ c) & b) ^ (a & c) = Maj(a,b,c) */
+       mov     tmp0, a_64        /* tmp = a */
+       RORQ    tmp0, 5 /* 39      ; tmp = a ror 5 */
+       xor     tmp0, a_64        /* tmp = (a ror 5) ^ a */
+       add     d_64, T1          /* e(next_state) = d + T1  */
+       RORQ    tmp0, 6 /* 34      ; tmp = ((a ror 5) ^ a) ror 6 */
+       xor     tmp0, a_64        /* tmp = (((a ror 5) ^ a) ror 6) ^ a */
+       lea     h_64, [T1 + T2]   /* a(next_state) = T1 + Maj(a,b,c) */
+       RORQ    tmp0, 28 /* 28     ; tmp = ((((a ror5)^a)ror6)^a)ror28 = S0(a) */
+       add     h_64, tmp0        /* a(next_state) = T1 + Maj(a,b,c) S0(a) */
+       RotateState
+.endm
+
+.macro SHA512_2Sched_2Round_avx t
+/*     ; Compute rounds %%t-2 and %%t-1
+       ; Compute message schedule QWORDS %%t and %%t+1
+
+       ;   Two rounds are computed based on the values for K[t-2]+W[t-2] and
+       ; K[t-1]+W[t-1] which were previously stored at WK_2 by the message
+       ; scheduler.
+       ;   The two new schedule QWORDS are stored at [W_t(%%t)] and [W_t(%%t+1)].
+       ; They are then added to their respective SHA512 constants at
+       ; [K_t(%%t)] and [K_t(%%t+1)] and stored at dqword [WK_2(%%t)]
+       ;   For brievity, the comments following vectored instructions only refer to
+       ; the first of a pair of QWORDS.
+       ; Eg. XMM4=W[t-2] really means XMM4={W[t-2]|W[t-1]}
+       ;   The computation of the message schedule and the rounds are tightly
+       ; stitched to take advantage of instruction-level parallelism.
+       ; For clarity, integer instructions (for the rounds calculation) are indented
+       ; by one tab. Vectored instructions (for the message scheduler) are indented
+       ; by two tabs. */
+
+               vmovdqa xmm4, [W_t(\t-2)]   /* XMM4 = W[t-2] */
+               vmovdqu xmm5, [W_t(\t-15)]  /* XMM5 = W[t-15] */
+       mov     T1,   f_64
+               vpsrlq  xmm0, xmm4, 61       /* XMM0 = W[t-2]>>61 */
+       mov     tmp0, e_64
+               vpsrlq  xmm6, xmm5, 1        /* XMM6 = W[t-15]>>1 */
+       xor     T1,   g_64
+       RORQ    tmp0, 23 /* 41 */
+               vpsrlq  xmm1, xmm4, 19       /* XMM1 = W[t-2]>>19 */
+       and     T1,   e_64
+       xor     tmp0, e_64
+               vpxor   xmm0, xmm0, xmm1           /* XMM0 = W[t-2]>>61 ^ W[t-2]>>19 */
+       xor     T1,   g_64
+       add     T1,   [WK_2(\t)];
+               vpsrlq  xmm7, xmm5, 8        /* XMM7 = W[t-15]>>8 */
+       RORQ    tmp0, 4 /* 18 */
+               vpsrlq  xmm2, xmm4, 6        /* XMM2 = W[t-2]>>6 */
+       xor     tmp0, e_64
+       mov     T2,   a_64
+       add     T1,   h_64
+               vpxor   xmm6, xmm6, xmm7           /* XMM6 = W[t-15]>>1 ^ W[t-15]>>8 */
+       RORQ    tmp0, 14 /* 14 */
+       add     T1,   tmp0
+               vpsrlq  xmm8, xmm5, 7        /* XMM8 = W[t-15]>>7 */
+       mov     tmp0, a_64
+       xor     T2,   c_64
+               vpsllq  xmm3, xmm4, (64-61)  /* XMM3 = W[t-2]<<3 */
+       and     tmp0, c_64
+       and     T2,   b_64
+               vpxor   xmm2, xmm2, xmm3           /* XMM2 = W[t-2]>>6 ^ W[t-2]<<3 */
+       xor     T2,   tmp0
+       mov     tmp0, a_64
+               vpsllq  xmm9, xmm5, (64-1)   /* XMM9 = W[t-15]<<63 */
+       RORQ    tmp0, 5 /* 39 */
+               vpxor   xmm8, xmm8, xmm9           /* XMM8 = W[t-15]>>7 ^ W[t-15]<<63 */
+       xor     tmp0, a_64
+       add     d_64, T1
+       RORQ    tmp0, 6 /* 34 */
+       xor     tmp0, a_64
+               vpxor   xmm6, xmm6, xmm8           /* XMM6 = W[t-15]>>1 ^ W[t-15]>>8 ^ W[t-15]>>7 ^ W[t-15]<<63 */
+       lea     h_64, [T1 + T2]
+       RORQ    tmp0, 28 /* 28 */
+               vpsllq  xmm4, xmm4, (64-19)        /* XMM4 = W[t-2]<<25 */
+       add     h_64, tmp0
+       RotateState
+               vpxor   xmm0, xmm0, xmm4           /* XMM0 = W[t-2]>>61 ^ W[t-2]>>19 ^ W[t-2]<<25 */
+       mov     T1, f_64
+               vpxor   xmm0, xmm0, xmm2           /* XMM0 = s1(W[t-2]) */
+       mov     tmp0, e_64
+       xor     T1,   g_64
+               vpaddq  xmm0, xmm0, [W_t(\t-16)]  /* XMM0 = s1(W[t-2]) + W[t-16] */
+               vmovdqu xmm1, [W_t(\t- 7)]  /* XMM1 = W[t-7] */
+       RORQ    tmp0, 23 /* 41 */
+       and     T1,   e_64
+       xor     tmp0, e_64
+       xor     T1,   g_64
+               vpsllq  xmm5, xmm5, (64-8)         /* XMM5 = W[t-15]<<56 */
+       add     T1,   [WK_2(\t+1)]
+               vpxor   xmm6, xmm6, xmm5           /* XMM6 = s0(W[t-15]) */
+       RORQ    tmp0, 4 /* 18 */
+               vpaddq  xmm0, xmm0, xmm6           /* XMM0 = s1(W[t-2]) + W[t-16] + s0(W[t-15]) */
+       xor     tmp0, e_64
+               vpaddq  xmm0, xmm0, xmm1           /* XMM0 = W[t] = s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16] */
+       mov     T2,   a_64
+       add     T1,   h_64
+       RORQ    tmp0, 14 /* 14 */
+       add     T1,   tmp0
+               vmovdqa [W_t(\t)], xmm0      /* Store W[t] */
+               vpaddq  xmm0, xmm0, [K_t(t)]        /* Compute W[t]+K[t] */
+               vmovdqa [WK_2(t)], xmm0       /* Store W[t]+K[t] for next rounds */
+       mov     tmp0, a_64
+       xor     T2,   c_64
+       and     tmp0, c_64
+       and     T2,   b_64
+       xor     T2,   tmp0
+       mov     tmp0, a_64
+       RORQ    tmp0, 5 /* 39 */
+       xor     tmp0, a_64
+       add     d_64, T1
+       RORQ    tmp0, 6 /* 34 */
+       xor     tmp0, a_64
+       lea     h_64, [T1 + T2]
+       RORQ    tmp0, 28 /* 28 */
+       add     h_64, tmp0
+       RotateState
+.endm
+
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; void sha512_avx(const void* M, void* D, uint64_t L);
+; Purpose: Updates the SHA512 digest stored at D with the message stored in M.
+; The size of the message pointed to by M must be an integer multiple of SHA512
+;   message blocks.
+; L is the message length in SHA512 blocks
+*/
+.globl _gcry_sha512_transform_amd64_avx
+.type _gcry_sha512_transform_amd64_avx,@function;
+.align 16
+_gcry_sha512_transform_amd64_avx:
+       xor eax, eax
+
+       cmp     msglen, 0
+       je      .Lnowork
+
+       vzeroupper
+
+       /* Allocate Stack Space */
+       sub     rsp, frame_size
+
+       /* Save GPRs */
+       mov     [rsp + frame_GPRSAVE + 8 * 0], rbx
+       mov     [rsp + frame_GPRSAVE + 8 * 1], r12
+       mov     [rsp + frame_GPRSAVE + 8 * 2], r13
+       mov     [rsp + frame_GPRSAVE + 8 * 3], r14
+       mov     [rsp + frame_GPRSAVE + 8 * 4], r15
+
+.Lupdateblock:
+
+       /* Load state variables */
+       mov     a_64, [DIGEST(0)]
+       mov     b_64, [DIGEST(1)]
+       mov     c_64, [DIGEST(2)]
+       mov     d_64, [DIGEST(3)]
+       mov     e_64, [DIGEST(4)]
+       mov     f_64, [DIGEST(5)]
+       mov     g_64, [DIGEST(6)]
+       mov     h_64, [DIGEST(7)]
+
+       t = 0
+       .rept 80/2 + 1
+       /* (80 rounds) / (2 rounds/iteration) + (1 iteration) */
+       /* +1 iteration because the scheduler leads hashing by 1 iteration */
+               .if t < 2
+                       /* BSWAP 2 QWORDS */
+                       vmovdqa xmm1, [.LXMM_QWORD_BSWAP ADD_RIP]
+                       vmovdqu xmm0, [MSG(t)]
+                       vpshufb xmm0, xmm0, xmm1     /* BSWAP */
+                       vmovdqa [W_t(t)], xmm0       /* Store Scheduled Pair */
+                       vpaddq  xmm0, xmm0, [K_t(t)] /* Compute W[t]+K[t] */
+                       vmovdqa [WK_2(t)], xmm0      /* Store into WK for rounds */
+               .elseif t < 16
+                       /* BSWAP 2 QWORDS, Compute 2 Rounds */
+                       vmovdqu xmm0, [MSG(t)]
+                       vpshufb xmm0, xmm0, xmm1     /* BSWAP */
+                       SHA512_Round (t - 2)         /* Round t-2 */
+                       vmovdqa [W_t(t)], xmm0       /* Store Scheduled Pair */
+                       vpaddq  xmm0, xmm0, [K_t(t)] /* Compute W[t]+K[t] */
+                       SHA512_Round (t - 1)         /* Round t-1 */
+                       vmovdqa [WK_2(t)], xmm0      /* W[t]+K[t] into WK */
+               .elseif t < 79
+                       /* Schedule 2 QWORDS; Compute 2 Rounds */
+                       SHA512_2Sched_2Round_avx t
+               .else
+                       /* Compute 2 Rounds */
+                       SHA512_Round (t - 2)
+                       SHA512_Round (t - 1)
+               .endif
+               t = ((t)+2)
+       .endr
+
+       /* Update digest */
+       add     [DIGEST(0)], a_64
+       add     [DIGEST(1)], b_64
+       add     [DIGEST(2)], c_64
+       add     [DIGEST(3)], d_64
+       add     [DIGEST(4)], e_64
+       add     [DIGEST(5)], f_64
+       add     [DIGEST(6)], g_64
+       add     [DIGEST(7)], h_64
+
+       /* Advance to next message block */
+       add     msg, 16*8
+       dec     msglen
+       jnz     .Lupdateblock
+
+       /* Restore GPRs */
+       mov     rbx, [rsp + frame_GPRSAVE + 8 * 0]
+       mov     r12, [rsp + frame_GPRSAVE + 8 * 1]
+       mov     r13, [rsp + frame_GPRSAVE + 8 * 2]
+       mov     r14, [rsp + frame_GPRSAVE + 8 * 3]
+       mov     r15, [rsp + frame_GPRSAVE + 8 * 4]
+
+       /* Restore Stack Pointer */
+       add     rsp, frame_size
+
+       vzeroall
+
+       /* Return stack burn depth */
+       mov     rax, frame_size
+
+.Lnowork:
+       ret
+
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Binary Data
+*/
+
+.data
+
+.align 16
+
+/* Mask for byte-swapping a couple of qwords in an XMM register using (v)pshufb. */
+.LXMM_QWORD_BSWAP:
+       .octa 0x08090a0b0c0d0e0f0001020304050607
+
+/* K[t] used in SHA512 hashing */
+.LK512:
+       .quad 0x428a2f98d728ae22,0x7137449123ef65cd
+       .quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
+       .quad 0x3956c25bf348b538,0x59f111f1b605d019
+       .quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118
+       .quad 0xd807aa98a3030242,0x12835b0145706fbe
+       .quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
+       .quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1
+       .quad 0x9bdc06a725c71235,0xc19bf174cf692694
+       .quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3
+       .quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
+       .quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483
+       .quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5
+       .quad 0x983e5152ee66dfab,0xa831c66d2db43210
+       .quad 0xb00327c898fb213f,0xbf597fc7beef0ee4
+       .quad 0xc6e00bf33da88fc2,0xd5a79147930aa725
+       .quad 0x06ca6351e003826f,0x142929670a0e6e70
+       .quad 0x27b70a8546d22ffc,0x2e1b21385c26c926
+       .quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df
+       .quad 0x650a73548baf63de,0x766a0abb3c77b2a8
+       .quad 0x81c2c92e47edaee6,0x92722c851482353b
+       .quad 0xa2bfe8a14cf10364,0xa81a664bbc423001
+       .quad 0xc24b8b70d0f89791,0xc76c51a30654be30
+       .quad 0xd192e819d6ef5218,0xd69906245565a910
+       .quad 0xf40e35855771202a,0x106aa07032bbd1b8
+       .quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53
+       .quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
+       .quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
+       .quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
+       .quad 0x748f82ee5defb2fc,0x78a5636f43172f60
+       .quad 0x84c87814a1f0ab72,0x8cc702081a6439ec
+       .quad 0x90befffa23631e28,0xa4506cebde82bde9
+       .quad 0xbef9a3f7b2c67915,0xc67178f2e372532b
+       .quad 0xca273eceea26619c,0xd186b8c721c0c207
+       .quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
+       .quad 0x06f067aa72176fba,0x0a637dc5a2c898a6
+       .quad 0x113f9804bef90dae,0x1b710b35131c471b
+       .quad 0x28db77f523047d84,0x32caab7b40c72493
+       .quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
+       .quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a
+       .quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817
+
+#endif
+#endif
diff --git a/cipher/sha512-avx2-bmi2-amd64.S b/cipher/sha512-avx2-bmi2-amd64.S
new file mode 100644 (file)
index 0000000..d6301f3
--- /dev/null
@@ -0,0 +1,787 @@
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; 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 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>
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && \
+    defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+    defined(HAVE_GCC_INLINE_ASM_AVX2) && defined(HAVE_GCC_INLINE_ASM_BMI2) && \
+    defined(USE_SHA512)
+
+#ifdef __PIC__
+#  define ADD_RIP +rip
+#else
+#  define ADD_RIP
+#endif
+
+.intel_syntax noprefix
+
+.text
+
+/* Virtual Registers */
+Y_0 = ymm4
+Y_1 = ymm5
+Y_2 = ymm6
+Y_3 = ymm7
+
+YTMP0 = ymm0
+YTMP1 = ymm1
+YTMP2 = ymm2
+YTMP3 = ymm3
+YTMP4 = ymm8
+XFER =  YTMP0
+
+BYTE_FLIP_MASK =  ymm9
+
+INP =         rdi /* 1st arg */
+CTX =         rsi /* 2nd arg */
+NUM_BLKS =    rdx /* 3rd arg */
+c =           rcx
+d =           r8
+e =           rdx
+y3 =          rdi
+
+TBL =   rbp
+
+a =     rax
+b =     rbx
+
+f =     r9
+g =     r10
+h =     r11
+old_h = r11
+
+T1 =    r12
+y0 =    r13
+y1 =    r14
+y2 =    r15
+
+y4 =    r12
+
+/* Local variables (stack frame) */
+#define frame_XFER      0
+#define frame_XFER_size (4*8)
+#define frame_SRND      (frame_XFER + frame_XFER_size)
+#define frame_SRND_size (1*8)
+#define frame_INP      (frame_SRND + frame_SRND_size)
+#define frame_INP_size (1*8)
+#define frame_INPEND      (frame_INP + frame_INP_size)
+#define frame_INPEND_size (1*8)
+#define frame_RSPSAVE      (frame_INPEND + frame_INPEND_size)
+#define frame_RSPSAVE_size (1*8)
+#define frame_GPRSAVE      (frame_RSPSAVE + frame_RSPSAVE_size)
+#define frame_GPRSAVE_size (6*8)
+#define frame_size (frame_GPRSAVE + frame_GPRSAVE_size)
+
+#define        VMOVDQ vmovdqu /*; assume buffers not aligned  */
+
+/* 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_YMM_AND_BSWAP ymm, [mem], byte_flip_mask */
+/* Load ymm with mem and byte swap each dword */
+.macro COPY_YMM_AND_BSWAP p1 p2 p3
+       VMOVDQ \p1, \p2
+       vpshufb \p1, \p1, \p3
+.endm
+/* rotate_Ys */
+/* Rotate values of symbols Y0...Y3 */
+.macro rotate_Ys
+       __Y_ = Y_0
+       Y_0 = Y_1
+       Y_1 = Y_2
+       Y_2 = Y_3
+       Y_3 = __Y_
+.endm
+
+/* RotateState */
+.macro RotateState
+       /* Rotate symbles a..h right */
+       old_h =  h
+       __TMP_ = h
+       h =      g
+       g =      f
+       f =      e
+       e =      d
+       d =      c
+       c =      b
+       b =      a
+       a =      __TMP_
+.endm
+
+/* %macro MY_VPALIGNR  YDST, YSRC1, YSRC2, RVAL */
+/* YDST = {YSRC1, YSRC2} >> RVAL*8 */
+.macro MY_VPALIGNR YDST, YSRC1, YSRC2, RVAL
+       vperm2f128      \YDST, \YSRC1, \YSRC2, 0x3      /* YDST = {YS1_LO, YS2_HI} */
+       vpalignr        \YDST, \YDST, \YSRC2, \RVAL     /* YDST = {YDS1, YS2} >> RVAL*8 */
+.endm
+
+.macro FOUR_ROUNDS_AND_SCHED
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
+
+               /* Extract w[t-7] */
+               MY_VPALIGNR     YTMP0, Y_3, Y_2, 8              /* YTMP0 = W[-7] */
+               /* Calculate w[t-16] + w[t-7] */
+               vpaddq          YTMP0, YTMP0, Y_0               /* YTMP0 = W[-7] + W[-16] */
+               /* Extract w[t-15] */
+               MY_VPALIGNR     YTMP1, Y_1, Y_0, 8              /* YTMP1 = W[-15] */
+
+               /* Calculate sigma0 */
+
+               /* Calculate w[t-15] ror 1 */
+               vpsrlq          YTMP2, YTMP1, 1
+               vpsllq          YTMP3, YTMP1, (64-1)
+               vpor            YTMP3, YTMP3, YTMP2             /* YTMP3 = W[-15] ror 1 */
+               /* Calculate w[t-15] shr 7 */
+               vpsrlq          YTMP4, YTMP1, 7                 /* YTMP4 = W[-15] >> 7 */
+
+       mov     y3, a           /* y3 = a                                       ; MAJA   */
+       rorx    y0, e, 41       /* y0 = e >> 41                                 ; S1A */
+       rorx    y1, e, 18       /* y1 = e >> 18                                 ; S1B */
+
+       add     h, [rsp+frame_XFER+0*8]         /* h = k + w + h                                ; --     */
+       or      y3, c           /* y3 = a|c                                     ; MAJA   */
+       mov     y2, f           /* y2 = f                                       ; CH     */
+       rorx    T1, a, 34       /* T1 = a >> 34                                 ; S0B */
+
+       xor     y0, y1          /* y0 = (e>>41) ^ (e>>18)                       ; S1 */
+       xor     y2, g           /* y2 = f^g                                     ; CH     */
+       rorx    y1, e, 14       /* y1 = (e >> 14)                                       ; S1 */
+
+       and     y2, e           /* y2 = (f^g)&e                                 ; CH     */
+       xor     y0, y1          /* y0 = (e>>41) ^ (e>>18) ^ (e>>14)             ; S1 */
+       rorx    y1, a, 39       /* y1 = a >> 39                                 ; S0A */
+       add     d, h            /* d = k + w + h + d                            ; --     */
+
+       and     y3, b           /* y3 = (a|c)&b                                 ; MAJA   */
+       xor     y1, T1          /* y1 = (a>>39) ^ (a>>34)                       ; S0 */
+       rorx    T1, a, 28       /* T1 = (a >> 28)                                       ; S0 */
+
+       xor     y2, g           /* y2 = CH = ((f^g)&e)^g                        ; CH     */
+       xor     y1, T1          /* y1 = (a>>39) ^ (a>>34) ^ (a>>28)             ; S0 */
+       mov     T1, a           /* T1 = a                                       ; MAJB   */
+       and     T1, c           /* T1 = a&c                                     ; MAJB   */
+
+       add     y2, y0          /* y2 = S1 + CH                                 ; --     */
+       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       ; --     */
+       add     h, y3           /* h = t1 + S0 + MAJ                            ; --     */
+
+RotateState
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;; */
+
+               /* Calculate w[t-15] ror 8 */
+               vpsrlq          YTMP2, YTMP1, 8
+               vpsllq          YTMP1, YTMP1, (64-8)
+               vpor            YTMP1, YTMP1, YTMP2             /* YTMP1 = W[-15] ror 8 */
+               /* XOR the three components */
+               vpxor           YTMP3, YTMP3, YTMP4             /* YTMP3 = W[-15] ror 1 ^ W[-15] >> 7 */
+               vpxor           YTMP1, YTMP3, YTMP1             /* YTMP1 = s0 */
+
+
+               /* Add three components, w[t-16], w[t-7] and sigma0 */
+               vpaddq          YTMP0, YTMP0, YTMP1             /* YTMP0 = W[-16] + W[-7] + s0 */
+               /* Move to appropriate lanes for calculating w[16] and w[17] */
+               vperm2f128      Y_0, YTMP0, YTMP0, 0x0          /* Y_0 = W[-16] + W[-7] + s0 {BABA} */
+               /* Move to appropriate lanes for calculating w[18] and w[19] */
+               vpand           YTMP0, YTMP0, [.LMASK_YMM_LO ADD_RIP]   /* YTMP0 = W[-16] + W[-7] + s0 {DC00} */
+
+               /* Calculate w[16] and w[17] in both 128 bit lanes */
+
+               /* Calculate sigma1 for w[16] and w[17] on both 128 bit lanes */
+               vperm2f128      YTMP2, Y_3, Y_3, 0x11           /* YTMP2 = W[-2] {BABA} */
+               vpsrlq          YTMP4, YTMP2, 6                 /* YTMP4 = W[-2] >> 6 {BABA} */
+
+
+       mov     y3, a           /* y3 = a                                       ; MAJA   */
+       rorx    y0, e, 41       /* y0 = e >> 41                                 ; S1A */
+       rorx    y1, e, 18       /* y1 = e >> 18                                 ; S1B */
+       add     h, [rsp+frame_XFER+1*8]         /* h = k + w + h                                ; --     */
+       or      y3, c           /* y3 = a|c                                     ; MAJA   */
+
+
+       mov     y2, f           /* y2 = f                                       ; CH     */
+       rorx    T1, a, 34       /* T1 = a >> 34                                 ; S0B */
+       xor     y0, y1          /* y0 = (e>>41) ^ (e>>18)                       ; S1 */
+       xor     y2, g           /* y2 = f^g                                     ; CH     */
+
+
+       rorx    y1, e, 14       /* y1 = (e >> 14)                                       ; S1 */
+       xor     y0, y1          /* y0 = (e>>41) ^ (e>>18) ^ (e>>14)             ; S1 */
+       rorx    y1, a, 39       /* y1 = a >> 39                                 ; S0A */
+       and     y2, e           /* y2 = (f^g)&e                                 ; CH     */
+       add     d, h            /* d = k + w + h + d                            ; --     */
+
+       and     y3, b           /* y3 = (a|c)&b                                 ; MAJA   */
+       xor     y1, T1          /* y1 = (a>>39) ^ (a>>34)                       ; S0 */
+
+       rorx    T1, a, 28       /* T1 = (a >> 28)                                       ; S0 */
+       xor     y2, g           /* y2 = CH = ((f^g)&e)^g                        ; CH     */
+
+       xor     y1, T1          /* y1 = (a>>39) ^ (a>>34) ^ (a>>28)             ; S0 */
+       mov     T1, a           /* T1 = a                                       ; MAJB   */
+       and     T1, c           /* T1 = a&c                                     ; MAJB   */
+       add     y2, y0          /* y2 = S1 + CH                                 ; --     */
+
+       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       ; --     */
+       add     h, y3           /* h = t1 + S0 + MAJ                            ; --     */
+
+RotateState
+
+
+
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;; */
+
+
+               vpsrlq          YTMP3, YTMP2, 19                /* YTMP3 = W[-2] >> 19 {BABA} */
+               vpsllq          YTMP1, YTMP2, (64-19)           /* YTMP1 = W[-2] << 19 {BABA} */
+               vpor            YTMP3, YTMP3, YTMP1             /* YTMP3 = W[-2] ror 19 {BABA} */
+               vpxor           YTMP4, YTMP4, YTMP3             /* YTMP4 = W[-2] ror 19 ^ W[-2] >> 6 {BABA} */
+               vpsrlq          YTMP3, YTMP2, 61                /* YTMP3 = W[-2] >> 61 {BABA} */
+               vpsllq          YTMP1, YTMP2, (64-61)           /* YTMP1 = W[-2] << 61 {BABA} */
+               vpor            YTMP3, YTMP3, YTMP1             /* YTMP3 = W[-2] ror 61 {BABA} */
+               vpxor           YTMP4, YTMP4, YTMP3             /* YTMP4 = s1 = (W[-2] ror 19) ^ (W[-2] ror 61) ^ (W[-2] >> 6) {BABA} */
+
+               /* Add sigma1 to the other compunents to get w[16] and w[17] */
+               vpaddq          Y_0, Y_0, YTMP4                 /* Y_0 = {W[1], W[0], W[1], W[0]} */
+
+               /* Calculate sigma1 for w[18] and w[19] for upper 128 bit lane */
+               vpsrlq          YTMP4, Y_0, 6                   /* YTMP4 = W[-2] >> 6 {DC--} */
+
+       mov     y3, a           /* y3 = a                                       ; MAJA   */
+       rorx    y0, e, 41       /* y0 = e >> 41                                 ; S1A */
+       add     h, [rsp+frame_XFER+2*8]         /* h = k + w + h                                ; --     */
+
+       rorx    y1, e, 18       /* y1 = e >> 18                                 ; S1B */
+       or      y3, c           /* y3 = a|c                                     ; MAJA   */
+       mov     y2, f           /* y2 = f                                       ; CH     */
+       xor     y2, g           /* y2 = f^g                                     ; CH     */
+
+       rorx    T1, a, 34       /* T1 = a >> 34                                 ; S0B */
+       xor     y0, y1          /* y0 = (e>>41) ^ (e>>18)                       ; S1 */
+       and     y2, e           /* y2 = (f^g)&e                                 ; CH     */
+
+       rorx    y1, e, 14       /* y1 = (e >> 14)                                       ; S1 */
+       add     d, h            /* d = k + w + h + d                            ; --     */
+       and     y3, b           /* y3 = (a|c)&b                                 ; MAJA   */
+
+       xor     y0, y1          /* y0 = (e>>41) ^ (e>>18) ^ (e>>14)             ; S1 */
+       rorx    y1, a, 39       /* y1 = a >> 39                                 ; S0A */
+       xor     y2, g           /* y2 = CH = ((f^g)&e)^g                        ; CH     */
+
+       xor     y1, T1          /* y1 = (a>>39) ^ (a>>34)                       ; S0 */
+       rorx    T1, a, 28       /* T1 = (a >> 28)                                       ; S0 */
+
+       xor     y1, T1          /* y1 = (a>>39) ^ (a>>34) ^ (a>>28)             ; S0 */
+       mov     T1, a           /* T1 = a                                       ; MAJB   */
+       and     T1, c           /* T1 = a&c                                     ; MAJB   */
+       add     y2, y0          /* y2 = S1 + CH                                 ; --     */
+
+       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       ; --     */
+
+       add     h, y3           /* h = t1 + S0 + MAJ                            ; --     */
+
+RotateState
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 3 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;; */
+
+               vpsrlq          YTMP3, Y_0, 19                  /* YTMP3 = W[-2] >> 19 {DC--} */
+               vpsllq          YTMP1, Y_0, (64-19)             /* YTMP1 = W[-2] << 19 {DC--} */
+               vpor            YTMP3, YTMP3, YTMP1             /* YTMP3 = W[-2] ror 19 {DC--} */
+               vpxor           YTMP4, YTMP4, YTMP3             /* YTMP4 = W[-2] ror 19 ^ W[-2] >> 6 {DC--} */
+               vpsrlq          YTMP3, Y_0, 61                  /* YTMP3 = W[-2] >> 61 {DC--} */
+               vpsllq          YTMP1, Y_0, (64-61)             /* YTMP1 = W[-2] << 61 {DC--} */
+               vpor            YTMP3, YTMP3, YTMP1             /* YTMP3 = W[-2] ror 61 {DC--} */
+               vpxor           YTMP4, YTMP4, YTMP3             /* YTMP4 = s1 = (W[-2] ror 19) ^ (W[-2] ror 61) ^ (W[-2] >> 6) {DC--} */
+
+               /* Add the sigma0 + w[t-7] + w[t-16] for w[18] and w[19] to newly calculated sigma1 to get w[18] and w[19] */
+               vpaddq          YTMP2, YTMP0, YTMP4             /* YTMP2 = {W[3], W[2], --, --} */
+
+               /* Form w[19, w[18], w17], w[16] */
+               vpblendd                Y_0, Y_0, YTMP2, 0xF0           /* Y_0 = {W[3], W[2], W[1], W[0]} */
+/*             vperm2f128              Y_0, Y_0, YTMP2, 0x30 */
+
+       mov     y3, a           /* y3 = a                                       ; MAJA   */
+       rorx    y0, e, 41       /* y0 = e >> 41                                 ; S1A */
+       rorx    y1, e, 18       /* y1 = e >> 18                                 ; S1B */
+       add     h, [rsp+frame_XFER+3*8]         /* h = k + w + h                                ; --     */
+       or      y3, c           /* y3 = a|c                                     ; MAJA   */
+
+
+       mov     y2, f           /* y2 = f                                       ; CH     */
+       rorx    T1, a, 34       /* T1 = a >> 34                                 ; S0B */
+       xor     y0, y1          /* y0 = (e>>41) ^ (e>>18)                       ; S1 */
+       xor     y2, g           /* y2 = f^g                                     ; CH     */
+
+
+       rorx    y1, e, 14       /* y1 = (e >> 14)                                       ; 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   */
+
+       xor     y0, y1          /* y0 = (e>>41) ^ (e>>18) ^ (e>>14)             ; S1 */
+       xor     y2, g           /* y2 = CH = ((f^g)&e)^g                        ; CH     */
+
+       rorx    y1, a, 39       /* y1 = a >> 39                                 ; S0A */
+       add     y2, y0          /* y2 = S1 + CH                                 ; --     */
+
+       xor     y1, T1          /* y1 = (a>>39) ^ (a>>34)                       ; S0 */
+       add     d, y2           /* d = k + w + h + d + S1 + CH = d + t1         ; --     */
+
+       rorx    T1, a, 28       /* T1 = (a >> 28)                                       ; S0 */
+
+       xor     y1, T1          /* y1 = (a>>39) ^ (a>>34) ^ (a>>28)             ; 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       ; --     */
+       add     h, y3           /* h = t1 + S0 + MAJ                            ; --     */
+
+RotateState
+
+rotate_Ys
+.endm
+
+.macro DO_4ROUNDS
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; RND N + 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
+
+       mov     y2, f           /* y2 = f                                       ; CH     */
+       rorx    y0, e, 41       /* y0 = e >> 41                                 ; S1A */
+       rorx    y1, e, 18       /* y1 = e >> 18                                 ; S1B */
+       xor     y2, g           /* y2 = f^g                                     ; CH     */
+
+       xor     y0, y1          /* y0 = (e>>41) ^ (e>>18)                       ; S1 */
+       rorx    y1, e, 14       /* y1 = (e >> 14)                                       ; S1 */
+       and     y2, e           /* y2 = (f^g)&e                                 ; CH     */
+
+       xor     y0, y1          /* y0 = (e>>41) ^ (e>>18) ^ (e>>14)             ; S1 */
+       rorx    T1, a, 34       /* T1 = a >> 34                                 ; S0B */
+       xor     y2, g           /* y2 = CH = ((f^g)&e)^g                        ; CH     */
+       rorx    y1, a, 39       /* y1 = a >> 39                                 ; S0A */
+       mov     y3, a           /* y3 = a                                       ; MAJA   */
+
+       xor     y1, T1          /* y1 = (a>>39) ^ (a>>34)                       ; S0 */
+       rorx    T1, a, 28       /* T1 = (a >> 28)                                       ; S0 */
+       add     h, [rsp + frame_XFER + 8*0]             /* h = k + w + h                                ; --     */
+       or      y3, c           /* y3 = a|c                                     ; MAJA   */
+
+       xor     y1, T1          /* y1 = (a>>39) ^ (a>>34) ^ (a>>28)             ; 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       ; --      */
+
+       /*add   h, y3           ; h = t1 + S0 + MAJ                            ; --      */
+
+       RotateState
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 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, 41       /* y0 = e >> 41                                 ; S1A */
+       rorx    y1, e, 18       /* y1 = e >> 18                                 ; S1B */
+       xor     y2, g           /* y2 = f^g                                     ; CH     */
+
+       xor     y0, y1          /* y0 = (e>>41) ^ (e>>18)                       ; S1 */
+       rorx    y1, e, 14       /* y1 = (e >> 14)                                       ; S1 */
+       and     y2, e           /* y2 = (f^g)&e                                 ; CH     */
+       add     old_h, y3       /* h = t1 + S0 + MAJ                            ; --     */
+
+       xor     y0, y1          /* y0 = (e>>41) ^ (e>>18) ^ (e>>14)             ; S1 */
+       rorx    T1, a, 34       /* T1 = a >> 34                                 ; S0B */
+       xor     y2, g           /* y2 = CH = ((f^g)&e)^g                        ; CH     */
+       rorx    y1, a, 39       /* y1 = a >> 39                                 ; S0A */
+       mov     y3, a           /* y3 = a                                       ; MAJA   */
+
+       xor     y1, T1          /* y1 = (a>>39) ^ (a>>34)                       ; S0 */
+       rorx    T1, a, 28       /* T1 = (a >> 28)                                       ; S0 */
+       add     h, [rsp + frame_XFER + 8*1]             /* h = k + w + h                                ; --     */
+       or      y3, c           /* y3 = a|c                                     ; MAJA   */
+
+       xor     y1, T1          /* y1 = (a>>39) ^ (a>>34) ^ (a>>28)             ; 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       ; --      */
+
+       /*add   h, y3           ; h = t1 + S0 + MAJ                            ; --      */
+
+       RotateState
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 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, 41       /* y0 = e >> 41                                 ; S1A */
+       rorx    y1, e, 18       /* y1 = e >> 18                                 ; S1B */
+       xor     y2, g           /* y2 = f^g                                     ; CH     */
+
+       xor     y0, y1          /* y0 = (e>>41) ^ (e>>18)                       ; S1 */
+       rorx    y1, e, 14       /* y1 = (e >> 14)                                       ; S1 */
+       and     y2, e           /* y2 = (f^g)&e                                 ; CH     */
+       add     old_h, y3       /* h = t1 + S0 + MAJ                            ; --     */
+
+       xor     y0, y1          /* y0 = (e>>41) ^ (e>>18) ^ (e>>14)             ; S1 */
+       rorx    T1, a, 34       /* T1 = a >> 34                                 ; S0B */
+       xor     y2, g           /* y2 = CH = ((f^g)&e)^g                        ; CH     */
+       rorx    y1, a, 39       /* y1 = a >> 39                                 ; S0A */
+       mov     y3, a           /* y3 = a                                       ; MAJA   */
+
+       xor     y1, T1          /* y1 = (a>>39) ^ (a>>34)                       ; S0 */
+       rorx    T1, a, 28       /* T1 = (a >> 28)                                       ; S0 */
+       add     h, [rsp + frame_XFER + 8*2]             /* h = k + w + h                                ; --     */
+       or      y3, c           /* y3 = a|c                                     ; MAJA   */
+
+       xor     y1, T1          /* y1 = (a>>39) ^ (a>>34) ^ (a>>28)             ; 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       ; --      */
+
+       /*add   h, y3           ; h = t1 + S0 + MAJ                            ; --      */
+
+       RotateState
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 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, 41       /* y0 = e >> 41                                 ; S1A */
+       rorx    y1, e, 18       /* y1 = e >> 18                                 ; S1B */
+       xor     y2, g           /* y2 = f^g                                     ; CH     */
+
+       xor     y0, y1          /* y0 = (e>>41) ^ (e>>18)                       ; S1 */
+       rorx    y1, e, 14       /* y1 = (e >> 14)                                       ; S1 */
+       and     y2, e           /* y2 = (f^g)&e                                 ; CH     */
+       add     old_h, y3       /* h = t1 + S0 + MAJ                            ; --     */
+
+       xor     y0, y1          /* y0 = (e>>41) ^ (e>>18) ^ (e>>14)             ; S1 */
+       rorx    T1, a, 34       /* T1 = a >> 34                                 ; S0B */
+       xor     y2, g           /* y2 = CH = ((f^g)&e)^g                        ; CH     */
+       rorx    y1, a, 39       /* y1 = a >> 39                                 ; S0A */
+       mov     y3, a           /* y3 = a                                       ; MAJA   */
+
+       xor     y1, T1          /* y1 = (a>>39) ^ (a>>34)                       ; S0 */
+       rorx    T1, a, 28       /* T1 = (a >> 28)                                       ; S0 */
+       add     h, [rsp + frame_XFER + 8*3]             /* h = k + w + h                                ; --     */
+       or      y3, c           /* y3 = a|c                                     ; MAJA   */
+
+       xor     y1, T1          /* y1 = (a>>39) ^ (a>>34) ^ (a>>28)             ; 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       ; --     */
+
+       add     h, y3           /* h = t1 + S0 + MAJ                            ; --     */
+
+       RotateState
+
+.endm
+
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; void sha512_rorx(const void* M, void* D, uint64_t L);
+; Purpose: Updates the SHA512 digest stored at D with the message stored in M.
+; The size of the message pointed to by M must be an integer multiple of SHA512
+;   message blocks.
+; L is the message length in SHA512 blocks
+*/
+.globl _gcry_sha512_transform_amd64_avx2
+.type _gcry_sha512_transform_amd64_avx2,@function;
+.align 16
+_gcry_sha512_transform_amd64_avx2:
+       xor eax, eax
+
+       cmp rdx, 0
+       je .Lnowork
+
+       vzeroupper
+
+       /* Allocate Stack Space */
+       mov     rax, rsp
+       sub     rsp, frame_size
+       and     rsp, ~(0x20 - 1)
+       mov     [rsp + frame_RSPSAVE], rax
+
+       /* Save GPRs */
+       mov     [rsp + frame_GPRSAVE + 8 * 0], rbp
+       mov     [rsp + frame_GPRSAVE + 8 * 1], rbx
+       mov     [rsp + frame_GPRSAVE + 8 * 2], r12
+       mov     [rsp + frame_GPRSAVE + 8 * 3], r13
+       mov     [rsp + frame_GPRSAVE + 8 * 4], r14
+       mov     [rsp + frame_GPRSAVE + 8 * 5], r15
+
+       vpblendd        xmm0, xmm0, xmm1, 0xf0
+       vpblendd        ymm0, ymm0, ymm1, 0xf0
+
+       shl     NUM_BLKS, 7     /* convert to bytes */
+       jz      .Ldone_hash
+       add     NUM_BLKS, INP   /* pointer to end of data */
+       mov     [rsp + frame_INPEND], NUM_BLKS
+
+       /*; load initial digest */
+       mov     a,[8*0 + CTX]
+       mov     b,[8*1 + CTX]
+       mov     c,[8*2 + CTX]
+       mov     d,[8*3 + CTX]
+       mov     e,[8*4 + CTX]
+       mov     f,[8*5 + CTX]
+       mov     g,[8*6 + CTX]
+       mov     h,[8*7 + CTX]
+
+       vmovdqa BYTE_FLIP_MASK, [.LPSHUFFLE_BYTE_FLIP_MASK ADD_RIP]
+
+.Loop0:
+       lea     TBL,[.LK512 ADD_RIP]
+
+       /*; byte swap first 16 dwords */
+       COPY_YMM_AND_BSWAP      Y_0, [INP + 0*32], BYTE_FLIP_MASK
+       COPY_YMM_AND_BSWAP      Y_1, [INP + 1*32], BYTE_FLIP_MASK
+       COPY_YMM_AND_BSWAP      Y_2, [INP + 2*32], BYTE_FLIP_MASK
+       COPY_YMM_AND_BSWAP      Y_3, [INP + 3*32], BYTE_FLIP_MASK
+
+       mov     [rsp + frame_INP], INP
+
+       /*; schedule 64 input dwords, by doing 12 rounds of 4 each */
+       movq    [rsp + frame_SRND],4
+
+.align 16
+.Loop1:
+       vpaddq  XFER, Y_0, [TBL + 0*32]
+       vmovdqa [rsp + frame_XFER], XFER
+       FOUR_ROUNDS_AND_SCHED
+
+       vpaddq  XFER, Y_0, [TBL + 1*32]
+       vmovdqa [rsp + frame_XFER], XFER
+       FOUR_ROUNDS_AND_SCHED
+
+       vpaddq  XFER, Y_0, [TBL + 2*32]
+       vmovdqa [rsp + frame_XFER], XFER
+       FOUR_ROUNDS_AND_SCHED
+
+       vpaddq  XFER, Y_0, [TBL + 3*32]
+       vmovdqa [rsp + frame_XFER], XFER
+       add     TBL, 4*32
+       FOUR_ROUNDS_AND_SCHED
+
+       subq    [rsp + frame_SRND], 1
+       jne     .Loop1
+
+       movq    [rsp + frame_SRND], 2
+.Loop2:
+       vpaddq  XFER, Y_0, [TBL + 0*32]
+       vmovdqa [rsp + frame_XFER], XFER
+       DO_4ROUNDS
+       vpaddq  XFER, Y_1, [TBL + 1*32]
+       vmovdqa [rsp + frame_XFER], XFER
+       add     TBL, 2*32
+       DO_4ROUNDS
+
+       vmovdqa Y_0, Y_2
+       vmovdqa Y_1, Y_3
+
+       subq    [rsp + frame_SRND], 1
+       jne     .Loop2
+
+       addm    [8*0 + CTX],a
+       addm    [8*1 + CTX],b
+       addm    [8*2 + CTX],c
+       addm    [8*3 + CTX],d
+       addm    [8*4 + CTX],e
+       addm    [8*5 + CTX],f
+       addm    [8*6 + CTX],g
+       addm    [8*7 + CTX],h
+
+       mov     INP, [rsp + frame_INP]
+       add     INP, 128
+       cmp     INP, [rsp + frame_INPEND]
+       jne     .Loop0
+
+.Ldone_hash:
+
+       /* Restore GPRs */
+       mov     rbp, [rsp + frame_GPRSAVE + 8 * 0]
+       mov     rbx, [rsp + frame_GPRSAVE + 8 * 1]
+       mov     r12, [rsp + frame_GPRSAVE + 8 * 2]
+       mov     r13, [rsp + frame_GPRSAVE + 8 * 3]
+       mov     r14, [rsp + frame_GPRSAVE + 8 * 4]
+       mov     r15, [rsp + frame_GPRSAVE + 8 * 5]
+
+       /* Restore Stack Pointer */
+       mov     rsp, [rsp + frame_RSPSAVE]
+
+       vzeroall
+
+       mov     eax, frame_size + 31
+.Lnowork:
+       ret
+
+/*;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; */
+/*;; Binary Data */
+
+.data
+
+.align 64
+/* K[t] used in SHA512 hashing */
+.LK512:
+       .quad   0x428a2f98d728ae22,0x7137449123ef65cd
+       .quad   0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
+       .quad   0x3956c25bf348b538,0x59f111f1b605d019
+       .quad   0x923f82a4af194f9b,0xab1c5ed5da6d8118
+       .quad   0xd807aa98a3030242,0x12835b0145706fbe
+       .quad   0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
+       .quad   0x72be5d74f27b896f,0x80deb1fe3b1696b1
+       .quad   0x9bdc06a725c71235,0xc19bf174cf692694
+       .quad   0xe49b69c19ef14ad2,0xefbe4786384f25e3
+       .quad   0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
+       .quad   0x2de92c6f592b0275,0x4a7484aa6ea6e483
+       .quad   0x5cb0a9dcbd41fbd4,0x76f988da831153b5
+       .quad   0x983e5152ee66dfab,0xa831c66d2db43210
+       .quad   0xb00327c898fb213f,0xbf597fc7beef0ee4
+       .quad   0xc6e00bf33da88fc2,0xd5a79147930aa725
+       .quad   0x06ca6351e003826f,0x142929670a0e6e70
+       .quad   0x27b70a8546d22ffc,0x2e1b21385c26c926
+       .quad   0x4d2c6dfc5ac42aed,0x53380d139d95b3df
+       .quad   0x650a73548baf63de,0x766a0abb3c77b2a8
+       .quad   0x81c2c92e47edaee6,0x92722c851482353b
+       .quad   0xa2bfe8a14cf10364,0xa81a664bbc423001
+       .quad   0xc24b8b70d0f89791,0xc76c51a30654be30
+       .quad   0xd192e819d6ef5218,0xd69906245565a910
+       .quad   0xf40e35855771202a,0x106aa07032bbd1b8
+       .quad   0x19a4c116b8d2d0c8,0x1e376c085141ab53
+       .quad   0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
+       .quad   0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
+       .quad   0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
+       .quad   0x748f82ee5defb2fc,0x78a5636f43172f60
+       .quad   0x84c87814a1f0ab72,0x8cc702081a6439ec
+       .quad   0x90befffa23631e28,0xa4506cebde82bde9
+       .quad   0xbef9a3f7b2c67915,0xc67178f2e372532b
+       .quad   0xca273eceea26619c,0xd186b8c721c0c207
+       .quad   0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
+       .quad   0x06f067aa72176fba,0x0a637dc5a2c898a6
+       .quad   0x113f9804bef90dae,0x1b710b35131c471b
+       .quad   0x28db77f523047d84,0x32caab7b40c72493
+       .quad   0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
+       .quad   0x4cc5d4becb3e42b6,0x597f299cfc657e2a
+       .quad   0x5fcb6fab3ad6faec,0x6c44198c4a475817
+
+.align 32
+
+/* Mask for byte-swapping a couple of qwords in an XMM register using (v)pshufb. */
+.LPSHUFFLE_BYTE_FLIP_MASK: .octa 0x08090a0b0c0d0e0f0001020304050607
+                          .octa 0x18191a1b1c1d1e1f1011121314151617
+
+.LMASK_YMM_LO:            .octa 0x00000000000000000000000000000000
+                          .octa 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+
+#endif
+#endif
diff --git a/cipher/sha512-ssse3-amd64.S b/cipher/sha512-ssse3-amd64.S
new file mode 100644 (file)
index 0000000..4c80baa
--- /dev/null
@@ -0,0 +1,421 @@
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; 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.
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+*/
+/*
+ * Conversion to GAS assembly and integration to libgcrypt
+ *  by Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * Note: original implementation was named as SHA512-SSE4. However, only SSSE3
+ *       is required.
+ */
+
+#ifdef __x86_64
+#include <config.h>
+#if defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) && \
+    defined(HAVE_INTEL_SYNTAX_PLATFORM_AS) && \
+    defined(HAVE_GCC_INLINE_ASM_SSSE3) && defined(USE_SHA512)
+
+#ifdef __PIC__
+#  define ADD_RIP +rip
+#else
+#  define ADD_RIP
+#endif
+
+.intel_syntax noprefix
+
+.text
+
+/* Virtual Registers */
+msg = rdi /* ARG1 */
+digest = rsi /* ARG2 */
+msglen = rdx /* ARG3 */
+T1 = rcx
+T2 = r8
+a_64 = r9
+b_64 = r10
+c_64 = r11
+d_64 = r12
+e_64 = r13
+f_64 = r14
+g_64 = r15
+h_64 = rbx
+tmp0 = rax
+
+/*
+; Local variables (stack frame)
+; Note: frame_size must be an odd multiple of 8 bytes to XMM align RSP
+*/
+frame_W      = 0 /* Message Schedule */
+frame_W_size = (80 * 8)
+frame_WK      = ((frame_W) + (frame_W_size)) /* W[t] + K[t] | W[t+1] + K[t+1] */
+frame_WK_size = (2 * 8)
+frame_GPRSAVE      = ((frame_WK) + (frame_WK_size))
+frame_GPRSAVE_size = (5 * 8)
+frame_size = ((frame_GPRSAVE) + (frame_GPRSAVE_size))
+
+
+/* Useful QWORD "arrays" for simpler memory references */
+#define MSG(i)    msg    + 8*(i)               /* Input message (arg1) */
+#define DIGEST(i) digest + 8*(i)               /* Output Digest (arg2) */
+#define K_t(i)    .LK512   + 8*(i) ADD_RIP     /* SHA Constants (static mem) */
+#define W_t(i)    rsp + frame_W  + 8*(i)       /* Message Schedule (stack frame) */
+#define WK_2(i)   rsp + frame_WK + 8*((i) % 2) /* W[t]+K[t] (stack frame) */
+/* MSG, DIGEST, K_t, W_t are arrays */
+/* WK_2(t) points to 1 of 2 qwords at frame.WK depdending on t being odd/even */
+
+.macro RotateState
+       /* Rotate symbles a..h right */
+       __TMP = h_64
+       h_64 =  g_64
+       g_64 =  f_64
+       f_64 =  e_64
+       e_64 =  d_64
+       d_64 =  c_64
+       c_64 =  b_64
+       b_64 =  a_64
+       a_64 =  __TMP
+.endm
+
+.macro SHA512_Round t
+       /* Compute Round %%t */
+       mov     T1,   f_64        /* T1 = f */
+       mov     tmp0, e_64        /* tmp = e */
+       xor     T1,   g_64        /* T1 = f ^ g */
+       ror     tmp0, 23 /* 41     ; tmp = e ror 23 */
+       and     T1,   e_64        /* T1 = (f ^ g) & e */
+       xor     tmp0, e_64        /* tmp = (e ror 23) ^ e */
+       xor     T1,   g_64        /* T1 = ((f ^ g) & e) ^ g = CH(e,f,g) */
+       add     T1,   [WK_2(\t)] /* W[t] + K[t] from message scheduler */
+       ror     tmp0, 4 /* 18      ; tmp = ((e ror 23) ^ e) ror 4 */
+       xor     tmp0, e_64        /* tmp = (((e ror 23) ^ e) ror 4) ^ e */
+       mov     T2,   a_64        /* T2 = a */
+       add     T1,   h_64        /* T1 = CH(e,f,g) + W[t] + K[t] + h */
+       ror     tmp0, 14 /* 14     ; tmp = ((((e ror23)^e)ror4)^e)ror14 = S1(e) */
+       add     T1,   tmp0        /* T1 = CH(e,f,g) + W[t] + K[t] + S1(e) */
+       mov     tmp0, a_64        /* tmp = a */
+       xor     T2,   c_64        /* T2 = a ^ c */
+       and     tmp0, c_64        /* tmp = a & c */
+       and     T2,   b_64        /* T2 = (a ^ c) & b */
+       xor     T2,   tmp0        /* T2 = ((a ^ c) & b) ^ (a & c) = Maj(a,b,c) */
+       mov     tmp0, a_64        /* tmp = a */
+       ror     tmp0, 5 /* 39      ; tmp = a ror 5 */
+       xor     tmp0, a_64        /* tmp = (a ror 5) ^ a */
+       add     d_64, T1          /* e(next_state) = d + T1  */
+       ror     tmp0, 6 /* 34      ; tmp = ((a ror 5) ^ a) ror 6 */
+       xor     tmp0, a_64        /* tmp = (((a ror 5) ^ a) ror 6) ^ a */
+       lea     h_64, [T1 + T2]   /* a(next_state) = T1 + Maj(a,b,c) */
+       ror     tmp0, 28 /* 28     ; tmp = ((((a ror5)^a)ror6)^a)ror28 = S0(a) */
+       add     h_64, tmp0        /* a(next_state) = T1 + Maj(a,b,c) S0(a) */
+       RotateState
+.endm
+
+.macro SHA512_2Sched_2Round_sse t
+/*     ; Compute rounds %%t-2 and %%t-1
+       ; Compute message schedule QWORDS %%t and %%t+1
+
+       ;   Two rounds are computed based on the values for K[t-2]+W[t-2] and
+       ; K[t-1]+W[t-1] which were previously stored at WK_2 by the message
+       ; scheduler.
+       ;   The two new schedule QWORDS are stored at [W_t(%%t)] and [W_t(%%t+1)].
+       ; They are then added to their respective SHA512 constants at
+       ; [K_t(%%t)] and [K_t(%%t+1)] and stored at dqword [WK_2(%%t)]
+       ;   For brievity, the comments following vectored instructions only refer to
+       ; the first of a pair of QWORDS.
+       ; Eg. XMM2=W[t-2] really means XMM2={W[t-2]|W[t-1]}
+       ;   The computation of the message schedule and the rounds are tightly
+       ; stitched to take advantage of instruction-level parallelism.
+       ; For clarity, integer instructions (for the rounds calculation) are indented
+       ; by one tab. Vectored instructions (for the message scheduler) are indented
+       ; by two tabs. */
+
+       mov     T1, f_64
+               movdqa  xmm2, [W_t(\t-2)]  /* XMM2 = W[t-2] */
+       xor     T1,   g_64
+       and     T1,   e_64
+               movdqa  xmm0, xmm2          /* XMM0 = W[t-2] */
+       xor     T1,   g_64
+       add     T1,   [WK_2(\t)]
+               movdqu  xmm5, [W_t(\t-15)] /* XMM5 = W[t-15] */
+       mov     tmp0, e_64
+       ror     tmp0, 23 /* 41 */
+               movdqa  xmm3, xmm5          /* XMM3 = W[t-15] */
+       xor     tmp0, e_64
+       ror     tmp0, 4 /* 18 */
+               psrlq   xmm0, 61 - 19       /* XMM0 = W[t-2] >> 42 */
+       xor     tmp0, e_64
+       ror     tmp0, 14 /* 14 */
+               psrlq   xmm3, (8 - 7)       /* XMM3 = W[t-15] >> 1 */
+       add     T1,   tmp0
+       add     T1,   h_64
+               pxor    xmm0, xmm2          /* XMM0 = (W[t-2] >> 42) ^ W[t-2] */
+       mov     T2,   a_64
+       xor     T2,   c_64
+               pxor    xmm3, xmm5          /* XMM3 = (W[t-15] >> 1) ^ W[t-15] */
+       and     T2,   b_64
+       mov     tmp0, a_64
+               psrlq   xmm0, 19 - 6        /* XMM0 = ((W[t-2]>>42)^W[t-2])>>13 */
+       and     tmp0, c_64
+       xor     T2,   tmp0
+               psrlq   xmm3, (7 - 1)       /* XMM3 = ((W[t-15]>>1)^W[t-15])>>6 */
+       mov     tmp0, a_64
+       ror     tmp0, 5 /* 39 */
+               pxor    xmm0, xmm2          /* XMM0 = (((W[t-2]>>42)^W[t-2])>>13)^W[t-2] */
+       xor     tmp0, a_64
+       ror     tmp0, 6 /* 34 */
+               pxor    xmm3, xmm5          /* XMM3 = (((W[t-15]>>1)^W[t-15])>>6)^W[t-15] */
+       xor     tmp0, a_64
+       ror     tmp0, 28 /* 28 */
+               psrlq   xmm0, 6             /* XMM0 = ((((W[t-2]>>42)^W[t-2])>>13)^W[t-2])>>6 */
+       add     T2,   tmp0
+       add     d_64, T1
+               psrlq   xmm3, 1             /* XMM3 = (((W[t-15]>>1)^W[t-15])>>6)^W[t-15]>>1 */
+       lea     h_64, [T1 + T2]
+       RotateState
+               movdqa  xmm1, xmm2          /* XMM1 = W[t-2] */
+       mov     T1, f_64
+       xor     T1,   g_64
+               movdqa  xmm4, xmm5          /* XMM4 = W[t-15] */
+       and     T1,   e_64
+       xor     T1,   g_64
+               psllq   xmm1, (64 - 19) - (64 - 61) /* XMM1 = W[t-2] << 42 */
+       add     T1,   [WK_2(\t+1)]
+       mov     tmp0, e_64
+               psllq   xmm4, (64 - 1) - (64 - 8) /* XMM4 = W[t-15] << 7 */
+       ror     tmp0, 23 /* 41 */
+       xor     tmp0, e_64
+               pxor    xmm1, xmm2          /* XMM1 = (W[t-2] << 42)^W[t-2] */
+       ror     tmp0, 4 /* 18 */
+       xor     tmp0, e_64
+               pxor    xmm4, xmm5          /* XMM4 = (W[t-15]<<7)^W[t-15] */
+       ror     tmp0, 14 /* 14 */
+       add     T1,   tmp0
+               psllq   xmm1, (64 - 61)     /* XMM1 = ((W[t-2] << 42)^W[t-2])<<3 */
+       add     T1,   h_64
+       mov     T2,   a_64
+               psllq   xmm4, (64 - 8)      /* XMM4 = ((W[t-15]<<7)^W[t-15])<<56 */
+       xor     T2,   c_64
+       and     T2,   b_64
+               pxor    xmm0, xmm1          /* XMM0 = s1(W[t-2]) */
+       mov     tmp0, a_64
+       and     tmp0, c_64
+               movdqu  xmm1, [W_t(\t- 7)] /* XMM1 = W[t-7] */
+       xor     T2,   tmp0
+               pxor    xmm3, xmm4          /* XMM3 = s0(W[t-15]) */
+       mov     tmp0, a_64
+               paddq   xmm0, xmm3          /* XMM0 = s1(W[t-2]) + s0(W[t-15]) */
+       ror     tmp0, 5 /* 39 */
+               paddq   xmm0, [W_t(\t-16)] /* XMM0 = s1(W[t-2]) + s0(W[t-15]) + W[t-16] */
+       xor     tmp0, a_64
+               paddq   xmm0, xmm1          /* XMM0 = s1(W[t-2]) + W[t-7] + s0(W[t-15]) + W[t-16] */
+       ror     tmp0, 6 /* 34 */
+               movdqa  [W_t(\t)], xmm0     /* Store scheduled qwords */
+       xor     tmp0, a_64
+               paddq   xmm0, [K_t(t)]      /* Compute W[t]+K[t] */
+       ror     tmp0, 28 /* 28 */
+               movdqa  [WK_2(t)], xmm0     /* Store W[t]+K[t] for next rounds */
+       add     T2,   tmp0
+       add     d_64, T1
+       lea     h_64, [T1 + T2]
+       RotateState
+.endm
+
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; void sha512_sse4(const void* M, void* D, uint64_t L);
+; Purpose: Updates the SHA512 digest stored at D with the message stored in M.
+; The size of the message pointed to by M must be an integer multiple of SHA512
+;   message blocks.
+; L is the message length in SHA512 blocks.
+*/
+.globl _gcry_sha512_transform_amd64_ssse3
+.type _gcry_sha512_transform_amd64_ssse3,@function;
+.align 16
+_gcry_sha512_transform_amd64_ssse3:
+       xor eax, eax
+
+       cmp msglen, 0
+       je .Lnowork
+
+       /* Allocate Stack Space */
+       sub     rsp, frame_size
+
+       /* Save GPRs */
+       mov     [rsp + frame_GPRSAVE + 8 * 0], rbx
+       mov     [rsp + frame_GPRSAVE + 8 * 1], r12
+       mov     [rsp + frame_GPRSAVE + 8 * 2], r13
+       mov     [rsp + frame_GPRSAVE + 8 * 3], r14
+       mov     [rsp + frame_GPRSAVE + 8 * 4], r15
+
+.Lupdateblock:
+
+       /* Load state variables */
+       mov     a_64, [DIGEST(0)]
+       mov     b_64, [DIGEST(1)]
+       mov     c_64, [DIGEST(2)]
+       mov     d_64, [DIGEST(3)]
+       mov     e_64, [DIGEST(4)]
+       mov     f_64, [DIGEST(5)]
+       mov     g_64, [DIGEST(6)]
+       mov     h_64, [DIGEST(7)]
+
+       t = 0
+       .rept 80/2 + 1
+       /* (80 rounds) / (2 rounds/iteration) + (1 iteration) */
+       /* +1 iteration because the scheduler leads hashing by 1 iteration */
+               .if t < 2
+                       /* BSWAP 2 QWORDS */
+                       movdqa  xmm1, [.LXMM_QWORD_BSWAP ADD_RIP]
+                       movdqu  xmm0, [MSG(t)]
+                       pshufb  xmm0, xmm1      /* BSWAP */
+                       movdqa  [W_t(t)], xmm0  /* Store Scheduled Pair */
+                       paddq   xmm0, [K_t(t)]  /* Compute W[t]+K[t] */
+                       movdqa  [WK_2(t)], xmm0 /* Store into WK for rounds */
+               .elseif t < 16
+                       /* BSWAP 2 QWORDS; Compute 2 Rounds */
+                       movdqu  xmm0, [MSG(t)]
+                       pshufb  xmm0, xmm1      /* BSWAP */
+                       SHA512_Round (t - 2)    /* Round t-2 */
+                       movdqa  [W_t(t)], xmm0  /* Store Scheduled Pair */
+                       paddq   xmm0, [K_t(t)]  /* Compute W[t]+K[t] */
+                       SHA512_Round (t - 1)    /* Round t-1 */
+                       movdqa  [WK_2(t)], xmm0 /* Store W[t]+K[t] into WK */
+               .elseif t < 79
+                       /* Schedule 2 QWORDS; Compute 2 Rounds */
+                       SHA512_2Sched_2Round_sse t
+               .else
+                       /* Compute 2 Rounds */
+                       SHA512_Round (t - 2)
+                       SHA512_Round (t - 1)
+               .endif
+               t = (t)+2
+       .endr
+
+       /* Update digest */
+       add     [DIGEST(0)], a_64
+       add     [DIGEST(1)], b_64
+       add     [DIGEST(2)], c_64
+       add     [DIGEST(3)], d_64
+       add     [DIGEST(4)], e_64
+       add     [DIGEST(5)], f_64
+       add     [DIGEST(6)], g_64
+       add     [DIGEST(7)], h_64
+
+       /* Advance to next message block */
+       add     msg, 16*8
+       dec     msglen
+       jnz     .Lupdateblock
+
+       /* Restore GPRs */
+       mov     rbx, [rsp + frame_GPRSAVE + 8 * 0]
+       mov     r12, [rsp + frame_GPRSAVE + 8 * 1]
+       mov     r13, [rsp + frame_GPRSAVE + 8 * 2]
+       mov     r14, [rsp + frame_GPRSAVE + 8 * 3]
+       mov     r15, [rsp + frame_GPRSAVE + 8 * 4]
+
+       /* Restore Stack Pointer */
+       add     rsp, frame_size
+
+       pxor    xmm0, xmm0
+       pxor    xmm1, xmm1
+       pxor    xmm2, xmm2
+       pxor    xmm3, xmm3
+       pxor    xmm4, xmm4
+       pxor    xmm5, xmm5
+
+       /* Return stack burn depth */
+       mov     rax, frame_size
+
+.Lnowork:
+       ret
+
+/*
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Binary Data
+*/
+
+.data
+
+.align 16
+
+/* Mask for byte-swapping a couple of qwords in an XMM register using (v)pshufb. */
+.LXMM_QWORD_BSWAP:
+       .octa 0x08090a0b0c0d0e0f0001020304050607
+
+/* K[t] used in SHA512 hashing */
+.LK512:
+       .quad 0x428a2f98d728ae22,0x7137449123ef65cd
+       .quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc
+       .quad 0x3956c25bf348b538,0x59f111f1b605d019
+       .quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118
+       .quad 0xd807aa98a3030242,0x12835b0145706fbe
+       .quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2
+       .quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1
+       .quad 0x9bdc06a725c71235,0xc19bf174cf692694
+       .quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3
+       .quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65
+       .quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483
+       .quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5
+       .quad 0x983e5152ee66dfab,0xa831c66d2db43210
+       .quad 0xb00327c898fb213f,0xbf597fc7beef0ee4
+       .quad 0xc6e00bf33da88fc2,0xd5a79147930aa725
+       .quad 0x06ca6351e003826f,0x142929670a0e6e70
+       .quad 0x27b70a8546d22ffc,0x2e1b21385c26c926
+       .quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df
+       .quad 0x650a73548baf63de,0x766a0abb3c77b2a8
+       .quad 0x81c2c92e47edaee6,0x92722c851482353b
+       .quad 0xa2bfe8a14cf10364,0xa81a664bbc423001
+       .quad 0xc24b8b70d0f89791,0xc76c51a30654be30
+       .quad 0xd192e819d6ef5218,0xd69906245565a910
+       .quad 0xf40e35855771202a,0x106aa07032bbd1b8
+       .quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53
+       .quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8
+       .quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb
+       .quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3
+       .quad 0x748f82ee5defb2fc,0x78a5636f43172f60
+       .quad 0x84c87814a1f0ab72,0x8cc702081a6439ec
+       .quad 0x90befffa23631e28,0xa4506cebde82bde9
+       .quad 0xbef9a3f7b2c67915,0xc67178f2e372532b
+       .quad 0xca273eceea26619c,0xd186b8c721c0c207
+       .quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178
+       .quad 0x06f067aa72176fba,0x0a637dc5a2c898a6
+       .quad 0x113f9804bef90dae,0x1b710b35131c471b
+       .quad 0x28db77f523047d84,0x32caab7b40c72493
+       .quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c
+       .quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a
+       .quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817
+
+#endif
+#endif
index 2163e60..26ed031 100644 (file)
 #include <string.h>
 #include "g10lib.h"
 #include "bithelp.h"
+#include "bufhelp.h"
 #include "cipher.h"
 #include "hash-common.h"
 
+
+/* USE_ARM_NEON_ASM indicates whether to enable ARM NEON assembly code. */
+#undef USE_ARM_NEON_ASM
+#if defined(HAVE_ARM_ARCH_V6) && defined(__ARMEL__)
+# if defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS) && \
+     defined(HAVE_GCC_INLINE_ASM_NEON)
+#  define USE_ARM_NEON_ASM 1
+# endif
+#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)
+# 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)
+# 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)
+# define USE_AVX2 1
+#endif
+
+
 typedef struct
 {
   u64 h0, h1, h2, h3, h4, h5, h6, h7;
-  u64 nblocks;
-  byte buf[128];
-  int count;
+} SHA512_STATE;
+
+typedef struct
+{
+  gcry_md_block_ctx_t bctx;
+  SHA512_STATE state;
+#ifdef USE_ARM_NEON_ASM
+  unsigned int use_neon:1;
+#endif
+#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
 } SHA512_CONTEXT;
 
+static unsigned int
+transform (void *context, const unsigned char *data);
+
 static void
-sha512_init (void *context)
+sha512_init (void *context, unsigned int flags)
 {
-  SHA512_CONTEXT *hd = context;
+  SHA512_CONTEXT *ctx = context;
+  SHA512_STATE *hd = &ctx->state;
+  unsigned int features = _gcry_get_hw_features ();
+
+  (void)flags;
 
   hd->h0 = U64_C(0x6a09e667f3bcc908);
   hd->h1 = U64_C(0xbb67ae8584caa73b);
@@ -75,14 +136,36 @@ sha512_init (void *context)
   hd->h6 = U64_C(0x1f83d9abfb41bd6b);
   hd->h7 = U64_C(0x5be0cd19137e2179);
 
-  hd->nblocks = 0;
-  hd->count = 0;
+  ctx->bctx.nblocks = 0;
+  ctx->bctx.nblocks_high = 0;
+  ctx->bctx.count = 0;
+  ctx->bctx.blocksize = 128;
+  ctx->bctx.bwrite = transform;
+
+#ifdef USE_ARM_NEON_ASM
+  ctx->use_neon = (features & HWF_ARM_NEON) != 0;
+#endif
+#ifdef USE_SSSE3
+  ctx->use_ssse3 = (features & HWF_INTEL_SSSE3) != 0;
+#endif
+#ifdef USE_AVX
+  ctx->use_avx = (features & HWF_INTEL_AVX) && (features & HWF_INTEL_CPU);
+#endif
+#ifdef USE_AVX2
+  ctx->use_avx2 = (features & HWF_INTEL_AVX2) && (features & HWF_INTEL_BMI2);
+#endif
+
+  (void)features;
 }
 
 static void
-sha384_init (void *context)
+sha384_init (void *context, unsigned int flags)
 {
-  SHA512_CONTEXT *hd = context;
+  SHA512_CONTEXT *ctx = context;
+  SHA512_STATE *hd = &ctx->state;
+  unsigned int features = _gcry_get_hw_features ();
+
+  (void)flags;
 
   hd->h0 = U64_C(0xcbbb9d5dc1059ed8);
   hd->h1 = U64_C(0x629a292a367cd507);
@@ -93,8 +176,26 @@ sha384_init (void *context)
   hd->h6 = U64_C(0xdb0c2e0d64f98fa7);
   hd->h7 = U64_C(0x47b5481dbefa4fa4);
 
-  hd->nblocks = 0;
-  hd->count = 0;
+  ctx->bctx.nblocks = 0;
+  ctx->bctx.nblocks_high = 0;
+  ctx->bctx.count = 0;
+  ctx->bctx.blocksize = 128;
+  ctx->bctx.bwrite = transform;
+
+#ifdef USE_ARM_NEON_ASM
+  ctx->use_neon = (features & HWF_ARM_NEON) != 0;
+#endif
+#ifdef USE_SSSE3
+  ctx->use_ssse3 = (features & HWF_INTEL_SSSE3) != 0;
+#endif
+#ifdef USE_AVX
+  ctx->use_avx = (features & HWF_INTEL_AVX) && (features & HWF_INTEL_CPU);
+#endif
+#ifdef USE_AVX2
+  ctx->use_avx2 = (features & HWF_INTEL_AVX2) && (features & HWF_INTEL_BMI2);
+#endif
+
+  (void)features;
 }
 
 
@@ -128,58 +229,59 @@ Sum1 (u64 x)
   return (ROTR (x, 14) ^ ROTR (x, 18) ^ ROTR (x, 41));
 }
 
+static const u64 k[] =
+  {
+    U64_C(0x428a2f98d728ae22), U64_C(0x7137449123ef65cd),
+    U64_C(0xb5c0fbcfec4d3b2f), U64_C(0xe9b5dba58189dbbc),
+    U64_C(0x3956c25bf348b538), U64_C(0x59f111f1b605d019),
+    U64_C(0x923f82a4af194f9b), U64_C(0xab1c5ed5da6d8118),
+    U64_C(0xd807aa98a3030242), U64_C(0x12835b0145706fbe),
+    U64_C(0x243185be4ee4b28c), U64_C(0x550c7dc3d5ffb4e2),
+    U64_C(0x72be5d74f27b896f), U64_C(0x80deb1fe3b1696b1),
+    U64_C(0x9bdc06a725c71235), U64_C(0xc19bf174cf692694),
+    U64_C(0xe49b69c19ef14ad2), U64_C(0xefbe4786384f25e3),
+    U64_C(0x0fc19dc68b8cd5b5), U64_C(0x240ca1cc77ac9c65),
+    U64_C(0x2de92c6f592b0275), U64_C(0x4a7484aa6ea6e483),
+    U64_C(0x5cb0a9dcbd41fbd4), U64_C(0x76f988da831153b5),
+    U64_C(0x983e5152ee66dfab), U64_C(0xa831c66d2db43210),
+    U64_C(0xb00327c898fb213f), U64_C(0xbf597fc7beef0ee4),
+    U64_C(0xc6e00bf33da88fc2), U64_C(0xd5a79147930aa725),
+    U64_C(0x06ca6351e003826f), U64_C(0x142929670a0e6e70),
+    U64_C(0x27b70a8546d22ffc), U64_C(0x2e1b21385c26c926),
+    U64_C(0x4d2c6dfc5ac42aed), U64_C(0x53380d139d95b3df),
+    U64_C(0x650a73548baf63de), U64_C(0x766a0abb3c77b2a8),
+    U64_C(0x81c2c92e47edaee6), U64_C(0x92722c851482353b),
+    U64_C(0xa2bfe8a14cf10364), U64_C(0xa81a664bbc423001),
+    U64_C(0xc24b8b70d0f89791), U64_C(0xc76c51a30654be30),
+    U64_C(0xd192e819d6ef5218), U64_C(0xd69906245565a910),
+    U64_C(0xf40e35855771202a), U64_C(0x106aa07032bbd1b8),
+    U64_C(0x19a4c116b8d2d0c8), U64_C(0x1e376c085141ab53),
+    U64_C(0x2748774cdf8eeb99), U64_C(0x34b0bcb5e19b48a8),
+    U64_C(0x391c0cb3c5c95a63), U64_C(0x4ed8aa4ae3418acb),
+    U64_C(0x5b9cca4f7763e373), U64_C(0x682e6ff3d6b2b8a3),
+    U64_C(0x748f82ee5defb2fc), U64_C(0x78a5636f43172f60),
+    U64_C(0x84c87814a1f0ab72), U64_C(0x8cc702081a6439ec),
+    U64_C(0x90befffa23631e28), U64_C(0xa4506cebde82bde9),
+    U64_C(0xbef9a3f7b2c67915), U64_C(0xc67178f2e372532b),
+    U64_C(0xca273eceea26619c), U64_C(0xd186b8c721c0c207),
+    U64_C(0xeada7dd6cde0eb1e), U64_C(0xf57d4f7fee6ed178),
+    U64_C(0x06f067aa72176fba), U64_C(0x0a637dc5a2c898a6),
+    U64_C(0x113f9804bef90dae), U64_C(0x1b710b35131c471b),
+    U64_C(0x28db77f523047d84), U64_C(0x32caab7b40c72493),
+    U64_C(0x3c9ebe0a15c9bebc), U64_C(0x431d67c49c100d4c),
+    U64_C(0x4cc5d4becb3e42b6), U64_C(0x597f299cfc657e2a),
+    U64_C(0x5fcb6fab3ad6faec), U64_C(0x6c44198c4a475817)
+  };
+
 /****************
  * Transform the message W which consists of 16 64-bit-words
  */
-static void
-transform (SHA512_CONTEXT *hd, const unsigned char *data)
+static unsigned int
+__transform (SHA512_STATE *hd, const unsigned char *data)
 {
   u64 a, b, c, d, e, f, g, h;
-  u64 w[80];
+  u64 w[16];
   int t;
-  static const u64 k[] =
-    {
-      U64_C(0x428a2f98d728ae22), U64_C(0x7137449123ef65cd),
-      U64_C(0xb5c0fbcfec4d3b2f), U64_C(0xe9b5dba58189dbbc),
-      U64_C(0x3956c25bf348b538), U64_C(0x59f111f1b605d019),
-      U64_C(0x923f82a4af194f9b), U64_C(0xab1c5ed5da6d8118),
-      U64_C(0xd807aa98a3030242), U64_C(0x12835b0145706fbe),
-      U64_C(0x243185be4ee4b28c), U64_C(0x550c7dc3d5ffb4e2),
-      U64_C(0x72be5d74f27b896f), U64_C(0x80deb1fe3b1696b1),
-      U64_C(0x9bdc06a725c71235), U64_C(0xc19bf174cf692694),
-      U64_C(0xe49b69c19ef14ad2), U64_C(0xefbe4786384f25e3),
-      U64_C(0x0fc19dc68b8cd5b5), U64_C(0x240ca1cc77ac9c65),
-      U64_C(0x2de92c6f592b0275), U64_C(0x4a7484aa6ea6e483),
-      U64_C(0x5cb0a9dcbd41fbd4), U64_C(0x76f988da831153b5),
-      U64_C(0x983e5152ee66dfab), U64_C(0xa831c66d2db43210),
-      U64_C(0xb00327c898fb213f), U64_C(0xbf597fc7beef0ee4),
-      U64_C(0xc6e00bf33da88fc2), U64_C(0xd5a79147930aa725),
-      U64_C(0x06ca6351e003826f), U64_C(0x142929670a0e6e70),
-      U64_C(0x27b70a8546d22ffc), U64_C(0x2e1b21385c26c926),
-      U64_C(0x4d2c6dfc5ac42aed), U64_C(0x53380d139d95b3df),
-      U64_C(0x650a73548baf63de), U64_C(0x766a0abb3c77b2a8),
-      U64_C(0x81c2c92e47edaee6), U64_C(0x92722c851482353b),
-      U64_C(0xa2bfe8a14cf10364), U64_C(0xa81a664bbc423001),
-      U64_C(0xc24b8b70d0f89791), U64_C(0xc76c51a30654be30),
-      U64_C(0xd192e819d6ef5218), U64_C(0xd69906245565a910),
-      U64_C(0xf40e35855771202a), U64_C(0x106aa07032bbd1b8),
-      U64_C(0x19a4c116b8d2d0c8), U64_C(0x1e376c085141ab53),
-      U64_C(0x2748774cdf8eeb99), U64_C(0x34b0bcb5e19b48a8),
-      U64_C(0x391c0cb3c5c95a63), U64_C(0x4ed8aa4ae3418acb),
-      U64_C(0x5b9cca4f7763e373), U64_C(0x682e6ff3d6b2b8a3),
-      U64_C(0x748f82ee5defb2fc), U64_C(0x78a5636f43172f60),
-      U64_C(0x84c87814a1f0ab72), U64_C(0x8cc702081a6439ec),
-      U64_C(0x90befffa23631e28), U64_C(0xa4506cebde82bde9),
-      U64_C(0xbef9a3f7b2c67915), U64_C(0xc67178f2e372532b),
-      U64_C(0xca273eceea26619c), U64_C(0xd186b8c721c0c207),
-      U64_C(0xeada7dd6cde0eb1e), U64_C(0xf57d4f7fee6ed178),
-      U64_C(0x06f067aa72176fba), U64_C(0x0a637dc5a2c898a6),
-      U64_C(0x113f9804bef90dae), U64_C(0x1b710b35131c471b),
-      U64_C(0x28db77f523047d84), U64_C(0x32caab7b40c72493),
-      U64_C(0x3c9ebe0a15c9bebc), U64_C(0x431d67c49c100d4c),
-      U64_C(0x4cc5d4becb3e42b6), U64_C(0x597f299cfc657e2a),
-      U64_C(0x5fcb6fab3ad6faec), U64_C(0x6c44198c4a475817)
-    };
 
   /* get values from the chaining vars */
   a = hd->h0;
@@ -191,35 +293,14 @@ transform (SHA512_CONTEXT *hd, const unsigned char *data)
   g = hd->h6;
   h = hd->h7;
 
-#ifdef WORDS_BIGENDIAN
-  memcpy (w, data, 128);
-#else
-  {
-    int i;
-    byte *p2;
-
-    for (i = 0, p2 = (byte *) w; i < 16; i++, p2 += 8)
-      {
-       p2[7] = *data++;
-       p2[6] = *data++;
-       p2[5] = *data++;
-       p2[4] = *data++;
-       p2[3] = *data++;
-       p2[2] = *data++;
-       p2[1] = *data++;
-       p2[0] = *data++;
-      }
-  }
-#endif
+  for ( t = 0; t < 16; t++ )
+    w[t] = buf_get_be64(data + t * 8);
 
 #define S0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7))
 #define S1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6))
 
-  for (t = 16; t < 80; t++)
-    w[t] = S1 (w[t - 2]) + w[t - 7] + S0 (w[t - 15]) + w[t - 16];
-
 
-  for (t = 0; t < 80; )
+  for (t = 0; t < 80 - 16; )
     {
       u64 t1, t2;
 
@@ -232,7 +313,8 @@ transform (SHA512_CONTEXT *hd, const unsigned char *data)
          Unrolled with inline:      330ms
       */
 #if 0 /* Not unrolled.  */
-      t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t];
+      t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t%16];
+      w[t%16] += S1 (w[(t - 2)%16]) + w[(t - 7)%16] + S0 (w[(t - 15)%16]);
       t2 = Sum0 (a) + Maj (a, b, c);
       h = g;
       g = f;
@@ -244,47 +326,204 @@ transform (SHA512_CONTEXT *hd, const unsigned char *data)
       a = t1 + t2;
       t++;
 #else /* Unrolled to interweave the chain variables.  */
-      t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t];
+      t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[0];
+      w[0] += S1 (w[14]) + w[9] + S0 (w[1]);
+      t2 = Sum0 (a) + Maj (a, b, c);
+      d += t1;
+      h = t1 + t2;
+
+      t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+1] + w[1];
+      w[1] += S1 (w[15]) + w[10] + S0 (w[2]);
+      t2 = Sum0 (h) + Maj (h, a, b);
+      c += t1;
+      g  = t1 + t2;
+
+      t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+2] + w[2];
+      w[2] += S1 (w[0]) + w[11] + S0 (w[3]);
+      t2 = Sum0 (g) + Maj (g, h, a);
+      b += t1;
+      f  = t1 + t2;
+
+      t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+3] + w[3];
+      w[3] += S1 (w[1]) + w[12] + S0 (w[4]);
+      t2 = Sum0 (f) + Maj (f, g, h);
+      a += t1;
+      e  = t1 + t2;
+
+      t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+4] + w[4];
+      w[4] += S1 (w[2]) + w[13] + S0 (w[5]);
+      t2 = Sum0 (e) + Maj (e, f, g);
+      h += t1;
+      d  = t1 + t2;
+
+      t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+5] + w[5];
+      w[5] += S1 (w[3]) + w[14] + S0 (w[6]);
+      t2 = Sum0 (d) + Maj (d, e, f);
+      g += t1;
+      c  = t1 + t2;
+
+      t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+6] + w[6];
+      w[6] += S1 (w[4]) + w[15] + S0 (w[7]);
+      t2 = Sum0 (c) + Maj (c, d, e);
+      f += t1;
+      b  = t1 + t2;
+
+      t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+7] + w[7];
+      w[7] += S1 (w[5]) + w[0] + S0 (w[8]);
+      t2 = Sum0 (b) + Maj (b, c, d);
+      e += t1;
+      a  = t1 + t2;
+
+      t1 = h + Sum1 (e) + Ch (e, f, g) + k[t+8] + w[8];
+      w[8] += S1 (w[6]) + w[1] + S0 (w[9]);
       t2 = Sum0 (a) + Maj (a, b, c);
       d += t1;
       h  = t1 + t2;
 
-      t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+1] + w[t+1];
+      t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+9] + w[9];
+      w[9] += S1 (w[7]) + w[2] + S0 (w[10]);
       t2 = Sum0 (h) + Maj (h, a, b);
       c += t1;
       g  = t1 + t2;
 
-      t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+2] + w[t+2];
+      t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+10] + w[10];
+      w[10] += S1 (w[8]) + w[3] + S0 (w[11]);
       t2 = Sum0 (g) + Maj (g, h, a);
       b += t1;
       f  = t1 + t2;
 
-      t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+3] + w[t+3];
+      t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+11] + w[11];
+      w[11] += S1 (w[9]) + w[4] + S0 (w[12]);
       t2 = Sum0 (f) + Maj (f, g, h);
       a += t1;
       e  = t1 + t2;
 
-      t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+4] + w[t+4];
+      t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+12] + w[12];
+      w[12] += S1 (w[10]) + w[5] + S0 (w[13]);
       t2 = Sum0 (e) + Maj (e, f, g);
       h += t1;
       d  = t1 + t2;
 
-      t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+5] + w[t+5];
+      t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+13] + w[13];
+      w[13] += S1 (w[11]) + w[6] + S0 (w[14]);
       t2 = Sum0 (d) + Maj (d, e, f);
       g += t1;
       c  = t1 + t2;
 
-      t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+6] + w[t+6];
+      t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+14] + w[14];
+      w[14] += S1 (w[12]) + w[7] + S0 (w[15]);
       t2 = Sum0 (c) + Maj (c, d, e);
       f += t1;
       b  = t1 + t2;
 
-      t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+7] + w[t+7];
+      t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+15] + w[15];
+      w[15] += S1 (w[13]) + w[8] + S0 (w[0]);
       t2 = Sum0 (b) + Maj (b, c, d);
       e += t1;
       a  = t1 + t2;
 
-      t += 8;
+      t += 16;
+#endif
+    }
+
+  for (; t < 80; )
+    {
+      u64 t1, t2;
+
+#if 0 /* Not unrolled.  */
+      t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[t%16];
+      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;
+      t++;
+#else /* Unrolled to interweave the chain variables.  */
+      t1 = h + Sum1 (e) + Ch (e, f, g) + k[t] + w[0];
+      t2 = Sum0 (a) + Maj (a, b, c);
+      d += t1;
+      h  = t1 + t2;
+
+      t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+1] + w[1];
+      t2 = Sum0 (h) + Maj (h, a, b);
+      c += t1;
+      g  = t1 + t2;
+
+      t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+2] + w[2];
+      t2 = Sum0 (g) + Maj (g, h, a);
+      b += t1;
+      f  = t1 + t2;
+
+      t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+3] + w[3];
+      t2 = Sum0 (f) + Maj (f, g, h);
+      a += t1;
+      e  = t1 + t2;
+
+      t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+4] + w[4];
+      t2 = Sum0 (e) + Maj (e, f, g);
+      h += t1;
+      d  = t1 + t2;
+
+      t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+5] + w[5];
+      t2 = Sum0 (d) + Maj (d, e, f);
+      g += t1;
+      c  = t1 + t2;
+
+      t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+6] + w[6];
+      t2 = Sum0 (c) + Maj (c, d, e);
+      f += t1;
+      b  = t1 + t2;
+
+      t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+7] + w[7];
+      t2 = Sum0 (b) + Maj (b, c, d);
+      e += t1;
+      a  = t1 + t2;
+
+      t1 = h + Sum1 (e) + Ch (e, f, g) + k[t+8] + w[8];
+      t2 = Sum0 (a) + Maj (a, b, c);
+      d += t1;
+      h  = t1 + t2;
+
+      t1 = g + Sum1 (d) + Ch (d, e, f) + k[t+9] + w[9];
+      t2 = Sum0 (h) + Maj (h, a, b);
+      c += t1;
+      g  = t1 + t2;
+
+      t1 = f + Sum1 (c) + Ch (c, d, e) + k[t+10] + w[10];
+      t2 = Sum0 (g) + Maj (g, h, a);
+      b += t1;
+      f  = t1 + t2;
+
+      t1 = e + Sum1 (b) + Ch (b, c, d) + k[t+11] + w[11];
+      t2 = Sum0 (f) + Maj (f, g, h);
+      a += t1;
+      e  = t1 + t2;
+
+      t1 = d + Sum1 (a) + Ch (a, b, c) + k[t+12] + w[12];
+      t2 = Sum0 (e) + Maj (e, f, g);
+      h += t1;
+      d  = t1 + t2;
+
+      t1 = c + Sum1 (h) + Ch (h, a, b) + k[t+13] + w[13];
+      t2 = Sum0 (d) + Maj (d, e, f);
+      g += t1;
+      c  = t1 + t2;
+
+      t1 = b + Sum1 (g) + Ch (g, h, a) + k[t+14] + w[14];
+      t2 = Sum0 (c) + Maj (c, d, e);
+      f += t1;
+      b  = t1 + t2;
+
+      t1 = a + Sum1 (f) + Ch (f, g, h) + k[t+15] + w[15];
+      t2 = Sum0 (b) + Maj (b, c, d);
+      e += t1;
+      a  = t1 + t2;
+
+      t += 16;
 #endif
     }
 
@@ -297,47 +536,69 @@ transform (SHA512_CONTEXT *hd, const unsigned char *data)
   hd->h5 += f;
   hd->h6 += g;
   hd->h7 += h;
+
+  return /* burn_stack */ (8 + 16) * sizeof(u64) + sizeof(u32) +
+                          3 * sizeof(void*);
 }
 
 
-/* Update the message digest with the contents
- * of INBUF with length INLEN.
- */
-static void
-sha512_write (void *context, const void *inbuf_arg, size_t inlen)
+#ifdef USE_ARM_NEON_ASM
+void _gcry_sha512_transform_armv7_neon (SHA512_STATE *hd,
+                                       const unsigned char *data,
+                                       const u64 k[]);
+#endif
+
+#ifdef USE_SSSE3
+unsigned int _gcry_sha512_transform_amd64_ssse3(const void *input_data,
+                                               void *state, size_t num_blks);
+#endif
+
+#ifdef USE_AVX
+unsigned int _gcry_sha512_transform_amd64_avx(const void *input_data,
+                                             void *state, size_t num_blks);
+#endif
+
+#ifdef USE_AVX2
+unsigned int _gcry_sha512_transform_amd64_avx2(const void *input_data,
+                                              void *state, size_t num_blks);
+#endif
+
+
+static unsigned int
+transform (void *context, const unsigned char *data)
 {
-  const unsigned char *inbuf = inbuf_arg;
-  SHA512_CONTEXT *hd = context;
+  SHA512_CONTEXT *ctx = context;
 
-  if (hd->count == 128)
-    {                          /* flush the buffer */
-      transform (hd, hd->buf);
-      _gcry_burn_stack (768);
-      hd->count = 0;
-      hd->nblocks++;
-    }
-  if (!inbuf)
-    return;
-  if (hd->count)
-    {
-      for (; inlen && hd->count < 128; inlen--)
-       hd->buf[hd->count++] = *inbuf++;
-      sha512_write (context, NULL, 0);
-      if (!inlen)
-       return;
-    }
+#ifdef USE_AVX2
+  if (ctx->use_avx2)
+    return _gcry_sha512_transform_amd64_avx2 (data, &ctx->state, 1)
+           + 4 * sizeof(void*);
+#endif
 
-  while (inlen >= 128)
+#ifdef USE_AVX
+  if (ctx->use_avx)
+    return _gcry_sha512_transform_amd64_avx (data, &ctx->state, 1)
+           + 4 * sizeof(void*);
+#endif
+
+#ifdef USE_SSSE3
+  if (ctx->use_ssse3)
+    return _gcry_sha512_transform_amd64_ssse3 (data, &ctx->state, 1)
+           + 4 * sizeof(void*);
+#endif
+
+#ifdef USE_ARM_NEON_ASM
+  if (ctx->use_neon)
     {
-      transform (hd, inbuf);
-      hd->count = 0;
-      hd->nblocks++;
-      inlen -= 128;
-      inbuf += 128;
+      _gcry_sha512_transform_armv7_neon (&ctx->state, data, k);
+
+      /* _gcry_sha512_transform_armv7_neon does not store sensitive data
+       * to stack.  */
+      return /* no burn_stack */ 0;
     }
-  _gcry_burn_stack (768);
-  for (; inlen && hd->count < 128; inlen--)
-    hd->buf[hd->count++] = *inbuf++;
+#endif
+
+  return __transform (&ctx->state, data) + 3 * sizeof(void*);
 }
 
 
@@ -353,18 +614,24 @@ static void
 sha512_final (void *context)
 {
   SHA512_CONTEXT *hd = context;
-  u64 t, msb, lsb;
+  unsigned int stack_burn_depth;
+  u64 t, th, msb, lsb;
   byte *p;
 
-  sha512_write (context, NULL, 0); /* flush */ ;
+  _gcry_md_block_write (context, NULL, 0); /* flush */ ;
+
+  t = hd->bctx.nblocks;
+  /* if (sizeof t == sizeof hd->bctx.nblocks) */
+  th = hd->bctx.nblocks_high;
+  /* else */
+  /*   th = hd->bctx.nblocks >> 64; In case we ever use u128  */
 
-  t = hd->nblocks;
   /* multiply by 128 to make a byte count */
   lsb = t << 7;
-  msb = t >> 57;
+  msb = (th << 7) | (t >> 57);
   /* add the count */
   t = lsb;
-  if ((lsb += hd->count) < t)
+  if ((lsb += hd->bctx.count) < t)
     msb++;
   /* multiply by 8 to make a bit count */
   t = lsb;
@@ -372,50 +639,28 @@ sha512_final (void *context)
   msb <<= 3;
   msb |= t >> 61;
 
-  if (hd->count < 112)
+  if (hd->bctx.count < 112)
     {                          /* enough room */
-      hd->buf[hd->count++] = 0x80;     /* pad */
-      while (hd->count < 112)
-       hd->buf[hd->count++] = 0;       /* pad */
+      hd->bctx.buf[hd->bctx.count++] = 0x80;   /* pad */
+      while (hd->bctx.count < 112)
+        hd->bctx.buf[hd->bctx.count++] = 0;    /* pad */
     }
   else
     {                          /* need one extra block */
-      hd->buf[hd->count++] = 0x80;     /* pad character */
-      while (hd->count < 128)
-       hd->buf[hd->count++] = 0;
-      sha512_write (context, NULL, 0); /* flush */ ;
-      memset (hd->buf, 0, 112);        /* fill next block with zeroes */
+      hd->bctx.buf[hd->bctx.count++] = 0x80;   /* pad character */
+      while (hd->bctx.count < 128)
+        hd->bctx.buf[hd->bctx.count++] = 0;
+      _gcry_md_block_write (context, NULL, 0); /* flush */ ;
+      memset (hd->bctx.buf, 0, 112);   /* fill next block with zeroes */
     }
   /* append the 128 bit count */
-  hd->buf[112] = msb >> 56;
-  hd->buf[113] = msb >> 48;
-  hd->buf[114] = msb >> 40;
-  hd->buf[115] = msb >> 32;
-  hd->buf[116] = msb >> 24;
-  hd->buf[117] = msb >> 16;
-  hd->buf[118] = msb >> 8;
-  hd->buf[119] = msb;
-
-  hd->buf[120] = lsb >> 56;
-  hd->buf[121] = lsb >> 48;
-  hd->buf[122] = lsb >> 40;
-  hd->buf[123] = lsb >> 32;
-  hd->buf[124] = lsb >> 24;
-  hd->buf[125] = lsb >> 16;
-  hd->buf[126] = lsb >> 8;
-  hd->buf[127] = lsb;
-  transform (hd, hd->buf);
-  _gcry_burn_stack (768);
-
-  p = hd->buf;
-#ifdef WORDS_BIGENDIAN
-#define X(a) do { *(u64*)p = hd->h##a ; p += 8; } while (0)
-#else /* little endian */
-#define X(a) do { *p++ = hd->h##a >> 56; *p++ = hd->h##a >> 48;              \
-                  *p++ = hd->h##a >> 40; *p++ = hd->h##a >> 32;              \
-                  *p++ = hd->h##a >> 24; *p++ = hd->h##a >> 16;              \
-                  *p++ = hd->h##a >> 8;  *p++ = hd->h##a; } while (0)
-#endif
+  buf_put_be64(hd->bctx.buf + 112, msb);
+  buf_put_be64(hd->bctx.buf + 120, lsb);
+  stack_burn_depth = transform (hd, hd->bctx.buf);
+  _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)
   X (0);
   X (1);
   X (2);
@@ -433,7 +678,7 @@ static byte *
 sha512_read (void *context)
 {
   SHA512_CONTEXT *hd = (SHA512_CONTEXT *) context;
-  return hd->buf;
+  return hd->bctx.buf;
 }
 
 
@@ -591,12 +836,10 @@ static gcry_md_oid_spec_t oid_spec_sha512[] =
 
 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, sha512_write, sha512_final, sha512_read,
+    sha512_init, _gcry_md_block_write, sha512_final, sha512_read,
     sizeof (SHA512_CONTEXT),
-  };
-md_extra_spec_t _gcry_digest_extraspec_sha512 =
-  {
     run_selftests
   };
 
@@ -619,11 +862,9 @@ static gcry_md_oid_spec_t oid_spec_sha384[] =
 
 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, sha512_write, sha512_final, sha512_read,
+    sha384_init, _gcry_md_block_write, sha512_final, sha512_read,
     sizeof (SHA512_CONTEXT),
-  };
-md_extra_spec_t _gcry_digest_extraspec_sha384 =
-  {
     run_selftests
   };
diff --git a/cipher/stribog.c b/cipher/stribog.c
new file mode 100644 (file)
index 0000000..297b64a
--- /dev/null
@@ -0,0 +1,1323 @@
+/* stribog.c - GOST R 34.11-2012 (Stribog) hash function
+ * 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 <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "g10lib.h"
+#include "bithelp.h"
+#include "bufhelp.h"
+#include "cipher.h"
+#include "hash-common.h"
+
+
+typedef struct
+{
+  gcry_md_block_ctx_t bctx;
+  union
+  {
+    u64 h[8];
+    unsigned char result[64];
+  };
+  u64 N[8];
+  u64 Sigma[8];
+} STRIBOG_CONTEXT;
+
+
+/* Pre-computed results of multiplication of bytes on A and reordered with
+   Pi[]. */
+static const u64 stribog_table[8][256] =
+{
+  /* 0 */
+  { U64_C(0xd01f715b5c7ef8e6), U64_C(0x16fa240980778325),
+    U64_C(0xa8a42e857ee049c8), U64_C(0x6ac1068fa186465b),
+    U64_C(0x6e417bd7a2e9320b), U64_C(0x665c8167a437daab),
+    U64_C(0x7666681aa89617f6), U64_C(0x4b959163700bdcf5),
+    U64_C(0xf14be6b78df36248), U64_C(0xc585bd689a625cff),
+    U64_C(0x9557d7fca67d82cb), U64_C(0x89f0b969af6dd366),
+    U64_C(0xb0833d48749f6c35), U64_C(0xa1998c23b1ecbc7c),
+    U64_C(0x8d70c431ac02a736), U64_C(0xd6dfbc2fd0a8b69e),
+    U64_C(0x37aeb3e551fa198b), U64_C(0x0b7d128a40b5cf9c),
+    U64_C(0x5a8f2008b5780cbc), U64_C(0xedec882284e333e5),
+    U64_C(0xd25fc177d3c7c2ce), U64_C(0x5e0f5d50b61778ec),
+    U64_C(0x1d873683c0c24cb9), U64_C(0xad040bcbb45d208c),
+    U64_C(0x2f89a0285b853c76), U64_C(0x5732fff6791b8d58),
+    U64_C(0x3e9311439ef6ec3f), U64_C(0xc9183a809fd3c00f),
+    U64_C(0x83adf3f5260a01ee), U64_C(0xa6791941f4e8ef10),
+    U64_C(0x103ae97d0ca1cd5d), U64_C(0x2ce948121dee1b4a),
+    U64_C(0x39738421dbf2bf53), U64_C(0x093da2a6cf0cf5b4),
+    U64_C(0xcd9847d89cbcb45f), U64_C(0xf9561c078b2d8ae8),
+    U64_C(0x9c6a755a6971777f), U64_C(0xbc1ebaa0712ef0c5),
+    U64_C(0x72e61542abf963a6), U64_C(0x78bb5fde229eb12e),
+    U64_C(0x14ba94250fceb90d), U64_C(0x844d6697630e5282),
+    U64_C(0x98ea08026a1e032f), U64_C(0xf06bbea144217f5c),
+    U64_C(0xdb6263d11ccb377a), U64_C(0x641c314b2b8ee083),
+    U64_C(0x320e96ab9b4770cf), U64_C(0x1ee7deb986a96b85),
+    U64_C(0xe96cf57a878c47b5), U64_C(0xfdd6615f8842feb8),
+    U64_C(0xc83862965601dd1b), U64_C(0x2ea9f83e92572162),
+    U64_C(0xf876441142ff97fc), U64_C(0xeb2c455608357d9d),
+    U64_C(0x5612a7e0b0c9904c), U64_C(0x6c01cbfb2d500823),
+    U64_C(0x4548a6a7fa037a2d), U64_C(0xabc4c6bf388b6ef4),
+    U64_C(0xbade77d4fdf8bebd), U64_C(0x799b07c8eb4cac3a),
+    U64_C(0x0c9d87e805b19cf0), U64_C(0xcb588aac106afa27),
+    U64_C(0xea0c1d40c1e76089), U64_C(0x2869354a1e816f1a),
+    U64_C(0xff96d17307fbc490), U64_C(0x9f0a9d602f1a5043),
+    U64_C(0x96373fc6e016a5f7), U64_C(0x5292dab8b3a6e41c),
+    U64_C(0x9b8ae0382c752413), U64_C(0x4f15ec3b7364a8a5),
+    U64_C(0x3fb349555724f12b), U64_C(0xc7c50d4415db66d7),
+    U64_C(0x92b7429ee379d1a7), U64_C(0xd37f99611a15dfda),
+    U64_C(0x231427c05e34a086), U64_C(0xa439a96d7b51d538),
+    U64_C(0xb403401077f01865), U64_C(0xdda2aea5901d7902),
+    U64_C(0x0a5d4a9c8967d288), U64_C(0xc265280adf660f93),
+    U64_C(0x8bb0094520d4e94e), U64_C(0x2a29856691385532),
+    U64_C(0x42a833c5bf072941), U64_C(0x73c64d54622b7eb2),
+    U64_C(0x07e095624504536c), U64_C(0x8a905153e906f45a),
+    U64_C(0x6f6123c16b3b2f1f), U64_C(0xc6e55552dc097bc3),
+    U64_C(0x4468feb133d16739), U64_C(0xe211e7f0c7398829),
+    U64_C(0xa2f96419f7879b40), U64_C(0x19074bdbc3ad38e9),
+    U64_C(0xf4ebc3f9474e0b0c), U64_C(0x43886bd376d53455),
+    U64_C(0xd8028beb5aa01046), U64_C(0x51f23282f5cdc320),
+    U64_C(0xe7b1c2be0d84e16d), U64_C(0x081dfab006dee8a0),
+    U64_C(0x3b33340d544b857b), U64_C(0x7f5bcabc679ae242),
+    U64_C(0x0edd37c48a08a6d8), U64_C(0x81ed43d9a9b33bc6),
+    U64_C(0xb1a3655ebd4d7121), U64_C(0x69a1eeb5e7ed6167),
+    U64_C(0xf6ab73d5c8f73124), U64_C(0x1a67a3e185c61fd5),
+    U64_C(0x2dc91004d43c065e), U64_C(0x0240b02c8fb93a28),
+    U64_C(0x90f7f2b26cc0eb8f), U64_C(0x3cd3a16f114fd617),
+    U64_C(0xaae49ea9f15973e0), U64_C(0x06c0cd748cd64e78),
+    U64_C(0xda423bc7d5192a6e), U64_C(0xc345701c16b41287),
+    U64_C(0x6d2193ede4821537), U64_C(0xfcf639494190e3ac),
+    U64_C(0x7c3b228621f1c57e), U64_C(0xfb16ac2b0494b0c0),
+    U64_C(0xbf7e529a3745d7f9), U64_C(0x6881b6a32e3f7c73),
+    U64_C(0xca78d2bad9b8e733), U64_C(0xbbfe2fc2342aa3a9),
+    U64_C(0x0dbddffecc6381e4), U64_C(0x70a6a56e2440598e),
+    U64_C(0xe4d12a844befc651), U64_C(0x8c509c2765d0ba22),
+    U64_C(0xee8c6018c28814d9), U64_C(0x17da7c1f49a59e31),
+    U64_C(0x609c4c1328e194d3), U64_C(0xb3e3d57232f44b09),
+    U64_C(0x91d7aaa4a512f69b), U64_C(0x0ffd6fd243dabbcc),
+    U64_C(0x50d26a943c1fde34), U64_C(0x6be15e9968545b4f),
+    U64_C(0x94778fea6faf9fdf), U64_C(0x2b09dd7058ea4826),
+    U64_C(0x677cd9716de5c7bf), U64_C(0x49d5214fffb2e6dd),
+    U64_C(0x0360e83a466b273c), U64_C(0x1fc786af4f7b7691),
+    U64_C(0xa0b9d435783ea168), U64_C(0xd49f0c035f118cb6),
+    U64_C(0x01205816c9d21d14), U64_C(0xac2453dd7d8f3d98),
+    U64_C(0x545217cc3f70aa64), U64_C(0x26b4028e9489c9c2),
+    U64_C(0xdec2469fd6765e3e), U64_C(0x04807d58036f7450),
+    U64_C(0xe5f17292823ddb45), U64_C(0xf30b569b024a5860),
+    U64_C(0x62dcfc3fa758aefb), U64_C(0xe84cad6c4e5e5aa1),
+    U64_C(0xccb81fce556ea94b), U64_C(0x53b282ae7a74f908),
+    U64_C(0x1b47fbf74c1402c1), U64_C(0x368eebf39828049f),
+    U64_C(0x7afbeff2ad278b06), U64_C(0xbe5e0a8cfe97caed),
+    U64_C(0xcfd8f7f413058e77), U64_C(0xf78b2bc301252c30),
+    U64_C(0x4d555c17fcdd928d), U64_C(0x5f2f05467fc565f8),
+    U64_C(0x24f4b2a21b30f3ea), U64_C(0x860dd6bbecb768aa),
+    U64_C(0x4c750401350f8f99), U64_C(0x0000000000000000),
+    U64_C(0xecccd0344d312ef1), U64_C(0xb5231806be220571),
+    U64_C(0xc105c030990d28af), U64_C(0x653c695de25cfd97),
+    U64_C(0x159acc33c61ca419), U64_C(0xb89ec7f872418495),
+    U64_C(0xa9847693b73254dc), U64_C(0x58cf90243ac13694),
+    U64_C(0x59efc832f3132b80), U64_C(0x5c4fed7c39ae42c4),
+    U64_C(0x828dabe3efd81cfa), U64_C(0xd13f294d95ace5f2),
+    U64_C(0x7d1b7a90e823d86a), U64_C(0xb643f03cf849224d),
+    U64_C(0x3df3f979d89dcb03), U64_C(0x7426d836272f2dde),
+    U64_C(0xdfe21e891fa4432a), U64_C(0x3a136c1b9d99986f),
+    U64_C(0xfa36f43dcd46add4), U64_C(0xc025982650df35bb),
+    U64_C(0x856d3e81aadc4f96), U64_C(0xc4a5e57e53b041eb),
+    U64_C(0x4708168b75ba4005), U64_C(0xaf44bbe73be41aa4),
+    U64_C(0x971767d029c4b8e3), U64_C(0xb9be9feebb939981),
+    U64_C(0x215497ecd18d9aae), U64_C(0x316e7e91dd2c57f3),
+    U64_C(0xcef8afe2dad79363), U64_C(0x3853dc371220a247),
+    U64_C(0x35ee03c9de4323a3), U64_C(0xe6919aa8c456fc79),
+    U64_C(0xe05157dc4880b201), U64_C(0x7bdbb7e464f59612),
+    U64_C(0x127a59518318f775), U64_C(0x332ecebd52956ddb),
+    U64_C(0x8f30741d23bb9d1e), U64_C(0xd922d3fd93720d52),
+    U64_C(0x7746300c61440ae2), U64_C(0x25d4eab4d2e2eefe),
+    U64_C(0x75068020eefd30ca), U64_C(0x135a01474acaea61),
+    U64_C(0x304e268714fe4ae7), U64_C(0xa519f17bb283c82c),
+    U64_C(0xdc82f6b359cf6416), U64_C(0x5baf781e7caa11a8),
+    U64_C(0xb2c38d64fb26561d), U64_C(0x34ce5bdf17913eb7),
+    U64_C(0x5d6fb56af07c5fd0), U64_C(0x182713cd0a7f25fd),
+    U64_C(0x9e2ac576e6c84d57), U64_C(0x9aaab82ee5a73907),
+    U64_C(0xa3d93c0f3e558654), U64_C(0x7e7b92aaae48ff56),
+    U64_C(0x872d8ead256575be), U64_C(0x41c8dbfff96c0e7d),
+    U64_C(0x99ca5014a3cc1e3b), U64_C(0x40e883e930be1369),
+    U64_C(0x1ca76e95091051ad), U64_C(0x4e35b42dbab6b5b1),
+    U64_C(0x05a0254ecabd6944), U64_C(0xe1710fca8152af15),
+    U64_C(0xf22b0e8dcb984574), U64_C(0xb763a82a319b3f59),
+    U64_C(0x63fca4296e8ab3ef), U64_C(0x9d4a2d4ca0a36a6b),
+    U64_C(0xe331bfe60eeb953d), U64_C(0xd5bf541596c391a2),
+    U64_C(0xf5cb9bef8e9c1618), U64_C(0x46284e9dbc685d11),
+    U64_C(0x2074cffa185f87ba), U64_C(0xbd3ee2b6b8fcedd1),
+    U64_C(0xae64e3f1f23607b0), U64_C(0xfeb68965ce29d984),
+    U64_C(0x55724fdaf6a2b770), U64_C(0x29496d5cd753720e),
+    U64_C(0xa75941573d3af204), U64_C(0x8e102c0bea69800a),
+    U64_C(0x111ab16bc573d049), U64_C(0xd7ffe439197aab8a),
+    U64_C(0xefac380e0b5a09cd), U64_C(0x48f579593660fbc9),
+    U64_C(0x22347fd697e6bd92), U64_C(0x61bc1405e13389c7),
+    U64_C(0x4ab5c975b9d9c1e1), U64_C(0x80cd1bcf606126d2),
+    U64_C(0x7186fd78ed92449a), U64_C(0x93971a882aabccb3),
+    U64_C(0x88d0e17f66bfce72), U64_C(0x27945a985d5bd4d6) },
+  /* 1 */
+  { U64_C(0xde553f8c05a811c8), U64_C(0x1906b59631b4f565),
+    U64_C(0x436e70d6b1964ff7), U64_C(0x36d343cb8b1e9d85),
+    U64_C(0x843dfacc858aab5a), U64_C(0xfdfc95c299bfc7f9),
+    U64_C(0x0f634bdea1d51fa2), U64_C(0x6d458b3b76efb3cd),
+    U64_C(0x85c3f77cf8593f80), U64_C(0x3c91315fbe737cb2),
+    U64_C(0x2148b03366ace398), U64_C(0x18f8b8264c6761bf),
+    U64_C(0xc830c1c495c9fb0f), U64_C(0x981a76102086a0aa),
+    U64_C(0xaa16012142f35760), U64_C(0x35cc54060c763cf6),
+    U64_C(0x42907d66cc45db2d), U64_C(0x8203d44b965af4bc),
+    U64_C(0x3d6f3cefc3a0e868), U64_C(0xbc73ff69d292bda7),
+    U64_C(0x8722ed0102e20a29), U64_C(0x8f8185e8cd34deb7),
+    U64_C(0x9b0561dda7ee01d9), U64_C(0x5335a0193227fad6),
+    U64_C(0xc9cecc74e81a6fd5), U64_C(0x54f5832e5c2431ea),
+    U64_C(0x99e47ba05d553470), U64_C(0xf7bee756acd226ce),
+    U64_C(0x384e05a5571816fd), U64_C(0xd1367452a47d0e6a),
+    U64_C(0xf29fde1c386ad85b), U64_C(0x320c77316275f7ca),
+    U64_C(0xd0c879e2d9ae9ab0), U64_C(0xdb7406c69110ef5d),
+    U64_C(0x45505e51a2461011), U64_C(0xfc029872e46c5323),
+    U64_C(0xfa3cb6f5f7bc0cc5), U64_C(0x031f17cd8768a173),
+    U64_C(0xbd8df2d9af41297d), U64_C(0x9d3b4f5ab43e5e3f),
+    U64_C(0x4071671b36feee84), U64_C(0x716207e7d3e3b83d),
+    U64_C(0x48d20ff2f9283a1a), U64_C(0x27769eb4757cbc7e),
+    U64_C(0x5c56ebc793f2e574), U64_C(0xa48b474f9ef5dc18),
+    U64_C(0x52cbada94ff46e0c), U64_C(0x60c7da982d8199c6),
+    U64_C(0x0e9d466edc068b78), U64_C(0x4eec2175eaf865fc),
+    U64_C(0x550b8e9e21f7a530), U64_C(0x6b7ba5bc653fec2b),
+    U64_C(0x5eb7f1ba6949d0dd), U64_C(0x57ea94e3db4c9099),
+    U64_C(0xf640eae6d101b214), U64_C(0xdd4a284182c0b0bb),
+    U64_C(0xff1d8fbf6304f250), U64_C(0xb8accb933bf9d7e8),
+    U64_C(0xe8867c478eb68c4d), U64_C(0x3f8e2692391bddc1),
+    U64_C(0xcb2fd60912a15a7c), U64_C(0xaec935dbab983d2f),
+    U64_C(0xf55ffd2b56691367), U64_C(0x80e2ce366ce1c115),
+    U64_C(0x179bf3f8edb27e1d), U64_C(0x01fe0db07dd394da),
+    U64_C(0xda8a0b76ecc37b87), U64_C(0x44ae53e1df9584cb),
+    U64_C(0xb310b4b77347a205), U64_C(0xdfab323c787b8512),
+    U64_C(0x3b511268d070b78e), U64_C(0x65e6e3d2b9396753),
+    U64_C(0x6864b271e2574d58), U64_C(0x259784c98fc789d7),
+    U64_C(0x02e11a7dfabb35a9), U64_C(0x8841a6dfa337158b),
+    U64_C(0x7ade78c39b5dcdd0), U64_C(0xb7cf804d9a2cc84a),
+    U64_C(0x20b6bd831b7f7742), U64_C(0x75bd331d3a88d272),
+    U64_C(0x418f6aab4b2d7a5e), U64_C(0xd9951cbb6babdaf4),
+    U64_C(0xb6318dfde7ff5c90), U64_C(0x1f389b112264aa83),
+    U64_C(0x492c024284fbaec0), U64_C(0xe33a0363c608f9a0),
+    U64_C(0x2688930408af28a4), U64_C(0xc7538a1a341ce4ad),
+    U64_C(0x5da8e677ee2171ae), U64_C(0x8c9e92254a5c7fc4),
+    U64_C(0x63d8cd55aae938b5), U64_C(0x29ebd8daa97a3706),
+    U64_C(0x959827b37be88aa1), U64_C(0x1484e4356adadf6e),
+    U64_C(0xa7945082199d7d6b), U64_C(0xbf6ce8a455fa1cd4),
+    U64_C(0x9cc542eac9edcae5), U64_C(0x79c16f0e1c356ca3),
+    U64_C(0x89bfab6fdee48151), U64_C(0xd4174d1830c5f0ff),
+    U64_C(0x9258048415eb419d), U64_C(0x6139d72850520d1c),
+    U64_C(0x6a85a80c18ec78f1), U64_C(0xcd11f88e0171059a),
+    U64_C(0xcceff53e7ca29140), U64_C(0xd229639f2315af19),
+    U64_C(0x90b91ef9ef507434), U64_C(0x5977d28d074a1be1),
+    U64_C(0x311360fce51d56b9), U64_C(0xc093a92d5a1f2f91),
+    U64_C(0x1a19a25bb6dc5416), U64_C(0xeb996b8a09de2d3e),
+    U64_C(0xfee3820f1ed7668a), U64_C(0xd7085ad5b7ad518c),
+    U64_C(0x7fff41890fe53345), U64_C(0xec5948bd67dde602),
+    U64_C(0x2fd5f65dbaaa68e0), U64_C(0xa5754affe32648c2),
+    U64_C(0xf8ddac880d07396c), U64_C(0x6fa491468c548664),
+    U64_C(0x0c7c5c1326bdbed1), U64_C(0x4a33158f03930fb3),
+    U64_C(0x699abfc19f84d982), U64_C(0xe4fa2054a80b329c),
+    U64_C(0x6707f9af438252fa), U64_C(0x08a368e9cfd6d49e),
+    U64_C(0x47b1442c58fd25b8), U64_C(0xbbb3dc5ebc91769b),
+    U64_C(0x1665fe489061eac7), U64_C(0x33f27a811fa66310),
+    U64_C(0x93a609346838d547), U64_C(0x30ed6d4c98cec263),
+    U64_C(0x1dd9816cd8df9f2a), U64_C(0x94662a03063b1e7b),
+    U64_C(0x83fdd9fbeb896066), U64_C(0x7b207573e68e590a),
+    U64_C(0x5f49fc0a149a4407), U64_C(0x343259b671a5a82c),
+    U64_C(0xfbc2bb458a6f981f), U64_C(0xc272b350a0a41a38),
+    U64_C(0x3aaf1fd8ada32354), U64_C(0x6cbb868b0b3c2717),
+    U64_C(0xa2b569c88d2583fe), U64_C(0xf180c9d1bf027928),
+    U64_C(0xaf37386bd64ba9f5), U64_C(0x12bacab2790a8088),
+    U64_C(0x4c0d3b0810435055), U64_C(0xb2eeb9070e9436df),
+    U64_C(0xc5b29067cea7d104), U64_C(0xdcb425f1ff132461),
+    U64_C(0x4f122cc5972bf126), U64_C(0xac282fa651230886),
+    U64_C(0xe7e537992f6393ef), U64_C(0xe61b3a2952b00735),
+    U64_C(0x709c0a57ae302ce7), U64_C(0xe02514ae416058d3),
+    U64_C(0xc44c9dd7b37445de), U64_C(0x5a68c5408022ba92),
+    U64_C(0x1c278cdca50c0bf0), U64_C(0x6e5a9cf6f18712be),
+    U64_C(0x86dce0b17f319ef3), U64_C(0x2d34ec2040115d49),
+    U64_C(0x4bcd183f7e409b69), U64_C(0x2815d56ad4a9a3dc),
+    U64_C(0x24698979f2141d0d), U64_C(0x0000000000000000),
+    U64_C(0x1ec696a15fb73e59), U64_C(0xd86b110b16784e2e),
+    U64_C(0x8e7f8858b0e74a6d), U64_C(0x063e2e8713d05fe6),
+    U64_C(0xe2c40ed3bbdb6d7a), U64_C(0xb1f1aeca89fc97ac),
+    U64_C(0xe1db191e3cb3cc09), U64_C(0x6418ee62c4eaf389),
+    U64_C(0xc6ad87aa49cf7077), U64_C(0xd6f65765ca7ec556),
+    U64_C(0x9afb6c6dda3d9503), U64_C(0x7ce05644888d9236),
+    U64_C(0x8d609f95378feb1e), U64_C(0x23a9aa4e9c17d631),
+    U64_C(0x6226c0e5d73aac6f), U64_C(0x56149953a69f0443),
+    U64_C(0xeeb852c09d66d3ab), U64_C(0x2b0ac2a753c102af),
+    U64_C(0x07c023376e03cb3c), U64_C(0x2ccae1903dc2c993),
+    U64_C(0xd3d76e2f5ec63bc3), U64_C(0x9e2458973356ff4c),
+    U64_C(0xa66a5d32644ee9b1), U64_C(0x0a427294356de137),
+    U64_C(0x783f62be61e6f879), U64_C(0x1344c70204d91452),
+    U64_C(0x5b96c8f0fdf12e48), U64_C(0xa90916ecc59bf613),
+    U64_C(0xbe92e5142829880e), U64_C(0x727d102a548b194e),
+    U64_C(0x1be7afebcb0fc0cc), U64_C(0x3e702b2244c8491b),
+    U64_C(0xd5e940a84d166425), U64_C(0x66f9f41f3e51c620),
+    U64_C(0xabe80c913f20c3ba), U64_C(0xf07ec461c2d1edf2),
+    U64_C(0xf361d3ac45b94c81), U64_C(0x0521394a94b8fe95),
+    U64_C(0xadd622162cf09c5c), U64_C(0xe97871f7f3651897),
+    U64_C(0xf4a1f09b2bba87bd), U64_C(0x095d6559b2054044),
+    U64_C(0x0bbc7f2448be75ed), U64_C(0x2af4cf172e129675),
+    U64_C(0x157ae98517094bb4), U64_C(0x9fda55274e856b96),
+    U64_C(0x914713499283e0ee), U64_C(0xb952c623462a4332),
+    U64_C(0x74433ead475b46a8), U64_C(0x8b5eb112245fb4f8),
+    U64_C(0xa34b6478f0f61724), U64_C(0x11a5dd7ffe6221fb),
+    U64_C(0xc16da49d27ccbb4b), U64_C(0x76a224d0bde07301),
+    U64_C(0x8aa0bca2598c2022), U64_C(0x4df336b86d90c48f),
+    U64_C(0xea67663a740db9e4), U64_C(0xef465f70e0b54771),
+    U64_C(0x39b008152acb8227), U64_C(0x7d1e5bf4f55e06ec),
+    U64_C(0x105bd0cf83b1b521), U64_C(0x775c2960c033e7db),
+    U64_C(0x7e014c397236a79f), U64_C(0x811cc386113255cf),
+    U64_C(0xeda7450d1a0e72d8), U64_C(0x5889df3d7a998f3b),
+    U64_C(0x2e2bfbedc779fc3a), U64_C(0xce0eef438619a4e9),
+    U64_C(0x372d4e7bf6cd095f), U64_C(0x04df34fae96b6a4f),
+    U64_C(0xf923a13870d4adb6), U64_C(0xa1aa7e050a4d228d),
+    U64_C(0xa8f71b5cb84862c9), U64_C(0xb52e9a306097fde3),
+    U64_C(0x0d8251a35b6e2a0b), U64_C(0x2257a7fee1c442eb),
+    U64_C(0x73831d9a29588d94), U64_C(0x51d4ba64c89ccf7f),
+    U64_C(0x502ab7d4b54f5ba5), U64_C(0x97793dce8153bf08),
+    U64_C(0xe5042de4d5d8a646), U64_C(0x9687307efc802bd2),
+    U64_C(0xa05473b5779eb657), U64_C(0xb4d097801d446939),
+    U64_C(0xcff0e2f3fbca3033), U64_C(0xc38cbee0dd778ee2),
+    U64_C(0x464f499c252eb162), U64_C(0xcad1dbb96f72cea6),
+    U64_C(0xba4dd1eec142e241), U64_C(0xb00fa37af42f0376) },
+  /* 2 */
+  { U64_C(0xcce4cd3aa968b245), U64_C(0x089d5484e80b7faf),
+    U64_C(0x638246c1b3548304), U64_C(0xd2fe0ec8c2355492),
+    U64_C(0xa7fbdf7ff2374eee), U64_C(0x4df1600c92337a16),
+    U64_C(0x84e503ea523b12fb), U64_C(0x0790bbfd53ab0c4a),
+    U64_C(0x198a780f38f6ea9d), U64_C(0x2ab30c8f55ec48cb),
+    U64_C(0xe0f7fed6b2c49db5), U64_C(0xb6ecf3f422cadbdc),
+    U64_C(0x409c9a541358df11), U64_C(0xd3ce8a56dfde3fe3),
+    U64_C(0xc3e9224312c8c1a0), U64_C(0x0d6dfa58816ba507),
+    U64_C(0xddf3e1b179952777), U64_C(0x04c02a42748bb1d9),
+    U64_C(0x94c2abff9f2decb8), U64_C(0x4f91752da8f8acf4),
+    U64_C(0x78682befb169bf7b), U64_C(0xe1c77a48af2ff6c4),
+    U64_C(0x0c5d7ec69c80ce76), U64_C(0x4cc1e4928fd81167),
+    U64_C(0xfeed3d24d9997b62), U64_C(0x518bb6dfc3a54a23),
+    U64_C(0x6dbf2d26151f9b90), U64_C(0xb5bc624b05ea664f),
+    U64_C(0xe86aaa525acfe21a), U64_C(0x4801ced0fb53a0be),
+    U64_C(0xc91463e6c00868ed), U64_C(0x1027a815cd16fe43),
+    U64_C(0xf67069a0319204cd), U64_C(0xb04ccc976c8abce7),
+    U64_C(0xc0b9b3fc35e87c33), U64_C(0xf380c77c58f2de65),
+    U64_C(0x50bb3241de4e2152), U64_C(0xdf93f490435ef195),
+    U64_C(0xf1e0d25d62390887), U64_C(0xaf668bfb1a3c3141),
+    U64_C(0xbc11b251f00a7291), U64_C(0x73a5eed47e427d47),
+    U64_C(0x25bee3f6ee4c3b2e), U64_C(0x43cc0beb34786282),
+    U64_C(0xc824e778dde3039c), U64_C(0xf97d86d98a327728),
+    U64_C(0xf2b043e24519b514), U64_C(0xe297ebf7880f4b57),
+    U64_C(0x3a94a49a98fab688), U64_C(0x868516cb68f0c419),
+    U64_C(0xeffa11af0964ee50), U64_C(0xa4ab4ec0d517f37d),
+    U64_C(0xa9c6b498547c567a), U64_C(0x8e18424f80fbbbb6),
+    U64_C(0x0bcdc53bcf2bc23c), U64_C(0x137739aaea3643d0),
+    U64_C(0x2c1333ec1bac2ff0), U64_C(0x8d48d3f0a7db0625),
+    U64_C(0x1e1ac3f26b5de6d7), U64_C(0xf520f81f16b2b95e),
+    U64_C(0x9f0f6ec450062e84), U64_C(0x0130849e1deb6b71),
+    U64_C(0xd45e31ab8c7533a9), U64_C(0x652279a2fd14e43f),
+    U64_C(0x3209f01e70f1c927), U64_C(0xbe71a770cac1a473),
+    U64_C(0x0e3d6be7a64b1894), U64_C(0x7ec8148cff29d840),
+    U64_C(0xcb7476c7fac3be0f), U64_C(0x72956a4a63a91636),
+    U64_C(0x37f95ec21991138f), U64_C(0x9e3fea5a4ded45f5),
+    U64_C(0x7b38ba50964902e8), U64_C(0x222e580bbde73764),
+    U64_C(0x61e253e0899f55e6), U64_C(0xfc8d2805e352ad80),
+    U64_C(0x35994be3235ac56d), U64_C(0x09add01af5e014de),
+    U64_C(0x5e8659a6780539c6), U64_C(0xb17c48097161d796),
+    U64_C(0x026015213acbd6e2), U64_C(0xd1ae9f77e515e901),
+    U64_C(0xb7dc776a3f21b0ad), U64_C(0xaba6a1b96eb78098),
+    U64_C(0x9bcf4486248d9f5d), U64_C(0x582666c536455efd),
+    U64_C(0xfdbdac9bfeb9c6f1), U64_C(0xc47999be4163cdea),
+    U64_C(0x765540081722a7ef), U64_C(0x3e548ed8ec710751),
+    U64_C(0x3d041f67cb51bac2), U64_C(0x7958af71ac82d40a),
+    U64_C(0x36c9da5c047a78fe), U64_C(0xed9a048e33af38b2),
+    U64_C(0x26ee7249c96c86bd), U64_C(0x900281bdeba65d61),
+    U64_C(0x11172c8bd0fd9532), U64_C(0xea0abf73600434f8),
+    U64_C(0x42fc8f75299309f3), U64_C(0x34a9cf7d3eb1ae1c),
+    U64_C(0x2b838811480723ba), U64_C(0x5ce64c8742ceef24),
+    U64_C(0x1adae9b01fd6570e), U64_C(0x3c349bf9d6bad1b3),
+    U64_C(0x82453c891c7b75c0), U64_C(0x97923a40b80d512b),
+    U64_C(0x4a61dbf1c198765c), U64_C(0xb48ce6d518010d3e),
+    U64_C(0xcfb45c858e480fd6), U64_C(0xd933cbf30d1e96ae),
+    U64_C(0xd70ea014ab558e3a), U64_C(0xc189376228031742),
+    U64_C(0x9262949cd16d8b83), U64_C(0xeb3a3bed7def5f89),
+    U64_C(0x49314a4ee6b8cbcf), U64_C(0xdcc3652f647e4c06),
+    U64_C(0xda635a4c2a3e2b3d), U64_C(0x470c21a940f3d35b),
+    U64_C(0x315961a157d174b4), U64_C(0x6672e81dda3459ac),
+    U64_C(0x5b76f77a1165e36e), U64_C(0x445cb01667d36ec8),
+    U64_C(0xc5491d205c88a69b), U64_C(0x456c34887a3805b9),
+    U64_C(0xffddb9bac4721013), U64_C(0x99af51a71e4649bf),
+    U64_C(0xa15be01cbc7729d5), U64_C(0x52db2760e485f7b0),
+    U64_C(0x8c78576eba306d54), U64_C(0xae560f6507d75a30),
+    U64_C(0x95f22f6182c687c9), U64_C(0x71c5fbf54489aba5),
+    U64_C(0xca44f259e728d57e), U64_C(0x88b87d2ccebbdc8d),
+    U64_C(0xbab18d32be4a15aa), U64_C(0x8be8ec93e99b611e),
+    U64_C(0x17b713e89ebdf209), U64_C(0xb31c5d284baa0174),
+    U64_C(0xeeca9531148f8521), U64_C(0xb8d198138481c348),
+    U64_C(0x8988f9b2d350b7fc), U64_C(0xb9e11c8d996aa839),
+    U64_C(0x5a4673e40c8e881f), U64_C(0x1687977683569978),
+    U64_C(0xbf4123eed72acf02), U64_C(0x4ea1f1b3b513c785),
+    U64_C(0xe767452be16f91ff), U64_C(0x7505d1b730021a7c),
+    U64_C(0xa59bca5ec8fc980c), U64_C(0xad069eda20f7e7a3),
+    U64_C(0x38f4b1bba231606a), U64_C(0x60d2d77e94743e97),
+    U64_C(0x9affc0183966f42c), U64_C(0x248e6768f3a7505f),
+    U64_C(0xcdd449a4b483d934), U64_C(0x87b59255751baf68),
+    U64_C(0x1bea6d2e023d3c7f), U64_C(0x6b1f12455b5ffcab),
+    U64_C(0x743555292de9710d), U64_C(0xd8034f6d10f5fddf),
+    U64_C(0xc6198c9f7ba81b08), U64_C(0xbb8109aca3a17edb),
+    U64_C(0xfa2d1766ad12cabb), U64_C(0xc729080166437079),
+    U64_C(0x9c5fff7b77269317), U64_C(0x0000000000000000),
+    U64_C(0x15d706c9a47624eb), U64_C(0x6fdf38072fd44d72),
+    U64_C(0x5fb6dd3865ee52b7), U64_C(0xa33bf53d86bcff37),
+    U64_C(0xe657c1b5fc84fa8e), U64_C(0xaa962527735cebe9),
+    U64_C(0x39c43525bfda0b1b), U64_C(0x204e4d2a872ce186),
+    U64_C(0x7a083ece8ba26999), U64_C(0x554b9c9db72efbfa),
+    U64_C(0xb22cd9b656416a05), U64_C(0x96a2bedea5e63a5a),
+    U64_C(0x802529a826b0a322), U64_C(0x8115ad363b5bc853),
+    U64_C(0x8375b81701901eb1), U64_C(0x3069e53f4a3a1fc5),
+    U64_C(0xbd2136cfede119e0), U64_C(0x18bafc91251d81ec),
+    U64_C(0x1d4a524d4c7d5b44), U64_C(0x05f0aedc6960daa8),
+    U64_C(0x29e39d3072ccf558), U64_C(0x70f57f6b5962c0d4),
+    U64_C(0x989fd53903ad22ce), U64_C(0xf84d024797d91c59),
+    U64_C(0x547b1803aac5908b), U64_C(0xf0d056c37fd263f6),
+    U64_C(0xd56eb535919e58d8), U64_C(0x1c7ad6d351963035),
+    U64_C(0x2e7326cd2167f912), U64_C(0xac361a443d1c8cd2),
+    U64_C(0x697f076461942a49), U64_C(0x4b515f6fdc731d2d),
+    U64_C(0x8ad8680df4700a6f), U64_C(0x41ac1eca0eb3b460),
+    U64_C(0x7d988533d80965d3), U64_C(0xa8f6300649973d0b),
+    U64_C(0x7765c4960ac9cc9e), U64_C(0x7ca801adc5e20ea2),
+    U64_C(0xdea3700e5eb59ae4), U64_C(0xa06b6482a19c42a4),
+    U64_C(0x6a2f96db46b497da), U64_C(0x27def6d7d487edcc),
+    U64_C(0x463ca5375d18b82a), U64_C(0xa6cb5be1efdc259f),
+    U64_C(0x53eba3fef96e9cc1), U64_C(0xce84d81b93a364a7),
+    U64_C(0xf4107c810b59d22f), U64_C(0x333974806d1aa256),
+    U64_C(0x0f0def79bba073e5), U64_C(0x231edc95a00c5c15),
+    U64_C(0xe437d494c64f2c6c), U64_C(0x91320523f64d3610),
+    U64_C(0x67426c83c7df32dd), U64_C(0x6eefbc99323f2603),
+    U64_C(0x9d6f7be56acdf866), U64_C(0x5916e25b2bae358c),
+    U64_C(0x7ff89012e2c2b331), U64_C(0x035091bf2720bd93),
+    U64_C(0x561b0d22900e4669), U64_C(0x28d319ae6f279e29),
+    U64_C(0x2f43a2533c8c9263), U64_C(0xd09e1be9f8fe8270),
+    U64_C(0xf740ed3e2c796fbc), U64_C(0xdb53ded237d5404c),
+    U64_C(0x62b2c25faebfe875), U64_C(0x0afd41a5d2c0a94d),
+    U64_C(0x6412fd3ce0ff8f4e), U64_C(0xe3a76f6995e42026),
+    U64_C(0x6c8fa9b808f4f0e1), U64_C(0xc2d9a6dd0f23aad1),
+    U64_C(0x8f28c6d19d10d0c7), U64_C(0x85d587744fd0798a),
+    U64_C(0xa20b71a39b579446), U64_C(0x684f83fa7c7f4138),
+    U64_C(0xe507500adba4471d), U64_C(0x3f640a46f19a6c20),
+    U64_C(0x1247bd34f7dd28a1), U64_C(0x2d23b77206474481),
+    U64_C(0x93521002cc86e0f2), U64_C(0x572b89bc8de52d18),
+    U64_C(0xfb1d93f8b0f9a1ca), U64_C(0xe95a2ecc4724896b),
+    U64_C(0x3ba420048511ddf9), U64_C(0xd63e248ab6bee54b),
+    U64_C(0x5dd6c8195f258455), U64_C(0x06a03f634e40673b),
+    U64_C(0x1f2a476c76b68da6), U64_C(0x217ec9b49ac78af7),
+    U64_C(0xecaa80102e4453c3), U64_C(0x14e78257b99d4f9a) },
+  /* 3 */
+  { U64_C(0x20329b2cc87bba05), U64_C(0x4f5eb6f86546a531),
+    U64_C(0xd4f44775f751b6b1), U64_C(0x8266a47b850dfa8b),
+    U64_C(0xbb986aa15a6ca985), U64_C(0xc979eb08f9ae0f99),
+    U64_C(0x2da6f447a2375ea1), U64_C(0x1e74275dcd7d8576),
+    U64_C(0xbc20180a800bc5f8), U64_C(0xb4a2f701b2dc65be),
+    U64_C(0xe726946f981b6d66), U64_C(0x48e6c453bf21c94c),
+    U64_C(0x42cad9930f0a4195), U64_C(0xefa47b64aacccd20),
+    U64_C(0x71180a8960409a42), U64_C(0x8bb3329bf6a44e0c),
+    U64_C(0xd34c35de2d36dacc), U64_C(0xa92f5b7cbc23dc96),
+    U64_C(0xb31a85aa68bb09c3), U64_C(0x13e04836a73161d2),
+    U64_C(0xb24dfc4129c51d02), U64_C(0x8ae44b70b7da5acd),
+    U64_C(0xe671ed84d96579a7), U64_C(0xa4bb3417d66f3832),
+    U64_C(0x4572ab38d56d2de8), U64_C(0xb1b47761ea47215c),
+    U64_C(0xe81c09cf70aba15d), U64_C(0xffbdb872ce7f90ac),
+    U64_C(0xa8782297fd5dc857), U64_C(0x0d946f6b6a4ce4a4),
+    U64_C(0xe4df1f4f5b995138), U64_C(0x9ebc71edca8c5762),
+    U64_C(0x0a2c1dc0b02b88d9), U64_C(0x3b503c115d9d7b91),
+    U64_C(0xc64376a8111ec3a2), U64_C(0xcec199a323c963e4),
+    U64_C(0xdc76a87ec58616f7), U64_C(0x09d596e073a9b487),
+    U64_C(0x14583a9d7d560daf), U64_C(0xf4c6dc593f2a0cb4),
+    U64_C(0xdd21d19584f80236), U64_C(0x4a4836983ddde1d3),
+    U64_C(0xe58866a41ae745f9), U64_C(0xf591a5b27e541875),
+    U64_C(0x891dc05074586693), U64_C(0x5b068c651810a89e),
+    U64_C(0xa30346bc0c08544f), U64_C(0x3dbf3751c684032d),
+    U64_C(0x2a1e86ec785032dc), U64_C(0xf73f5779fca830ea),
+    U64_C(0xb60c05ca30204d21), U64_C(0x0cc316802b32f065),
+    U64_C(0x8770241bdd96be69), U64_C(0xb861e18199ee95db),
+    U64_C(0xf805cad91418fcd1), U64_C(0x29e70dccbbd20e82),
+    U64_C(0xc7140f435060d763), U64_C(0x0f3a9da0e8b0cc3b),
+    U64_C(0xa2543f574d76408e), U64_C(0xbd7761e1c175d139),
+    U64_C(0x4b1f4f737ca3f512), U64_C(0x6dc2df1f2fc137ab),
+    U64_C(0xf1d05c3967b14856), U64_C(0xa742bf3715ed046c),
+    U64_C(0x654030141d1697ed), U64_C(0x07b872abda676c7d),
+    U64_C(0x3ce84eba87fa17ec), U64_C(0xc1fb0403cb79afdf),
+    U64_C(0x3e46bc7105063f73), U64_C(0x278ae987121cd678),
+    U64_C(0xa1adb4778ef47cd0), U64_C(0x26dd906c5362c2b9),
+    U64_C(0x05168060589b44e2), U64_C(0xfbfc41f9d79ac08f),
+    U64_C(0x0e6de44ba9ced8fa), U64_C(0x9feb08068bf243a3),
+    U64_C(0x7b341749d06b129b), U64_C(0x229c69e74a87929a),
+    U64_C(0xe09ee6c4427c011b), U64_C(0x5692e30e725c4c3a),
+    U64_C(0xda99a33e5e9f6e4b), U64_C(0x353dd85af453a36b),
+    U64_C(0x25241b4c90e0fee7), U64_C(0x5de987258309d022),
+    U64_C(0xe230140fc0802984), U64_C(0x93281e86a0c0b3c6),
+    U64_C(0xf229d719a4337408), U64_C(0x6f6c2dd4ad3d1f34),
+    U64_C(0x8ea5b2fbae3f0aee), U64_C(0x8331dd90c473ee4a),
+    U64_C(0x346aa1b1b52db7aa), U64_C(0xdf8f235e06042aa9),
+    U64_C(0xcc6f6b68a1354b7b), U64_C(0x6c95a6f46ebf236a),
+    U64_C(0x52d31a856bb91c19), U64_C(0x1a35ded6d498d555),
+    U64_C(0xf37eaef2e54d60c9), U64_C(0x72e181a9a3c2a61c),
+    U64_C(0x98537aad51952fde), U64_C(0x16f6c856ffaa2530),
+    U64_C(0xd960281e9d1d5215), U64_C(0x3a0745fa1ce36f50),
+    U64_C(0x0b7b642bf1559c18), U64_C(0x59a87eae9aec8001),
+    U64_C(0x5e100c05408bec7c), U64_C(0x0441f98b19e55023),
+    U64_C(0xd70dcc5534d38aef), U64_C(0x927f676de1bea707),
+    U64_C(0x9769e70db925e3e5), U64_C(0x7a636ea29115065a),
+    U64_C(0x468b201816ef11b6), U64_C(0xab81a9b73edff409),
+    U64_C(0xc0ac7de88a07bb1e), U64_C(0x1f235eb68c0391b7),
+    U64_C(0x6056b074458dd30f), U64_C(0xbe8eeac102f7ed67),
+    U64_C(0xcd381283e04b5fba), U64_C(0x5cbefecec277c4e3),
+    U64_C(0xd21b4c356c48ce0d), U64_C(0x1019c31664b35d8c),
+    U64_C(0x247362a7d19eea26), U64_C(0xebe582efb3299d03),
+    U64_C(0x02aef2cb82fc289f), U64_C(0x86275df09ce8aaa8),
+    U64_C(0x28b07427faac1a43), U64_C(0x38a9b7319e1f47cf),
+    U64_C(0xc82e92e3b8d01b58), U64_C(0x06ef0b409b1978bc),
+    U64_C(0x62f842bfc771fb90), U64_C(0x9904034610eb3b1f),
+    U64_C(0xded85ab5477a3e68), U64_C(0x90d195a663428f98),
+    U64_C(0x5384636e2ac708d8), U64_C(0xcbd719c37b522706),
+    U64_C(0xae9729d76644b0eb), U64_C(0x7c8c65e20a0c7ee6),
+    U64_C(0x80c856b007f1d214), U64_C(0x8c0b40302cc32271),
+    U64_C(0xdbcedad51fe17a8a), U64_C(0x740e8ae938dbdea0),
+    U64_C(0xa615c6dc549310ad), U64_C(0x19cc55f6171ae90b),
+    U64_C(0x49b1bdb8fe5fdd8d), U64_C(0xed0a89af2830e5bf),
+    U64_C(0x6a7aadb4f5a65bd6), U64_C(0x7e22972988f05679),
+    U64_C(0xf952b3325566e810), U64_C(0x39fecedadf61530e),
+    U64_C(0x6101c99f04f3c7ce), U64_C(0x2e5f7f6761b562ff),
+    U64_C(0xf08725d226cf5c97), U64_C(0x63af3b54860fef51),
+    U64_C(0x8ff2cb10ef411e2f), U64_C(0x884ab9bb35267252),
+    U64_C(0x4df04433e7ba8dae), U64_C(0x9afd8866d3690741),
+    U64_C(0x66b9bb34de94abb3), U64_C(0x9baaf18d92171380),
+    U64_C(0x543c11c5f0a064a5), U64_C(0x17a1b1bdbed431f1),
+    U64_C(0xb5f58eeaf3a2717f), U64_C(0xc355f6c849858740),
+    U64_C(0xec5df044694ef17e), U64_C(0xd83751f5dc6346d4),
+    U64_C(0xfc4433520dfdacf2), U64_C(0x0000000000000000),
+    U64_C(0x5a51f58e596ebc5f), U64_C(0x3285aaf12e34cf16),
+    U64_C(0x8d5c39db6dbd36b0), U64_C(0x12b731dde64f7513),
+    U64_C(0x94906c2d7aa7dfbb), U64_C(0x302b583aacc8e789),
+    U64_C(0x9d45facd090e6b3c), U64_C(0x2165e2c78905aec4),
+    U64_C(0x68d45f7f775a7349), U64_C(0x189b2c1d5664fdca),
+    U64_C(0xe1c99f2f030215da), U64_C(0x6983269436246788),
+    U64_C(0x8489af3b1e148237), U64_C(0xe94b702431d5b59c),
+    U64_C(0x33d2d31a6f4adbd7), U64_C(0xbfd9932a4389f9a6),
+    U64_C(0xb0e30e8aab39359d), U64_C(0xd1e2c715afcaf253),
+    U64_C(0x150f43763c28196e), U64_C(0xc4ed846393e2eb3d),
+    U64_C(0x03f98b20c3823c5e), U64_C(0xfd134ab94c83b833),
+    U64_C(0x556b682eb1de7064), U64_C(0x36c4537a37d19f35),
+    U64_C(0x7559f30279a5ca61), U64_C(0x799ae58252973a04),
+    U64_C(0x9c12832648707ffd), U64_C(0x78cd9c6913e92ec5),
+    U64_C(0x1d8dac7d0effb928), U64_C(0x439da0784e745554),
+    U64_C(0x413352b3cc887dcb), U64_C(0xbacf134a1b12bd44),
+    U64_C(0x114ebafd25cd494d), U64_C(0x2f08068c20cb763e),
+    U64_C(0x76a07822ba27f63f), U64_C(0xeab2fb04f25789c2),
+    U64_C(0xe3676de481fe3d45), U64_C(0x1b62a73d95e6c194),
+    U64_C(0x641749ff5c68832c), U64_C(0xa5ec4dfc97112cf3),
+    U64_C(0xf6682e92bdd6242b), U64_C(0x3f11c59a44782bb2),
+    U64_C(0x317c21d1edb6f348), U64_C(0xd65ab5be75ad9e2e),
+    U64_C(0x6b2dd45fb4d84f17), U64_C(0xfaab381296e4d44e),
+    U64_C(0xd0b5befeeeb4e692), U64_C(0x0882ef0b32d7a046),
+    U64_C(0x512a91a5a83b2047), U64_C(0x963e9ee6f85bf724),
+    U64_C(0x4e09cf132438b1f0), U64_C(0x77f701c9fb59e2fe),
+    U64_C(0x7ddb1c094b726a27), U64_C(0x5f4775ee01f5f8bd),
+    U64_C(0x9186ec4d223c9b59), U64_C(0xfeeac1998f01846d),
+    U64_C(0xac39db1ce4b89874), U64_C(0xb75b7c21715e59e0),
+    U64_C(0xafc0503c273aa42a), U64_C(0x6e3b543fec430bf5),
+    U64_C(0x704f7362213e8e83), U64_C(0x58ff0745db9294c0),
+    U64_C(0x67eec2df9feabf72), U64_C(0xa0facd9ccf8a6811),
+    U64_C(0xb936986ad890811a), U64_C(0x95c715c63bd9cb7a),
+    U64_C(0xca8060283a2c33c7), U64_C(0x507de84ee9453486),
+    U64_C(0x85ded6d05f6a96f6), U64_C(0x1cdad5964f81ade9),
+    U64_C(0xd5a33e9eb62fa270), U64_C(0x40642b588df6690a),
+    U64_C(0x7f75eec2c98e42b8), U64_C(0x2cf18dace3494a60),
+    U64_C(0x23cb100c0bf9865b), U64_C(0xeef3028febb2d9e1),
+    U64_C(0x4425d2d394133929), U64_C(0xaad6d05c7fa1e0c8),
+    U64_C(0xad6ea2f7a5c68cb5), U64_C(0xc2028f2308fb9381),
+    U64_C(0x819f2f5b468fc6d5), U64_C(0xc5bafd88d29cfffc),
+    U64_C(0x47dc59f357910577), U64_C(0x2b49ff07392e261d),
+    U64_C(0x57c59ae5332258fb), U64_C(0x73b6f842e2bcb2dd),
+    U64_C(0xcf96e04862b77725), U64_C(0x4ca73dd8a6c4996f),
+    U64_C(0x015779eb417e14c1), U64_C(0x37932a9176af8bf4) },
+  /* 4 */
+  { U64_C(0x190a2c9b249df23e), U64_C(0x2f62f8b62263e1e9),
+    U64_C(0x7a7f754740993655), U64_C(0x330b7ba4d5564d9f),
+    U64_C(0x4c17a16a46672582), U64_C(0xb22f08eb7d05f5b8),
+    U64_C(0x535f47f40bc148cc), U64_C(0x3aec5d27d4883037),
+    U64_C(0x10ed0a1825438f96), U64_C(0x516101f72c233d17),
+    U64_C(0x13cc6f949fd04eae), U64_C(0x739853c441474bfd),
+    U64_C(0x653793d90d3f5b1b), U64_C(0x5240647b96b0fc2f),
+    U64_C(0x0c84890ad27623e0), U64_C(0xd7189b32703aaea3),
+    U64_C(0x2685de3523bd9c41), U64_C(0x99317c5b11bffefa),
+    U64_C(0x0d9baa854f079703), U64_C(0x70b93648fbd48ac5),
+    U64_C(0xa80441fce30bc6be), U64_C(0x7287704bdc36ff1e),
+    U64_C(0xb65384ed33dc1f13), U64_C(0xd36417343ee34408),
+    U64_C(0x39cd38ab6e1bf10f), U64_C(0x5ab861770a1f3564),
+    U64_C(0x0ebacf09f594563b), U64_C(0xd04572b884708530),
+    U64_C(0x3cae9722bdb3af47), U64_C(0x4a556b6f2f5cbaf2),
+    U64_C(0xe1704f1f76c4bd74), U64_C(0x5ec4ed7144c6dfcf),
+    U64_C(0x16afc01d4c7810e6), U64_C(0x283f113cd629ca7a),
+    U64_C(0xaf59a8761741ed2d), U64_C(0xeed5a3991e215fac),
+    U64_C(0x3bf37ea849f984d4), U64_C(0xe413e096a56ce33c),
+    U64_C(0x2c439d3a98f020d1), U64_C(0x637559dc6404c46b),
+    U64_C(0x9e6c95d1e5f5d569), U64_C(0x24bb9836045fe99a),
+    U64_C(0x44efa466dac8ecc9), U64_C(0xc6eab2a5c80895d6),
+    U64_C(0x803b50c035220cc4), U64_C(0x0321658cba93c138),
+    U64_C(0x8f9ebc465dc7ee1c), U64_C(0xd15a5137190131d3),
+    U64_C(0x0fa5ec8668e5e2d8), U64_C(0x91c979578d1037b1),
+    U64_C(0x0642ca05693b9f70), U64_C(0xefca80168350eb4f),
+    U64_C(0x38d21b24f36a45ec), U64_C(0xbeab81e1af73d658),
+    U64_C(0x8cbfd9cae7542f24), U64_C(0xfd19cc0d81f11102),
+    U64_C(0x0ac6430fbb4dbc90), U64_C(0x1d76a09d6a441895),
+    U64_C(0x2a01573ff1cbbfa1), U64_C(0xb572e161894fde2b),
+    U64_C(0x8124734fa853b827), U64_C(0x614b1fdf43e6b1b0),
+    U64_C(0x68ac395c4238cc18), U64_C(0x21d837bfd7f7b7d2),
+    U64_C(0x20c714304a860331), U64_C(0x5cfaab726324aa14),
+    U64_C(0x74c5ba4eb50d606e), U64_C(0xf3a3030474654739),
+    U64_C(0x23e671bcf015c209), U64_C(0x45f087e947b9582a),
+    U64_C(0xd8bd77b418df4c7b), U64_C(0xe06f6c90ebb50997),
+    U64_C(0x0bd96080263c0873), U64_C(0x7e03f9410e40dcfe),
+    U64_C(0xb8e94be4c6484928), U64_C(0xfb5b0608e8ca8e72),
+    U64_C(0x1a2b49179e0e3306), U64_C(0x4e29e76961855059),
+    U64_C(0x4f36c4e6fcf4e4ba), U64_C(0x49740ee395cf7bca),
+    U64_C(0xc2963ea386d17f7d), U64_C(0x90d65ad810618352),
+    U64_C(0x12d34c1b02a1fa4d), U64_C(0xfa44258775bb3a91),
+    U64_C(0x18150f14b9ec46dd), U64_C(0x1491861e6b9a653d),
+    U64_C(0x9a1019d7ab2c3fc2), U64_C(0x3668d42d06fe13d7),
+    U64_C(0xdcc1fbb25606a6d0), U64_C(0x969490dd795a1c22),
+    U64_C(0x3549b1a1bc6dd2ef), U64_C(0xc94f5e23a0ed770e),
+    U64_C(0xb9f6686b5b39fdcb), U64_C(0xc4d4f4a6efeae00d),
+    U64_C(0xe732851a1fff2204), U64_C(0x94aad6de5eb869f9),
+    U64_C(0x3f8ff2ae07206e7f), U64_C(0xfe38a9813b62d03a),
+    U64_C(0xa7a1ad7a8bee2466), U64_C(0x7b6056c8dde882b6),
+    U64_C(0x302a1e286fc58ca7), U64_C(0x8da0fa457a259bc7),
+    U64_C(0xb3302b64e074415b), U64_C(0x5402ae7eff8b635f),
+    U64_C(0x08f8050c9cafc94b), U64_C(0xae468bf98a3059ce),
+    U64_C(0x88c355cca98dc58f), U64_C(0xb10e6d67c7963480),
+    U64_C(0xbad70de7e1aa3cf3), U64_C(0xbfb4a26e320262bb),
+    U64_C(0xcb711820870f02d5), U64_C(0xce12b7a954a75c9d),
+    U64_C(0x563ce87dd8691684), U64_C(0x9f73b65e7884618a),
+    U64_C(0x2b1e74b06cba0b42), U64_C(0x47cec1ea605b2df1),
+    U64_C(0x1c698312f735ac76), U64_C(0x5fdbcefed9b76b2c),
+    U64_C(0x831a354c8fb1cdfc), U64_C(0x820516c312c0791f),
+    U64_C(0xb74ca762aeadabf0), U64_C(0xfc06ef821c80a5e1),
+    U64_C(0x5723cbf24518a267), U64_C(0x9d4df05d5f661451),
+    U64_C(0x588627742dfd40bf), U64_C(0xda8331b73f3d39a0),
+    U64_C(0x17b0e392d109a405), U64_C(0xf965400bcf28fba9),
+    U64_C(0x7c3dbf4229a2a925), U64_C(0x023e460327e275db),
+    U64_C(0x6cd0b55a0ce126b3), U64_C(0xe62da695828e96e7),
+    U64_C(0x42ad6e63b3f373b9), U64_C(0xe50cc319381d57df),
+    U64_C(0xc5cbd729729b54ee), U64_C(0x46d1e265fd2a9912),
+    U64_C(0x6428b056904eeff8), U64_C(0x8be23040131e04b7),
+    U64_C(0x6709d5da2add2ec0), U64_C(0x075de98af44a2b93),
+    U64_C(0x8447dcc67bfbe66f), U64_C(0x6616f655b7ac9a23),
+    U64_C(0xd607b8bded4b1a40), U64_C(0x0563af89d3a85e48),
+    U64_C(0x3db1b4ad20c21ba4), U64_C(0x11f22997b8323b75),
+    U64_C(0x292032b34b587e99), U64_C(0x7f1cdace9331681d),
+    U64_C(0x8e819fc9c0b65aff), U64_C(0xa1e3677fe2d5bb16),
+    U64_C(0xcd33d225ee349da5), U64_C(0xd9a2543b85aef898),
+    U64_C(0x795e10cbfa0af76d), U64_C(0x25a4bbb9992e5d79),
+    U64_C(0x78413344677b438e), U64_C(0xf0826688cef68601),
+    U64_C(0xd27b34bba392f0eb), U64_C(0x551d8df162fad7bc),
+    U64_C(0x1e57c511d0d7d9ad), U64_C(0xdeffbdb171e4d30b),
+    U64_C(0xf4feea8e802f6caa), U64_C(0xa480c8f6317de55e),
+    U64_C(0xa0fc44f07fa40ff5), U64_C(0x95b5f551c3c9dd1a),
+    U64_C(0x22f952336d6476ea), U64_C(0x0000000000000000),
+    U64_C(0xa6be8ef5169f9085), U64_C(0xcc2cf1aa73452946),
+    U64_C(0x2e7ddb39bf12550a), U64_C(0xd526dd3157d8db78),
+    U64_C(0x486b2d6c08becf29), U64_C(0x9b0f3a58365d8b21),
+    U64_C(0xac78cdfaadd22c15), U64_C(0xbc95c7e28891a383),
+    U64_C(0x6a927f5f65dab9c3), U64_C(0xc3891d2c1ba0cb9e),
+    U64_C(0xeaa92f9f50f8b507), U64_C(0xcf0d9426c9d6e87e),
+    U64_C(0xca6e3baf1a7eb636), U64_C(0xab25247059980786),
+    U64_C(0x69b31ad3df4978fb), U64_C(0xe2512a93cc577c4c),
+    U64_C(0xff278a0ea61364d9), U64_C(0x71a615c766a53e26),
+    U64_C(0x89dc764334fc716c), U64_C(0xf87a638452594f4a),
+    U64_C(0xf2bc208be914f3da), U64_C(0x8766b94ac1682757),
+    U64_C(0xbbc82e687cdb8810), U64_C(0x626a7a53f9757088),
+    U64_C(0xa2c202f358467a2e), U64_C(0x4d0882e5db169161),
+    U64_C(0x09e7268301de7da8), U64_C(0xe897699c771ac0dc),
+    U64_C(0xc8507dac3d9cc3ed), U64_C(0xc0a878a0a1330aa6),
+    U64_C(0x978bb352e42ba8c1), U64_C(0xe9884a13ea6b743f),
+    U64_C(0x279afdbabecc28a2), U64_C(0x047c8c064ed9eaab),
+    U64_C(0x507e2278b15289f4), U64_C(0x599904fbb08cf45c),
+    U64_C(0xbd8ae46d15e01760), U64_C(0x31353da7f2b43844),
+    U64_C(0x8558ff49e68a528c), U64_C(0x76fbfc4d92ef15b5),
+    U64_C(0x3456922e211c660c), U64_C(0x86799ac55c1993b4),
+    U64_C(0x3e90d1219a51da9c), U64_C(0x2d5cbeb505819432),
+    U64_C(0x982e5fd48cce4a19), U64_C(0xdb9c1238a24c8d43),
+    U64_C(0xd439febecaa96f9b), U64_C(0x418c0bef0960b281),
+    U64_C(0x158ea591f6ebd1de), U64_C(0x1f48e69e4da66d4e),
+    U64_C(0x8afd13cf8e6fb054), U64_C(0xf5e1c9011d5ed849),
+    U64_C(0xe34e091c5126c8af), U64_C(0xad67ee7530a398f6),
+    U64_C(0x43b24dec2e82c75a), U64_C(0x75da99c1287cd48d),
+    U64_C(0x92e81cdb3783f689), U64_C(0xa3dd217cc537cecd),
+    U64_C(0x60543c50de970553), U64_C(0x93f73f54aaf2426a),
+    U64_C(0xa91b62737e7a725d), U64_C(0xf19d4507538732e2),
+    U64_C(0x77e4dfc20f9ea156), U64_C(0x7d229ccdb4d31dc6),
+    U64_C(0x1b346a98037f87e5), U64_C(0xedf4c615a4b29e94),
+    U64_C(0x4093286094110662), U64_C(0xb0114ee85ae78063),
+    U64_C(0x6ff1d0d6b672e78b), U64_C(0x6dcf96d591909250),
+    U64_C(0xdfe09e3eec9567e8), U64_C(0x3214582b4827f97c),
+    U64_C(0xb46dc2ee143e6ac8), U64_C(0xf6c0ac8da7cd1971),
+    U64_C(0xebb60c10cd8901e4), U64_C(0xf7df8f023abcad92),
+    U64_C(0x9c52d3d2c217a0b2), U64_C(0x6b8d5cd0f8ab0d20),
+    U64_C(0x3777f7a29b8fa734), U64_C(0x011f238f9d71b4e3),
+    U64_C(0xc1b75b2f3c42be45), U64_C(0x5de588fdfe551ef7),
+    U64_C(0x6eeef3592b035368), U64_C(0xaa3a07ffc4e9b365),
+    U64_C(0xecebe59a39c32a77), U64_C(0x5ba742f8976e8187),
+    U64_C(0x4b4a48e0b22d0e11), U64_C(0xddded83dcb771233),
+    U64_C(0xa59feb79ac0c51bd), U64_C(0xc7f5912a55792135) },
+  /* 5 */
+  { U64_C(0x6d6ae04668a9b08a), U64_C(0x3ab3f04b0be8c743),
+    U64_C(0xe51e166b54b3c908), U64_C(0xbe90a9eb35c2f139),
+    U64_C(0xb2c7066637f2bec1), U64_C(0xaa6945613392202c),
+    U64_C(0x9a28c36f3b5201eb), U64_C(0xddce5a93ab536994),
+    U64_C(0x0e34133ef6382827), U64_C(0x52a02ba1ec55048b),
+    U64_C(0xa2f88f97c4b2a177), U64_C(0x8640e513ca2251a5),
+    U64_C(0xcdf1d36258137622), U64_C(0xfe6cb708dedf8ddb),
+    U64_C(0x8a174a9ec8121e5d), U64_C(0x679896036b81560e),
+    U64_C(0x59ed033395795fee), U64_C(0x1dd778ab8b74edaf),
+    U64_C(0xee533ef92d9f926d), U64_C(0x2a8c79baf8a8d8f5),
+    U64_C(0x6bcf398e69b119f6), U64_C(0xe20491742fafdd95),
+    U64_C(0x276488e0809c2aec), U64_C(0xea955b82d88f5cce),
+    U64_C(0x7102c63a99d9e0c4), U64_C(0xf9763017a5c39946),
+    U64_C(0x429fa2501f151b3d), U64_C(0x4659c72bea05d59e),
+    U64_C(0x984b7fdccf5a6634), U64_C(0xf742232953fbb161),
+    U64_C(0x3041860e08c021c7), U64_C(0x747bfd9616cd9386),
+    U64_C(0x4bb1367192312787), U64_C(0x1b72a1638a6c44d3),
+    U64_C(0x4a0e68a6e8359a66), U64_C(0x169a5039f258b6ca),
+    U64_C(0xb98a2ef44edee5a4), U64_C(0xd9083fe85e43a737),
+    U64_C(0x967f6ce239624e13), U64_C(0x8874f62d3c1a7982),
+    U64_C(0x3c1629830af06e3f), U64_C(0x9165ebfd427e5a8e),
+    U64_C(0xb5dd81794ceeaa5c), U64_C(0x0de8f15a7834f219),
+    U64_C(0x70bd98ede3dd5d25), U64_C(0xaccc9ca9328a8950),
+    U64_C(0x56664eda1945ca28), U64_C(0x221db34c0f8859ae),
+    U64_C(0x26dbd637fa98970d), U64_C(0x1acdffb4f068f932),
+    U64_C(0x4585254f64090fa0), U64_C(0x72de245e17d53afa),
+    U64_C(0x1546b25d7c546cf4), U64_C(0x207e0ffffb803e71),
+    U64_C(0xfaaad2732bcf4378), U64_C(0xb462dfae36ea17bd),
+    U64_C(0xcf926fd1ac1b11fd), U64_C(0xe0672dc7dba7ba4a),
+    U64_C(0xd3fa49ad5d6b41b3), U64_C(0x8ba81449b216a3bc),
+    U64_C(0x14f9ec8a0650d115), U64_C(0x40fc1ee3eb1d7ce2),
+    U64_C(0x23a2ed9b758ce44f), U64_C(0x782c521b14fddc7e),
+    U64_C(0x1c68267cf170504e), U64_C(0xbcf31558c1ca96e6),
+    U64_C(0xa781b43b4ba6d235), U64_C(0xf6fd7dfe29ff0c80),
+    U64_C(0xb0a4bad5c3fad91e), U64_C(0xd199f51ea963266c),
+    U64_C(0x414340349119c103), U64_C(0x5405f269ed4dadf7),
+    U64_C(0xabd61bb649969dcd), U64_C(0x6813dbeae7bdc3c8),
+    U64_C(0x65fb2ab09f8931d1), U64_C(0xf1e7fae152e3181d),
+    U64_C(0xc1a67cef5a2339da), U64_C(0x7a4feea8e0f5bba1),
+    U64_C(0x1e0b9acf05783791), U64_C(0x5b8ebf8061713831),
+    U64_C(0x80e53cdbcb3af8d9), U64_C(0x7e898bd315e57502),
+    U64_C(0xc6bcfbf0213f2d47), U64_C(0x95a38e86b76e942d),
+    U64_C(0x092e94218d243cba), U64_C(0x8339debf453622e7),
+    U64_C(0xb11be402b9fe64ff), U64_C(0x57d9100d634177c9),
+    U64_C(0xcc4e8db52217cbc3), U64_C(0x3b0cae9c71ec7aa2),
+    U64_C(0xfb158ca451cbfe99), U64_C(0x2b33276d82ac6514),
+    U64_C(0x01bf5ed77a04bde1), U64_C(0xc5601994af33f779),
+    U64_C(0x75c4a3416cc92e67), U64_C(0xf3844652a6eb7fc2),
+    U64_C(0x3487e375fdd0ef64), U64_C(0x18ae430704609eed),
+    U64_C(0x4d14efb993298efb), U64_C(0x815a620cb13e4538),
+    U64_C(0x125c354207487869), U64_C(0x9eeea614ce42cf48),
+    U64_C(0xce2d3106d61fac1c), U64_C(0xbbe99247bad6827b),
+    U64_C(0x071a871f7b1c149d), U64_C(0x2e4a1cc10db81656),
+    U64_C(0x77a71ff298c149b8), U64_C(0x06a5d9c80118a97c),
+    U64_C(0xad73c27e488e34b1), U64_C(0x443a7b981e0db241),
+    U64_C(0xe3bbcfa355ab6074), U64_C(0x0af276450328e684),
+    U64_C(0x73617a896dd1871b), U64_C(0x58525de4ef7de20f),
+    U64_C(0xb7be3dcab8e6cd83), U64_C(0x19111dd07e64230c),
+    U64_C(0x842359a03e2a367a), U64_C(0x103f89f1f3401fb6),
+    U64_C(0xdc710444d157d475), U64_C(0xb835702334da5845),
+    U64_C(0x4320fc876511a6dc), U64_C(0xd026abc9d3679b8d),
+    U64_C(0x17250eee885c0b2b), U64_C(0x90dab52a387ae76f),
+    U64_C(0x31fed8d972c49c26), U64_C(0x89cba8fa461ec463),
+    U64_C(0x2ff5421677bcabb7), U64_C(0x396f122f85e41d7d),
+    U64_C(0xa09b332430bac6a8), U64_C(0xc888e8ced7070560),
+    U64_C(0xaeaf201ac682ee8f), U64_C(0x1180d7268944a257),
+    U64_C(0xf058a43628e7a5fc), U64_C(0xbd4c4b8fbbce2b07),
+    U64_C(0xa1246df34abe7b49), U64_C(0x7d5569b79be9af3c),
+    U64_C(0xa9b5a705bd9efa12), U64_C(0xdb6b835baa4bc0e8),
+    U64_C(0x05793bac8f147342), U64_C(0x21c1512881848390),
+    U64_C(0xfdb0556c50d357e5), U64_C(0x613d4fcb6a99ff72),
+    U64_C(0x03dce2648e0cda3e), U64_C(0xe949b9e6568386f0),
+    U64_C(0xfc0f0bbb2ad7ea04), U64_C(0x6a70675913b5a417),
+    U64_C(0x7f36d5046fe1c8e3), U64_C(0x0c57af8d02304ff8),
+    U64_C(0x32223abdfcc84618), U64_C(0x0891caf6f720815b),
+    U64_C(0xa63eeaec31a26fd4), U64_C(0x2507345374944d33),
+    U64_C(0x49d28ac266394058), U64_C(0xf5219f9aa7f3d6be),
+    U64_C(0x2d96fea583b4cc68), U64_C(0x5a31e1571b7585d0),
+    U64_C(0x8ed12fe53d02d0fe), U64_C(0xdfade6205f5b0e4b),
+    U64_C(0x4cabb16ee92d331a), U64_C(0x04c6657bf510cea3),
+    U64_C(0xd73c2cd6a87b8f10), U64_C(0xe1d87310a1a307ab),
+    U64_C(0x6cd5be9112ad0d6b), U64_C(0x97c032354366f3f2),
+    U64_C(0xd4e0ceb22677552e), U64_C(0x0000000000000000),
+    U64_C(0x29509bde76a402cb), U64_C(0xc27a9e8bd42fe3e4),
+    U64_C(0x5ef7842cee654b73), U64_C(0xaf107ecdbc86536e),
+    U64_C(0x3fcacbe784fcb401), U64_C(0xd55f90655c73e8cf),
+    U64_C(0xe6c2f40fdabf1336), U64_C(0xe8f6e7312c873b11),
+    U64_C(0xeb2a0555a28be12f), U64_C(0xe4a148bc2eb774e9),
+    U64_C(0x9b979db84156bc0a), U64_C(0x6eb60222e6a56ab4),
+    U64_C(0x87ffbbc4b026ec44), U64_C(0xc703a5275b3b90a6),
+    U64_C(0x47e699fc9001687f), U64_C(0x9c8d1aa73a4aa897),
+    U64_C(0x7cea3760e1ed12dd), U64_C(0x4ec80ddd1d2554c5),
+    U64_C(0x13e36b957d4cc588), U64_C(0x5d2b66486069914d),
+    U64_C(0x92b90999cc7280b0), U64_C(0x517cc9c56259deb5),
+    U64_C(0xc937b619ad03b881), U64_C(0xec30824ad997f5b2),
+    U64_C(0xa45d565fc5aa080b), U64_C(0xd6837201d27f32f1),
+    U64_C(0x635ef3789e9198ad), U64_C(0x531f75769651b96a),
+    U64_C(0x4f77530a6721e924), U64_C(0x486dd4151c3dfdb9),
+    U64_C(0x5f48dafb9461f692), U64_C(0x375b011173dc355a),
+    U64_C(0x3da9775470f4d3de), U64_C(0x8d0dcd81b30e0ac0),
+    U64_C(0x36e45fc609d888bb), U64_C(0x55baacbe97491016),
+    U64_C(0x8cb29356c90ab721), U64_C(0x76184125e2c5f459),
+    U64_C(0x99f4210bb55edbd5), U64_C(0x6f095cf59ca1d755),
+    U64_C(0x9f51f8c3b44672a9), U64_C(0x3538bda287d45285),
+    U64_C(0x50c39712185d6354), U64_C(0xf23b1885dcefc223),
+    U64_C(0x79930ccc6ef9619f), U64_C(0xed8fdc9da3934853),
+    U64_C(0xcb540aaa590bdf5e), U64_C(0x5c94389f1a6d2cac),
+    U64_C(0xe77daad8a0bbaed7), U64_C(0x28efc5090ca0bf2a),
+    U64_C(0xbf2ff73c4fc64cd8), U64_C(0xb37858b14df60320),
+    U64_C(0xf8c96ec0dfc724a7), U64_C(0x828680683f329f06),
+    U64_C(0x941cd051cd6a29cc), U64_C(0xc3c5c05cae2b5e05),
+    U64_C(0xb601631dc2e27062), U64_C(0xc01922382027843b),
+    U64_C(0x24b86a840e90f0d2), U64_C(0xd245177a276ffc52),
+    U64_C(0x0f8b4de98c3c95c6), U64_C(0x3e759530fef809e0),
+    U64_C(0x0b4d2892792c5b65), U64_C(0xc4df4743d5374a98),
+    U64_C(0xa5e20888bfaeb5ea), U64_C(0xba56cc90c0d23f9a),
+    U64_C(0x38d04cf8ffe0a09c), U64_C(0x62e1adafe495254c),
+    U64_C(0x0263bcb3f40867df), U64_C(0xcaeb547d230f62bf),
+    U64_C(0x6082111c109d4293), U64_C(0xdad4dd8cd04f7d09),
+    U64_C(0xefec602e579b2f8c), U64_C(0x1fb4c4187f7c8a70),
+    U64_C(0xffd3e9dfa4db303a), U64_C(0x7bf0b07f9af10640),
+    U64_C(0xf49ec14dddf76b5f), U64_C(0x8f6e713247066d1f),
+    U64_C(0x339d646a86ccfbf9), U64_C(0x64447467e58d8c30),
+    U64_C(0x2c29a072f9b07189), U64_C(0xd8b7613f24471ad6),
+    U64_C(0x6627c8d41185ebef), U64_C(0xa347d140beb61c96),
+    U64_C(0xde12b8f7255fb3aa), U64_C(0x9d324470404e1576),
+    U64_C(0x9306574eb6763d51), U64_C(0xa80af9d2c79a47f3),
+    U64_C(0x859c0777442e8b9b), U64_C(0x69ac853d9db97e29) },
+  /* 6 */
+  { U64_C(0xc3407dfc2de6377e), U64_C(0x5b9e93eea4256f77),
+    U64_C(0xadb58fdd50c845e0), U64_C(0x5219ff11a75bed86),
+    U64_C(0x356b61cfd90b1de9), U64_C(0xfb8f406e25abe037),
+    U64_C(0x7a5a0231c0f60796), U64_C(0x9d3cd216e1f5020b),
+    U64_C(0x0c6550fb6b48d8f3), U64_C(0xf57508c427ff1c62),
+    U64_C(0x4ad35ffa71cb407d), U64_C(0x6290a2da1666aa6d),
+    U64_C(0xe284ec2349355f9f), U64_C(0xb3c307c53d7c84ec),
+    U64_C(0x05e23c0468365a02), U64_C(0x190bac4d6c9ebfa8),
+    U64_C(0x94bbbee9e28b80fa), U64_C(0xa34fc777529cb9b5),
+    U64_C(0xcc7b39f095bcd978), U64_C(0x2426addb0ce532e3),
+    U64_C(0x7e79329312ce4fc7), U64_C(0xab09a72eebec2917),
+    U64_C(0xf8d15499f6b9d6c2), U64_C(0x1a55b8babf8c895d),
+    U64_C(0xdb8add17fb769a85), U64_C(0xb57f2f368658e81b),
+    U64_C(0x8acd36f18f3f41f6), U64_C(0x5ce3b7bba50f11d3),
+    U64_C(0x114dcc14d5ee2f0a), U64_C(0xb91a7fcded1030e8),
+    U64_C(0x81d5425fe55de7a1), U64_C(0xb6213bc1554adeee),
+    U64_C(0x80144ef95f53f5f2), U64_C(0x1e7688186db4c10c),
+    U64_C(0x3b912965db5fe1bc), U64_C(0xc281715a97e8252d),
+    U64_C(0x54a5d7e21c7f8171), U64_C(0x4b12535ccbc5522e),
+    U64_C(0x1d289cefbea6f7f9), U64_C(0x6ef5f2217d2e729e),
+    U64_C(0xe6a7dc819b0d17ce), U64_C(0x1b94b41c05829b0e),
+    U64_C(0x33d7493c622f711e), U64_C(0xdcf7f942fa5ce421),
+    U64_C(0x600fba8b7f7a8ecb), U64_C(0x46b60f011a83988e),
+    U64_C(0x235b898e0dcf4c47), U64_C(0x957ab24f588592a9),
+    U64_C(0x4354330572b5c28c), U64_C(0xa5f3ef84e9b8d542),
+    U64_C(0x8c711e02341b2d01), U64_C(0x0b1874ae6a62a657),
+    U64_C(0x1213d8e306fc19ff), U64_C(0xfe6d7c6a4d9dba35),
+    U64_C(0x65ed868f174cd4c9), U64_C(0x88522ea0e6236550),
+    U64_C(0x899322065c2d7703), U64_C(0xc01e690bfef4018b),
+    U64_C(0x915982ed8abddaf8), U64_C(0xbe675b98ec3a4e4c),
+    U64_C(0xa996bf7f82f00db1), U64_C(0xe1daf8d49a27696a),
+    U64_C(0x2effd5d3dc8986e7), U64_C(0xd153a51f2b1a2e81),
+    U64_C(0x18caa0ebd690adfb), U64_C(0x390e3134b243c51a),
+    U64_C(0x2778b92cdff70416), U64_C(0x029f1851691c24a6),
+    U64_C(0x5e7cafeacc133575), U64_C(0xfa4e4cc89fa5f264),
+    U64_C(0x5a5f9f481e2b7d24), U64_C(0x484c47ab18d764db),
+    U64_C(0x400a27f2a1a7f479), U64_C(0xaeeb9b2a83da7315),
+    U64_C(0x721c626879869734), U64_C(0x042330a2d2384851),
+    U64_C(0x85f672fd3765aff0), U64_C(0xba446b3a3e02061d),
+    U64_C(0x73dd6ecec3888567), U64_C(0xffac70ccf793a866),
+    U64_C(0xdfa9edb5294ed2d4), U64_C(0x6c6aea7014325638),
+    U64_C(0x834a5a0e8c41c307), U64_C(0xcdba35562fb2cb2b),
+    U64_C(0x0ad97808d06cb404), U64_C(0x0f3b440cb85aee06),
+    U64_C(0xe5f9c876481f213b), U64_C(0x98deee1289c35809),
+    U64_C(0x59018bbfcd394bd1), U64_C(0xe01bf47220297b39),
+    U64_C(0xde68e1139340c087), U64_C(0x9fa3ca4788e926ad),
+    U64_C(0xbb85679c840c144e), U64_C(0x53d8f3b71d55ffd5),
+    U64_C(0x0da45c5dd146caa0), U64_C(0x6f34fe87c72060cd),
+    U64_C(0x57fbc315cf6db784), U64_C(0xcee421a1fca0fdde),
+    U64_C(0x3d2d0196607b8d4b), U64_C(0x642c8a29ad42c69a),
+    U64_C(0x14aff010bdd87508), U64_C(0xac74837beac657b3),
+    U64_C(0x3216459ad821634d), U64_C(0x3fb219c70967a9ed),
+    U64_C(0x06bc28f3bb246cf7), U64_C(0xf2082c9126d562c6),
+    U64_C(0x66b39278c45ee23c), U64_C(0xbd394f6f3f2878b9),
+    U64_C(0xfd33689d9e8f8cc0), U64_C(0x37f4799eb017394f),
+    U64_C(0x108cc0b26fe03d59), U64_C(0xda4bd1b1417888d6),
+    U64_C(0xb09d1332ee6eb219), U64_C(0x2f3ed975668794b4),
+    U64_C(0x58c0871977375982), U64_C(0x7561463d78ace990),
+    U64_C(0x09876cff037e82f1), U64_C(0x7fb83e35a8c05d94),
+    U64_C(0x26b9b58a65f91645), U64_C(0xef20b07e9873953f),
+    U64_C(0x3148516d0b3355b8), U64_C(0x41cb2b541ba9e62a),
+    U64_C(0x790416c613e43163), U64_C(0xa011d380818e8f40),
+    U64_C(0x3a5025c36151f3ef), U64_C(0xd57095bdf92266d0),
+    U64_C(0x498d4b0da2d97688), U64_C(0x8b0c3a57353153a5),
+    U64_C(0x21c491df64d368e1), U64_C(0x8f2f0af5e7091bf4),
+    U64_C(0x2da1c1240f9bb012), U64_C(0xc43d59a92ccc49da),
+    U64_C(0xbfa6573e56345c1f), U64_C(0x828b56a8364fd154),
+    U64_C(0x9a41f643e0df7caf), U64_C(0xbcf843c985266aea),
+    U64_C(0x2b1de9d7b4bfdce5), U64_C(0x20059d79dedd7ab2),
+    U64_C(0x6dabe6d6ae3c446b), U64_C(0x45e81bf6c991ae7b),
+    U64_C(0x6351ae7cac68b83e), U64_C(0xa432e32253b6c711),
+    U64_C(0xd092a9b991143cd2), U64_C(0xcac711032e98b58f),
+    U64_C(0xd8d4c9e02864ac70), U64_C(0xc5fc550f96c25b89),
+    U64_C(0xd7ef8dec903e4276), U64_C(0x67729ede7e50f06f),
+    U64_C(0xeac28c7af045cf3d), U64_C(0xb15c1f945460a04a),
+    U64_C(0x9cfddeb05bfb1058), U64_C(0x93c69abce3a1fe5e),
+    U64_C(0xeb0380dc4a4bdd6e), U64_C(0xd20db1e8f8081874),
+    U64_C(0x229a8528b7c15e14), U64_C(0x44291750739fbc28),
+    U64_C(0xd3ccbd4e42060a27), U64_C(0xf62b1c33f4ed2a97),
+    U64_C(0x86a8660ae4779905), U64_C(0xd62e814a2a305025),
+    U64_C(0x477703a7a08d8add), U64_C(0x7b9b0e977af815c5),
+    U64_C(0x78c51a60a9ea2330), U64_C(0xa6adfb733aaae3b7),
+    U64_C(0x97e5aa1e3199b60f), U64_C(0x0000000000000000),
+    U64_C(0xf4b404629df10e31), U64_C(0x5564db44a6719322),
+    U64_C(0x9207961a59afec0d), U64_C(0x9624a6b88b97a45c),
+    U64_C(0x363575380a192b1c), U64_C(0x2c60cd82b595a241),
+    U64_C(0x7d272664c1dc7932), U64_C(0x7142769faa94a1c1),
+    U64_C(0xa1d0df263b809d13), U64_C(0x1630e841d4c451ae),
+    U64_C(0xc1df65ad44fa13d8), U64_C(0x13d2d445bcf20bac),
+    U64_C(0xd915c546926abe23), U64_C(0x38cf3d92084dd749),
+    U64_C(0xe766d0272103059d), U64_C(0xc7634d5effde7f2f),
+    U64_C(0x077d2455012a7ea4), U64_C(0xedbfa82ff16fb199),
+    U64_C(0xaf2a978c39d46146), U64_C(0x42953fa3c8bbd0df),
+    U64_C(0xcb061da59496a7dc), U64_C(0x25e7a17db6eb20b0),
+    U64_C(0x34aa6d6963050fba), U64_C(0xa76cf7d580a4f1e4),
+    U64_C(0xf7ea10954ee338c4), U64_C(0xfcf2643b24819e93),
+    U64_C(0xcf252d0746aeef8d), U64_C(0x4ef06f58a3f3082c),
+    U64_C(0x563acfb37563a5d7), U64_C(0x5086e740ce47c920),
+    U64_C(0x2982f186dda3f843), U64_C(0x87696aac5e798b56),
+    U64_C(0x5d22bb1d1f010380), U64_C(0x035e14f7d31236f5),
+    U64_C(0x3cec0d30da759f18), U64_C(0xf3c920379cdb7095),
+    U64_C(0xb8db736b571e22bb), U64_C(0xdd36f5e44052f672),
+    U64_C(0xaac8ab8851e23b44), U64_C(0xa857b3d938fe1fe2),
+    U64_C(0x17f1e4e76eca43fd), U64_C(0xec7ea4894b61a3ca),
+    U64_C(0x9e62c6e132e734fe), U64_C(0xd4b1991b432c7483),
+    U64_C(0x6ad6c283af163acf), U64_C(0x1ce9904904a8e5aa),
+    U64_C(0x5fbda34c761d2726), U64_C(0xf910583f4cb7c491),
+    U64_C(0xc6a241f845d06d7c), U64_C(0x4f3163fe19fd1a7f),
+    U64_C(0xe99c988d2357f9c8), U64_C(0x8eee06535d0709a7),
+    U64_C(0x0efa48aa0254fc55), U64_C(0xb4be23903c56fa48),
+    U64_C(0x763f52caabbedf65), U64_C(0xeee1bcd8227d876c),
+    U64_C(0xe345e085f33b4dcc), U64_C(0x3e731561b369bbbe),
+    U64_C(0x2843fd2067adea10), U64_C(0x2adce5710eb1ceb6),
+    U64_C(0xb7e03767ef44ccbd), U64_C(0x8db012a48e153f52),
+    U64_C(0x61ceb62dc5749c98), U64_C(0xe85d942b9959eb9b),
+    U64_C(0x4c6f7709caef2c8a), U64_C(0x84377e5b8d6bbda3),
+    U64_C(0x30895dcbb13d47eb), U64_C(0x74a04a9bc2a2fbc3),
+    U64_C(0x6b17ce251518289c), U64_C(0xe438c4d0f2113368),
+    U64_C(0x1fb784bed7bad35f), U64_C(0x9b80fae55ad16efc),
+    U64_C(0x77fe5e6c11b0cd36), U64_C(0xc858095247849129),
+    U64_C(0x08466059b97090a2), U64_C(0x01c10ca6ba0e1253),
+    U64_C(0x6988d6747c040c3a), U64_C(0x6849dad2c60a1e69),
+    U64_C(0x5147ebe67449db73), U64_C(0xc99905f4fd8a837a),
+    U64_C(0x991fe2b433cd4a5a), U64_C(0xf09734c04fc94660),
+    U64_C(0xa28ecbd1e892abe6), U64_C(0xf1563866f5c75433),
+    U64_C(0x4dae7baf70e13ed9), U64_C(0x7ce62ac27bd26b61),
+    U64_C(0x70837a39109ab392), U64_C(0x90988e4b30b3c8ab),
+    U64_C(0xb2020b63877296bf), U64_C(0x156efcb607d6675b) },
+  /* 7 */
+  { U64_C(0xe63f55ce97c331d0), U64_C(0x25b506b0015bba16),
+    U64_C(0xc8706e29e6ad9ba8), U64_C(0x5b43d3775d521f6a),
+    U64_C(0x0bfa3d577035106e), U64_C(0xab95fc172afb0e66),
+    U64_C(0xf64b63979e7a3276), U64_C(0xf58b4562649dad4b),
+    U64_C(0x48f7c3dbae0c83f1), U64_C(0xff31916642f5c8c5),
+    U64_C(0xcbb048dc1c4a0495), U64_C(0x66b8f83cdf622989),
+    U64_C(0x35c130e908e2b9b0), U64_C(0x7c761a61f0b34fa1),
+    U64_C(0x3601161cf205268d), U64_C(0x9e54ccfe2219b7d6),
+    U64_C(0x8b7d90a538940837), U64_C(0x9cd403588ea35d0b),
+    U64_C(0xbc3c6fea9ccc5b5a), U64_C(0xe5ff733b6d24aeed),
+    U64_C(0xceed22de0f7eb8d2), U64_C(0xec8581cab1ab545e),
+    U64_C(0xb96105e88ff8e71d), U64_C(0x8ca03501871a5ead),
+    U64_C(0x76ccce65d6db2a2f), U64_C(0x5883f582a7b58057),
+    U64_C(0x3f7be4ed2e8adc3e), U64_C(0x0fe7be06355cd9c9),
+    U64_C(0xee054e6c1d11be83), U64_C(0x1074365909b903a6),
+    U64_C(0x5dde9f80b4813c10), U64_C(0x4a770c7d02b6692c),
+    U64_C(0x5379c8d5d7809039), U64_C(0xb4067448161ed409),
+    U64_C(0x5f5e5026183bd6cd), U64_C(0xe898029bf4c29df9),
+    U64_C(0x7fb63c940a54d09c), U64_C(0xc5171f897f4ba8bc),
+    U64_C(0xa6f28db7b31d3d72), U64_C(0x2e4f3be7716eaa78),
+    U64_C(0x0d6771a099e63314), U64_C(0x82076254e41bf284),
+    U64_C(0x2f0fd2b42733df98), U64_C(0x5c9e76d3e2dc49f0),
+    U64_C(0x7aeb569619606cdb), U64_C(0x83478b07b2468764),
+    U64_C(0xcfadcb8d5923cd32), U64_C(0x85dac7f05b95a41e),
+    U64_C(0xb5469d1b4043a1e9), U64_C(0xb821ecbbd9a592fd),
+    U64_C(0x1b8e0b0e798c13c8), U64_C(0x62a57b6d9a0be02e),
+    U64_C(0xfcf1b793b81257f8), U64_C(0x9d94ea0bd8fe28eb),
+    U64_C(0x4cea408aeb654a56), U64_C(0x23284a47e888996c),
+    U64_C(0x2d8f1d128b893545), U64_C(0xf4cbac3132c0d8ab),
+    U64_C(0xbd7c86b9ca912eba), U64_C(0x3a268eef3dbe6079),
+    U64_C(0xf0d62f6077a9110c), U64_C(0x2735c916ade150cb),
+    U64_C(0x89fd5f03942ee2ea), U64_C(0x1acee25d2fd16628),
+    U64_C(0x90f39bab41181bff), U64_C(0x430dfe8cde39939f),
+    U64_C(0xf70b8ac4c8274796), U64_C(0x1c53aeaac6024552),
+    U64_C(0x13b410acf35e9c9b), U64_C(0xa532ab4249faa24f),
+    U64_C(0x2b1251e5625a163f), U64_C(0xd7e3e676da4841c7),
+    U64_C(0xa7b264e4e5404892), U64_C(0xda8497d643ae72d3),
+    U64_C(0x861ae105a1723b23), U64_C(0x38a6414991048aa4),
+    U64_C(0x6578dec92585b6b4), U64_C(0x0280cfa6acbaeadd),
+    U64_C(0x88bdb650c273970a), U64_C(0x9333bd5ebbff84c2),
+    U64_C(0x4e6a8f2c47dfa08b), U64_C(0x321c954db76cef2a),
+    U64_C(0x418d312a72837942), U64_C(0xb29b38bfffcdf773),
+    U64_C(0x6c022c38f90a4c07), U64_C(0x5a033a240b0f6a8a),
+    U64_C(0x1f93885f3ce5da6f), U64_C(0xc38a537e96988bc6),
+    U64_C(0x39e6a81ac759ff44), U64_C(0x29929e43cee0fce2),
+    U64_C(0x40cdd87924de0ca2), U64_C(0xe9d8ebc8a29fe819),
+    U64_C(0x0c2798f3cfbb46f4), U64_C(0x55e484223e53b343),
+    U64_C(0x4650948ecd0d2fd8), U64_C(0x20e86cb2126f0651),
+    U64_C(0x6d42c56baf5739e7), U64_C(0xa06fc1405ace1e08),
+    U64_C(0x7babbfc54f3d193b), U64_C(0x424d17df8864e67f),
+    U64_C(0xd8045870ef14980e), U64_C(0xc6d7397c85ac3781),
+    U64_C(0x21a885e1443273b1), U64_C(0x67f8116f893f5c69),
+    U64_C(0x24f5efe35706cff6), U64_C(0xd56329d076f2ab1a),
+    U64_C(0x5e1eb9754e66a32d), U64_C(0x28d2771098bd8902),
+    U64_C(0x8f6013f47dfdc190), U64_C(0x17a993fdb637553c),
+    U64_C(0xe0a219397e1012aa), U64_C(0x786b9930b5da8606),
+    U64_C(0x6e82e39e55b0a6da), U64_C(0x875a0856f72f4ec3),
+    U64_C(0x3741ff4fa458536d), U64_C(0xac4859b3957558fc),
+    U64_C(0x7ef6d5c75c09a57c), U64_C(0xc04a758b6c7f14fb),
+    U64_C(0xf9acdd91ab26ebbf), U64_C(0x7391a467c5ef9668),
+    U64_C(0x335c7c1ee1319aca), U64_C(0xa91533b18641e4bb),
+    U64_C(0xe4bf9a683b79db0d), U64_C(0x8e20faa72ba0b470),
+    U64_C(0x51f907737b3a7ae4), U64_C(0x2268a314bed5ec8c),
+    U64_C(0xd944b123b949edee), U64_C(0x31dcb3b84d8b7017),
+    U64_C(0xd3fe65279f218860), U64_C(0x097af2f1dc8ffab3),
+    U64_C(0x9b09a6fc312d0b91), U64_C(0xcc6ded78a3c4520f),
+    U64_C(0x3481d9ba5ebfcc50), U64_C(0x4f2a667f1182d56b),
+    U64_C(0xdfd9fdd4509ace94), U64_C(0x26752045fbbc252b),
+    U64_C(0xbffc491f662bc467), U64_C(0xdd593272fc202449),
+    U64_C(0x3cbbc218d46d4303), U64_C(0x91b372f817456e1f),
+    U64_C(0x681faf69bc6385a0), U64_C(0xb686bbeebaa43ed4),
+    U64_C(0x1469b5084cd0ca01), U64_C(0x98c98009cbca94ac),
+    U64_C(0x6438379a73d8c354), U64_C(0xc2caba2dc0c5fe26),
+    U64_C(0x3e3b0dbe78d7a9de), U64_C(0x50b9ee202d670f04),
+    U64_C(0x4590b27b37eab0e5), U64_C(0x6025b4cb36b10af3),
+    U64_C(0xfb2c1237079c0162), U64_C(0xa12f28130c936be8),
+    U64_C(0x4b37e52e54eb1ccc), U64_C(0x083a1ba28ad28f53),
+    U64_C(0xc10a9cd83a22611b), U64_C(0x9f1425ad7444c236),
+    U64_C(0x069d4cf7e9d3237a), U64_C(0xedc56899e7f621be),
+    U64_C(0x778c273680865fcf), U64_C(0x309c5aeb1bd605f7),
+    U64_C(0x8de0dc52d1472b4d), U64_C(0xf8ec34c2fd7b9e5f),
+    U64_C(0xea18cd3d58787724), U64_C(0xaad515447ca67b86),
+    U64_C(0x9989695a9d97e14c), U64_C(0x0000000000000000),
+    U64_C(0xf196c63321f464ec), U64_C(0x71116bc169557cb5),
+    U64_C(0xaf887f466f92c7c1), U64_C(0x972e3e0ffe964d65),
+    U64_C(0x190ec4a8d536f915), U64_C(0x95aef1a9522ca7b8),
+    U64_C(0xdc19db21aa7d51a9), U64_C(0x94ee18fa0471d258),
+    U64_C(0x8087adf248a11859), U64_C(0xc457f6da2916dd5c),
+    U64_C(0xfa6cfb6451c17482), U64_C(0xf256e0c6db13fbd1),
+    U64_C(0x6a9f60cf10d96f7d), U64_C(0x4daaa9d9bd383fb6),
+    U64_C(0x03c026f5fae79f3d), U64_C(0xde99148706c7bb74),
+    U64_C(0x2a52b8b6340763df), U64_C(0x6fc20acd03edd33a),
+    U64_C(0xd423c08320afdefa), U64_C(0xbbe1ca4e23420dc0),
+    U64_C(0x966ed75ca8cb3885), U64_C(0xeb58246e0e2502c4),
+    U64_C(0x055d6a021334bc47), U64_C(0xa47242111fa7d7af),
+    U64_C(0xe3623fcc84f78d97), U64_C(0x81c744a11efc6db9),
+    U64_C(0xaec8961539cfb221), U64_C(0xf31609958d4e8e31),
+    U64_C(0x63e5923ecc5695ce), U64_C(0x47107ddd9b505a38),
+    U64_C(0xa3afe7b5a0298135), U64_C(0x792b7063e387f3e6),
+    U64_C(0x0140e953565d75e0), U64_C(0x12f4f9ffa503e97b),
+    U64_C(0x750ce8902c3cb512), U64_C(0xdbc47e8515f30733),
+    U64_C(0x1ed3610c6ab8af8f), U64_C(0x5239218681dde5d9),
+    U64_C(0xe222d69fd2aaf877), U64_C(0xfe71783514a8bd25),
+    U64_C(0xcaf0a18f4a177175), U64_C(0x61655d9860ec7f13),
+    U64_C(0xe77fbc9dc19e4430), U64_C(0x2ccff441ddd440a5),
+    U64_C(0x16e97aaee06a20dc), U64_C(0xa855dae2d01c915b),
+    U64_C(0x1d1347f9905f30b2), U64_C(0xb7c652bdecf94b34),
+    U64_C(0xd03e43d265c6175d), U64_C(0xfdb15ec0ee4f2218),
+    U64_C(0x57644b8492e9599e), U64_C(0x07dda5a4bf8e569a),
+    U64_C(0x54a46d71680ec6a3), U64_C(0x5624a2d7c4b42c7e),
+    U64_C(0xbebca04c3076b187), U64_C(0x7d36f332a6ee3a41),
+    U64_C(0x3b6667bc6be31599), U64_C(0x695f463aea3ef040),
+    U64_C(0xad08b0e0c3282d1c), U64_C(0xb15b1e4a052a684e),
+    U64_C(0x44d05b2861b7c505), U64_C(0x15295c5b1a8dbfe1),
+    U64_C(0x744c01c37a61c0f2), U64_C(0x59c31cd1f1e8f5b7),
+    U64_C(0xef45a73f4b4ccb63), U64_C(0x6bdf899c46841a9d),
+    U64_C(0x3dfb2b4b823036e3), U64_C(0xa2ef0ee6f674f4d5),
+    U64_C(0x184e2dfb836b8cf5), U64_C(0x1134df0a5fe47646),
+    U64_C(0xbaa1231d751f7820), U64_C(0xd17eaa81339b62bd),
+    U64_C(0xb01bf71953771dae), U64_C(0x849a2ea30dc8d1fe),
+    U64_C(0x705182923f080955), U64_C(0x0ea757556301ac29),
+    U64_C(0x041d83514569c9a7), U64_C(0x0abad4042668658e),
+    U64_C(0x49b72a88f851f611), U64_C(0x8a3d79f66ec97dd7),
+    U64_C(0xcd2d042bf59927ef), U64_C(0xc930877ab0f0ee48),
+    U64_C(0x9273540deda2f122), U64_C(0xc797d02fd3f14261),
+    U64_C(0xe1e2f06a284d674a), U64_C(0xd2be8c74c97cfd80),
+    U64_C(0x9a494faf67707e71), U64_C(0xb3dbd1eca9908293),
+    U64_C(0x72d14d3493b2e388), U64_C(0xd6a30f258c153427) },
+};
+
+static const u64 C16[13][16] =
+{
+  { U64_C(0xdd806559f2a64507), U64_C(0x05767436cc744d23),
+    U64_C(0xa2422a08a460d315), U64_C(0x4b7ce09192676901),
+    U64_C(0x714eb88d7585c4fc), U64_C(0x2f6a76432e45d016),
+    U64_C(0xebcb2f81c0657c1f), U64_C(0xb1085bda1ecadae9) },
+  { U64_C(0xe679047021b19bb7), U64_C(0x55dda21bd7cbcd56),
+    U64_C(0x5cb561c2db0aa7ca), U64_C(0x9ab5176b12d69958),
+    U64_C(0x61d55e0f16b50131), U64_C(0xf3feea720a232b98),
+    U64_C(0x4fe39d460f70b5d7), U64_C(0x6fa3b58aa99d2f1a) },
+  { U64_C(0x991e96f50aba0ab2), U64_C(0xc2b6f443867adb31),
+    U64_C(0xc1c93a376062db09), U64_C(0xd3e20fe490359eb1),
+    U64_C(0xf2ea7514b1297b7b), U64_C(0x06f15e5f529c1f8b),
+    U64_C(0x0a39fc286a3d8435), U64_C(0xf574dcac2bce2fc7) },
+  { U64_C(0x220cbebc84e3d12e), U64_C(0x3453eaa193e837f1),
+    U64_C(0xd8b71333935203be), U64_C(0xa9d72c82ed03d675),
+    U64_C(0x9d721cad685e353f), U64_C(0x488e857e335c3c7d),
+    U64_C(0xf948e1a05d71e4dd), U64_C(0xef1fdfb3e81566d2) },
+  { U64_C(0x601758fd7c6cfe57), U64_C(0x7a56a27ea9ea63f5),
+    U64_C(0xdfff00b723271a16), U64_C(0xbfcd1747253af5a3),
+    U64_C(0x359e35d7800fffbd), U64_C(0x7f151c1f1686104a),
+    U64_C(0x9a3f410c6ca92363), U64_C(0x4bea6bacad474799) },
+  { U64_C(0xfa68407a46647d6e), U64_C(0xbf71c57236904f35),
+    U64_C(0x0af21f66c2bec6b6), U64_C(0xcffaa6b71c9ab7b4),
+    U64_C(0x187f9ab49af08ec6), U64_C(0x2d66c4f95142a46c),
+    U64_C(0x6fa4c33b7a3039c0), U64_C(0xae4faeae1d3ad3d9) },
+  { U64_C(0x8886564d3a14d493), U64_C(0x3517454ca23c4af3),
+    U64_C(0x06476983284a0504), U64_C(0x0992abc52d822c37),
+    U64_C(0xd3473e33197a93c9), U64_C(0x399ec6c7e6bf87c9),
+    U64_C(0x51ac86febf240954), U64_C(0xf4c70e16eeaac5ec) },
+  { U64_C(0xa47f0dd4bf02e71e), U64_C(0x36acc2355951a8d9),
+    U64_C(0x69d18d2bd1a5c42f), U64_C(0xf4892bcb929b0690),
+    U64_C(0x89b4443b4ddbc49a), U64_C(0x4eb7f8719c36de1e),
+    U64_C(0x03e7aa020c6e4141), U64_C(0x9b1f5b424d93c9a7) },
+  { U64_C(0x7261445183235adb), U64_C(0x0e38dc92cb1f2a60),
+    U64_C(0x7b2b8a9aa6079c54), U64_C(0x800a440bdbb2ceb1),
+    U64_C(0x3cd955b7e00d0984), U64_C(0x3a7d3a1b25894224),
+    U64_C(0x944c9ad8ec165fde), U64_C(0x378f5a541631229b) },
+  { U64_C(0x74b4c7fb98459ced), U64_C(0x3698fad1153bb6c3),
+    U64_C(0x7a1e6c303b7652f4), U64_C(0x9fe76702af69334b),
+    U64_C(0x1fffe18a1b336103), U64_C(0x8941e71cff8a78db),
+    U64_C(0x382ae548b2e4f3f3), U64_C(0xabbedea680056f52) },
+  { U64_C(0x6bcaa4cd81f32d1b), U64_C(0xdea2594ac06fd85d),
+    U64_C(0xefbacd1d7d476e98), U64_C(0x8a1d71efea48b9ca),
+    U64_C(0x2001802114846679), U64_C(0xd8fa6bbbebab0761),
+    U64_C(0x3002c6cd635afe94), U64_C(0x7bcd9ed0efc889fb) },
+  { U64_C(0x48bc924af11bd720), U64_C(0xfaf417d5d9b21b99),
+    U64_C(0xe71da4aa88e12852), U64_C(0x5d80ef9d1891cc86),
+    U64_C(0xf82012d430219f9b), U64_C(0xcda43c32bcdf1d77),
+    U64_C(0xd21380b00449b17a), U64_C(0x378ee767f11631ba) },
+};
+
+
+#define strido(out, temp, i) do { \
+       u64 t; \
+       t  = stribog_table[0][(temp[0] >> (i * 8)) & 0xff]; \
+       t ^= stribog_table[1][(temp[1] >> (i * 8)) & 0xff]; \
+       t ^= stribog_table[2][(temp[2] >> (i * 8)) & 0xff]; \
+       t ^= stribog_table[3][(temp[3] >> (i * 8)) & 0xff]; \
+       t ^= stribog_table[4][(temp[4] >> (i * 8)) & 0xff]; \
+       t ^= stribog_table[5][(temp[5] >> (i * 8)) & 0xff]; \
+       t ^= stribog_table[6][(temp[6] >> (i * 8)) & 0xff]; \
+       t ^= stribog_table[7][(temp[7] >> (i * 8)) & 0xff]; \
+       out[i] = t; } while(0)
+
+static void LPSX (u64 *out, const u64 *a, const u64 *b)
+{
+  u64 temp[8];
+  temp[0] = a[0] ^ b[0];
+  temp[1] = a[1] ^ b[1];
+  temp[2] = a[2] ^ b[2];
+  temp[3] = a[3] ^ b[3];
+  temp[4] = a[4] ^ b[4];
+  temp[5] = a[5] ^ b[5];
+  temp[6] = a[6] ^ b[6];
+  temp[7] = a[7] ^ b[7];
+  strido (out, temp, 0);
+  strido (out, temp, 1);
+  strido (out, temp, 2);
+  strido (out, temp, 3);
+  strido (out, temp, 4);
+  strido (out, temp, 5);
+  strido (out, temp, 6);
+  strido (out, temp, 7);
+}
+
+static inline void g (u64 *h, u64 *m, u64 *N)
+{
+  u64 K[8];
+  u64 T[8];
+  int i;
+
+  LPSX (K, h, N);
+
+  LPSX (T, K, m);
+  LPSX (K, K, C16[0]);
+  for (i = 1; i < 12; i++)
+    {
+      LPSX (T, K, T);
+      LPSX (K, K, C16[i]);
+    }
+
+  h[0] ^= T[0] ^ K[0] ^ m[0];
+  h[1] ^= T[1] ^ K[1] ^ m[1];
+  h[2] ^= T[2] ^ K[2] ^ m[2];
+  h[3] ^= T[3] ^ K[3] ^ m[3];
+  h[4] ^= T[4] ^ K[4] ^ m[4];
+  h[5] ^= T[5] ^ K[5] ^ m[5];
+  h[6] ^= T[6] ^ K[6] ^ m[6];
+  h[7] ^= T[7] ^ K[7] ^ m[7];
+}
+
+
+static unsigned int
+transform64 (void *context, const unsigned char *inbuf_arg);
+
+
+static void
+stribog_init_512 (void *context, unsigned int flags)
+{
+  STRIBOG_CONTEXT *hd = context;
+
+  (void)flags;
+
+  memset (hd, 0, sizeof (*hd));
+
+  hd->bctx.blocksize = 64;
+  hd->bctx.bwrite = transform64;
+}
+
+static void
+stribog_init_256 (void *context, unsigned int flags)
+{
+  STRIBOG_CONTEXT *hd = context;
+
+  stribog_init_512 (context, flags);
+  memset (hd->h, 1, 64);
+}
+
+static void
+transform (STRIBOG_CONTEXT *hd, const unsigned char *data, unsigned count)
+{
+  u64 M[8];
+  u64 l;
+  int i;
+
+  for (i = 0; i < 8; i++)
+    M[i] = buf_get_le64(data + i * 8);
+
+  g (hd->h, M, hd->N);
+  l = hd->N[0];
+  hd->N[0] += count;
+  if (hd->N[0] < l)
+    { /* overflow */
+      for (i = 1; i < 8; i++)
+        {
+          hd->N[i]++;
+          if (hd->N[i] != 0)
+            break;
+        }
+    }
+
+  hd->Sigma[0] += M[0];
+  for (i = 1; i < 8; i++)
+    if (hd->Sigma[i-1] < M[i-1])
+      hd->Sigma[i] += M[i] + 1;
+    else
+      hd->Sigma[i] += M[i];
+}
+
+static unsigned int
+transform64 (void *context, const unsigned char *inbuf_arg)
+{
+  STRIBOG_CONTEXT *hd = context;
+
+  transform (hd, inbuf_arg, 64 * 8);
+
+  return /* burn_stack */ 768;
+}
+
+/*
+   The routine finally 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: 32
+   bytes with the message the digest.  */
+static void
+stribog_final (void *context)
+{
+  STRIBOG_CONTEXT *hd = context;
+  u64 Z[8] = {};
+  int i;
+
+  _gcry_md_block_write (context, NULL, 0); /* flush */ ;
+  /* PAD. It does not count towards message length */
+  i = hd->bctx.count;
+  /* After flush we have at least one byte free) */
+  hd->bctx.buf[i++] = 1;
+  while (i < 64)
+    hd->bctx.buf[i++] = 0;
+  transform (hd, hd->bctx.buf, hd->bctx.count * 8);
+
+  g (hd->h, hd->N, Z);
+  g (hd->h, hd->Sigma, Z);
+
+  for (i = 0; i < 8; i++)
+    hd->h[i] = le_bswap64(hd->h[i]);
+
+  _gcry_burn_stack (768);
+}
+
+static byte *
+stribog_read_512 (void *context)
+{
+  STRIBOG_CONTEXT *hd = context;
+
+  return hd->result;
+}
+
+static byte *
+stribog_read_256 (void *context)
+{
+  STRIBOG_CONTEXT *hd = context;
+
+  return hd->result + 32;
+}
+
+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,
+    sizeof (STRIBOG_CONTEXT)
+  };
+
+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,
+    sizeof (STRIBOG_CONTEXT)
+  };
index d4ad514..414dcc4 100644 (file)
 
 #include "g10lib.h"
 #include "cipher.h"
+#include "hash-common.h"
+#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;
   u64  a, b, c;
-  byte buf[64];
-  int  count;
-  u32  nblocks;
   int  variant;  /* 0 = old code, 1 = fixed code, 2 - TIGER2.  */
 } TIGER_CONTEXT;
 
@@ -588,6 +589,9 @@ static u64 sbox4[256] = {
   U64_C(0xc83223f1720aef96) /* 1022 */, U64_C(0xc3a0396f7363a51f) /* 1023 */
 };
 
+static unsigned int
+transform ( void *ctx, const unsigned char *data );
+
 static void
 do_init (void *context, int variant)
 {
@@ -596,26 +600,36 @@ do_init (void *context, int variant)
   hd->a = 0x0123456789abcdefLL;
   hd->b = 0xfedcba9876543210LL;
   hd->c = 0xf096a5b4c3b2e187LL;
-  hd->nblocks = 0;
-  hd->count = 0;
+
+  hd->bctx.nblocks = 0;
+  hd->bctx.nblocks_high = 0;
+  hd->bctx.count = 0;
+  hd->bctx.blocksize = 64;
+  hd->bctx.bwrite = transform;
   hd->variant = variant;
 }
 
 static void
-tiger_init (void *context)
+tiger_init (void *context, unsigned int flags)
 {
+  (void)flags;
+
   do_init (context, 0);
 }
 
 static void
-tiger1_init (void *context)
+tiger1_init (void *context, unsigned int flags)
 {
+  (void)flags;
+
   do_init (context, 1);
 }
 
 static void
-tiger2_init (void *context)
+tiger2_init (void *context, unsigned int flags)
 {
+  (void)flags;
+
   do_init (context, 2);
 }
 
@@ -686,29 +700,16 @@ key_schedule( u64 *x )
 /****************
  * Transform the message DATA which consists of 512 bytes (8 words)
  */
-static void
-transform ( TIGER_CONTEXT *hd, const unsigned char *data )
+static unsigned int
+transform ( void *ctx, const unsigned char *data )
 {
+  TIGER_CONTEXT *hd = ctx;
   u64 a,b,c,aa,bb,cc;
   u64 x[8];
-#ifdef WORDS_BIGENDIAN
-#define MKWORD(d,n) \
-               (  ((u64)(d)[8*(n)+7]) << 56 | ((u64)(d)[8*(n)+6]) << 48  \
-                | ((u64)(d)[8*(n)+5]) << 40 | ((u64)(d)[8*(n)+4]) << 32  \
-                | ((u64)(d)[8*(n)+3]) << 24 | ((u64)(d)[8*(n)+2]) << 16  \
-                | ((u64)(d)[8*(n)+1]) << 8  | ((u64)(d)[8*(n)  ])       )
-  x[0] = MKWORD(data, 0);
-  x[1] = MKWORD(data, 1);
-  x[2] = MKWORD(data, 2);
-  x[3] = MKWORD(data, 3);
-  x[4] = MKWORD(data, 4);
-  x[5] = MKWORD(data, 5);
-  x[6] = MKWORD(data, 6);
-  x[7] = MKWORD(data, 7);
-#undef MKWORD
-#else
-  memcpy( &x[0], data, 64 );
-#endif
+  int i;
+
+  for ( i = 0; i < 8; i++ )
+    x[i] = buf_get_le64(data + i * 8);
 
   /* save */
   a = aa = hd->a;
@@ -729,48 +730,8 @@ transform ( TIGER_CONTEXT *hd, const unsigned char *data )
   hd->a = a;
   hd->b = b;
   hd->c = c;
-}
-
-
-
-/* Update the message digest with the contents
- * of INBUF with length INLEN.
- */
-static void
-tiger_write ( void *context, const void *inbuf_arg, size_t inlen)
-{
-  const unsigned char *inbuf = inbuf_arg;
-  TIGER_CONTEXT *hd = context;
-
-  if( hd->count == 64 ) /* flush the buffer */
-    {
-      transform( hd, hd->buf );
-      _gcry_burn_stack (21*8+11*sizeof(void*));
-      hd->count = 0;
-      hd->nblocks++;
-    }
-  if( !inbuf )
-    return;
-  if( hd->count )
-    {
-      for( ; inlen && hd->count < 64; inlen-- )
-        hd->buf[hd->count++] = *inbuf++;
-      tiger_write( hd, NULL, 0 );
-      if( !inlen )
-        return;
-    }
 
-  while( inlen >= 64 )
-    {
-      transform( hd, inbuf );
-      hd->count = 0;
-      hd->nblocks++;
-      inlen -= 64;
-      inbuf += 64;
-    }
-  _gcry_burn_stack (21*8+11*sizeof(void*));
-  for( ; inlen && hd->count < 64; inlen-- )
-    hd->buf[hd->count++] = *inbuf++;
+  return /*burn_stack*/ 21*8+11*sizeof(void*);
 }
 
 
@@ -781,19 +742,25 @@ static void
 tiger_final( void *context )
 {
   TIGER_CONTEXT *hd = context;
-  u32 t, msb, lsb;
+  u32 t, th, msb, lsb;
   byte *p;
+  unsigned int burn;
   byte pad = hd->variant == 2? 0x80 : 0x01;
 
-  tiger_write(hd, NULL, 0); /* flush */;
+  _gcry_md_block_write(hd, NULL, 0); /* flush */;
+
+  t = hd->bctx.nblocks;
+  if (sizeof t == sizeof hd->bctx.nblocks)
+    th = hd->bctx.nblocks_high;
+  else
+    th = hd->bctx.nblocks >> 32;
 
-  t = hd->nblocks;
   /* multiply by 64 to make a byte count */
   lsb = t << 6;
-  msb = t >> 26;
+  msb = (th << 6) | (t >> 26);
   /* add the count */
   t = lsb;
-  if( (lsb += hd->count) < t )
+  if( (lsb += hd->bctx.count) < t )
     msb++;
   /* multiply by 8 to make a bit count */
   t = lsb;
@@ -801,45 +768,29 @@ tiger_final( void *context )
   msb <<= 3;
   msb |= t >> 29;
 
-  if( hd->count < 56 )  /* enough room */
+  if( hd->bctx.count < 56 )  /* enough room */
     {
-      hd->buf[hd->count++] = pad;
-      while( hd->count < 56 )
-        hd->buf[hd->count++] = 0;  /* pad */
+      hd->bctx.buf[hd->bctx.count++] = pad;
+      while( hd->bctx.count < 56 )
+        hd->bctx.buf[hd->bctx.count++] = 0;  /* pad */
     }
   else  /* need one extra block */
     {
-      hd->buf[hd->count++] = pad; /* pad character */
-      while( hd->count < 64 )
-        hd->buf[hd->count++] = 0;
-      tiger_write(hd, NULL, 0);  /* flush */;
-      memset(hd->buf, 0, 56 ); /* fill next block with zeroes */
+      hd->bctx.buf[hd->bctx.count++] = pad; /* pad character */
+      while( hd->bctx.count < 64 )
+        hd->bctx.buf[hd->bctx.count++] = 0;
+      _gcry_md_block_write(hd, NULL, 0);  /* flush */;
+      memset(hd->bctx.buf, 0, 56 ); /* fill next block with zeroes */
     }
   /* append the 64 bit count */
-  hd->buf[56] = lsb       ;
-  hd->buf[57] = lsb >>  8;
-  hd->buf[58] = lsb >> 16;
-  hd->buf[59] = lsb >> 24;
-  hd->buf[60] = msb       ;
-  hd->buf[61] = msb >>  8;
-  hd->buf[62] = msb >> 16;
-  hd->buf[63] = msb >> 24;
-  transform( hd, hd->buf );
-  _gcry_burn_stack (21*8+11*sizeof(void*));
-
-  p = hd->buf;
-#ifdef WORDS_BIGENDIAN
-#define X(a) do { *(u64*)p = hd->a ; p += 8; } while(0)
-#else /* little endian */
-#define X(a) do { *p++ = hd->a >> 56; *p++ = hd->a >> 48; \
-                 *p++ = hd->a >> 40; *p++ = hd->a >> 32; \
-                 *p++ = hd->a >> 24; *p++ = hd->a >> 16; \
-                 *p++ = hd->a >>  8; *p++ = hd->a;       } while(0)
-#endif
-#define Y(a) do { *p++ = hd->a      ; *p++ = hd->a >> 8;  \
-                 *p++ = hd->a >> 16; *p++ = hd->a >> 24; \
-                 *p++ = hd->a >> 32; *p++ = hd->a >> 40; \
-                 *p++ = hd->a >> 48; *p++ = hd->a >> 56; } while(0)
+  buf_put_le32(hd->bctx.buf + 56, lsb);
+  buf_put_le32(hd->bctx.buf + 60, msb);
+  burn = transform( hd, hd->bctx.buf );
+  _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)
   if (hd->variant == 0)
     {
       X(a);
@@ -861,7 +812,7 @@ tiger_read( void *context )
 {
   TIGER_CONTEXT *hd = context;
 
-  return hd->buf;
+  return hd->bctx.buf;
 }
 
 
@@ -871,8 +822,9 @@ tiger_read( void *context )
    an OID anymore because that would not be correct.  */
 gcry_md_spec_t _gcry_digest_spec_tiger =
   {
+    GCRY_MD_TIGER, {0, 0},
     "TIGER192", NULL, 0, NULL, 24,
-    tiger_init, tiger_write, tiger_final, tiger_read,
+    tiger_init, _gcry_md_block_write, tiger_final, tiger_read,
     sizeof (TIGER_CONTEXT)
   };
 
@@ -893,8 +845,9 @@ static gcry_md_oid_spec_t oid_spec_tiger1[] =
 
 gcry_md_spec_t _gcry_digest_spec_tiger1 =
   {
+    GCRY_MD_TIGER1, {0, 0},
     "TIGER", asn1, DIM (asn1), oid_spec_tiger1, 24,
-    tiger1_init, tiger_write, tiger_final, tiger_read,
+    tiger1_init, _gcry_md_block_write, tiger_final, tiger_read,
     sizeof (TIGER_CONTEXT)
   };
 
@@ -903,8 +856,9 @@ gcry_md_spec_t _gcry_digest_spec_tiger1 =
 /* This is TIGER2 which usues a changed padding algorithm.  */
 gcry_md_spec_t _gcry_digest_spec_tiger2 =
   {
+    GCRY_MD_TIGER2, {0, 0},
     "TIGER2", NULL, 0, NULL, 24,
-    tiger2_init, tiger_write, tiger_final, tiger_read,
+    tiger2_init, _gcry_md_block_write, tiger_final, tiger_read,
     sizeof (TIGER_CONTEXT)
   };
 
diff --git a/cipher/twofish-amd64.S b/cipher/twofish-amd64.S
new file mode 100644 (file)
index 0000000..c923d22
--- /dev/null
@@ -0,0 +1,731 @@
+/* twofish-amd64.S  -  AMD64 assembly implementation of Twofish cipher
+ *
+ * Copyright © 2013 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(USE_TWOFISH)
+
+#ifdef __PIC__
+#  define RIP %rip
+#else
+#  define RIP
+#endif
+
+.text
+
+/* structure of TWOFISH_context: */
+#define s0 0
+#define s1 ((s0) + 4 * 256)
+#define s2 ((s1) + 4 * 256)
+#define s3 ((s2) + 4 * 256)
+#define w  ((s3) + 4 * 256)
+#define k  ((w) + 4 * 8)
+
+/* register macros */
+#define CTX    %rdi
+
+#define RA     %rax
+#define RB     %rbx
+#define RC     %rcx
+#define RD     %rdx
+
+#define RAd    %eax
+#define RBd    %ebx
+#define RCd    %ecx
+#define RDd    %edx
+
+#define RAbl   %al
+#define RBbl   %bl
+#define RCbl   %cl
+#define RDbl   %dl
+
+#define RAbh   %ah
+#define RBbh   %bh
+#define RCbh   %ch
+#define RDbh   %dh
+
+#define RX     %r8
+#define RY     %r9
+
+#define RXd    %r8d
+#define RYd    %r9d
+
+#define RT0    %rsi
+#define RT1    %rbp
+#define RT2    %r10
+#define RT3    %r11
+
+#define RT0d   %esi
+#define RT1d   %ebp
+#define RT2d   %r10d
+#define RT3d   %r11d
+
+/***********************************************************************
+ * AMD64 assembly implementation of the Twofish cipher
+ ***********************************************************************/
+#define enc_g1_2(a, b, x, y) \
+       movzbl b ## bl, RT3d; \
+       movzbl b ## bh, RT1d; \
+       movzbl a ## bl, RT2d; \
+       movzbl a ## bh, RT0d; \
+       rorl $16, b ## d; \
+       rorl $16, a ## d; \
+       movl s1(CTX, RT3, 4), RYd; \
+       movzbl b ## bl, RT3d; \
+       movl s0(CTX, RT2, 4), RXd; \
+       movzbl a ## bl, RT2d; \
+       xorl s2(CTX, RT1, 4), RYd; \
+       movzbl b ## bh, RT1d; \
+       xorl s1(CTX, RT0, 4), RXd; \
+       movzbl a ## bh, RT0d; \
+       rorl $16, b ## d; \
+       rorl $16, a ## d; \
+       xorl s3(CTX, RT3, 4), RYd; \
+       xorl s2(CTX, RT2, 4), RXd; \
+       xorl s0(CTX, RT1, 4), RYd; \
+       xorl s3(CTX, RT0, 4), RXd;
+
+#define dec_g1_2(a, b, x, y) \
+       movzbl a ## bl, RT2d; \
+       movzbl a ## bh, RT0d; \
+       movzbl b ## bl, RT3d; \
+       movzbl b ## bh, RT1d; \
+       rorl $16, a ## d; \
+       rorl $16, b ## d; \
+       movl s0(CTX, RT2, 4), RXd; \
+       movzbl a ## bl, RT2d; \
+       movl s1(CTX, RT3, 4), RYd; \
+       movzbl b ## bl, RT3d; \
+       xorl s1(CTX, RT0, 4), RXd; \
+       movzbl a ## bh, RT0d; \
+       xorl s2(CTX, RT1, 4), RYd; \
+       movzbl b ## bh, RT1d; \
+       rorl $16, a ## d; \
+       rorl $16, b ## d; \
+       xorl s2(CTX, RT2, 4), RXd; \
+       xorl s3(CTX, RT3, 4), RYd; \
+       xorl s3(CTX, RT0, 4), RXd; \
+       xorl s0(CTX, RT1, 4), RYd;
+
+#define encrypt_round(ra, rb, rc, rd, n) \
+       enc_g1_2(##ra, ##rb, RX, RY); \
+       \
+       leal (RXd, RYd, 2), RT0d; \
+       addl RYd, RXd; \
+       addl (k + 8 * (n) + 4)(CTX), RT0d; \
+       roll $1, rd ## d; \
+       addl (k + 8 * (n))(CTX), RXd; \
+       xorl RT0d, rd ## d; \
+       xorl RXd, rc ## d; \
+       rorl $1, rc ## d;
+
+#define decrypt_round(ra, rb, rc, rd, n) \
+       dec_g1_2(##ra, ##rb, RX, RY); \
+       \
+       leal (RXd, RYd, 2), RT0d; \
+       addl RYd, RXd; \
+       addl (k + 8 * (n) + 4)(CTX), RT0d; \
+       roll $1, rc ## d; \
+       addl (k + 8 * (n))(CTX), RXd; \
+       xorl RXd, rc ## d; \
+       xorl RT0d, rd ## d; \
+       rorl $1, rd ## d;
+
+#define encrypt_cycle(a, b, c, d, nc) \
+       encrypt_round(##a, ##b, ##c, ##d, (nc) * 2); \
+       encrypt_round(##c, ##d, ##a, ##b, (nc) * 2 + 1);
+
+#define decrypt_cycle(a, b, c, d, nc) \
+       decrypt_round(##c, ##d, ##a, ##b, (nc) * 2 + 1); \
+       decrypt_round(##a, ##b, ##c, ##d, (nc) * 2);
+
+#define inpack(in, n, x, m) \
+       movl (4 * (n))(in), x; \
+       xorl (w + 4 * (m))(CTX), x;
+
+#define outunpack(out, n, x, m) \
+       xorl (w + 4 * (m))(CTX), x; \
+       movl x, (4 * (n))(out);
+
+.align 8
+.globl _gcry_twofish_amd64_encrypt_block
+.type   _gcry_twofish_amd64_encrypt_block,@function;
+
+_gcry_twofish_amd64_encrypt_block:
+       /* input:
+        *      %rdi: context, CTX
+        *      %rsi: dst
+        *      %rdx: src
+        */
+       subq $(3 * 8), %rsp;
+       movq %rsi, (0 * 8)(%rsp);
+       movq %rbp, (1 * 8)(%rsp);
+       movq %rbx, (2 * 8)(%rsp);
+
+       movq %rdx, RX;
+       inpack(RX, 0, RAd, 0);
+       inpack(RX, 1, RBd, 1);
+       inpack(RX, 2, RCd, 2);
+       inpack(RX, 3, RDd, 3);
+
+       encrypt_cycle(RA, RB, RC, RD, 0);
+       encrypt_cycle(RA, RB, RC, RD, 1);
+       encrypt_cycle(RA, RB, RC, RD, 2);
+       encrypt_cycle(RA, RB, RC, RD, 3);
+       encrypt_cycle(RA, RB, RC, RD, 4);
+       encrypt_cycle(RA, RB, RC, RD, 5);
+       encrypt_cycle(RA, RB, RC, RD, 6);
+       encrypt_cycle(RA, RB, RC, RD, 7);
+
+       movq (0 * 8)(%rsp), RX; /*dst*/
+       outunpack(RX, 0, RCd, 4);
+       outunpack(RX, 1, RDd, 5);
+       outunpack(RX, 2, RAd, 6);
+       outunpack(RX, 3, RBd, 7);
+
+       movq (2 * 8)(%rsp), %rbx;
+       movq (1 * 8)(%rsp), %rbp;
+       addq $(3 * 8), %rsp;
+
+       ret;
+.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;
+
+_gcry_twofish_amd64_decrypt_block:
+       /* input:
+        *      %rdi: context, CTX
+        *      %rsi: dst
+        *      %rdx: src
+        */
+       subq $(3 * 8), %rsp;
+       movq %rsi, (0 * 8)(%rsp);
+       movq %rbp, (1 * 8)(%rsp);
+       movq %rbx, (2 * 8)(%rsp);
+
+       movq %rdx, RX;
+       inpack(RX, 0, RCd, 4);
+       inpack(RX, 1, RDd, 5);
+       inpack(RX, 2, RAd, 6);
+       inpack(RX, 3, RBd, 7);
+
+       decrypt_cycle(RA, RB, RC, RD, 7);
+       decrypt_cycle(RA, RB, RC, RD, 6);
+       decrypt_cycle(RA, RB, RC, RD, 5);
+       decrypt_cycle(RA, RB, RC, RD, 4);
+       decrypt_cycle(RA, RB, RC, RD, 3);
+       decrypt_cycle(RA, RB, RC, RD, 2);
+       decrypt_cycle(RA, RB, RC, RD, 1);
+       decrypt_cycle(RA, RB, RC, RD, 0);
+
+       movq (0 * 8)(%rsp), RX; /*dst*/
+       outunpack(RX, 0, RAd, 0);
+       outunpack(RX, 1, RBd, 1);
+       outunpack(RX, 2, RCd, 2);
+       outunpack(RX, 3, RDd, 3);
+
+       movq (2 * 8)(%rsp), %rbx;
+       movq (1 * 8)(%rsp), %rbp;
+       addq $(3 * 8), %rsp;
+
+       ret;
+.size _gcry_twofish_amd64_encrypt_block,.-_gcry_twofish_amd64_encrypt_block;
+
+#undef CTX
+
+#undef RA
+#undef RB
+#undef RC
+#undef RD
+
+#undef RAd
+#undef RBd
+#undef RCd
+#undef RDd
+
+#undef RAbl
+#undef RBbl
+#undef RCbl
+#undef RDbl
+
+#undef RAbh
+#undef RBbh
+#undef RCbh
+#undef RDbh
+
+#undef RX
+#undef RY
+
+#undef RXd
+#undef RYd
+
+#undef RT0
+#undef RT1
+#undef RT2
+#undef RT3
+
+#undef RT0d
+#undef RT1d
+#undef RT2d
+#undef RT3d
+
+/***********************************************************************
+ * AMD64 assembly implementation of the Twofish cipher, 3-way parallel
+ ***********************************************************************/
+#define CTX %rdi
+#define RIO %rdx
+
+#define RAB0 %rax
+#define RAB1 %rbx
+#define RAB2 %rcx
+
+#define RAB0d %eax
+#define RAB1d %ebx
+#define RAB2d %ecx
+
+#define RAB0bh %ah
+#define RAB1bh %bh
+#define RAB2bh %ch
+
+#define RAB0bl %al
+#define RAB1bl %bl
+#define RAB2bl %cl
+
+#define RCD0 %r8
+#define RCD1 %r9
+#define RCD2 %r10
+
+#define RCD0d %r8d
+#define RCD1d %r9d
+#define RCD2d %r10d
+
+#define RX0 %rbp
+#define RX1 %r11
+#define RX2 %r12
+
+#define RX0d %ebp
+#define RX1d %r11d
+#define RX2d %r12d
+
+#define RY0 %r13
+#define RY1 %r14
+#define RY2 %r15
+
+#define RY0d %r13d
+#define RY1d %r14d
+#define RY2d %r15d
+
+#define RT0 %rdx
+#define RT1 %rsi
+
+#define RT0d %edx
+#define RT1d %esi
+
+#define do16bit_ror(rot, op1, op2, T0, T1, tmp1, tmp2, ab, dst) \
+       movzbl ab ## bl,                tmp2 ## d; \
+       movzbl ab ## bh,                tmp1 ## d; \
+       rorq $(rot),                    ab; \
+       op1##l T0(CTX, tmp2, 4),        dst ## d; \
+       op2##l T1(CTX, tmp1, 4),        dst ## d;
+
+/*
+ * Combined G1 & G2 function. Reordered with help of rotates to have moves
+ * at beginning.
+ */
+#define g1g2_3(ab, cd, Tx0, Tx1, Tx2, Tx3, Ty0, Ty1, Ty2, Ty3, x, y) \
+       /* G1,1 && G2,1 */ \
+       do16bit_ror(32, mov, xor, Tx0, Tx1, RT0, x ## 0, ab ## 0, x ## 0); \
+       do16bit_ror(48, mov, xor, Ty1, Ty2, RT0, y ## 0, ab ## 0, y ## 0); \
+       \
+       do16bit_ror(32, mov, xor, Tx0, Tx1, RT0, x ## 1, ab ## 1, x ## 1); \
+       do16bit_ror(48, mov, xor, Ty1, Ty2, RT0, y ## 1, ab ## 1, y ## 1); \
+       \
+       do16bit_ror(32, mov, xor, Tx0, Tx1, RT0, x ## 2, ab ## 2, x ## 2); \
+       do16bit_ror(48, mov, xor, Ty1, Ty2, RT0, y ## 2, ab ## 2, y ## 2); \
+       \
+       /* G1,2 && G2,2 */ \
+       do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 0, x ## 0); \
+       do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 0, y ## 0); \
+       xchgq cd ## 0, ab ## 0; \
+       \
+       do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 1, x ## 1); \
+       do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 1, y ## 1); \
+       xchgq cd ## 1, ab ## 1; \
+       \
+       do16bit_ror(32, xor, xor, Tx2, Tx3, RT0, RT1, ab ## 2, x ## 2); \
+       do16bit_ror(16, xor, xor, Ty3, Ty0, RT0, RT1, ab ## 2, y ## 2); \
+       xchgq cd ## 2, ab ## 2;
+
+#define enc_round_end(ab, x, y, n) \
+       addl y ## d,                    x ## d; \
+       addl x ## d,                    y ## d; \
+       addl k+4*(2*(n))(CTX),          x ## d; \
+       xorl ab ## d,                   x ## d; \
+       addl k+4*(2*(n)+1)(CTX),        y ## d; \
+       shrq $32,                       ab; \
+       roll $1,                        ab ## d; \
+       xorl y ## d,                    ab ## d; \
+       shlq $32,                       ab; \
+       rorl $1,                        x ## d; \
+       orq x,                          ab;
+
+#define dec_round_end(ba, x, y, n) \
+       addl y ## d,                    x ## d; \
+       addl x ## d,                    y ## d; \
+       addl k+4*(2*(n))(CTX),          x ## d; \
+       addl k+4*(2*(n)+1)(CTX),        y ## d; \
+       xorl ba ## d,                   y ## d; \
+       shrq $32,                       ba; \
+       roll $1,                        ba ## d; \
+       xorl x ## d,                    ba ## d; \
+       shlq $32,                       ba; \
+       rorl $1,                        y ## d; \
+       orq y,                          ba;
+
+#define encrypt_round3(ab, cd, n) \
+       g1g2_3(ab, cd, s0, s1, s2, s3, s0, s1, s2, s3, RX, RY); \
+       \
+       enc_round_end(ab ## 0, RX0, RY0, n); \
+       enc_round_end(ab ## 1, RX1, RY1, n); \
+       enc_round_end(ab ## 2, RX2, RY2, n);
+
+#define decrypt_round3(ba, dc, n) \
+       g1g2_3(ba, dc, s1, s2, s3, s0, s3, s0, s1, s2, RY, RX); \
+       \
+       dec_round_end(ba ## 0, RX0, RY0, n); \
+       dec_round_end(ba ## 1, RX1, RY1, n); \
+       dec_round_end(ba ## 2, RX2, RY2, n);
+
+#define encrypt_cycle3(ab, cd, n) \
+       encrypt_round3(ab, cd, n*2); \
+       encrypt_round3(ab, cd, (n*2)+1);
+
+#define decrypt_cycle3(ba, dc, n) \
+       decrypt_round3(ba, dc, (n*2)+1); \
+       decrypt_round3(ba, dc, (n*2));
+
+#define inpack3(xy, m) \
+       xorq w+4*m(CTX),                xy ## 0; \
+       xorq w+4*m(CTX),                xy ## 1; \
+       xorq w+4*m(CTX),                xy ## 2;
+
+#define outunpack3(xy, m) \
+       xorq w+4*m(CTX),                xy ## 0; \
+       xorq w+4*m(CTX),                xy ## 1; \
+       xorq w+4*m(CTX),                xy ## 2;
+
+#define inpack_enc3() \
+       inpack3(RAB, 0); \
+       inpack3(RCD, 2);
+
+#define outunpack_enc3() \
+       outunpack3(RAB, 6); \
+       outunpack3(RCD, 4);
+
+#define inpack_dec3() \
+       inpack3(RAB, 4); \
+       rorq $32,                       RAB0; \
+       rorq $32,                       RAB1; \
+       rorq $32,                       RAB2; \
+       inpack3(RCD, 6); \
+       rorq $32,                       RCD0; \
+       rorq $32,                       RCD1; \
+       rorq $32,                       RCD2;
+
+#define outunpack_dec3() \
+       rorq $32,                       RCD0; \
+       rorq $32,                       RCD1; \
+       rorq $32,                       RCD2; \
+       outunpack3(RCD, 0); \
+       rorq $32,                       RAB0; \
+       rorq $32,                       RAB1; \
+       rorq $32,                       RAB2; \
+       outunpack3(RAB, 2);
+
+.align 8
+.type __twofish_enc_blk3,@function;
+
+__twofish_enc_blk3:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      RAB0,RCD0,RAB1,RCD1,RAB2,RCD2: three plaintext blocks
+        * output:
+        *      RCD0,RAB0,RCD1,RAB1,RCD2,RAB2: three ciphertext blocks
+        */
+       inpack_enc3();
+
+       encrypt_cycle3(RAB, RCD, 0);
+       encrypt_cycle3(RAB, RCD, 1);
+       encrypt_cycle3(RAB, RCD, 2);
+       encrypt_cycle3(RAB, RCD, 3);
+       encrypt_cycle3(RAB, RCD, 4);
+       encrypt_cycle3(RAB, RCD, 5);
+       encrypt_cycle3(RAB, RCD, 6);
+       encrypt_cycle3(RAB, RCD, 7);
+
+       outunpack_enc3();
+
+       ret;
+.size __twofish_enc_blk3,.-__twofish_enc_blk3;
+
+.align 8
+.type  __twofish_dec_blk3,@function;
+
+__twofish_dec_blk3:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      RAB0,RCD0,RAB1,RCD1,RAB2,RCD2: three ciphertext blocks
+        * output:
+        *      RCD0,RAB0,RCD1,RAB1,RCD2,RAB2: three plaintext blocks
+        */
+       inpack_dec3();
+
+       decrypt_cycle3(RAB, RCD, 7);
+       decrypt_cycle3(RAB, RCD, 6);
+       decrypt_cycle3(RAB, RCD, 5);
+       decrypt_cycle3(RAB, RCD, 4);
+       decrypt_cycle3(RAB, RCD, 3);
+       decrypt_cycle3(RAB, RCD, 2);
+       decrypt_cycle3(RAB, RCD, 1);
+       decrypt_cycle3(RAB, RCD, 0);
+
+       outunpack_dec3();
+
+       ret;
+.size __twofish_dec_blk3,.-__twofish_dec_blk3;
+
+.align 8
+.globl _gcry_twofish_amd64_ctr_enc
+.type   _gcry_twofish_amd64_ctr_enc,@function;
+_gcry_twofish_amd64_ctr_enc:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (3 blocks)
+        *      %rdx: src (3 blocks)
+        *      %rcx: iv (big endian, 128bit)
+        */
+       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, (7 * 8)(%rsp);
+       movq %rcx, RX0;
+
+       /* load IV and byteswap */
+       movq 8(RX0), RT0;
+       movq 0(RX0), RT1;
+       movq RT0, RCD0;
+       movq RT1, RAB0;
+       bswapq RT0;
+       bswapq RT1;
+
+       /* construct IVs */
+       movq RT0, RCD1;
+       movq RT1, RAB1;
+       movq RT0, RCD2;
+       movq RT1, RAB2;
+       addq $1, RCD1;
+       adcq $0, RAB1;
+       bswapq RCD1;
+       bswapq RAB1;
+       addq $2, RCD2;
+       adcq $0, RAB2;
+       bswapq RCD2;
+       bswapq RAB2;
+       addq $3, RT0;
+       adcq $0, RT1;
+       bswapq RT0;
+       bswapq RT1;
+
+       /* store new IV */
+       movq RT0, 8(RX0);
+       movq RT1, 0(RX0);
+
+       call __twofish_enc_blk3;
+
+       movq (7 * 8)(%rsp), RX0; /*src*/
+       movq (6 * 8)(%rsp), RX1; /*dst*/
+
+       /* XOR key-stream with plaintext */
+       xorq (0 * 8)(RX0), RCD0;
+       xorq (1 * 8)(RX0), RAB0;
+       xorq (2 * 8)(RX0), RCD1;
+       xorq (3 * 8)(RX0), RAB1;
+       xorq (4 * 8)(RX0), RCD2;
+       xorq (5 * 8)(RX0), RAB2;
+       movq RCD0, (0 * 8)(RX1);
+       movq RAB0, (1 * 8)(RX1);
+       movq RCD1, (2 * 8)(RX1);
+       movq RAB1, (3 * 8)(RX1);
+       movq RCD2, (4 * 8)(RX1);
+       movq 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;
+.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;
+_gcry_twofish_amd64_cbc_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (3 blocks)
+        *      %rdx: src (3 blocks)
+        *      %rcx: iv (128bit)
+        */
+       subq $(9 * 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, (7 * 8)(%rsp);
+       movq %rcx, (8 * 8)(%rsp);
+       movq %rdx, RX0;
+
+       /* load input */
+       movq (0 * 8)(RX0), RAB0;
+       movq (1 * 8)(RX0), RCD0;
+       movq (2 * 8)(RX0), RAB1;
+       movq (3 * 8)(RX0), RCD1;
+       movq (4 * 8)(RX0), RAB2;
+       movq (5 * 8)(RX0), RCD2;
+
+       call __twofish_dec_blk3;
+
+       movq (8 * 8)(%rsp), RT0; /*iv*/
+       movq (7 * 8)(%rsp), RX0; /*src*/
+       movq (6 * 8)(%rsp), RX1; /*dst*/
+
+       movq (4 * 8)(RX0), RY0;
+       movq (5 * 8)(RX0), RY1;
+       xorq (0 * 8)(RT0), RCD0;
+       xorq (1 * 8)(RT0), RAB0;
+       xorq (0 * 8)(RX0), RCD1;
+       xorq (1 * 8)(RX0), RAB1;
+       xorq (2 * 8)(RX0), RCD2;
+       xorq (3 * 8)(RX0), RAB2;
+       movq RY0, (0 * 8)(RT0);
+       movq RY1, (1 * 8)(RT0);
+
+       movq RCD0, (0 * 8)(RX1);
+       movq RAB0, (1 * 8)(RX1);
+       movq RCD1, (2 * 8)(RX1);
+       movq RAB1, (3 * 8)(RX1);
+       movq RCD2, (4 * 8)(RX1);
+       movq 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 $(9 * 8), %rsp;
+
+       ret;
+.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;
+_gcry_twofish_amd64_cfb_dec:
+       /* input:
+        *      %rdi: ctx, CTX
+        *      %rsi: dst (3 blocks)
+        *      %rdx: src (3 blocks)
+        *      %rcx: iv (128bit)
+        */
+       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, (7 * 8)(%rsp);
+       movq %rdx, RX0;
+       movq %rcx, RX1;
+
+       /* load input */
+       movq (0 * 8)(RX1), RAB0;
+       movq (1 * 8)(RX1), RCD0;
+       movq (0 * 8)(RX0), RAB1;
+       movq (1 * 8)(RX0), RCD1;
+       movq (2 * 8)(RX0), RAB2;
+       movq (3 * 8)(RX0), RCD2;
+
+       /* Update IV */
+       movq (4 * 8)(RX0), RY0;
+       movq (5 * 8)(RX0), RY1;
+       movq RY0, (0 * 8)(RX1);
+       movq RY1, (1 * 8)(RX1);
+
+       call __twofish_enc_blk3;
+
+       movq (7 * 8)(%rsp), RX0; /*src*/
+       movq (6 * 8)(%rsp), RX1; /*dst*/
+
+       xorq (0 * 8)(RX0), RCD0;
+       xorq (1 * 8)(RX0), RAB0;
+       xorq (2 * 8)(RX0), RCD1;
+       xorq (3 * 8)(RX0), RAB1;
+       xorq (4 * 8)(RX0), RCD2;
+       xorq (5 * 8)(RX0), RAB2;
+       movq RCD0, (0 * 8)(RX1);
+       movq RAB0, (1 * 8)(RX1);
+       movq RCD1, (2 * 8)(RX1);
+       movq RAB1, (3 * 8)(RX1);
+       movq RCD2, (4 * 8)(RX1);
+       movq 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;
+.size _gcry_twofish_amd64_cfb_dec,.-_gcry_twofish_amd64_cfb_dec;
+
+#endif /*USE_TWOFISH*/
+#endif /*__x86_64*/
diff --git a/cipher/twofish-arm.S b/cipher/twofish-arm.S
new file mode 100644 (file)
index 0000000..ead2240
--- /dev/null
@@ -0,0 +1,363 @@
+/* twofish-arm.S  -  ARM assembly implementation of Twofish cipher
+ *
+ * Copyright © 2013 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 TWOFISH_context: */
+#define s0 0
+#define s1 ((s0) + 4 * 256)
+#define s2 ((s1) + 4 * 256)
+#define s3 ((s2) + 4 * 256)
+#define w  ((s3) + 4 * 256)
+#define k  ((w) + 4 * 8)
+
+/* register macros */
+#define CTX %r0
+#define CTXs0 %r0
+#define CTXs1 %r1
+#define CTXs3 %r7
+
+#define RA %r3
+#define RB %r4
+#define RC %r5
+#define RD %r6
+
+#define RX %r2
+#define RY %ip
+
+#define RMASK %lr
+
+#define RT0 %r8
+#define RT1 %r9
+#define RT2 %r10
+#define RT3 %r11
+
+/* helper macros */
+#define ldr_unaligned_le(rout, rsrc, offs, rtmp) \
+       ldrb rout, [rsrc, #((offs) + 0)]; \
+       ldrb rtmp, [rsrc, #((offs) + 1)]; \
+       orr rout, rout, rtmp, lsl #8; \
+       ldrb rtmp, [rsrc, #((offs) + 2)]; \
+       orr rout, rout, rtmp, lsl #16; \
+       ldrb rtmp, [rsrc, #((offs) + 3)]; \
+       orr rout, rout, rtmp, lsl #24;
+
+#define str_unaligned_le(rin, rdst, offs, rtmp0, rtmp1) \
+       mov rtmp0, rin, lsr #8; \
+       strb rin, [rdst, #((offs) + 0)]; \
+       mov rtmp1, rin, lsr #16; \
+       strb rtmp0, [rdst, #((offs) + 1)]; \
+       mov rtmp0, rin, lsr #24; \
+       strb rtmp1, [rdst, #((offs) + 2)]; \
+       strb rtmp0, [rdst, #((offs) + 3)];
+
+#ifndef __ARMEL__
+       /* bswap on big-endian */
+       #define host_to_le(reg) \
+               rev reg, reg;
+       #define le_to_host(reg) \
+               rev reg, reg;
+#else
+       /* nop on little-endian */
+       #define host_to_le(reg) /*_*/
+       #define le_to_host(reg) /*_*/
+#endif
+
+#define ldr_input_aligned_le(rin, a, b, c, d) \
+       ldr a, [rin, #0]; \
+       ldr b, [rin, #4]; \
+       le_to_host(a); \
+       ldr c, [rin, #8]; \
+       le_to_host(b); \
+       ldr d, [rin, #12]; \
+       le_to_host(c); \
+       le_to_host(d);
+
+#define str_output_aligned_le(rout, a, b, c, d) \
+       le_to_host(a); \
+       le_to_host(b); \
+       str a, [rout, #0]; \
+       le_to_host(c); \
+       str b, [rout, #4]; \
+       le_to_host(d); \
+       str c, [rout, #8]; \
+       str d, [rout, #12];
+
+#ifdef __ARM_FEATURE_UNALIGNED
+       /* unaligned word reads/writes allowed */
+       #define ldr_input_le(rin, ra, rb, rc, rd, rtmp) \
+               ldr_input_aligned_le(rin, ra, rb, rc, rd)
+
+       #define str_output_le(rout, ra, rb, rc, rd, rtmp0, rtmp1) \
+               str_output_aligned_le(rout, ra, rb, rc, rd)
+#else
+       /* need to handle unaligned reads/writes by byte reads */
+       #define ldr_input_le(rin, ra, rb, rc, rd, rtmp0) \
+               tst rin, #3; \
+               beq 1f; \
+                       ldr_unaligned_le(ra, rin, 0, rtmp0); \
+                       ldr_unaligned_le(rb, rin, 4, rtmp0); \
+                       ldr_unaligned_le(rc, rin, 8, rtmp0); \
+                       ldr_unaligned_le(rd, rin, 12, rtmp0); \
+                       b 2f; \
+               1:;\
+                       ldr_input_aligned_le(rin, ra, rb, rc, rd); \
+               2:;
+
+       #define str_output_le(rout, ra, rb, rc, rd, rtmp0, rtmp1) \
+               tst rout, #3; \
+               beq 1f; \
+                       str_unaligned_le(ra, rout, 0, rtmp0, rtmp1); \
+                       str_unaligned_le(rb, rout, 4, rtmp0, rtmp1); \
+                       str_unaligned_le(rc, rout, 8, rtmp0, rtmp1); \
+                       str_unaligned_le(rd, rout, 12, rtmp0, rtmp1); \
+                       b 2f; \
+               1:;\
+                       str_output_aligned_le(rout, ra, rb, rc, rd); \
+               2:;
+#endif
+
+/**********************************************************************
+  1-way twofish
+ **********************************************************************/
+#define encrypt_round(a, b, rc, rd, n, ror_a, adj_a) \
+       and RT0, RMASK, b, lsr#(8 - 2); \
+       and RY, RMASK, b, lsr#(16 - 2); \
+       add RT0, RT0, #(s2 - s1); \
+       and RT1, RMASK, b, lsr#(24 - 2); \
+       ldr RY, [CTXs3, RY]; \
+       and RT2, RMASK, b, lsl#(2); \
+       ldr RT0, [CTXs1, RT0]; \
+       and RT3, RMASK, a, lsr#(16 - 2 + (adj_a)); \
+       ldr RT1, [CTXs0, RT1]; \
+       and RX, RMASK, a, lsr#(8 - 2 + (adj_a)); \
+       ldr RT2, [CTXs1, RT2]; \
+       add RT3, RT3, #(s2 - s1); \
+       ldr RX, [CTXs1, RX]; \
+       ror_a(a); \
+       \
+       eor RY, RY, RT0; \
+       ldr RT3, [CTXs1, RT3]; \
+       and RT0, RMASK, a, lsl#(2); \
+       eor RY, RY, RT1; \
+       and RT1, RMASK, a, lsr#(24 - 2); \
+       eor RY, RY, RT2; \
+       ldr RT0, [CTXs0, RT0]; \
+       eor RX, RX, RT3; \
+       ldr RT1, [CTXs3, RT1]; \
+       eor RX, RX, RT0; \
+       \
+       ldr RT3, [CTXs3, #(k - s3 + 8 * (n) + 4)]; \
+       eor RX, RX, RT1; \
+       ldr RT2, [CTXs3, #(k - s3 + 8 * (n))]; \
+       \
+       add RT0, RX, RY, lsl #1; \
+       add RX, RX, RY; \
+       add RT0, RT0, RT3; \
+       add RX, RX, RT2; \
+       eor rd, RT0, rd, ror #31; \
+       eor rc, rc, RX;
+
+#define dummy(x) /*_*/
+
+#define ror1(r) \
+       ror r, r, #1;
+
+#define decrypt_round(a, b, rc, rd, n, ror_b, adj_b) \
+       and RT3, RMASK, b, lsl#(2 - (adj_b)); \
+       and RT1, RMASK, b, lsr#(8 - 2 + (adj_b)); \
+       ror_b(b); \
+       and RT2, RMASK, a, lsl#(2); \
+       and RT0, RMASK, a, lsr#(8 - 2); \
+       \
+       ldr RY, [CTXs1, RT3]; \
+       add RT1, RT1, #(s2 - s1); \
+       ldr RX, [CTXs0, RT2]; \
+       and RT3, RMASK, b, lsr#(16 - 2); \
+       ldr RT1, [CTXs1, RT1]; \
+       and RT2, RMASK, a, lsr#(16 - 2); \
+       ldr RT0, [CTXs1, RT0]; \
+       \
+       add RT2, RT2, #(s2 - s1); \
+       ldr RT3, [CTXs3, RT3]; \
+       eor RY, RY, RT1; \
+       \
+       and RT1, RMASK, b, lsr#(24 - 2); \
+       eor RX, RX, RT0; \
+       ldr RT2, [CTXs1, RT2]; \
+       and RT0, RMASK, a, lsr#(24 - 2); \
+       \
+       ldr RT1, [CTXs0, RT1]; \
+       \
+       eor RY, RY, RT3; \
+       ldr RT0, [CTXs3, RT0]; \
+       eor RX, RX, RT2; \
+       eor RY, RY, RT1; \
+       \
+       ldr RT1, [CTXs3, #(k - s3 + 8 * (n) + 4)]; \
+       eor RX, RX, RT0; \
+       ldr RT2, [CTXs3, #(k - s3 + 8 * (n))]; \
+       \
+       add RT0, RX, RY, lsl #1; \
+       add RX, RX, RY; \
+       add RT0, RT0, RT1; \
+       add RX, RX, RT2; \
+       eor rd, rd, RT0; \
+       eor rc, RX, rc, ror #31;
+
+#define first_encrypt_cycle(nc) \
+       encrypt_round(RA, RB, RC, RD, (nc) * 2, dummy, 0); \
+       encrypt_round(RC, RD, RA, RB, (nc) * 2 + 1, ror1, 1);
+
+#define encrypt_cycle(nc) \
+       encrypt_round(RA, RB, RC, RD, (nc) * 2, ror1, 1); \
+       encrypt_round(RC, RD, RA, RB, (nc) * 2 + 1, ror1, 1);
+
+#define last_encrypt_cycle(nc) \
+       encrypt_round(RA, RB, RC, RD, (nc) * 2, ror1, 1); \
+       encrypt_round(RC, RD, RA, RB, (nc) * 2 + 1, ror1, 1); \
+       ror1(RA);
+
+#define first_decrypt_cycle(nc) \
+       decrypt_round(RC, RD, RA, RB, (nc) * 2 + 1, dummy, 0); \
+       decrypt_round(RA, RB, RC, RD, (nc) * 2, ror1, 1);
+
+#define decrypt_cycle(nc) \
+       decrypt_round(RC, RD, RA, RB, (nc) * 2 + 1, ror1, 1); \
+       decrypt_round(RA, RB, RC, RD, (nc) * 2, ror1, 1);
+
+#define last_decrypt_cycle(nc) \
+       decrypt_round(RC, RD, RA, RB, (nc) * 2 + 1, ror1, 1); \
+       decrypt_round(RA, RB, RC, RD, (nc) * 2, ror1, 1); \
+       ror1(RD);
+
+.align 3
+.globl _gcry_twofish_arm_encrypt_block
+.type   _gcry_twofish_arm_encrypt_block,%function;
+
+_gcry_twofish_arm_encrypt_block:
+       /* input:
+        *      %r0: ctx
+        *      %r1: dst
+        *      %r2: src
+        */
+       push {%r1, %r4-%r11, %ip, %lr};
+
+       add RY, CTXs0, #w;
+
+       ldr_input_le(%r2, RA, RB, RC, RD, RT0);
+
+       /* Input whitening */
+       ldm RY, {RT0, RT1, RT2, RT3};
+       add CTXs3, CTXs0, #(s3 - s0);
+       add CTXs1, CTXs0, #(s1 - s0);
+       mov RMASK, #(0xff << 2);
+       eor RA, RA, RT0;
+       eor RB, RB, RT1;
+       eor RC, RC, RT2;
+       eor RD, RD, RT3;
+
+       first_encrypt_cycle(0);
+       encrypt_cycle(1);
+       encrypt_cycle(2);
+       encrypt_cycle(3);
+       encrypt_cycle(4);
+       encrypt_cycle(5);
+       encrypt_cycle(6);
+       last_encrypt_cycle(7);
+
+       add RY, CTXs3, #(w + 4*4 - s3);
+       pop {%r1}; /* dst */
+
+       /* Output whitening */
+       ldm RY, {RT0, RT1, RT2, RT3};
+       eor RC, RC, RT0;
+       eor RD, RD, RT1;
+       eor RA, RA, RT2;
+       eor RB, RB, RT3;
+
+       str_output_le(%r1, RC, RD, RA, RB, RT0, RT1);
+
+       pop {%r4-%r11, %ip, %pc};
+.ltorg
+.size _gcry_twofish_arm_encrypt_block,.-_gcry_twofish_arm_encrypt_block;
+
+.align 3
+.globl _gcry_twofish_arm_decrypt_block
+.type   _gcry_twofish_arm_decrypt_block,%function;
+
+_gcry_twofish_arm_decrypt_block:
+       /* input:
+        *      %r0: ctx
+        *      %r1: dst
+        *      %r2: src
+        */
+       push {%r1, %r4-%r11, %ip, %lr};
+
+       add CTXs3, CTXs0, #(s3 - s0);
+
+       ldr_input_le(%r2, RC, RD, RA, RB, RT0);
+
+       add RY, CTXs3, #(w + 4*4 - s3);
+       add CTXs3, CTXs0, #(s3 - s0);
+
+       /* Input whitening */
+       ldm RY, {RT0, RT1, RT2, RT3};
+       add CTXs1, CTXs0, #(s1 - s0);
+       mov RMASK, #(0xff << 2);
+       eor RC, RC, RT0;
+       eor RD, RD, RT1;
+       eor RA, RA, RT2;
+       eor RB, RB, RT3;
+
+       first_decrypt_cycle(7);
+       decrypt_cycle(6);
+       decrypt_cycle(5);
+       decrypt_cycle(4);
+       decrypt_cycle(3);
+       decrypt_cycle(2);
+       decrypt_cycle(1);
+       last_decrypt_cycle(0);
+
+       add RY, CTXs0, #w;
+       pop {%r1}; /* dst */
+
+       /* Output whitening */
+       ldm RY, {RT0, RT1, RT2, RT3};
+       eor RA, RA, RT0;
+       eor RB, RB, RT1;
+       eor RC, RC, RT2;
+       eor RD, RD, RT3;
+
+       str_output_le(%r1, RA, RB, RC, RD, RT0, RT1);
+
+       pop {%r4-%r11, %ip, %pc};
+.size _gcry_twofish_arm_decrypt_block,.-_gcry_twofish_arm_decrypt_block;
+
+#endif /*HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS*/
+#endif /*__ARMEL__*/
index f1a93ca..ecd76e3 100644 (file)
 #include "types.h"  /* for byte and u32 typedefs */
 #include "g10lib.h"
 #include "cipher.h"
+#include "bufhelp.h"
+#include "cipher-selftest.h"
+
+
+#define TWOFISH_BLOCKSIZE 16
+
+
+/* USE_AMD64_ASM indicates whether to use AMD64 assembly code. */
+#undef USE_AMD64_ASM
+#if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS)
+# define USE_AMD64_ASM 1
+#endif
+
+/* USE_ARM_ASM indicates whether to use ARM assembly code. */
+#undef USE_ARM_ASM
+#if defined(__ARMEL__)
+# if defined(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS)
+#  define USE_ARM_ASM 1
+# endif
+#endif
+
 
 /* Prototype for the self-test function. */
 static const char *selftest(void);
@@ -714,6 +735,36 @@ twofish_setkey (void *context, const byte *key, unsigned int keylen)
 
 
 \f
+#ifdef USE_AMD64_ASM
+
+/* Assembly implementations of Twofish. */
+extern void _gcry_twofish_amd64_encrypt_block(const TWOFISH_context *c,
+                                             byte *out, const byte *in);
+
+extern void _gcry_twofish_amd64_decrypt_block(const TWOFISH_context *c,
+                                             byte *out, const byte *in);
+
+/* These assembly implementations process three blocks in parallel. */
+extern void _gcry_twofish_amd64_ctr_enc(const TWOFISH_context *c, byte *out,
+                                       const byte *in, byte *ctr);
+
+extern void _gcry_twofish_amd64_cbc_dec(const TWOFISH_context *c, byte *out,
+                                       const byte *in, byte *iv);
+
+extern void _gcry_twofish_amd64_cfb_dec(const TWOFISH_context *c, byte *out,
+                                       const byte *in, byte *iv);
+
+#elif defined(USE_ARM_ASM)
+
+/* Assembly implementations of Twofish. */
+extern void _gcry_twofish_arm_encrypt_block(const TWOFISH_context *c,
+                                             byte *out, const byte *in);
+
+extern void _gcry_twofish_arm_decrypt_block(const TWOFISH_context *c,
+                                             byte *out, const byte *in);
+
+#else /*!USE_AMD64_ASM && !USE_ARM_ASM*/
+
 /* Macros to compute the g() function in the encryption and decryption
  * rounds.  G1 is the straight g() function; G2 includes the 8-bit
  * rotation for the high 32-bit word. */
@@ -764,16 +815,40 @@ twofish_setkey (void *context, const byte *key, unsigned int keylen)
  * whitening subkey number m. */
 
 #define INPACK(n, x, m) \
-   x = in[4 * (n)] ^ (in[4 * (n) + 1] << 8) \
-     ^ (in[4 * (n) + 2] << 16) ^ (in[4 * (n) + 3] << 24) ^ ctx->w[m]
+   x = buf_get_le32(in + (n) * 4); \
+   x ^= ctx->w[m]
 
 #define OUTUNPACK(n, x, m) \
    x ^= ctx->w[m]; \
-   out[4 * (n)] = x; out[4 * (n) + 1] = x >> 8; \
-   out[4 * (n) + 2] = x >> 16; out[4 * (n) + 3] = x >> 24
+   buf_put_le32(out + (n) * 4, x)
+
+#endif /*!USE_AMD64_ASM*/
+
 \f
 /* Encrypt one block.  in and out may be the same. */
 
+#ifdef USE_AMD64_ASM
+
+static unsigned int
+twofish_encrypt (void *context, byte *out, const byte *in)
+{
+  TWOFISH_context *ctx = context;
+  _gcry_twofish_amd64_encrypt_block(ctx, out, in);
+  return /*burn_stack*/ (4*sizeof (void*));
+}
+
+#elif defined(USE_ARM_ASM)
+
+static unsigned int
+twofish_encrypt (void *context, byte *out, const byte *in)
+{
+  TWOFISH_context *ctx = context;
+  _gcry_twofish_arm_encrypt_block(ctx, out, in);
+  return /*burn_stack*/ (4*sizeof (void*));
+}
+
+#else /*!USE_AMD64_ASM && !USE_ARM_ASM*/
+
 static void
 do_twofish_encrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
 {
@@ -806,17 +881,41 @@ do_twofish_encrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
   OUTUNPACK (3, b, 7);
 }
 
-static void
+static unsigned int
 twofish_encrypt (void *context, byte *out, const byte *in)
 {
   TWOFISH_context *ctx = context;
   do_twofish_encrypt (ctx, out, in);
-  _gcry_burn_stack (24+3*sizeof (void*));
+  return /*burn_stack*/ (24+3*sizeof (void*));
 }
 
+#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/
+
 \f
 /* Decrypt one block.  in and out may be the same. */
 
+#ifdef USE_AMD64_ASM
+
+static unsigned int
+twofish_decrypt (void *context, byte *out, const byte *in)
+{
+  TWOFISH_context *ctx = context;
+  _gcry_twofish_amd64_decrypt_block(ctx, out, in);
+  return /*burn_stack*/ (4*sizeof (void*));
+}
+
+#elif defined(USE_ARM_ASM)
+
+static unsigned int
+twofish_decrypt (void *context, byte *out, const byte *in)
+{
+  TWOFISH_context *ctx = context;
+  _gcry_twofish_arm_decrypt_block(ctx, out, in);
+  return /*burn_stack*/ (4*sizeof (void*));
+}
+
+#else /*!USE_AMD64_ASM && !USE_ARM_ASM*/
+
 static void
 do_twofish_decrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
 {
@@ -849,13 +948,216 @@ do_twofish_decrypt (const TWOFISH_context *ctx, byte *out, const byte *in)
   OUTUNPACK (3, d, 3);
 }
 
-static void
+static unsigned int
 twofish_decrypt (void *context, byte *out, const byte *in)
 {
   TWOFISH_context *ctx = context;
 
   do_twofish_decrypt (ctx, out, in);
-  _gcry_burn_stack (24+3*sizeof (void*));
+  return /*burn_stack*/ (24+3*sizeof (void*));
+}
+
+#endif /*!USE_AMD64_ASM && !USE_ARM_ASM*/
+
+\f
+
+/* 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 TWOFISH_BLOCKSIZE. */
+void
+_gcry_twofish_ctr_enc(void *context, unsigned char *ctr, void *outbuf_arg,
+                     const void *inbuf_arg, size_t nblocks)
+{
+  TWOFISH_context *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned char tmpbuf[TWOFISH_BLOCKSIZE];
+  unsigned int burn, burn_stack_depth = 0;
+  int i;
+
+#ifdef USE_AMD64_ASM
+  {
+    /* Process data in 3 block chunks. */
+    while (nblocks >= 3)
+      {
+        _gcry_twofish_amd64_ctr_enc(ctx, outbuf, inbuf, ctr);
+
+        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... */
+    /* TODO: use caching instead? */
+  }
+#endif
+
+  for ( ;nblocks; nblocks-- )
+    {
+      /* Encrypt the counter. */
+      burn = twofish_encrypt(ctx, tmpbuf, ctr);
+      if (burn > burn_stack_depth)
+        burn_stack_depth = burn;
+
+      /* XOR the input with the encrypted counter and store in output.  */
+      buf_xor(outbuf, tmpbuf, inbuf, TWOFISH_BLOCKSIZE);
+      outbuf += TWOFISH_BLOCKSIZE;
+      inbuf  += TWOFISH_BLOCKSIZE;
+      /* Increment the counter.  */
+      for (i = TWOFISH_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_twofish_cbc_dec(void *context, unsigned char *iv, void *outbuf_arg,
+                     const void *inbuf_arg, size_t nblocks)
+{
+  TWOFISH_context *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned char savebuf[TWOFISH_BLOCKSIZE];
+  unsigned int burn, burn_stack_depth = 0;
+
+#ifdef USE_AMD64_ASM
+  {
+    /* Process data in 3 block chunks. */
+    while (nblocks >= 3)
+      {
+        _gcry_twofish_amd64_cbc_dec(ctx, outbuf, inbuf, iv);
+
+        nblocks -= 3;
+        outbuf += 3 * TWOFISH_BLOCKSIZE;
+        inbuf += 3 * TWOFISH_BLOCKSIZE;
+
+        burn = 9 * sizeof(void*);
+        if (burn > burn_stack_depth)
+          burn_stack_depth = burn;
+      }
+
+    /* 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.  */
+      burn = twofish_decrypt (ctx, savebuf, inbuf);
+      if (burn > burn_stack_depth)
+        burn_stack_depth = burn;
+
+      buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, TWOFISH_BLOCKSIZE);
+      inbuf += TWOFISH_BLOCKSIZE;
+      outbuf += TWOFISH_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_twofish_cfb_dec(void *context, unsigned char *iv, void *outbuf_arg,
+                   const void *inbuf_arg, size_t nblocks)
+{
+  TWOFISH_context *ctx = context;
+  unsigned char *outbuf = outbuf_arg;
+  const unsigned char *inbuf = inbuf_arg;
+  unsigned int burn, burn_stack_depth = 0;
+
+#ifdef USE_AMD64_ASM
+  {
+    /* Process data in 3 block chunks. */
+    while (nblocks >= 3)
+      {
+        _gcry_twofish_amd64_cfb_dec(ctx, outbuf, inbuf, iv);
+
+        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... */
+  }
+#endif
+
+  for ( ;nblocks; nblocks-- )
+    {
+      burn = twofish_encrypt(ctx, iv, iv);
+      if (burn > burn_stack_depth)
+        burn_stack_depth = burn;
+
+      buf_xor_n_copy(outbuf, iv, inbuf, TWOFISH_BLOCKSIZE);
+      outbuf += TWOFISH_BLOCKSIZE;
+      inbuf += TWOFISH_BLOCKSIZE;
+    }
+
+  _gcry_burn_stack(burn_stack_depth);
+}
+
+\f
+
+/* Run the self-tests for TWOFISH-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 = TWOFISH_BLOCKSIZE;
+  const int context_size = sizeof(TWOFISH_context);
+
+  return _gcry_selftest_helper_ctr("TWOFISH", &twofish_setkey,
+           &twofish_encrypt, &_gcry_twofish_ctr_enc, nblocks, blocksize,
+          context_size);
+}
+
+/* Run the self-tests for TWOFISH-CBC, tests bulk CBC decryption.
+   Returns NULL on success. */
+static const char *
+selftest_cbc (void)
+{
+  const int nblocks = 3+2;
+  const int blocksize = TWOFISH_BLOCKSIZE;
+  const int context_size = sizeof(TWOFISH_context);
+
+  return _gcry_selftest_helper_cbc("TWOFISH", &twofish_setkey,
+           &twofish_encrypt, &_gcry_twofish_cbc_dec, nblocks, blocksize,
+          context_size);
+}
+
+/* Run the self-tests for TWOFISH-CFB, tests bulk CBC decryption.
+   Returns NULL on success. */
+static const char *
+selftest_cfb (void)
+{
+  const int nblocks = 3+2;
+  const int blocksize = TWOFISH_BLOCKSIZE;
+  const int context_size = sizeof(TWOFISH_context);
+
+  return _gcry_selftest_helper_cfb("TWOFISH", &twofish_setkey,
+           &twofish_encrypt, &_gcry_twofish_cfb_dec, nblocks, blocksize,
+          context_size);
 }
 
 \f
@@ -866,6 +1168,7 @@ selftest (void)
 {
   TWOFISH_context ctx; /* Expanded key. */
   byte scratch[16];    /* Encryption/decryption result buffer. */
+  const char *r;
 
   /* Test vectors for single encryption/decryption.  Note that I am using
    * the vectors from the Twofish paper's "known answer test", I=3 for
@@ -915,6 +1218,13 @@ selftest (void)
   if (memcmp (scratch, plaintext_256, sizeof (plaintext_256)))
     return "Twofish-256 test decryption failed.";
 
+  if ((r = selftest_ctr()) != NULL)
+    return r;
+  if ((r = selftest_cbc()) != NULL)
+    return r;
+  if ((r = selftest_cfb()) != NULL)
+    return r;
+
   return NULL;
 }
 \f
@@ -1029,12 +1339,14 @@ main()
 
 gcry_cipher_spec_t _gcry_cipher_spec_twofish =
   {
+    GCRY_CIPHER_TWOFISH, {0, 0},
     "TWOFISH", NULL, NULL, 16, 256, sizeof (TWOFISH_context),
     twofish_setkey, twofish_encrypt, twofish_decrypt
   };
 
 gcry_cipher_spec_t _gcry_cipher_spec_twofish128 =
   {
+    GCRY_CIPHER_TWOFISH128, {0, 0},
     "TWOFISH128", NULL, NULL, 16, 128, sizeof (TWOFISH_context),
     twofish_setkey, twofish_encrypt, twofish_decrypt
   };
index c89a572..338d44e 100644 (file)
  * 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/>.
  */
 
 /* This is an implementation of the Whirlpool hashing algorithm, which
    has been developed by Vincent Rijmen and Paulo S. L. M. Barreto;
    it's homepage is located at:
-   http://planeta.terra.com.br/informatica/paulobarreto/WhirlpoolPage.html.
+   http://www.larc.usp.br/~pbarreto/WhirlpoolPage.html
 
    The S-Boxes and the structure of the main transformation function,
    which implements an optimized version of the algorithm, is taken
    from the reference implementation available from
-   http://planeta.terra.com.br/informatica/paulobarreto/whirlpool.zip.  */
+   http://www.larc.usp.br/~pbarreto/whirlpool.zip
+ */
 
 #include <config.h>
 #include <stdio.h>
@@ -38,7 +37,8 @@
 #include "g10lib.h"
 #include "cipher.h"
 
-#include "bithelp.h"
+#include "bufhelp.h"
+#include "hash-common.h"
 
 /* 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];
 
 typedef struct {
+  gcry_md_block_ctx_t bctx;
   whirlpool_block_t hash_state;
-  unsigned char buffer[BLOCK_SIZE];
-  size_t count;
-  unsigned char length[32];
+  int use_bugemu;
+  struct {
+    size_t count;
+    unsigned char length[32];
+  } bugemu;
 } whirlpool_context_t;
 
 \f
@@ -66,30 +69,13 @@ typedef struct {
    counter.  */
 #define buffer_to_block(buffer, block, i) \
   for (i = 0; i < 8; i++) \
-    (block)[i] = ((u64) (0 \
-                         | (((u64) (buffer)[i * 8 + 0]) << 56) \
-                         | (((u64) (buffer)[i * 8 + 1]) << 48) \
-                         | (((u64) (buffer)[i * 8 + 2]) << 40) \
-                         | (((u64) (buffer)[i * 8 + 3]) << 32) \
-                         | (((u64) (buffer)[i * 8 + 4]) << 24) \
-                         | (((u64) (buffer)[i * 8 + 5]) << 16) \
-                         | (((u64) (buffer)[i * 8 + 6]) <<  8) \
-                         | (((u64) (buffer)[i * 8 + 7]) <<  0)));
+    (block)[i] = buf_get_be64((buffer) + i * 8);
 
 /* Convert the block BLOCK into a buffer BUFFER, using I as
    counter.  */
 #define block_to_buffer(buffer, block, i) \
   for (i = 0; i < 8; i++) \
-    { \
-      (buffer)[i * 8 + 0] = (block[i] >> 56) & 0xFF; \
-      (buffer)[i * 8 + 1] = (block[i] >> 48) & 0xFF; \
-      (buffer)[i * 8 + 2] = (block[i] >> 40) & 0xFF; \
-      (buffer)[i * 8 + 3] = (block[i] >> 32) & 0xFF; \
-      (buffer)[i * 8 + 4] = (block[i] >> 24) & 0xFF; \
-      (buffer)[i * 8 + 5] = (block[i] >> 16) & 0xFF; \
-      (buffer)[i * 8 + 6] = (block[i] >>  8) & 0xFF; \
-      (buffer)[i * 8 + 7] = (block[i] >>  0) & 0xFF; \
-    }
+    buf_put_be64((buffer) + i * 8, (block)[i]);
 
 /* Copy the block BLOCK_SRC to BLOCK_DST, using I as counter.  */
 #define block_copy(block_dst, block_src, i) \
@@ -1177,23 +1163,15 @@ static const u64 C7[256] =
     U64_C (0xf8c7f8933fed6bf8), U64_C (0x86228644a411c286),
   };
 
-\f
-
-static void
-whirlpool_init (void *ctx)
-{
-  whirlpool_context_t *context = ctx;
-
-  memset (context, 0, sizeof (*context));
-}
-
 
+\f
 /*
  * Transform block.
  */
-static void
-whirlpool_transform (whirlpool_context_t *context, const unsigned char *data)
+static unsigned int
+whirlpool_transform (void *ctx, const unsigned char *data)
 {
+  whirlpool_context_t *context = ctx;
   whirlpool_block_t data_block;
   whirlpool_block_t key;
   whirlpool_block_t state;
@@ -1285,11 +1263,35 @@ whirlpool_transform (whirlpool_context_t *context, const unsigned char *data)
 
   block_xor (context->hash_state, data_block, i);
   block_xor (context->hash_state, state, i);
+
+  return /*burn_stack*/ 4 * sizeof(whirlpool_block_t) + 2 * sizeof(int) +
+                        4 * sizeof(void*);
 }
 
+
+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;
+}
+
+
+/* Bug compatibility Whirlpool version.  */
 static void
-whirlpool_add (whirlpool_context_t *context,
-              const void *buffer_arg, size_t buffer_n)
+whirlpool_add_bugemu (whirlpool_context_t *context,
+                      const void *buffer_arg, size_t buffer_n)
 {
   const unsigned char *buffer = buffer_arg;
   u64 buffer_size;
@@ -1298,40 +1300,37 @@ whirlpool_add (whirlpool_context_t *context,
 
   buffer_size = buffer_n;
 
-  if (context->count == BLOCK_SIZE)
+  if (context->bugemu.count == BLOCK_SIZE)
     {
       /* Flush the buffer.  */
-      whirlpool_transform (context, context->buffer);
-      /*_gcry_burn_stack (80+6*sizeof(void*));*/ /* FIXME */
-      context->count = 0;
+      whirlpool_transform (context, context->bctx.buf);
+      context->bugemu.count = 0;
     }
   if (! buffer)
     return; /* Nothing to add.  */
 
-  if (context->count)
+  if (context->bugemu.count)
     {
-      while (buffer_n && (context->count < BLOCK_SIZE))
+      while (buffer_n && (context->bugemu.count < BLOCK_SIZE))
        {
-         context->buffer[context->count++] = *buffer++;
+         context->bctx.buf[context->bugemu.count++] = *buffer++;
          buffer_n--;
        }
-      whirlpool_add (context, NULL, 0);
+      whirlpool_add_bugemu (context, NULL, 0);
       if (!buffer_n)
-       /* Done.  */
-        return;
+        return; /* Done.  This is the bug we emulate.  */
     }
-  /*_gcry_burn_stack (80+6*sizeof(void*));*/ /* FIXME */
 
   while (buffer_n >= BLOCK_SIZE)
     {
       whirlpool_transform (context, buffer);
-      context->count = 0;
+      context->bugemu.count = 0;
       buffer_n -= BLOCK_SIZE;
       buffer += BLOCK_SIZE;
     }
-  while (buffer_n && (context->count < BLOCK_SIZE))
+  while (buffer_n && (context->bugemu.count < BLOCK_SIZE))
     {
-      context->buffer[context->count++] = *buffer++;
+      context->bctx.buf[context->bugemu.count++] = *buffer++;
       buffer_n--;
     }
 
@@ -1343,20 +1342,65 @@ whirlpool_add (whirlpool_context_t *context,
       if (! (buffer_size || carry))
        break;
 
-      carry += context->length[32 - i] + (buffer_size & 0xFF);
-      context->length[32 - i] = carry;
+      carry += context->bugemu.length[32 - i] + (buffer_size & 0xFF);
+      context->bugemu.length[32 - i] = carry;
       buffer_size >>= 8;
       carry >>= 8;
     }
   gcry_assert (! (buffer_size || carry));
 }
 
+
+/* Bug compatibility Whirlpool version.  */
+static void
+whirlpool_final_bugemu (void *ctx)
+{
+  whirlpool_context_t *context = ctx;
+  unsigned int i;
+
+  /* Flush.  */
+  whirlpool_add_bugemu (context, NULL, 0);
+
+  /* Pad.  */
+  context->bctx.buf[context->bugemu.count++] = 0x80;
+
+  if (context->bugemu.count > 32)
+    {
+      /* An extra block is necessary.  */
+      while (context->bugemu.count < 64)
+       context->bctx.buf[context->bugemu.count++] = 0;
+      whirlpool_add_bugemu (context, NULL, 0);
+    }
+  while (context->bugemu.count < 32)
+    context->bctx.buf[context->bugemu.count++] = 0;
+
+  /* Add length of message.  */
+  memcpy (context->bctx.buf + context->bugemu.count,
+          context->bugemu.length, 32);
+  context->bugemu.count += 32;
+  whirlpool_add_bugemu (context, NULL, 0);
+
+  block_to_buffer (context->bctx.buf, context->hash_state, i);
+}
+
+
 static void
 whirlpool_write (void *ctx, const void *buffer, size_t buffer_n)
 {
   whirlpool_context_t *context = ctx;
 
-  whirlpool_add (context, buffer, buffer_n);
+  if (context->use_bugemu)
+    {
+      whirlpool_add_bugemu (context, buffer, buffer_n);
+    }
+  else
+    {
+      u64 old_nblocks = context->bctx.nblocks;
+
+      _gcry_md_block_write (context, buffer, buffer_n);
+
+      gcry_assert (old_nblocks <= context->bctx.nblocks);
+    }
 }
 
 static void
@@ -1364,29 +1408,60 @@ whirlpool_final (void *ctx)
 {
   whirlpool_context_t *context = ctx;
   unsigned int i;
+  u64 t, th, lsb, msb;
+  unsigned char *length;
+
+  if (context->use_bugemu)
+    {
+      whirlpool_final_bugemu (ctx);
+      return;
+    }
+
+  t = context->bctx.nblocks;
+  /* if (sizeof t == sizeof context->bctx.nblocks) */
+  th = context->bctx.nblocks_high;
+  /* else */
+  /*   th = context->bctx.nblocks >> 64; In case we ever use u128 */
+
+  /* multiply by 64 to make a byte count */
+  lsb = t << 6;
+  msb = (th << 6) | (t >> 58);
+  /* add the count */
+  t = lsb;
+  if ((lsb += context->bctx.count) < t)
+    msb++;
+  /* multiply by 8 to make a bit count */
+  t = lsb;
+  lsb <<= 3;
+  msb <<= 3;
+  msb |= t >> 61;
 
   /* Flush.  */
-  whirlpool_add (context, NULL, 0);
+  whirlpool_write (context, NULL, 0);
 
   /* Pad.  */
-  context->buffer[context->count++] = 0x80;
+  context->bctx.buf[context->bctx.count++] = 0x80;
 
-  if (context->count > 32)
+  if (context->bctx.count > 32)
     {
       /* An extra block is necessary.  */
-      while (context->count < 64)
-       context->buffer[context->count++] = 0;
-      whirlpool_add (context, NULL, 0);
+      while (context->bctx.count < 64)
+       context->bctx.buf[context->bctx.count++] = 0;
+      whirlpool_write (context, NULL, 0);
     }
-  while (context->count < 32)
-    context->buffer[context->count++] = 0;
+  while (context->bctx.count < 32)
+    context->bctx.buf[context->bctx.count++] = 0;
 
   /* Add length of message.  */
-  memcpy (context->buffer + context->count, context->length, 32);
-  context->count += 32;
-  whirlpool_add (context, NULL, 0);
+  length = context->bctx.buf + context->bctx.count;
+  buf_put_be64(&length[0 * 8], 0);
+  buf_put_be64(&length[1 * 8], 0);
+  buf_put_be64(&length[2 * 8], msb);
+  buf_put_be64(&length[3 * 8], lsb);
+  context->bctx.count += 32;
+  whirlpool_write (context, NULL, 0);
 
-  block_to_buffer (context->buffer, context->hash_state, i);
+  block_to_buffer (context->bctx.buf, context->hash_state, i);
 }
 
 static byte *
@@ -1394,11 +1469,12 @@ whirlpool_read (void *ctx)
 {
   whirlpool_context_t *context = ctx;
 
-  return context->buffer;
+  return context->bctx.buf;
 }
 
 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,
     sizeof (whirlpool_context_t)
index 5e335d1..bb2d26b 100644 (file)
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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; \
+    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;; \
+    esac; \
+    test $$am__dry = yes; \
+  }
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -71,41 +88,64 @@ DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in clock.c \
        getpid.c
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.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/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/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
        $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
-       $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+       $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/acinclude.m4 \
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
 LTLIBRARIES = $(noinst_LTLIBRARIES)
 am_libcompat_la_OBJECTS = compat.lo
 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
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
 am__depfiles_maybe = depfiles
 am__mv = mv -f
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
-       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+       $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(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 = @
 CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
-       $(LDFLAGS) -o $@
+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   " $@;
 SOURCES = $(libcompat_la_SOURCES)
 DIST_SOURCES = $(libcompat_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AR = @AR@
 AS = @AS@
 AUTOCONF = @AUTOCONF@
@@ -120,6 +160,7 @@ CCAS = @CCAS@
 CCASDEPMODE = @CCASDEPMODE@
 CCASFLAGS = @CCASFLAGS@
 CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
@@ -139,6 +180,8 @@ FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
 FGREP = @FGREP@
 GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
 GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_HWF_MODULES = @GCRYPT_HWF_MODULES@
+GCRYPT_KDFS = @GCRYPT_KDFS@
 GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
 GCRYPT_RANDOM = @GCRYPT_RANDOM@
 GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
@@ -164,14 +207,19 @@ 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@
 MKDIR_P = @MKDIR_P@
 MPI_SFLAGS = @MPI_SFLAGS@
 NM = @NM@
@@ -194,16 +242,19 @@ PTH_CONFIG = @PTH_CONFIG@
 PTH_LIBS = @PTH_LIBS@
 RANLIB = @RANLIB@
 RC = @RC@
+RUN_LARGE_DATA_TESTS = @RUN_LARGE_DATA_TESTS@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
 SYS_SOCKET_H = @SYS_SOCKET_H@
 VERSION = @VERSION@
+VERSION_NUMBER = @VERSION_NUMBER@
 abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
@@ -239,7 +290,6 @@ libdir = @libdir@
 libexecdir = @libexecdir@
 localedir = @localedir@
 localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 oldincludedir = @oldincludedir@
@@ -309,8 +359,8 @@ clean-noinstLTLIBRARIES:
          echo "rm -f \"$${dir}/so_locations\""; \
          rm -f "$${dir}/so_locations"; \
        done
-libcompat.la: $(libcompat_la_OBJECTS) $(libcompat_la_DEPENDENCIES) 
-       $(LINK)  $(libcompat_la_OBJECTS) $(libcompat_la_LIBADD) $(LIBS)
+libcompat.la: $(libcompat_la_OBJECTS) $(libcompat_la_DEPENDENCIES) $(EXTRA_libcompat_la_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK)  $(libcompat_la_OBJECTS) $(libcompat_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
        -rm -f *.$(OBJEXT)
@@ -323,25 +373,25 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compat.Plo@am__quote@
 
 .c.o:
-@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@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@  $(COMPILE) -c $<
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
 
 .c.obj:
-@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@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@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
 
 .c.lo:
-@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
 mostlyclean-libtool:
        -rm -f *.lo
@@ -445,10 +495,15 @@ install-am: all-am
 
 installcheck: installcheck-am
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-         `test -z '$(STRIP)' || \
-           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+       if test -z '$(STRIP)'; then \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+             install; \
+       else \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+           "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+       fi
 mostlyclean-generic:
 
 clean-generic:
index e2a0393..f59a41c 100644 (file)
 const char *
 _gcry_compat_identification (void)
 {
+  /* For complete list of copyright holders see the file AUTHORS in
+     the source distribution.  */
   static const char blurb[] =
     "\n\n"
     "This is Libgcrypt " PACKAGE_VERSION " - The GNU Crypto Library\n"
-    "Copyright 2000, 2002, 2003, 2004, 2007, 2008, 2009,\n"
-    "          2010, 2011 Free Software Foundation, Inc.\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"
+    "\n"
+    "(" BUILD_REVISION " " BUILD_TIMESTAMP ")\n"
     "\n\n";
   return blurb;
 }
index 54b6679..d4202db 100644 (file)
 /* Define if building universal (internal helper macro) */
 #undef AC_APPLE_UNIVERSAL_BUILD
 
-/* Subversion revision used to build this package */
+/* GIT commit id revision used to build this package */
 #undef BUILD_REVISION
 
+/* The time this package was configured for a build */
+#undef BUILD_TIMESTAMP
+
 /* configure did not test for endianess */
 #undef DISABLED_ENDIAN_CHECK
 
 /* Enable support for Intel AES-NI instructions. */
 #undef ENABLE_AESNI_SUPPORT
 
+/* Enable support for Intel AVX2 instructions. */
+#undef ENABLE_AVX2_SUPPORT
+
+/* Enable support for Intel AVX instructions. */
+#undef ENABLE_AVX_SUPPORT
+
+/* Enable support for Intel DRNG (RDRAND instruction). */
+#undef ENABLE_DRNG_SUPPORT
+
 /* Define to support an HMAC based integrity check */
 #undef ENABLE_HMAC_BINARY_CHECK
 
+/* Enable support for ARM NEON instructions. */
+#undef ENABLE_NEON_SUPPORT
+
 /* Enable support for the PadLock engine. */
 #undef ENABLE_PADLOCK_SUPPORT
 
+/* Enable support for Intel PCLMUL instructions. */
+#undef ENABLE_PCLMUL_SUPPORT
+
 /* Define to use the GNU C visibility attribute. */
 #undef GCRY_USE_VISIBILITY
 
 /* The default error source for libgcrypt. */
 #undef GPG_ERR_SOURCE_DEFAULT
 
+/* Defined if ARM architecture is v6 or newer */
+#undef HAVE_ARM_ARCH_V6
+
 /* Define to 1 if you have the `atexit' function. */
 #undef HAVE_ATEXIT
 
 /* Defined if the mlock() call does not work */
 #undef HAVE_BROKEN_MLOCK
 
+/* Defined if compiler has '__builtin_bswap32' intrinsic */
+#undef HAVE_BUILTIN_BSWAP32
+
+/* Defined if compiler has '__builtin_bswap64' intrinsic */
+#undef HAVE_BUILTIN_BSWAP64
+
 /* Defined if a `byte' is typedef'd */
 #undef HAVE_BYTE_TYPEDEF
 
 /* Define to 1 if you have the `clock_gettime' function. */
 #undef HAVE_CLOCK_GETTIME
 
+/* Defined if underlying assembler is compatible with amd64 assembly
+   implementations */
+#undef HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS
+
+/* Defined if underlying assembler is compatible with ARM assembly
+   implementations */
+#undef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS
+
+/* Defined for Alpha platforms */
+#undef HAVE_CPU_ARCH_ALPHA
+
+/* Defined for ARM platforms */
+#undef HAVE_CPU_ARCH_ARM
+
+/* Defined for M68k platforms */
+#undef HAVE_CPU_ARCH_M68K
+
+/* Defined for MIPS platforms */
+#undef HAVE_CPU_ARCH_MIPS
+
+/* Defined for PPC platforms */
+#undef HAVE_CPU_ARCH_PPC
+
+/* Defined for SPARC platforms */
+#undef HAVE_CPU_ARCH_SPARC
+
+/* Defined for the x86 platforms */
+#undef HAVE_CPU_ARCH_X86
+
 /* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you
    don't. */
 #undef HAVE_DECL_SYS_SIGLIST
 /* Define to 1 if you have the `fcntl' function. */
 #undef HAVE_FCNTL
 
+/* Define to 1 if you have the `flockfile' function. */
+#undef HAVE_FLOCKFILE
+
 /* Define to 1 if you have the `ftruncate' function. */
 #undef HAVE_FTRUNCATE
 
+/* Define if inline asm memory barrier is supported */
+#undef HAVE_GCC_ASM_VOLATILE_MEMORY
+
+/* Defined if a GCC style "__attribute__ ((aligned (n))" is supported */
+#undef HAVE_GCC_ATTRIBUTE_ALIGNED
+
+/* Defined if inline assembler supports AVX instructions */
+#undef HAVE_GCC_INLINE_ASM_AVX
+
+/* Defined if inline assembler supports AVX2 instructions */
+#undef HAVE_GCC_INLINE_ASM_AVX2
+
+/* Defined if inline assembler supports BMI2 instructions */
+#undef HAVE_GCC_INLINE_ASM_BMI2
+
+/* Defined if inline assembler supports NEON instructions */
+#undef HAVE_GCC_INLINE_ASM_NEON
+
+/* Defined if inline assembler supports PCLMUL instructions */
+#undef HAVE_GCC_INLINE_ASM_PCLMUL
+
+/* Defined if inline assembler supports SSSE3 instructions */
+#undef HAVE_GCC_INLINE_ASM_SSSE3
+
 /* Define to 1 if you have the `gethrtime' function. */
 #undef HAVE_GETHRTIME
 
 /* Define to 1 if you have the `gettimeofday' function. */
 #undef HAVE_GETTIMEOFDAY
 
+/* Defined if underlying assembler is compatible with Intel syntax assembly
+   implementations */
+#undef HAVE_INTEL_SYNTAX_PLATFORM_AS
+
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
 /* 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 to 1 if you have the `raise' function. */
 #undef HAVE_RAISE
 
 /* Defined if a `ushort' is typedef'd */
 #undef HAVE_USHORT_TYPEDEF
 
+/* Defined if variable length arrays are supported */
+#undef HAVE_VLA
+
 /* Define to 1 if you have the `vprintf' function. */
 #undef HAVE_VPRINTF
 
 /* List of available digest algorithms */
 #undef LIBGCRYPT_DIGESTS
 
+/* List of available KDF algorithms */
+#undef LIBGCRYPT_KDFS
+
 /* List of available public key cipher algorithms */
 #undef LIBGCRYPT_PUBKEY_CIPHERS
 
 /* 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
 
 #undef USE_GNU_PTH
 
 /* Defined if this module should be included */
+#undef USE_GOST28147
+
+/* Defined if this module should be included */
+#undef USE_GOST_R_3411_12
+
+/* Defined if this module should be included */
+#undef USE_GOST_R_3411_94
+
+/* Defined if this module should be included */
+#undef USE_IDEA
+
+/* 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_RSA
 
 /* Defined if this module should be included */
+#undef USE_SALSA20
+
+/* Defined if this module should be included */
+#undef USE_SCRYPT
+
+/* Defined if this module should be included */
 #undef USE_SEED
 
 /* Defined if this module should be included */
 /* Defined if this module should be included */
 #undef USE_SHA512
 
+/* Define if the old Solaris multithreading library can be used. */
+#undef USE_SOLARIS_THREADS
+
+/* Define if references to the old Solaris multithreading library should be
+   made weak. */
+#undef USE_SOLARIS_THREADS_WEAK
+
 /* Enable extensions on AIX 3, Interix.  */
 #ifndef _ALL_SOURCE
 # undef _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
 
 #endif
 
 
+/* Define to supported assembler block keyword, if plain 'asm' was not
+   supported */
+#undef asm
+
 /* Define to empty if `const' does not conform to ANSI C. */
 #undef const
 
    properly prefixed.  */
 #define CAMELLIA_EXT_SYM_PREFIX _gcry_
 
-/* This error code is only available with gpg-error 1.7.  Thus
-   we define it here with the usual gcry prefix.  */
-#define GCRY_GPG_ERR_NOT_OPERATIONAL  176
-
-
 #endif /*_GCRYPT_CONFIG_H_INCLUDED*/
 
index 20a5bbf..12b0833 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,13 +1,13 @@
 #! /bin/sh
 # From configure.ac Revision.
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.64 for libgcrypt 1.5.0.
+# Generated by GNU Autoconf 2.69 for libgcrypt 1.6.1.
 #
-# Report bugs to <bug-libgcrypt@gnupg.org>.
+# Report bugs to <http://bugs.gnupg.org>.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
 #
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software
-# Foundation, Inc.
 #
 # This configure script is free software; the Free Software Foundation
 # gives unlimited permission to copy, distribute and modify it.
@@ -90,6 +90,7 @@ fi
 IFS=" ""       $as_nl"
 
 # Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
 case $0 in #((
   *[\\/]* ) as_myself=$0 ;;
   *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -134,6 +135,31 @@ export LANGUAGE
 # CDPATH.
 (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
 if test "x$CONFIG_SHELL" = x; then
   as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
   emulate sh
@@ -167,12 +193,21 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
 else
   exitcode=1; echo positional parameters were not saved.
 fi
-test x\$exitcode = x0 || exit 1"
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
   as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
   as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
   eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
   test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
-test \$(( 1 + 1 )) = 2 || exit 1"
+test \$(( 1 + 1 )) = 2 || exit 1
+
+  test -n \"\${ZSH_VERSION+set}\${BASH_VERSION+set}\" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    ECHO=\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO\$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test \"X\`printf %s \$ECHO\`\" = \"X\$ECHO\" \\
+      || test \"X\`print -r -- \$ECHO\`\" = \"X\$ECHO\" ) || exit 1"
   if (eval "$as_required") 2>/dev/null; then :
   as_have_required=yes
 else
@@ -212,14 +247,25 @@ IFS=$as_save_IFS
 
 
       if test "x$CONFIG_SHELL" != x; then :
-  # We cannot yet assume a decent shell, so we have to provide a
-       # neutralization value for shells without unset; and this also
-       # works around shells that cannot unset nonexistent variables.
-       BASH_ENV=/dev/null
-       ENV=/dev/null
-       (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
-       export CONFIG_SHELL
-       exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
 fi
 
     if test x$as_have_required = xno; then :
@@ -230,10 +276,10 @@ fi
     $as_echo "$0: be upgraded to zsh 4.3.4 or later."
   else
     $as_echo "$0: Please tell bug-autoconf@gnu.org and
-$0: bug-libgcrypt@gnupg.org about your system, including
-$0: any error possibly output before this message. Then
-$0: install a modern shell, or manually run the script
-$0: under such a shell if you do have one."
+$0: http://bugs.gnupg.org about your system, including any
+$0: error possibly output before this message. Then install
+$0: a modern shell, or manually run the script under such a
+$0: shell if you do have one."
   fi
   exit 1
 fi
@@ -318,10 +364,18 @@ $as_echo X"$as_dir" |
       test -d "$as_dir" && break
     done
     test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
 
 
 } # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
 # as_fn_append VAR VALUE
 # ----------------------
 # Append the text in VALUE to the end of the definition contained in VAR. Take
@@ -358,19 +412,19 @@ else
 fi # as_fn_arith
 
 
-# as_fn_error ERROR [LINENO LOG_FD]
-# ---------------------------------
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
 # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
 # provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with status $?, using 1 if that was 0.
+# script with STATUS, using 1 if that was 0.
 as_fn_error ()
 {
-  as_status=$?; test $as_status -eq 0 && as_status=1
-  if test "$3"; then
-    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-  $as_echo "$as_me: error: $1" >&2
+  $as_echo "$as_me: error: $2" >&2
   as_fn_exit $as_status
 } # as_fn_error
 
@@ -443,6 +497,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits
   chmod +x "$as_me.lineno" ||
     { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
 
+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
   # Don't try to exec as it changes $[0], causing all sort of problems
   # (the dirname of $[0] is not the place where we might find the
   # original and so on.  Autoconf is especially sensitive to this).
@@ -477,16 +535,16 @@ if (echo >conf$$.file) 2>/dev/null; then
     # ... but there are two gotchas:
     # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
     # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-    # In both cases, we have to default to `cp -p'.
+    # In both cases, we have to default to `cp -pR'.
     ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-      as_ln_s='cp -p'
+      as_ln_s='cp -pR'
   elif ln conf$$.file conf$$ 2>/dev/null; then
     as_ln_s=ln
   else
-    as_ln_s='cp -p'
+    as_ln_s='cp -pR'
   fi
 else
-  as_ln_s='cp -p'
+  as_ln_s='cp -pR'
 fi
 rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
 rmdir conf$$.dir 2>/dev/null
@@ -498,28 +556,8 @@ else
   as_mkdir_p=false
 fi
 
-if test -x / >/dev/null 2>&1; then
-  as_test_x='test -x'
-else
-  if ls -dL / >/dev/null 2>&1; then
-    as_ls_L_option=L
-  else
-    as_ls_L_option=
-  fi
-  as_test_x='
-    eval sh -c '\''
-      if test -d "$1"; then
-       test -d "$1/.";
-      else
-       case $1 in #(
-       -*)set "./$1";;
-       esac;
-       case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
-       ???[sx]*):;;*)false;;esac;fi
-    '\'' sh
-  '
-fi
-as_executable_p=$as_test_x
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
 
 # Sed expression to map a string onto a valid CPP name.
 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -527,160 +565,14 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
 # Sed expression to map a string onto a valid variable name.
 as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
 
-
-
-# Check that we are running under the correct shell.
 SHELL=${CONFIG_SHELL-/bin/sh}
 
-case X$lt_ECHO in
-X*--fallback-echo)
-  # Remove one level of quotation (which was required for Make).
-  ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','`
-  ;;
-esac
-
-ECHO=${lt_ECHO-echo}
-if test "X$1" = X--no-reexec; then
-  # Discard the --no-reexec flag, and continue.
-  shift
-elif test "X$1" = X--fallback-echo; then
-  # Avoid inline document here, it may be left over
-  :
-elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
-  # Yippee, $ECHO works!
-  :
-else
-  # Restart under the correct shell.
-  exec $SHELL "$0" --no-reexec ${1+"$@"}
-fi
-
-if test "X$1" = X--fallback-echo; then
-  # used as fallback echo
-  shift
-  cat <<_LT_EOF
-$*
-_LT_EOF
-  exit 0
-fi
-
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-if test -z "$lt_ECHO"; then
-  if test "X${echo_test_string+set}" != Xset; then
-    # find a string as large as possible, as long as the shell can cope with it
-    for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do
-      # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
-      if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
-        { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
-      then
-        break
-      fi
-    done
-  fi
-
-  if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
-     echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
-     test "X$echo_testing_string" = "X$echo_test_string"; then
-    :
-  else
-    # The Solaris, AIX, and Digital Unix default echo programs unquote
-    # backslashes.  This makes it impossible to quote backslashes using
-    #   echo "$something" | sed 's/\\/\\\\/g'
-    #
-    # So, first we look for a working echo in the user's PATH.
-
-    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
-    for dir in $PATH /usr/ucb; do
-      IFS="$lt_save_ifs"
-      if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
-         test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
-         echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
-         test "X$echo_testing_string" = "X$echo_test_string"; then
-        ECHO="$dir/echo"
-        break
-      fi
-    done
-    IFS="$lt_save_ifs"
-
-    if test "X$ECHO" = Xecho; then
-      # We didn't find a better echo, so look for alternatives.
-      if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
-         echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
-         test "X$echo_testing_string" = "X$echo_test_string"; then
-        # This shell has a builtin print -r that does the trick.
-        ECHO='print -r'
-      elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
-          test "X$CONFIG_SHELL" != X/bin/ksh; then
-        # If we have ksh, try running configure again with it.
-        ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
-        export ORIGINAL_CONFIG_SHELL
-        CONFIG_SHELL=/bin/ksh
-        export CONFIG_SHELL
-        exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"}
-      else
-        # Try using printf.
-        ECHO='printf %s\n'
-        if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
-          echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
-          test "X$echo_testing_string" = "X$echo_test_string"; then
-         # Cool, printf works
-         :
-        elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
-            test "X$echo_testing_string" = 'X\t' &&
-            echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
-            test "X$echo_testing_string" = "X$echo_test_string"; then
-         CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
-         export CONFIG_SHELL
-         SHELL="$CONFIG_SHELL"
-         export SHELL
-         ECHO="$CONFIG_SHELL $0 --fallback-echo"
-        elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` &&
-            test "X$echo_testing_string" = 'X\t' &&
-            echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
-            test "X$echo_testing_string" = "X$echo_test_string"; then
-         ECHO="$CONFIG_SHELL $0 --fallback-echo"
-        else
-         # maybe with a smaller string...
-         prev=:
-
-         for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do
-           if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
-           then
-             break
-           fi
-           prev="$cmd"
-         done
-
-         if test "$prev" != 'sed 50q "$0"'; then
-           echo_test_string=`eval $prev`
-           export echo_test_string
-           exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"}
-         else
-           # Oops.  We lost completely, so just stick with echo.
-           ECHO=echo
-         fi
-        fi
-      fi
-    fi
-  fi
-fi
-
-# Copy echo and quote the copy suitably for passing to libtool from
-# the Makefile, instead of quoting the original, which is used later.
-lt_ECHO=$ECHO
-if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then
-   lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo"
-fi
-
 
-
-
-exec 7<&0 </dev/null 6>&1
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
 
 # Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
 # so uname gets run too.
 ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
 
@@ -699,9 +591,9 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='libgcrypt'
 PACKAGE_TARNAME='libgcrypt'
-PACKAGE_VERSION='1.5.0'
-PACKAGE_STRING='libgcrypt 1.5.0'
-PACKAGE_BUGREPORT='bug-libgcrypt@gnupg.org'
+PACKAGE_VERSION='1.6.1'
+PACKAGE_STRING='libgcrypt 1.6.1'
+PACKAGE_BUGREPORT='http://bugs.gnupg.org'
 PACKAGE_URL=''
 
 ac_unique_file="src/libgcrypt.vers"
@@ -742,16 +634,19 @@ ac_includes_default="\
 # include <unistd.h>
 #endif"
 
+gl_use_threads_default=
 ac_subst_vars='am__EXEEXT_FALSE
 am__EXEEXT_TRUE
 LTLIBOBJS
-BUILD_FILEVERSION
 BUILD_TIMESTAMP
+BUILD_FILEVERSION
 BUILD_REVISION
+GCRYPT_HWF_MODULES
 LIBGCRYPT_DIGESTS
 LIBGCRYPT_PUBKEY_CIPHERS
 LIBGCRYPT_CIPHERS
 GCRYPT_RANDOM
+GCRYPT_KDFS
 GCRYPT_DIGESTS
 GCRYPT_PUBKEY_CIPHERS
 GCRYPT_CIPHERS
@@ -763,6 +658,8 @@ LIBGCRYPT_CONFIG_API_VERSION
 NOEXECSTACK_FLAGS
 CROSS_COMPILING_FALSE
 CROSS_COMPILING_TRUE
+DL_LIBS
+LIBOBJS
 MPI_MOD_C_UDIV_QRNND_FALSE
 MPI_MOD_C_UDIV_QRNND_TRUE
 MPI_MOD_C_UDIV_FALSE
@@ -800,11 +697,13 @@ MPI_MOD_ASM_MPIH_SUB1_TRUE
 MPI_MOD_ASM_MPIH_ADD1_FALSE
 MPI_MOD_ASM_MPIH_ADD1_TRUE
 MPI_SFLAGS
-DL_LIBS
-LIBOBJS
 FALLBACK_SOCKLEN_T
 SYS_SOCKET_H
 INSERT_SYS_SELECT_H
+LTLIBMULTITHREAD
+LIBMULTITHREAD
+LTLIBTHREAD
+LIBTHREAD
 PTH_LIBS
 PTH_CFLAGS
 PTH_CONFIG
@@ -815,6 +714,7 @@ HAVE_LD_VERSION_SCRIPT_FALSE
 HAVE_LD_VERSION_SCRIPT_TRUE
 ENABLE_O_FLAG_MUNGING_FALSE
 ENABLE_O_FLAG_MUNGING_TRUE
+RUN_LARGE_DATA_TESTS
 USE_RANDOM_DAEMON_FALSE
 USE_RANDOM_DAEMON_TRUE
 emacs_local_vars_end
@@ -830,8 +730,9 @@ OTOOL
 LIPO
 NMEDIT
 DSYMUTIL
-lt_ECHO
+MANIFEST_TOOL
 RANLIB
+ac_ct_AR
 AR
 LN_S
 NM
@@ -844,6 +745,7 @@ LIBTOOL
 OBJDUMP
 DLLTOOL
 AS
+CC_FOR_BUILD
 EGREP
 GREP
 am__fastdepCCAS_FALSE
@@ -855,6 +757,7 @@ CPP
 am__fastdepCC_FALSE
 am__fastdepCC_TRUE
 CCDEPMODE
+am__nodep
 AMDEPBACKSLASH
 AMDEP_FALSE
 AMDEP_TRUE
@@ -868,9 +771,14 @@ CPPFLAGS
 LDFLAGS
 CFLAGS
 CC
+VERSION_NUMBER
 LIBGCRYPT_LT_REVISION
 LIBGCRYPT_LT_AGE
 LIBGCRYPT_LT_CURRENT
+AM_BACKSLASH
+AM_DEFAULT_VERBOSITY
+AM_DEFAULT_V
+AM_V
 MAINT
 MAINTAINER_MODE_FALSE
 MAINTAINER_MODE_TRUE
@@ -947,31 +855,43 @@ ac_subst_files=''
 ac_user_opts='
 enable_option_checking
 enable_maintainer_mode
+enable_silent_rules
 enable_dependency_tracking
 enable_static
 enable_shared
 with_pic
 enable_fast_install
 with_gnu_ld
+with_sysroot
 enable_libtool_lock
 enable_endian_check
 enable_ciphers
 enable_pubkey_ciphers
 enable_digests
+enable_kdfs
 enable_random
 enable_dev_random
 with_egd_socket
 enable_random_daemon
 enable_asm
 enable_m_guard
+enable_large_data_tests
 with_capabilities
 enable_hmac_binary_check
 enable_padlock_support
 enable_aesni_support
+enable_pclmul_support
+enable_drng_support
+enable_avx_support
+enable_avx2_support
+enable_neon_support
 enable_O_flag_munging
+enable_amd64_as_feature_detection
 enable_ld_version_script
+with_libgpg_error_prefix
 with_gpg_error_prefix
 with_pth_prefix
+enable_threads
 enable_mpi_path
 enable_optimization
 enable_noexecstack
@@ -986,7 +906,8 @@ LIBS
 CPPFLAGS
 CPP
 CCAS
-CCASFLAGS'
+CCASFLAGS
+CC_FOR_BUILD'
 
 
 # Initialize some variables set by options.
@@ -1049,8 +970,9 @@ do
   fi
 
   case $ac_option in
-  *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
-  *)   ac_optarg=yes ;;
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
   esac
 
   # Accept the important Cygnus configure options, so we can diagnose typos.
@@ -1095,7 +1017,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid feature name: $ac_useropt"
+      as_fn_error $? "invalid feature name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -1121,7 +1043,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid feature name: $ac_useropt"
+      as_fn_error $? "invalid feature name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -1325,7 +1247,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid package name: $ac_useropt"
+      as_fn_error $? "invalid package name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -1341,7 +1263,7 @@ do
     ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
     # Reject names that are not valid shell variable names.
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid package name: $ac_useropt"
+      as_fn_error $? "invalid package name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
     ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
     case $ac_user_opts in
@@ -1371,8 +1293,8 @@ do
   | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
     x_libraries=$ac_optarg ;;
 
-  -*) as_fn_error "unrecognized option: \`$ac_option'
-Try \`$0 --help' for more information."
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
     ;;
 
   *=*)
@@ -1380,7 +1302,7 @@ Try \`$0 --help' for more information."
     # Reject names that are not valid shell variable names.
     case $ac_envvar in #(
       '' | [0-9]* | *[!_$as_cr_alnum]* )
-      as_fn_error "invalid variable name: \`$ac_envvar'" ;;
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
     esac
     eval $ac_envvar=\$ac_optarg
     export $ac_envvar ;;
@@ -1390,7 +1312,7 @@ Try \`$0 --help' for more information."
     $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
     expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
       $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
-    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
     ;;
 
   esac
@@ -1398,13 +1320,13 @@ done
 
 if test -n "$ac_prev"; then
   ac_option=--`echo $ac_prev | sed 's/_/-/g'`
-  as_fn_error "missing argument to $ac_option"
+  as_fn_error $? "missing argument to $ac_option"
 fi
 
 if test -n "$ac_unrecognized_opts"; then
   case $enable_option_checking in
     no) ;;
-    fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
     *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
   esac
 fi
@@ -1427,7 +1349,7 @@ do
     [\\/$]* | ?:[\\/]* )  continue;;
     NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
   esac
-  as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
 done
 
 # There might be people who depend on the old broken behavior: `$host'
@@ -1441,8 +1363,6 @@ target=$target_alias
 if test "x$host_alias" != x; then
   if test "x$build_alias" = x; then
     cross_compiling=maybe
-    $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
-    If a cross compiler is detected then cross compile mode will be used." >&2
   elif test "x$build_alias" != "x$host_alias"; then
     cross_compiling=yes
   fi
@@ -1457,9 +1377,9 @@ test "$silent" = yes && exec 6>/dev/null
 ac_pwd=`pwd` && test -n "$ac_pwd" &&
 ac_ls_di=`ls -di .` &&
 ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
-  as_fn_error "working directory cannot be determined"
+  as_fn_error $? "working directory cannot be determined"
 test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
-  as_fn_error "pwd does not report name of working directory"
+  as_fn_error $? "pwd does not report name of working directory"
 
 
 # Find the source files, if location was not specified.
@@ -1498,11 +1418,11 @@ else
 fi
 if test ! -r "$srcdir/$ac_unique_file"; then
   test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
-  as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
 fi
 ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
 ac_abs_confdir=`(
-       cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
+       cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
        pwd)`
 # When building in place, set srcdir=.
 if test "$ac_abs_confdir" = "$ac_pwd"; then
@@ -1528,7 +1448,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.5.0 to adapt to many kinds of systems.
+\`configure' configures libgcrypt 1.6.1 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1542,7 +1462,7 @@ Configuration:
       --help=short        display options specific to this package
       --help=recursive    display the short help of all the included packages
   -V, --version           display version information and exit
-  -q, --quiet, --silent   do not print \`checking...' messages
+  -q, --quiet, --silent   do not print \`checking ...' messages
       --cache-file=FILE   cache test results in FILE [disabled]
   -C, --config-cache      alias for \`--cache-file=config.cache'
   -n, --no-create         do not create output files
@@ -1598,7 +1518,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of libgcrypt 1.5.0:";;
+     short | recursive ) echo "Configuration of libgcrypt 1.6.1:";;
    esac
   cat <<\_ACEOF
 
@@ -1608,6 +1528,8 @@ Optional Features:
   --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-static[=PKGS]  build static libraries [default=no]
@@ -1623,22 +1545,37 @@ Optional Features:
                           select the public-key ciphers to include
   --enable-digests=digests
                           select the message digests 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
   --disable-asm           Disable MPI assembler modules
   --enable-m-guard        Enable memory guard facility
+  --enable-large-data-tests
+                          Enable the real long ruinning large data tests
   --enable-hmac-binary-check
                           Enable library integrity check
   --disable-padlock-support
                           Disable support for the PadLock Engine of VIA
                           processors
   --disable-aesni-support Disable support for the Intel AES-NI instructions
+  --disable-pclmul-support
+                          Disable support for the Intel PCLMUL instructions
+  --disable-drng-support  Disable support for the Intel DRNG (RDRAND
+                          instruction)
+  --disable-avx-support   Disable support for the Intel AVX instructions
+  --disable-avx2-support  Disable support for the Intel AVX2 instructions
+  --disable-neon-support  Disable support for the ARM NEON instructions
   --disable-O-flag-munging
                           Disable modification of the cc -O flag
+  --disable-amd64-as-feature-detection
+                          Disable the auto-detection of AMD64 as(1) 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
@@ -1648,13 +1585,16 @@ Optional Features:
 Optional Packages:
   --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
   --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
-  --with-pic              try to use only PIC/non-PIC objects [default=use
+  --with-pic[=PKGS]       try to use only PIC/non-PIC objects [default=use
                           both]
   --with-gnu-ld           assume the C compiler uses GNU ld [default=no]
+  --with-sysroot=DIR Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).
   --with-egd-socket=NAME  Use NAME for the EGD socket)
-  --with-capabilities     Use linux capabilities default=no
-  --with-gpg-error-prefix=PFX
+  --with-capabilities     Use linux capabilities [default=no]
+  --with-libgpg-error-prefix=PFX
                           prefix where GPG Error is installed (optional)
+
   --with-pth-prefix=PFX   prefix where GNU Pth is installed (optional)
 
 Some influential environment variables:
@@ -1663,16 +1603,18 @@ Some influential environment variables:
   LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
               nonstandard directory <lib dir>
   LIBS        libraries to pass to the linker, e.g. -l<library>
-  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
               you have headers in a nonstandard directory <include dir>
   CPP         C preprocessor
   CCAS        assembler compiler command (defaults to CC)
   CCASFLAGS   assembler compiler flags (defaults to CFLAGS)
+  CC_FOR_BUILD
+              build system C compiler
 
 Use these variables to override the choices made by `configure' or to help
 it to find libraries and programs with nonstandard names/locations.
 
-Report bugs to <bug-libgcrypt@gnupg.org>.
+Report bugs to <http://bugs.gnupg.org>.
 _ACEOF
 ac_status=$?
 fi
@@ -1735,10 +1677,10 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-libgcrypt configure 1.5.0
-generated by GNU Autoconf 2.64
+libgcrypt configure 1.6.1
+generated by GNU Autoconf 2.69
 
-Copyright (C) 2009 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it.
 _ACEOF
@@ -1782,8 +1724,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
        ac_retval=1
 fi
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-  return $ac_retval
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
 
 } # ac_fn_c_try_compile
 
@@ -1808,7 +1750,7 @@ $as_echo "$ac_try_echo"; } >&5
     mv -f conftest.er1 conftest.err
   fi
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } >/dev/null && {
+  test $ac_status = 0; } > conftest.i && {
         test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
         test ! -s conftest.err
        }; then :
@@ -1819,8 +1761,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
     ac_retval=1
 fi
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-  return $ac_retval
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
 
 } # ac_fn_c_try_cpp
 
@@ -1851,7 +1793,7 @@ $as_echo "$ac_try_echo"; } >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext && {
         test "$cross_compiling" = yes ||
-        $as_test_x conftest$ac_exeext
+        test -x conftest$ac_exeext
        }; then :
   ac_retval=0
 else
@@ -1865,8 +1807,8 @@ fi
   # interfere with the next link command; also delete a directory that is
   # left behind by Apple's compiler.  We do this before executing the actions.
   rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-  return $ac_retval
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
 
 } # ac_fn_c_try_link
 
@@ -1878,10 +1820,10 @@ fi
 ac_fn_c_check_header_mongrel ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  if eval \${$3+:} false; then :
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
 fi
 eval ac_res=\$$3
@@ -1917,7 +1859,7 @@ if ac_fn_c_try_cpp "$LINENO"; then :
 else
   ac_header_preproc=no
 fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
 $as_echo "$ac_header_preproc" >&6; }
 
@@ -1940,17 +1882,15 @@ $as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
 $as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
     { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( cat <<\_ASBOX
-## -------------------------------------- ##
-## Report this to bug-libgcrypt@gnupg.org ##
-## -------------------------------------- ##
-_ASBOX
+( $as_echo "## ------------------------------------ ##
+## Report this to http://bugs.gnupg.org ##
+## ------------------------------------ ##"
      ) | sed "s/^/$as_me: WARNING:     /" >&2
     ;;
 esac
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   eval "$3=\$ac_header_compiler"
@@ -1959,7 +1899,7 @@ eval ac_res=\$$3
               { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
 fi
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_header_mongrel
 
@@ -2000,8 +1940,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
        ac_retval=$ac_status
 fi
   rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-  return $ac_retval
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
 
 } # ac_fn_c_try_run
 
@@ -2014,7 +1954,7 @@ ac_fn_c_check_header_compile ()
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2032,7 +1972,7 @@ fi
 eval ac_res=\$$3
               { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_header_compile
 
@@ -2044,7 +1984,7 @@ ac_fn_c_check_func ()
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2099,7 +2039,7 @@ fi
 eval ac_res=\$$3
               { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_func
 
@@ -2120,7 +2060,8 @@ int
 main ()
 {
 static int test_array [1 - 2 * !(($2) >= 0)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
 
   ;
   return 0;
@@ -2136,7 +2077,8 @@ int
 main ()
 {
 static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
 
   ;
   return 0;
@@ -2162,7 +2104,8 @@ int
 main ()
 {
 static int test_array [1 - 2 * !(($2) < 0)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
 
   ;
   return 0;
@@ -2178,7 +2121,8 @@ int
 main ()
 {
 static int test_array [1 - 2 * !(($2) >= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
 
   ;
   return 0;
@@ -2212,7 +2156,8 @@ int
 main ()
 {
 static int test_array [1 - 2 * !(($2) <= $ac_mid)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
 
   ;
   return 0;
@@ -2276,8 +2221,8 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
 rm -f conftest.val
 
   fi
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-  return $ac_retval
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval
 
 } # ac_fn_c_compute_int
 
@@ -2290,7 +2235,7 @@ ac_fn_c_check_type ()
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   eval "$3=no"
@@ -2331,19 +2276,22 @@ fi
 eval ac_res=\$$3
               { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_type
 
-# ac_fn_c_check_decl LINENO SYMBOL VAR
-# ------------------------------------
-# Tests whether SYMBOL is declared, setting cache variable VAR accordingly.
+# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
+# ---------------------------------------------
+# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
+# accordingly.
 ac_fn_c_check_decl ()
 {
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $2 is declared" >&5
-$as_echo_n "checking whether $2 is declared... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  as_decl_name=`echo $2|sed 's/ *(.*//'`
+  as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
+$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -2352,8 +2300,12 @@ $4
 int
 main ()
 {
-#ifndef $2
-  (void) $2;
+#ifndef $as_decl_name
+#ifdef __cplusplus
+  (void) $as_decl_use;
+#else
+  (void) $as_decl_name;
+#endif
 #endif
 
   ;
@@ -2370,15 +2322,15 @@ fi
 eval ac_res=\$$3
               { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
 
 } # ac_fn_c_check_decl
 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.5.0, which was
-generated by GNU Autoconf 2.64.  Invocation command line was
+It was created by libgcrypt $as_me 1.6.1, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
 
@@ -2488,11 +2440,9 @@ trap 'exit_status=$?
   {
     echo
 
-    cat <<\_ASBOX
-## ---------------- ##
+    $as_echo "## ---------------- ##
 ## Cache variables. ##
-## ---------------- ##
-_ASBOX
+## ---------------- ##"
     echo
     # The following way of writing the cache mishandles newlines in values,
 (
@@ -2526,11 +2476,9 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
 )
     echo
 
-    cat <<\_ASBOX
-## ----------------- ##
+    $as_echo "## ----------------- ##
 ## Output variables. ##
-## ----------------- ##
-_ASBOX
+## ----------------- ##"
     echo
     for ac_var in $ac_subst_vars
     do
@@ -2543,11 +2491,9 @@ _ASBOX
     echo
 
     if test -n "$ac_subst_files"; then
-      cat <<\_ASBOX
-## ------------------- ##
+      $as_echo "## ------------------- ##
 ## File substitutions. ##
-## ------------------- ##
-_ASBOX
+## ------------------- ##"
       echo
       for ac_var in $ac_subst_files
       do
@@ -2561,11 +2507,9 @@ _ASBOX
     fi
 
     if test -s confdefs.h; then
-      cat <<\_ASBOX
-## ----------- ##
+      $as_echo "## ----------- ##
 ## confdefs.h. ##
-## ----------- ##
-_ASBOX
+## ----------- ##"
       echo
       cat confdefs.h
       echo
@@ -2620,7 +2564,12 @@ _ACEOF
 ac_site_file1=NONE
 ac_site_file2=NONE
 if test -n "$CONFIG_SITE"; then
-  ac_site_file1=$CONFIG_SITE
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
 elif test "x$prefix" != xNONE; then
   ac_site_file1=$prefix/share/config.site
   ac_site_file2=$prefix/etc/config.site
@@ -2631,18 +2580,22 @@ fi
 for ac_site_file in "$ac_site_file1" "$ac_site_file2"
 do
   test "x$ac_site_file" = xNONE && continue
-  if test -r "$ac_site_file"; then
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
 $as_echo "$as_me: loading site script $ac_site_file" >&6;}
     sed 's/^/| /' "$ac_site_file" >&5
-    . "$ac_site_file"
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
   fi
 done
 
 if test -r "$cache_file"; then
-  # Some versions of bash will fail to source /dev/null (special
-  # files actually), so we avoid doing that.
-  if test -f "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
 $as_echo "$as_me: loading cache $cache_file" >&6;}
     case $cache_file in
@@ -2711,7 +2664,7 @@ if $ac_cache_corrupted; then
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
   { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
-  as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
 fi
 ## -------------------- ##
 ## Main body of script. ##
@@ -2724,41 +2677,47 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
+
 # LT Version numbers, remember to change them just *before* a release.
 #   (Interfaces removed:    CURRENT++, AGE=0, REVISION=0)
 #   (Interfaces added:      CURRENT++, AGE++, REVISION=0)
 #   (No interfaces changed:                   REVISION++)
-LIBGCRYPT_LT_CURRENT=18
-LIBGCRYPT_LT_AGE=7
-LIBGCRYPT_LT_REVISION=0
+LIBGCRYPT_LT_CURRENT=20
+LIBGCRYPT_LT_AGE=0
+LIBGCRYPT_LT_REVISION=1
 
 
 # If the API is changed in an incompatible way: increment the next counter.
+#
+# 1.6: ABI and API change but the change is to most users irrelevant
+#      and thus the API version number has not been incremented.
 LIBGCRYPT_CONFIG_API_VERSION=1
 
-NEED_GPG_ERROR_VERSION=1.8
+# 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
 
-is_development_version=no
-
-BUILD_REVISION=41756
 PACKAGE=$PACKAGE_NAME
 VERSION=$PACKAGE_VERSION
 
-
-am__api_version='1.11'
-
 ac_aux_dir=
-for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
-  for ac_t in install-sh install.sh shtool; do
-    if test -f "$ac_dir/$ac_t"; then
-      ac_aux_dir=$ac_dir
-      ac_install_sh="$ac_aux_dir/$ac_t -c"
-      break 2
-    fi
-  done
+for ac_dir in build-aux "$srcdir"/build-aux; do
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
 done
 if test -z "$ac_aux_dir"; then
-  as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in build-aux \"$srcdir\"/build-aux" "$LINENO" 5
 fi
 
 # These three variables are undocumented and unsupported,
@@ -2770,6 +2729,9 @@ ac_config_sub="$SHELL $ac_aux_dir/config.sub"  # Please don't use this var.
 ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
 
 
+
+am__api_version='1.11'
+
 # Find a good install program.  We prefer a C program (faster),
 # so one script is as good as another.  But avoid the broken or
 # incompatible versions:
@@ -2787,7 +2749,7 @@ ac_configure="$SHELL $ac_aux_dir/configure"  # Please don't use this var.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5
 $as_echo_n "checking for a BSD-compatible install... " >&6; }
 if test -z "$INSTALL"; then
-if test "${ac_cv_path_install+set}" = set; then :
+if ${ac_cv_path_install+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -2807,7 +2769,7 @@ case $as_dir/ in #((
     # by default.
     for ac_prog in ginstall scoinst install; do
       for ac_exec_ext in '' $ac_executable_extensions; do
-       if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+       if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
          if test $ac_prog = install &&
            grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then
            # AIX install.  It has an incompatible calling convention.
@@ -2874,11 +2836,11 @@ am_lf='
 '
 case `pwd` in
   *[\\\"\#\$\&\'\`$am_lf]*)
-    as_fn_error "unsafe absolute working directory name" "$LINENO" 5;;
+    as_fn_error $? "unsafe absolute working directory name" "$LINENO" 5;;
 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
@@ -2900,7 +2862,7 @@ if (
       # 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
+      as_fn_error $? "ls -t appears to fail.  Make sure there is not a broken
 alias in your environment" "$LINENO" 5
    fi
 
@@ -2910,7 +2872,7 @@ then
    # Ok.
    :
 else
-   as_fn_error "newly created file is older than distributed files!
+   as_fn_error $? "newly created file is older than distributed files!
 Check your system clock" "$LINENO" 5
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
@@ -2964,7 +2926,7 @@ if test "$cross_compiling" != no; then
 set dummy ${ac_tool_prefix}strip; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_STRIP+set}" = set; then :
+if ${ac_cv_prog_STRIP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$STRIP"; then
@@ -2976,7 +2938,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_STRIP="${ac_tool_prefix}strip"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -3004,7 +2966,7 @@ if test -z "$ac_cv_prog_STRIP"; then
 set dummy strip; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+if ${ac_cv_prog_ac_ct_STRIP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_STRIP"; then
@@ -3016,7 +2978,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_STRIP="strip"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -3057,7 +3019,7 @@ INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a thread-safe mkdir -p" >&5
 $as_echo_n "checking for a thread-safe mkdir -p... " >&6; }
 if test -z "$MKDIR_P"; then
-  if test "${ac_cv_path_mkdir+set}" = set; then :
+  if ${ac_cv_path_mkdir+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -3067,7 +3029,7 @@ do
   test -z "$as_dir" && as_dir=.
     for ac_prog in mkdir gmkdir; do
         for ac_exec_ext in '' $ac_executable_extensions; do
-          { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; } || continue
+          as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext" || continue
           case `"$as_dir/$ac_prog$ac_exec_ext" --version 2>&1` in #(
             'mkdir (GNU coreutils) '* | \
             'mkdir (coreutils) '* | \
@@ -3082,6 +3044,7 @@ IFS=$as_save_IFS
 
 fi
 
+  test -d ./--version && rmdir ./--version
   if test "${ac_cv_path_mkdir+set}" = set; then
     MKDIR_P="$ac_cv_path_mkdir -p"
   else
@@ -3089,7 +3052,6 @@ fi
     # value for MKDIR_P within a source directory, because that will
     # break other packages using the cache if that directory is
     # removed, or if the value is a relative name.
-    test -d ./--version && rmdir ./--version
     MKDIR_P="$ac_install_sh -d"
   fi
 fi
@@ -3108,7 +3070,7 @@ do
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_AWK+set}" = set; then :
+if ${ac_cv_prog_AWK+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$AWK"; then
@@ -3120,7 +3082,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_AWK="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -3148,7 +3110,7 @@ done
 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
 set x ${MAKE-make}
 ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
-if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat >conftest.make <<\_ACEOF
@@ -3156,7 +3118,7 @@ SHELL = /bin/sh
 all:
        @echo '@@@%%%=$(MAKE)=@@@%%%'
 _ACEOF
-# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
 case `${MAKE-make} -f conftest.make 2>/dev/null` in
   *@@@%%%=?*=@@@%%%*)
     eval ac_cv_prog_make_${ac_make}_set=yes;;
@@ -3190,7 +3152,7 @@ if test "`cd $srcdir && pwd`" != "`pwd`"; then
   am__isrc=' -I$(srcdir)'
   # test to see if srcdir already configured
   if test -f $srcdir/config.status; then
-    as_fn_error "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
+    as_fn_error $? "source directory already configured; run \"make distclean\" there first" "$LINENO" 5
   fi
 fi
 
@@ -3206,7 +3168,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='libgcrypt'
- VERSION='1.5.0'
+ VERSION='1.6.1'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -3236,11 +3198,11 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"}
 
 # We need awk for the "check" target.  The system "awk" is bad on
 # some platforms.
-# Always define AMTAR for backward compatibility.
-
-AMTAR=${AMTAR-"${am_missing_run}tar"}
+# 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}'
 
-am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
+am__tar='$${TAR-tar} chof - "$$tardir"' am__untar='$${TAR-tar} xf -'
 
 
 
@@ -3252,27 +3214,27 @@ ac_config_headers="$ac_config_headers config.h"
 
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
-  as_fn_error "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
+  as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5
 $as_echo_n "checking build system type... " >&6; }
-if test "${ac_cv_build+set}" = set; then :
+if ${ac_cv_build+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_build_alias=$build_alias
 test "x$ac_build_alias" = x &&
   ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"`
 test "x$ac_build_alias" = x &&
-  as_fn_error "cannot guess build type; you must specify one" "$LINENO" 5
+  as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5
 ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` ||
-  as_fn_error "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
+  as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5
 
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5
 $as_echo "$ac_cv_build" >&6; }
 case $ac_cv_build in
 *-*-*) ;;
-*) as_fn_error "invalid value of canonical build" "$LINENO" 5;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
 esac
 build=$ac_cv_build
 ac_save_IFS=$IFS; IFS='-'
@@ -3290,14 +3252,14 @@ case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5
 $as_echo_n "checking host system type... " >&6; }
-if test "${ac_cv_host+set}" = set; then :
+if ${ac_cv_host+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test "x$host_alias" = x; then
   ac_cv_host=$ac_cv_build
 else
   ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` ||
-    as_fn_error "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
+    as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5
 fi
 
 fi
@@ -3305,7 +3267,7 @@ fi
 $as_echo "$ac_cv_host" >&6; }
 case $ac_cv_host in
 *-*-*) ;;
-*) as_fn_error "invalid value of canonical host" "$LINENO" 5;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
 esac
 host=$ac_cv_host
 ac_save_IFS=$IFS; IFS='-'
@@ -3344,6 +3306,45 @@ fi
   MAINT=$MAINTAINER_MODE_TRUE
 
 
+# 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='\'
+
 
 
 
@@ -3367,6 +3368,8 @@ cat >>confdefs.h <<_ACEOF
 #define VERSION "$VERSION"
 _ACEOF
 
+VERSION_NUMBER=0x010601
+
 
 
 ######################
@@ -3377,7 +3380,7 @@ _ACEOF
 $as_echo_n "checking whether ${MAKE-make} sets \$(MAKE)... " >&6; }
 set x ${MAKE-make}
 ac_make=`$as_echo "$2" | sed 's/+/p/g; s/[^a-zA-Z0-9_]/_/g'`
-if { as_var=ac_cv_prog_make_${ac_make}_set; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${ac_cv_prog_make_${ac_make}_set+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat >conftest.make <<\_ACEOF
@@ -3385,7 +3388,7 @@ SHELL = /bin/sh
 all:
        @echo '@@@%%%=$(MAKE)=@@@%%%'
 _ACEOF
-# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+# GNU make sometimes prints "make[1]: Entering ...", which would confuse us.
 case `${MAKE-make} -f conftest.make 2>/dev/null` in
   *@@@%%%=?*=@@@%%%*)
     eval ac_cv_prog_make_${ac_make}_set=yes;;
@@ -3428,7 +3431,7 @@ if test -n "$ac_tool_prefix"; then
 set dummy ${ac_tool_prefix}gcc; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
@@ -3440,7 +3443,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}gcc"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -3468,7 +3471,7 @@ if test -z "$ac_cv_prog_CC"; then
 set dummy gcc; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_CC"; then
@@ -3480,7 +3483,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="gcc"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -3521,7 +3524,7 @@ if test -z "$CC"; then
 set dummy ${ac_tool_prefix}cc; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
@@ -3533,7 +3536,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}cc"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -3561,7 +3564,7 @@ if test -z "$CC"; then
 set dummy cc; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
@@ -3574,7 +3577,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
        ac_prog_rejected=yes
        continue
@@ -3620,7 +3623,7 @@ if test -z "$CC"; then
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$CC"; then
@@ -3632,7 +3635,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -3664,7 +3667,7 @@ do
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_CC"; then
@@ -3676,7 +3679,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -3718,8 +3721,8 @@ fi
 
 test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "no acceptable C compiler found in \$PATH
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
 
 # Provide some information about the compiler.
 $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
@@ -3740,32 +3743,30 @@ $as_echo "$ac_try_echo"; } >&5
 ... rest of stderr output deleted ...
          10q' conftest.err >conftest.er1
     cat conftest.er1 >&5
-    rm -f conftest.er1 conftest.err
   fi
+  rm -f conftest.er1 conftest.err
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
 done
 
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <stdio.h>
+
 int
 main ()
 {
-FILE *f = fopen ("conftest.out", "w");
- return ferror (f) || fclose (f) != 0;
 
   ;
   return 0;
 }
 _ACEOF
 ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out"
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
 # Try to create an executable without -o first, disregard a.out.
 # It will help us diagnose broken compilers, and finding out an intuition
 # of exeext.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
-$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
 ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
 
 # The possible output files:
@@ -3827,62 +3828,28 @@ test "$ac_cv_exeext" = no && ac_cv_exeext=
 else
   ac_file=''
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
-$as_echo "$ac_file" >&6; }
 if test -z "$ac_file"; then :
-  $as_echo "$as_me: failed program was:" >&5
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "C compiler cannot create executables
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
 ac_exeext=$ac_cv_exeext
 
-# Check that the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
-$as_echo_n "checking whether the C compiler works... " >&6; }
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
-  if { ac_try='./$ac_file'
-  { { 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
-    cross_compiling=no
-  else
-    if test "$cross_compiling" = maybe; then
-       cross_compiling=yes
-    else
-       { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." "$LINENO" 5; }
-    fi
-  fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-
-rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
 ac_clean_files=$ac_clean_files_save
-# Check that the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
-$as_echo_n "checking whether we are cross compiling... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
-$as_echo "$cross_compiling" >&6; }
-
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
 $as_echo_n "checking for suffix of executables... " >&6; }
 if { { ac_try="$ac_link"
@@ -3912,19 +3879,78 @@ done
 else
   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
 fi
-rm -f conftest$ac_cv_exeext
+rm -f conftest conftest$ac_cv_exeext
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
 $as_echo "$ac_cv_exeext" >&6; }
 
 rm -f conftest.$ac_ext
 EXEEXT=$ac_cv_exeext
 ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+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_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { 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
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+       cross_compiling=yes
+    else
+       { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
 $as_echo_n "checking for suffix of object files... " >&6; }
-if test "${ac_cv_objext+set}" = set; then :
+if ${ac_cv_objext+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -3964,8 +3990,8 @@ sed 's/^/| /' conftest.$ac_ext >&5
 
 { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
 fi
 rm -f conftest.$ac_cv_objext conftest.$ac_ext
 fi
@@ -3975,7 +4001,7 @@ OBJEXT=$ac_cv_objext
 ac_objext=$OBJEXT
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+if ${ac_cv_c_compiler_gnu+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -4012,7 +4038,7 @@ ac_test_CFLAGS=${CFLAGS+set}
 ac_save_CFLAGS=$CFLAGS
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
 $as_echo_n "checking whether $CC accepts -g... " >&6; }
-if test "${ac_cv_prog_cc_g+set}" = set; then :
+if ${ac_cv_prog_cc_g+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_save_c_werror_flag=$ac_c_werror_flag
@@ -4090,7 +4116,7 @@ else
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then :
+if ${ac_cv_prog_cc_c89+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_cv_prog_cc_c89=no
@@ -4099,8 +4125,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 #include <stdarg.h>
 #include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+struct stat;
 /* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
 struct buf { int x; };
 FILE * (*rcsopen) (struct buf *, struct stat *, int);
@@ -4236,6 +4261,7 @@ fi
 if test "x$enable_dependency_tracking" != xno; then
   am_depcomp="$ac_aux_dir/depcomp"
   AMDEPBACKSLASH='\'
+  am__nodep='_no'
 fi
  if test "x$enable_dependency_tracking" != xno; then
   AMDEP_TRUE=
@@ -4251,7 +4277,7 @@ depcc="$CC"   am_compiler_list=
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
 $as_echo_n "checking dependency style of $depcc... " >&6; }
-if test "${am_cv_CC_dependencies_compiler_type+set}" = set; then :
+if ${am_cv_CC_dependencies_compiler_type+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
@@ -4260,6 +4286,7 @@ else
   # 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'.
+  rm -rf conftest.dir
   mkdir conftest.dir
   # Copy depcomp to subdir because otherwise we won't find it if we're
   # using a relative directory.
@@ -4319,7 +4346,7 @@ else
        break
       fi
       ;;
-    msvisualcpp | msvcmsys)
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
       # 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.
@@ -4386,7 +4413,7 @@ if test -n "$CPP" && test -d "$CPP"; then
   CPP=
 fi
 if test -z "$CPP"; then
-  if test "${ac_cv_prog_CPP+set}" = set; then :
+  if ${ac_cv_prog_CPP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
       # Double quotes because CPP needs to be expanded
@@ -4416,7 +4443,7 @@ else
   # Broken: fails on valid input.
 continue
 fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 
   # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
@@ -4432,11 +4459,11 @@ else
 ac_preproc_ok=:
 break
 fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.i conftest.err conftest.$ac_ext
 if $ac_preproc_ok; then :
   break
 fi
@@ -4475,7 +4502,7 @@ else
   # Broken: fails on valid input.
 continue
 fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 
   # OK, works on sane cases.  Now check whether nonexistent headers
   # can be detected and how.
@@ -4491,18 +4518,18 @@ else
 ac_preproc_ok=:
 break
 fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 
 done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.i conftest.err conftest.$ac_ext
 if $ac_preproc_ok; then :
 
 else
   { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
 fi
 
 ac_ext=c
@@ -4520,7 +4547,7 @@ $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 { as_var=ac_cv_prog_cc_${ac_cc}_c_o; eval "test \"\${$as_var+set}\" = set"; }; then :
+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
@@ -4648,7 +4675,7 @@ depcc="$CCAS"   am_compiler_list=
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking dependency style of $depcc" >&5
 $as_echo_n "checking dependency style of $depcc... " >&6; }
-if test "${am_cv_CCAS_dependencies_compiler_type+set}" = set; then :
+if ${am_cv_CCAS_dependencies_compiler_type+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
@@ -4657,6 +4684,7 @@ else
   # 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'.
+  rm -rf conftest.dir
   mkdir conftest.dir
   # Copy depcomp to subdir because otherwise we won't find it if we're
   # using a relative directory.
@@ -4714,7 +4742,7 @@ else
        break
       fi
       ;;
-    msvisualcpp | msvcmsys)
+    msvc7 | msvc7msys | msvisualcpp | msvcmsys)
       # 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.
@@ -4772,7 +4800,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing strerror" >&5
 $as_echo_n "checking for library containing strerror... " >&6; }
-if test "${ac_cv_search_strerror+set}" = set; then :
+if ${ac_cv_search_strerror+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_func_search_save_LIBS=$LIBS
@@ -4806,11 +4834,11 @@ for ac_lib in '' cposix; do
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext
-  if test "${ac_cv_search_strerror+set}" = set; then :
+  if ${ac_cv_search_strerror+:} false; then :
   break
 fi
 done
-if test "${ac_cv_search_strerror+set}" = set; then :
+if ${ac_cv_search_strerror+:} false; then :
 
 else
   ac_cv_search_strerror=no
@@ -4833,7 +4861,7 @@ do
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_AWK+set}" = set; then :
+if ${ac_cv_prog_AWK+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$AWK"; then
@@ -4845,7 +4873,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_AWK="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -4873,7 +4901,7 @@ done
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
 $as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then :
+if ${ac_cv_path_GREP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -z "$GREP"; then
@@ -4887,7 +4915,7 @@ do
     for ac_prog in grep ggrep; do
     for ac_exec_ext in '' $ac_executable_extensions; do
       ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
-      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+      as_fn_executable_p "$ac_path_GREP" || continue
 # Check for GNU ac_path_GREP and select it if it is found.
   # Check for GNU $ac_path_GREP
 case `"$ac_path_GREP" --version 2>&1` in
@@ -4922,7 +4950,7 @@ esac
   done
 IFS=$as_save_IFS
   if test -z "$ac_cv_path_GREP"; then
-    as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
   fi
 else
   ac_cv_path_GREP=$GREP
@@ -4936,7 +4964,7 @@ $as_echo "$ac_cv_path_GREP" >&6; }
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
 $as_echo_n "checking for egrep... " >&6; }
-if test "${ac_cv_path_EGREP+set}" = set; then :
+if ${ac_cv_path_EGREP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
@@ -4953,7 +4981,7 @@ do
     for ac_prog in egrep; do
     for ac_exec_ext in '' $ac_executable_extensions; do
       ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
-      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+      as_fn_executable_p "$ac_path_EGREP" || continue
 # Check for GNU ac_path_EGREP and select it if it is found.
   # Check for GNU $ac_path_EGREP
 case `"$ac_path_EGREP" --version 2>&1` in
@@ -4988,7 +5016,7 @@ esac
   done
 IFS=$as_save_IFS
   if test -z "$ac_cv_path_EGREP"; then
-    as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
   fi
 else
   ac_cv_path_EGREP=$EGREP
@@ -5003,7 +5031,7 @@ $as_echo "$ac_cv_path_EGREP" >&6; }
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
 $as_echo_n "checking for ANSI C header files... " >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then :
+if ${ac_cv_header_stdc+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -5120,8 +5148,7 @@ do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
 "
-eval as_val=\$$as_ac_Header
-   if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
   cat >>confdefs.h <<_ACEOF
 #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
@@ -5133,7 +5160,7 @@ done
 
 
   ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
-if test "x$ac_cv_header_minix_config_h" = x""yes; then :
+if test "x$ac_cv_header_minix_config_h" = xyes; then :
   MINIX=yes
 else
   MINIX=
@@ -5155,14 +5182,14 @@ $as_echo "#define _MINIX 1" >>confdefs.h
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether it is safe to define __EXTENSIONS__" >&5
 $as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
-if test "${ac_cv_safe_to_define___extensions__+set}" = set; then :
+if ${ac_cv_safe_to_define___extensions__+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
-#        define __EXTENSIONS__ 1
-         $ac_includes_default
+#         define __EXTENSIONS__ 1
+          $ac_includes_default
 int
 main ()
 {
@@ -5194,6 +5221,23 @@ $as_echo "$ac_cv_safe_to_define___extensions__" >&6; }
 
 
 
+# We need to compile and run a program on the build machine.  A
+# comment in libgpg-error says that the AC_PROG_CC_FOR_BUILD macro in
+# the AC archive is broken for autoconf 2.57.  Given that there is no
+# newer version of that macro, we assume that it is also broken for
+# autoconf 2.61 and thus we use a simple but usually sufficient
+# approach.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for cc for build" >&5
+$as_echo_n "checking for cc for build... " >&6; }
+if test "$cross_compiling" = "yes"; then
+  CC_FOR_BUILD="${CC_FOR_BUILD-cc}"
+else
+  CC_FOR_BUILD="${CC_FOR_BUILD-$CC}"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC_FOR_BUILD" >&5
+$as_echo "$CC_FOR_BUILD" >&6; }
+
+
 
 
 case `pwd` in
@@ -5204,8 +5248,8 @@ esac
 
 
 
-macro_version='2.2.6b'
-macro_revision='1.3017'
+macro_version='2.4.2'
+macro_revision='1.3337'
 
 
 
@@ -5221,29 +5265,98 @@ macro_revision='1.3017'
 
 ltmain="$ac_aux_dir/ltmain.sh"
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
-$as_echo_n "checking for a sed that does not truncate output... " >&6; }
-if test "${ac_cv_path_SED+set}" = set; then :
-  $as_echo_n "(cached) " >&6
-else
-            ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
-     for ac_i in 1 2 3 4 5 6 7; do
-       ac_script="$ac_script$as_nl$ac_script"
-     done
-     echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
-     { ac_script=; unset ac_script;}
-     if test -z "$SED"; then
-  ac_path_SED_found=false
-  # Loop through the user's path and test for each of PROGNAME-LIST
-  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
+# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\(["`\\]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+
+ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to print strings" >&5
+$as_echo_n "checking how to print strings... " >&6; }
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
+else
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
+fi
+
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO ""
+}
+
+case "$ECHO" in
+  printf*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: printf" >&5
+$as_echo "printf" >&6; } ;;
+  print*) { $as_echo "$as_me:${as_lineno-$LINENO}: result: print -r" >&5
+$as_echo "print -r" >&6; } ;;
+  *) { $as_echo "$as_me:${as_lineno-$LINENO}: result: cat" >&5
+$as_echo "cat" >&6; } ;;
+esac
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5
+$as_echo_n "checking for a sed that does not truncate output... " >&6; }
+if ${ac_cv_path_SED+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+            ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/
+     for ac_i in 1 2 3 4 5 6 7; do
+       ac_script="$ac_script$as_nl$ac_script"
+     done
+     echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed
+     { ac_script=; unset ac_script;}
+     if test -z "$SED"; then
+  ac_path_SED_found=false
+  # Loop through the user's path and test for each of PROGNAME-LIST
+  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_prog in sed gsed; do
     for ac_exec_ext in '' $ac_executable_extensions; do
       ac_path_SED="$as_dir/$ac_prog$ac_exec_ext"
-      { test -f "$ac_path_SED" && $as_test_x "$ac_path_SED"; } || continue
+      as_fn_executable_p "$ac_path_SED" || continue
 # Check for GNU ac_path_SED and select it if it is found.
   # Check for GNU $ac_path_SED
 case `"$ac_path_SED" --version 2>&1` in
@@ -5278,7 +5391,7 @@ esac
   done
 IFS=$as_save_IFS
   if test -z "$ac_cv_path_SED"; then
-    as_fn_error "no acceptable sed could be found in \$PATH" "$LINENO" 5
+    as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5
   fi
 else
   ac_cv_path_SED=$SED
@@ -5305,7 +5418,7 @@ Xsed="$SED -e 1s/^X//"
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5
 $as_echo_n "checking for fgrep... " >&6; }
-if test "${ac_cv_path_FGREP+set}" = set; then :
+if ${ac_cv_path_FGREP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1
@@ -5322,7 +5435,7 @@ do
     for ac_prog in fgrep; do
     for ac_exec_ext in '' $ac_executable_extensions; do
       ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext"
-      { test -f "$ac_path_FGREP" && $as_test_x "$ac_path_FGREP"; } || continue
+      as_fn_executable_p "$ac_path_FGREP" || continue
 # Check for GNU ac_path_FGREP and select it if it is found.
   # Check for GNU $ac_path_FGREP
 case `"$ac_path_FGREP" --version 2>&1` in
@@ -5357,7 +5470,7 @@ esac
   done
 IFS=$as_save_IFS
   if test -z "$ac_cv_path_FGREP"; then
-    as_fn_error "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+    as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
   fi
 else
   ac_cv_path_FGREP=$FGREP
@@ -5436,7 +5549,7 @@ else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5
 $as_echo_n "checking for non-GNU ld... " >&6; }
 fi
-if test "${lt_cv_path_LD+set}" = set; then :
+if ${lt_cv_path_LD+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -z "$LD"; then
@@ -5473,10 +5586,10 @@ else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
-test -z "$LD" && as_fn_error "no acceptable ld found in \$PATH" "$LINENO" 5
+test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5
 $as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; }
-if test "${lt_cv_prog_gnu_ld+set}" = set; then :
+if ${lt_cv_prog_gnu_ld+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   # I'd rather use --version here, but apparently some GNU lds only accept -v.
@@ -5503,7 +5616,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5
 $as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; }
-if test "${lt_cv_path_NM+set}" = set; then :
+if ${lt_cv_path_NM+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$NM"; then
@@ -5556,14 +5669,17 @@ if test "$lt_cv_path_NM" != "no"; then
   NM="$lt_cv_path_NM"
 else
   # Didn't find any BSD compatible name lister, look for dumpbin.
-  if test -n "$ac_tool_prefix"; then
-  for ac_prog in "dumpbin -symbols" "link -dump -symbols"
+  if test -n "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    if test -n "$ac_tool_prefix"; then
+  for ac_prog in dumpbin "link -dump"
   do
     # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
 set dummy $ac_tool_prefix$ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_DUMPBIN+set}" = set; then :
+if ${ac_cv_prog_DUMPBIN+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$DUMPBIN"; then
@@ -5575,7 +5691,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -5601,13 +5717,13 @@ fi
 fi
 if test -z "$DUMPBIN"; then
   ac_ct_DUMPBIN=$DUMPBIN
-  for ac_prog in "dumpbin -symbols" "link -dump -symbols"
+  for ac_prog in dumpbin "link -dump"
 do
   # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_DUMPBIN+set}" = set; then :
+if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_DUMPBIN"; then
@@ -5619,7 +5735,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_DUMPBIN="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -5656,6 +5772,15 @@ esac
   fi
 fi
 
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  fi
 
   if test "$DUMPBIN" != ":"; then
     NM="$DUMPBIN"
@@ -5670,18 +5795,18 @@ test -z "$NM" && NM=nm
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5
 $as_echo_n "checking the name lister ($NM) interface... " >&6; }
-if test "${lt_cv_nm_interface+set}" = set; then :
+if ${lt_cv_nm_interface+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_nm_interface="BSD nm"
   echo "int some_variable = 0;" > conftest.$ac_ext
-  (eval echo "\"\$as_me:5678: $ac_compile\"" >&5)
+  (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&5)
   (eval "$ac_compile" 2>conftest.err)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:5681: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
   (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:5684: output\"" >&5)
+  (eval echo "\"\$as_me:$LINENO: output\"" >&5)
   cat conftest.out >&5
   if $GREP 'External.*some_variable' conftest.out > /dev/null; then
     lt_cv_nm_interface="MS dumpbin"
@@ -5705,7 +5830,7 @@ fi
 # find the maximum length of command line arguments
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5
 $as_echo_n "checking the maximum length of command line arguments... " >&6; }
-if test "${lt_cv_sys_max_cmd_len+set}" = set; then :
+if ${lt_cv_sys_max_cmd_len+:} false; then :
   $as_echo_n "(cached) " >&6
 else
     i=0
@@ -5738,6 +5863,11 @@ else
     lt_cv_sys_max_cmd_len=8192;
     ;;
 
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
   amigaos*)
     # On AmigaOS with pdksh, this test takes hours, literally.
     # So we just punt and use a minimum line length of 8192.
@@ -5763,6 +5893,11 @@ else
     lt_cv_sys_max_cmd_len=196608
     ;;
 
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
   osf*)
     # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
     # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
@@ -5802,8 +5937,8 @@ else
       # If test is not a shell built-in, we'll probably end up computing a
       # maximum length that is only half of the actual maximum length, but
       # we can't tell.
-      while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
-                = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
+      while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+                = "X$teststring$teststring"; } >/dev/null 2>&1 &&
              test $i != 17 # 1/2 MB should be enough
       do
         i=`expr $i + 1`
@@ -5845,8 +5980,8 @@ $as_echo_n "checking whether the shell understands some XSI constructs... " >&6;
 # Try some XSI features
 xsi_shell=no
 ( _lt_dummy="a/b/c"
-  test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
-      = c,a/b,, \
+  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
     && eval 'test $(( 1 + 1 )) -eq 2 \
     && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
   && xsi_shell=yes
@@ -5895,9 +6030,83 @@ esac
 
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to $host format" >&5
+$as_echo_n "checking how to convert $build file names to $host format... " >&6; }
+if ${lt_cv_to_host_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
+    ;;
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
+    ;;
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+
+fi
+
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_host_file_cmd" >&5
+$as_echo "$lt_cv_to_host_file_cmd" >&6; }
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to convert $build file names to toolchain format" >&5
+$as_echo_n "checking how to convert $build file names to toolchain format... " >&6; }
+if ${lt_cv_to_tool_file_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  #assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
+
+fi
+
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_to_tool_file_cmd" >&5
+$as_echo "$lt_cv_to_tool_file_cmd" >&6; }
+
+
+
+
+
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5
 $as_echo_n "checking for $LD option to reload object files... " >&6; }
-if test "${lt_cv_ld_reload_flag+set}" = set; then :
+if ${lt_cv_ld_reload_flag+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_ld_reload_flag='-r'
@@ -5911,6 +6120,11 @@ case $reload_flag in
 esac
 reload_cmds='$LD$reload_flag -o $output$reload_objs'
 case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test "$GCC" != yes; then
+      reload_cmds=false
+    fi
+    ;;
   darwin*)
     if test "$GCC" = yes; then
       reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
@@ -5933,7 +6147,7 @@ if test -n "$ac_tool_prefix"; then
 set dummy ${ac_tool_prefix}objdump; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OBJDUMP+set}" = set; then :
+if ${ac_cv_prog_OBJDUMP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$OBJDUMP"; then
@@ -5945,7 +6159,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -5973,7 +6187,7 @@ if test -z "$ac_cv_prog_OBJDUMP"; then
 set dummy objdump; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then :
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_OBJDUMP"; then
@@ -5985,7 +6199,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_OBJDUMP="objdump"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6029,7 +6243,7 @@ test -z "$OBJDUMP" && OBJDUMP=objdump
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5
 $as_echo_n "checking how to recognize dependent libraries... " >&6; }
-if test "${lt_cv_deplibs_check_method+set}" = set; then :
+if ${lt_cv_deplibs_check_method+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_file_magic_cmd='$MAGIC_CMD'
@@ -6071,16 +6285,18 @@ mingw* | pw32*)
   # Base MSYS/MinGW do not provide the 'file' command needed by
   # func_win32_libid shell function, so use a weaker test based on 'objdump',
   # unless we find 'file', for example because we are cross-compiling.
-  if ( file / ) >/dev/null 2>&1; then
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
     lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
     lt_cv_file_magic_cmd='func_win32_libid'
   else
-    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
     lt_cv_file_magic_cmd='$OBJDUMP -f'
   fi
   ;;
 
-cegcc)
+cegcc*)
   # use the weaker test based on 'objdump'. See mingw*.
   lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
   lt_cv_file_magic_cmd='$OBJDUMP -f'
@@ -6110,6 +6326,10 @@ gnu*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
+haiku*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
 hpux10.20* | hpux11*)
   lt_cv_file_magic_cmd=/usr/bin/file
   case $host_cpu in
@@ -6118,11 +6338,11 @@ hpux10.20* | hpux11*)
     lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
     ;;
   hppa*64*)
-    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]'
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]'
     lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
     ;;
   *)
-    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library'
+    lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9]\.[0-9]) shared library'
     lt_cv_file_magic_test_file=/usr/lib/libc.sl
     ;;
   esac
@@ -6143,8 +6363,8 @@ irix5* | irix6* | nonstopux*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-# This must be Linux ELF.
-linux* | k*bsd*-gnu)
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
@@ -6225,6 +6445,21 @@ esac
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5
 $as_echo "$lt_cv_deplibs_check_method" >&6; }
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[\1]\/[\1]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
 file_magic_cmd=$lt_cv_file_magic_cmd
 deplibs_check_method=$lt_cv_deplibs_check_method
 test -z "$deplibs_check_method" && deplibs_check_method=unknown
@@ -6240,16 +6475,26 @@ test -z "$deplibs_check_method" && deplibs_check_method=unknown
 
 
 
+
+
+
+
+
+
+
+
+
+
 if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ar; ac_word=$2
+  # Extract the first word of "${ac_tool_prefix}dlltool", so it can be a program name with args.
+set dummy ${ac_tool_prefix}dlltool; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_AR+set}" = set; then :
+if ${ac_cv_prog_DLLTOOL+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  if test -n "$AR"; then
-  ac_cv_prog_AR="$AR" # Let the user override the test.
+  if test -n "$DLLTOOL"; then
+  ac_cv_prog_DLLTOOL="$DLLTOOL" # Let the user override the test.
 else
 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
@@ -6257,8 +6502,8 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_AR="${ac_tool_prefix}ar"
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -6268,10 +6513,10 @@ IFS=$as_save_IFS
 
 fi
 fi
-AR=$ac_cv_prog_AR
-if test -n "$AR"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
-$as_echo "$AR" >&6; }
+DLLTOOL=$ac_cv_prog_DLLTOOL
+if test -n "$DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DLLTOOL" >&5
+$as_echo "$DLLTOOL" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
@@ -6279,17 +6524,17 @@ fi
 
 
 fi
-if test -z "$ac_cv_prog_AR"; then
-  ac_ct_AR=$AR
-  # Extract the first word of "ar", so it can be a program name with args.
-set dummy ar; ac_word=$2
+if test -z "$ac_cv_prog_DLLTOOL"; then
+  ac_ct_DLLTOOL=$DLLTOOL
+  # Extract the first word of "dlltool", so it can be a program name with args.
+set dummy dlltool; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_AR+set}" = set; then :
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  if test -n "$ac_ct_AR"; then
-  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
+  if test -n "$ac_ct_DLLTOOL"; then
+  ac_cv_prog_ac_ct_DLLTOOL="$ac_ct_DLLTOOL" # Let the user override the test.
 else
 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
@@ -6297,8 +6542,8 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_ac_ct_AR="ar"
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_DLLTOOL="dlltool"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -6308,17 +6553,17 @@ IFS=$as_save_IFS
 
 fi
 fi
-ac_ct_AR=$ac_cv_prog_ac_ct_AR
-if test -n "$ac_ct_AR"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
-$as_echo "$ac_ct_AR" >&6; }
+ac_ct_DLLTOOL=$ac_cv_prog_ac_ct_DLLTOOL
+if test -n "$ac_ct_DLLTOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DLLTOOL" >&5
+$as_echo "$ac_ct_DLLTOOL" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
 
-  if test "x$ac_ct_AR" = x; then
-    AR="false"
+  if test "x$ac_ct_DLLTOOL" = x; then
+    DLLTOOL="false"
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
@@ -6326,18 +6571,51 @@ yes:)
 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
-    AR=$ac_ct_AR
+    DLLTOOL=$ac_ct_DLLTOOL
   fi
 else
-  AR="$ac_cv_prog_AR"
+  DLLTOOL="$ac_cv_prog_DLLTOOL"
 fi
 
-test -z "$AR" && AR=ar
-test -z "$AR_FLAGS" && AR_FLAGS=cru
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+
+
+
+
 
 
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to associate runtime and link libraries" >&5
+$as_echo_n "checking how to associate runtime and link libraries... " >&6; }
+if ${lt_cv_sharedlib_from_linklib_cmd+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+  ;;
+esac
 
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sharedlib_from_linklib_cmd" >&5
+$as_echo "$lt_cv_sharedlib_from_linklib_cmd" >&6; }
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
 
 
 
@@ -6346,15 +6624,17 @@ test -z "$AR_FLAGS" && AR_FLAGS=cru
 
 
 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.
-set dummy ${ac_tool_prefix}strip; ac_word=$2
+  for ac_prog in ar
+  do
+    # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_STRIP+set}" = set; then :
+if ${ac_cv_prog_AR+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  if test -n "$STRIP"; then
-  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+  if test -n "$AR"; then
+  ac_cv_prog_AR="$AR" # Let the user override the test.
 else
 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
@@ -6362,8 +6642,8 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_STRIP="${ac_tool_prefix}strip"
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_AR="$ac_tool_prefix$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -6373,28 +6653,32 @@ IFS=$as_save_IFS
 
 fi
 fi
-STRIP=$ac_cv_prog_STRIP
-if test -n "$STRIP"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
-$as_echo "$STRIP" >&6; }
+AR=$ac_cv_prog_AR
+if test -n "$AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
 
 
+    test -n "$AR" && break
+  done
 fi
-if test -z "$ac_cv_prog_STRIP"; then
-  ac_ct_STRIP=$STRIP
-  # Extract the first word of "strip", so it can be a program name with args.
-set dummy strip; ac_word=$2
+if test -z "$AR"; then
+  ac_ct_AR=$AR
+  for ac_prog in ar
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_STRIP+set}" = set; then :
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  if test -n "$ac_ct_STRIP"; then
-  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+  if test -n "$ac_ct_AR"; then
+  ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
 else
 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
@@ -6402,8 +6686,8 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_ac_ct_STRIP="strip"
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+    ac_cv_prog_ac_ct_AR="$ac_prog"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -6413,17 +6697,21 @@ IFS=$as_save_IFS
 
 fi
 fi
-ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
-if test -n "$ac_ct_STRIP"; then
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
-$as_echo "$ac_ct_STRIP" >&6; }
+ac_ct_AR=$ac_cv_prog_ac_ct_AR
+if test -n "$ac_ct_AR"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
 $as_echo "no" >&6; }
 fi
 
-  if test "x$ac_ct_STRIP" = x; then
-    STRIP=":"
+
+  test -n "$ac_ct_AR" && break
+done
+
+  if test "x$ac_ct_AR" = x; then
+    AR="false"
   else
     case $cross_compiling:$ac_tool_warned in
 yes:)
@@ -6431,37 +6719,198 @@ yes:)
 $as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
 ac_tool_warned=yes ;;
 esac
-    STRIP=$ac_ct_STRIP
+    AR=$ac_ct_AR
   fi
-else
-  STRIP="$ac_cv_prog_STRIP"
 fi
 
-test -z "$STRIP" && STRIP=:
+: ${AR=ar}
+: ${AR_FLAGS=cru}
 
 
 
 
 
 
-if test -n "$ac_tool_prefix"; then
-  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
-set dummy ${ac_tool_prefix}ranlib; ac_word=$2
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
-$as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_RANLIB+set}" = set; then :
+
+
+
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for archiver @FILE support" >&5
+$as_echo_n "checking for archiver @FILE support... " >&6; }
+if ${lt_cv_ar_at_file+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  if test -n "$RANLIB"; then
-  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+  lt_cv_ar_at_file=no
+   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&5'
+      { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+      if test "$ac_status" -eq 0; then
+       # Ensure the archiver fails upon bogus file names.
+       rm -f conftest.$ac_objext libconftest.a
+       { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$lt_ar_try\""; } >&5
+  (eval $lt_ar_try) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+       if test "$ac_status" -ne 0; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ar_at_file" >&5
+$as_echo "$lt_cv_ar_at_file" >&6; }
+
+if test "x$lt_cv_ar_at_file" = xno; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+
+
+
+
+
+
+
+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.
+set dummy ${ac_tool_prefix}strip; 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_prog_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$STRIP"; then
+  ac_cv_prog_STRIP="$STRIP" # Let the user override the test.
+else
+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_prog_STRIP="${ac_tool_prefix}strip"
+    $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
+
+fi
+fi
+STRIP=$ac_cv_prog_STRIP
+if test -n "$STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5
+$as_echo "$STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_STRIP"; then
+  ac_ct_STRIP=$STRIP
+  # Extract the first word of "strip", so it can be a program name with args.
+set dummy strip; 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_prog_ac_ct_STRIP+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_STRIP"; then
+  ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test.
+else
+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_prog_ac_ct_STRIP="strip"
+    $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
+
+fi
+fi
+ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP
+if test -n "$ac_ct_STRIP"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5
+$as_echo "$ac_ct_STRIP" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_STRIP" = x; then
+    STRIP=":"
+  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
+    STRIP=$ac_ct_STRIP
+  fi
+else
+  STRIP="$ac_cv_prog_STRIP"
+fi
+
+test -z "$STRIP" && STRIP=:
+
+
+
+
+
+
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
+set dummy ${ac_tool_prefix}ranlib; 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_prog_RANLIB+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$RANLIB"; then
+  ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+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 { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6489,7 +6938,7 @@ if test -z "$ac_cv_prog_RANLIB"; then
 set dummy ranlib; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then :
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_RANLIB"; then
@@ -6501,7 +6950,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_RANLIB="ranlib"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -6551,15 +7000,27 @@ old_postuninstall_cmds=
 if test -n "$RANLIB"; then
   case $host_os in
   openbsd*)
-    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
     ;;
   *)
-    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
     ;;
   esac
-  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
 fi
 
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
+
+
+
+
+
+
 
 
 
@@ -6606,7 +7067,7 @@ compiler=$CC
 # Check for command to grab the raw symbol name followed by C symbol from nm.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5
 $as_echo_n "checking command to parse $NM output from $compiler object... " >&6; }
-if test "${lt_cv_sys_global_symbol_pipe+set}" = set; then :
+if ${lt_cv_sys_global_symbol_pipe+:} false; then :
   $as_echo_n "(cached) " >&6
 else
 
@@ -6667,8 +7128,8 @@ esac
 lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
 
 # Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\)[ ]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
 
 # Handle CRLF in mingw tool chain
 opt_cr=
@@ -6692,6 +7153,7 @@ for ac_symprfx in "" "_"; do
     # which start with @ or ?.
     lt_cv_sys_global_symbol_pipe="$AWK '"\
 "     {last_section=section; section=\$ 3};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
 "     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
 "     \$ 0!~/External *\|/{next};"\
 "     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
@@ -6704,6 +7166,7 @@ for ac_symprfx in "" "_"; do
   else
     lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[     ]\($symcode$symcode*\)[         ][      ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
   fi
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
 
   # Check to see that the pipe works correctly.
   pipe_works=no
@@ -6729,8 +7192,8 @@ _LT_EOF
   test $ac_status = 0; }; then
     # Now try to grab the symbols.
     nlist=conftest.nm
-    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5
-  (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5
+  (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } && test -s "$nlist"; then
@@ -6745,6 +7208,18 @@ _LT_EOF
       if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
        if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
          cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT_DLSYM_CONST
+#else
+# define LT_DLSYM_CONST const
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -6756,7 +7231,7 @@ _LT_EOF
          cat <<_LT_EOF >> conftest.$ac_ext
 
 /* The mapping between symbol names and symbols.  */
-const struct {
+LT_DLSYM_CONST struct {
   const char *name;
   void       *address;
 }
@@ -6782,8 +7257,8 @@ static const void *lt_preloaded_setup() {
 _LT_EOF
          # Now try linking the two files.
          mv conftest.$ac_objext conftstm.$ac_objext
-         lt_save_LIBS="$LIBS"
-         lt_save_CFLAGS="$CFLAGS"
+         lt_globsym_save_LIBS=$LIBS
+         lt_globsym_save_CFLAGS=$CFLAGS
          LIBS="conftstm.$ac_objext"
          CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag"
          if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5
@@ -6793,8 +7268,8 @@ _LT_EOF
   test $ac_status = 0; } && test -s conftest${ac_exeext}; then
            pipe_works=yes
          fi
-         LIBS="$lt_save_LIBS"
-         CFLAGS="$lt_save_CFLAGS"
+         LIBS=$lt_globsym_save_LIBS
+         CFLAGS=$lt_globsym_save_CFLAGS
        else
          echo "cannot find nm_test_func in $nlist" >&5
        fi
@@ -6831,6 +7306,17 @@ else
 $as_echo "ok" >&6; }
 fi
 
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[@]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
+
+
+
+
 
 
 
@@ -6852,6 +7338,44 @@ fi
 
 
 
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysroot" >&5
+$as_echo_n "checking for sysroot... " >&6; }
+
+# Check whether --with-sysroot was given.
+if test "${with_sysroot+set}" = set; then :
+  withval=$with_sysroot;
+else
+  with_sysroot=no
+fi
+
+
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+   if test "$GCC" = yes; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_sysroot}" >&5
+$as_echo "${with_sysroot}" >&6; }
+   as_fn_error $? "The sysroot must be an absolute path." "$LINENO" 5
+   ;;
+esac
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${lt_sysroot:-no}" >&5
+$as_echo "${lt_sysroot:-no}" >&6; }
+
+
+
+
+
 # Check whether --enable-libtool-lock was given.
 if test "${enable_libtool_lock+set}" = set; then :
   enableval=$enable_libtool_lock;
@@ -6883,7 +7407,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 6886 "configure"' > conftest.$ac_ext
+  echo '#line '$LINENO' "configure"' > conftest.$ac_ext
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -6936,7 +7460,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
          x86_64-*linux*)
            LD="${LD-ld} -m elf_i386"
            ;;
-         ppc64-*linux*|powerpc64-*linux*)
+         powerpc64le-*)
+           LD="${LD-ld} -m elf32lppclinux"
+           ;;
+         powerpc64-*)
            LD="${LD-ld} -m elf32ppclinux"
            ;;
          s390x-*linux*)
@@ -6955,7 +7482,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
          x86_64-*linux*)
            LD="${LD-ld} -m elf_x86_64"
            ;;
-         ppc*-*linux*|powerpc*-*linux*)
+         powerpcle-*)
+           LD="${LD-ld} -m elf64lppc"
+           ;;
+         powerpc-*)
            LD="${LD-ld} -m elf64ppc"
            ;;
          s390*-*linux*|s390*-*tpf*)
@@ -6977,7 +7507,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
   CFLAGS="$CFLAGS -belf"
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5
 $as_echo_n "checking whether the C compiler needs -belf... " >&6; }
-if test "${lt_cv_cc_needs_belf+set}" = set; then :
+if ${lt_cv_cc_needs_belf+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_ext=c
@@ -7018,7 +7548,7 @@ $as_echo "$lt_cv_cc_needs_belf" >&6; }
     CFLAGS="$SAVE_CFLAGS"
   fi
   ;;
-sparc*-*solaris*)
+*-*solaris*)
   # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
@@ -7029,7 +7559,20 @@ sparc*-*solaris*)
     case `/usr/bin/file conftest.o` in
     *64-bit*)
       case $lt_cv_prog_gnu_ld in
-      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      yes*)
+        case $host in
+        i?86-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD="${LD-ld}_sol2"
+        fi
+        ;;
       *)
        if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
          LD="${LD-ld} -64"
@@ -7045,6 +7588,123 @@ esac
 
 need_locks="$enable_libtool_lock"
 
+if test -n "$ac_tool_prefix"; then
+  # Extract the first word of "${ac_tool_prefix}mt", so it can be a program name with args.
+set dummy ${ac_tool_prefix}mt; 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_prog_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$MANIFEST_TOOL"; then
+  ac_cv_prog_MANIFEST_TOOL="$MANIFEST_TOOL" # Let the user override the test.
+else
+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_prog_MANIFEST_TOOL="${ac_tool_prefix}mt"
+    $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
+
+fi
+fi
+MANIFEST_TOOL=$ac_cv_prog_MANIFEST_TOOL
+if test -n "$MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MANIFEST_TOOL" >&5
+$as_echo "$MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+fi
+if test -z "$ac_cv_prog_MANIFEST_TOOL"; then
+  ac_ct_MANIFEST_TOOL=$MANIFEST_TOOL
+  # Extract the first word of "mt", so it can be a program name with args.
+set dummy mt; 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_prog_ac_ct_MANIFEST_TOOL+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test -n "$ac_ct_MANIFEST_TOOL"; then
+  ac_cv_prog_ac_ct_MANIFEST_TOOL="$ac_ct_MANIFEST_TOOL" # Let the user override the test.
+else
+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_prog_ac_ct_MANIFEST_TOOL="mt"
+    $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
+
+fi
+fi
+ac_ct_MANIFEST_TOOL=$ac_cv_prog_ac_ct_MANIFEST_TOOL
+if test -n "$ac_ct_MANIFEST_TOOL"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_MANIFEST_TOOL" >&5
+$as_echo "$ac_ct_MANIFEST_TOOL" >&6; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+  if test "x$ac_ct_MANIFEST_TOOL" = x; then
+    MANIFEST_TOOL=":"
+  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
+    MANIFEST_TOOL=$ac_ct_MANIFEST_TOOL
+  fi
+else
+  MANIFEST_TOOL="$ac_cv_prog_MANIFEST_TOOL"
+fi
+
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5
+$as_echo_n "checking if $MANIFEST_TOOL is a manifest tool... " >&6; }
+if ${lt_cv_path_mainfest_tool+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&5
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5
+$as_echo "$lt_cv_path_mainfest_tool" >&6; }
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+  MANIFEST_TOOL=:
+fi
+
+
+
+
+
 
   case $host_os in
     rhapsody* | darwin*)
@@ -7053,7 +7713,7 @@ need_locks="$enable_libtool_lock"
 set dummy ${ac_tool_prefix}dsymutil; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_DSYMUTIL+set}" = set; then :
+if ${ac_cv_prog_DSYMUTIL+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$DSYMUTIL"; then
@@ -7065,7 +7725,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7093,7 +7753,7 @@ if test -z "$ac_cv_prog_DSYMUTIL"; then
 set dummy dsymutil; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then :
+if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_DSYMUTIL"; then
@@ -7105,7 +7765,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_DSYMUTIL="dsymutil"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7145,7 +7805,7 @@ fi
 set dummy ${ac_tool_prefix}nmedit; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_NMEDIT+set}" = set; then :
+if ${ac_cv_prog_NMEDIT+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$NMEDIT"; then
@@ -7157,7 +7817,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7185,7 +7845,7 @@ if test -z "$ac_cv_prog_NMEDIT"; then
 set dummy nmedit; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then :
+if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_NMEDIT"; then
@@ -7197,7 +7857,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_NMEDIT="nmedit"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7237,7 +7897,7 @@ fi
 set dummy ${ac_tool_prefix}lipo; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_LIPO+set}" = set; then :
+if ${ac_cv_prog_LIPO+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$LIPO"; then
@@ -7249,7 +7909,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_LIPO="${ac_tool_prefix}lipo"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7277,7 +7937,7 @@ if test -z "$ac_cv_prog_LIPO"; then
 set dummy lipo; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_LIPO+set}" = set; then :
+if ${ac_cv_prog_ac_ct_LIPO+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_LIPO"; then
@@ -7289,7 +7949,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_LIPO="lipo"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7329,7 +7989,7 @@ fi
 set dummy ${ac_tool_prefix}otool; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OTOOL+set}" = set; then :
+if ${ac_cv_prog_OTOOL+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$OTOOL"; then
@@ -7341,7 +8001,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_OTOOL="${ac_tool_prefix}otool"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7369,7 +8029,7 @@ if test -z "$ac_cv_prog_OTOOL"; then
 set dummy otool; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OTOOL+set}" = set; then :
+if ${ac_cv_prog_ac_ct_OTOOL+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_OTOOL"; then
@@ -7381,7 +8041,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_OTOOL="otool"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7421,7 +8081,7 @@ fi
 set dummy ${ac_tool_prefix}otool64; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OTOOL64+set}" = set; then :
+if ${ac_cv_prog_OTOOL64+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$OTOOL64"; then
@@ -7433,7 +8093,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7461,7 +8121,7 @@ if test -z "$ac_cv_prog_OTOOL64"; then
 set dummy otool64; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OTOOL64+set}" = set; then :
+if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_OTOOL64"; then
@@ -7473,7 +8133,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_OTOOL64="otool64"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7536,7 +8196,7 @@ fi
 
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5
 $as_echo_n "checking for -single_module linker flag... " >&6; }
-if test "${lt_cv_apple_cc_single_mod+set}" = set; then :
+if ${lt_cv_apple_cc_single_mod+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_apple_cc_single_mod=no
@@ -7552,7 +8212,13 @@ else
        $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
          -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
         _lt_result=$?
-       if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+       # If there is a non-empty error log, and "single_module"
+       # appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+         cat conftest.err >&5
+       # Otherwise, if the output was created with a 0 exit code from
+       # the compiler, it worked.
+       elif test -f libconftest.dylib && test $_lt_result -eq 0; then
          lt_cv_apple_cc_single_mod=yes
        else
          cat conftest.err >&5
@@ -7563,9 +8229,10 @@ else
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5
 $as_echo "$lt_cv_apple_cc_single_mod" >&6; }
+
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5
 $as_echo_n "checking for -exported_symbols_list linker flag... " >&6; }
-if test "${lt_cv_ld_exported_symbols_list+set}" = set; then :
+if ${lt_cv_ld_exported_symbols_list+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_ld_exported_symbols_list=no
@@ -7595,6 +8262,41 @@ rm -f core conftest.err conftest.$ac_objext \
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5
 $as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
+
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -force_load linker flag" >&5
+$as_echo_n "checking for -force_load linker flag... " >&6; }
+if ${lt_cv_ld_force_load+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5
+      echo "$AR cru libconftest.a conftest.o" >&5
+      $AR cru libconftest.a conftest.o 2>&5
+      echo "$RANLIB libconftest.a" >&5
+      $RANLIB libconftest.a 2>&5
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+       cat conftest.err >&5
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+       lt_cv_ld_force_load=yes
+      else
+       cat conftest.err >&5
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_force_load" >&5
+$as_echo "$lt_cv_ld_force_load" >&6; }
     case $host_os in
     rhapsody* | darwin1.[012])
       _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
@@ -7622,7 +8324,7 @@ $as_echo "$lt_cv_ld_exported_symbols_list" >&6; }
     else
       _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
     fi
-    if test "$DSYMUTIL" != ":"; then
+    if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
       _lt_dsymutil='~$DSYMUTIL $lib || :'
     else
       _lt_dsymutil=
@@ -7634,7 +8336,7 @@ for ac_header in dlfcn.h
 do :
   ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default
 "
-if test "x$ac_cv_header_dlfcn_h" = x""yes; then :
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_DLFCN_H 1
 _ACEOF
@@ -7645,17 +8347,19 @@ done
 
 
 
+
+
 # Set options
 enable_win32_dll=yes
 
 case $host in
-*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*)
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
   if test -n "$ac_tool_prefix"; then
   # Extract the first word of "${ac_tool_prefix}as", so it can be a program name with args.
 set dummy ${ac_tool_prefix}as; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_AS+set}" = set; then :
+if ${ac_cv_prog_AS+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$AS"; then
@@ -7667,7 +8371,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_AS="${ac_tool_prefix}as"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7695,7 +8399,7 @@ if test -z "$ac_cv_prog_AS"; then
 set dummy as; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_AS+set}" = set; then :
+if ${ac_cv_prog_ac_ct_AS+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_AS"; then
@@ -7707,7 +8411,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_AS="as"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7747,7 +8451,7 @@ fi
 set dummy ${ac_tool_prefix}dlltool; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_DLLTOOL+set}" = set; then :
+if ${ac_cv_prog_DLLTOOL+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$DLLTOOL"; then
@@ -7759,7 +8463,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_DLLTOOL="${ac_tool_prefix}dlltool"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7787,7 +8491,7 @@ if test -z "$ac_cv_prog_DLLTOOL"; then
 set dummy dlltool; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_DLLTOOL+set}" = set; then :
+if ${ac_cv_prog_ac_ct_DLLTOOL+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_DLLTOOL"; then
@@ -7799,7 +8503,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_DLLTOOL="dlltool"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7839,7 +8543,7 @@ fi
 set dummy ${ac_tool_prefix}objdump; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_OBJDUMP+set}" = set; then :
+if ${ac_cv_prog_OBJDUMP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$OBJDUMP"; then
@@ -7851,7 +8555,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -7879,7 +8583,7 @@ if test -z "$ac_cv_prog_OBJDUMP"; then
 set dummy objdump; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_OBJDUMP+set}" = set; then :
+if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_OBJDUMP"; then
@@ -7891,7 +8595,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_OBJDUMP="objdump"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -8017,7 +8721,22 @@ fi
 
 # Check whether --with-pic was given.
 if test "${with_pic+set}" = set; then :
-  withval=$with_pic; pic_mode="$withval"
+  withval=$with_pic; lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for lt_pkg in $withval; do
+       IFS="$lt_save_ifs"
+       if test "X$lt_pkg" = "X$lt_p"; then
+         pic_mode=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac
 else
   pic_mode=default
 fi
@@ -8094,6 +8813,11 @@ LIBTOOL='$(SHELL) $(top_builddir)/libtool'
 
 
 
+
+
+
+
+
 test -z "$LN_S" && LN_S="ln -s"
 
 
@@ -8115,7 +8839,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5
 $as_echo_n "checking for objdir... " >&6; }
-if test "${lt_cv_objdir+set}" = set; then :
+if ${lt_cv_objdir+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   rm -f .libs 2>/dev/null
@@ -8143,19 +8867,6 @@ _ACEOF
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
 case $host_os in
 aix3*)
   # AIX sometimes has problems with the GCC collect2 program.  For some
@@ -8168,23 +8879,6 @@ aix3*)
   ;;
 esac
 
-# Sed substitution that helps us do robust quoting.  It backslashifies
-# metacharacters that are still active within double-quoted strings.
-sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
-
-# Same as above, but do not quote variable references.
-double_quote_subst='s/\(["`\\]\)/\\\1/g'
-
-# Sed substitution to delay expansion of an escaped shell variable in a
-# double_quote_subst'ed string.
-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
-
-# Sed substitution to delay expansion of an escaped single quote.
-delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
-
-# Sed substitution to avoid accidental globbing in evaled expressions
-no_glob_subst='s/\*/\\\*/g'
-
 # Global variables:
 ofile=libtool
 can_build_shared=yes
@@ -8213,7 +8907,7 @@ for cc_temp in $compiler""; do
     *) break;;
   esac
 done
-cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
 
 
 # Only perform the check for file, if the check method requires it
@@ -8223,7 +8917,7 @@ file_magic*)
   if test "$file_magic_cmd" = '$MAGIC_CMD'; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5
 $as_echo_n "checking for ${ac_tool_prefix}file... " >&6; }
-if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $MAGIC_CMD in
@@ -8289,7 +8983,7 @@ if test -z "$lt_cv_path_MAGIC_CMD"; then
   if test -n "$ac_tool_prefix"; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5
 $as_echo_n "checking for file... " >&6; }
-if test "${lt_cv_path_MAGIC_CMD+set}" = set; then :
+if ${lt_cv_path_MAGIC_CMD+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $MAGIC_CMD in
@@ -8422,11 +9116,16 @@ if test -n "$compiler"; then
 lt_prog_compiler_no_builtin_flag=
 
 if test "$GCC" = yes; then
-  lt_prog_compiler_no_builtin_flag=' -fno-builtin'
+  case $cc_basename in
+  nvcc*)
+    lt_prog_compiler_no_builtin_flag=' -Xcompiler -fno-builtin' ;;
+  *)
+    lt_prog_compiler_no_builtin_flag=' -fno-builtin' ;;
+  esac
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5
 $as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; }
-if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then :
+if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_prog_compiler_rtti_exceptions=no
@@ -8442,15 +9141,15 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8445: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:8449: \$? = $ac_status" >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
-     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
      $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
      if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
        lt_cv_prog_compiler_rtti_exceptions=yes
@@ -8479,8 +9178,6 @@ fi
 lt_prog_compiler_pic=
 lt_prog_compiler_static=
 
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
-$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
 
   if test "$GCC" = yes; then
     lt_prog_compiler_wl='-Wl,'
@@ -8528,6 +9225,12 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
       lt_prog_compiler_pic='-fno-common'
       ;;
 
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      lt_prog_compiler_static=
+      ;;
+
     hpux*)
       # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
       # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
@@ -8570,6 +9273,15 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
       lt_prog_compiler_pic='-fPIC'
       ;;
     esac
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      lt_prog_compiler_wl='-Xlinker '
+      if test -n "$lt_prog_compiler_pic"; then
+        lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic"
+      fi
+      ;;
+    esac
   else
     # PORTME Check for flag to pass linker flags through the system compiler.
     case $host_os in
@@ -8611,7 +9323,7 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
       lt_prog_compiler_static='-non_shared'
       ;;
 
-    linux* | k*bsd*-gnu)
+    linux* | k*bsd*-gnu | kopensolaris*-gnu)
       case $cc_basename in
       # old Intel for x86_64 which still supported -KPIC.
       ecc*)
@@ -8632,7 +9344,13 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
        lt_prog_compiler_pic='--shared'
        lt_prog_compiler_static='--static'
        ;;
-      pgcc* | pgf77* | pgf90* | pgf95*)
+      nagfor*)
+       # NAG Fortran compiler
+       lt_prog_compiler_wl='-Wl,-Wl,,'
+       lt_prog_compiler_pic='-PIC'
+       lt_prog_compiler_static='-Bstatic'
+       ;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
         # Portland Group compilers (*not* the Pentium gcc compiler,
        # which looks to be a dead project)
        lt_prog_compiler_wl='-Wl,'
@@ -8644,25 +9362,40 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
         # All Alpha code is PIC.
         lt_prog_compiler_static='-non_shared'
         ;;
-      xl*)
-       # IBM XL C 8.0/Fortran 10.1 on PPC
+      xl* | bgxl* | bgf* | mpixl*)
+       # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
        lt_prog_compiler_wl='-Wl,'
        lt_prog_compiler_pic='-qpic'
        lt_prog_compiler_static='-qstaticlink'
        ;;
       *)
        case `$CC -V 2>&1 | sed 5q` in
+       *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*)
+         # Sun Fortran 8.3 passes all unrecognized flags to the linker
+         lt_prog_compiler_pic='-KPIC'
+         lt_prog_compiler_static='-Bstatic'
+         lt_prog_compiler_wl=''
+         ;;
+       *Sun\ F* | *Sun*Fortran*)
+         lt_prog_compiler_pic='-KPIC'
+         lt_prog_compiler_static='-Bstatic'
+         lt_prog_compiler_wl='-Qoption ld '
+         ;;
        *Sun\ C*)
          # Sun C 5.9
          lt_prog_compiler_pic='-KPIC'
          lt_prog_compiler_static='-Bstatic'
          lt_prog_compiler_wl='-Wl,'
          ;;
-       *Sun\ F*)
-         # Sun Fortran 8.3 passes all unrecognized flags to the linker
-         lt_prog_compiler_pic='-KPIC'
+        *Intel*\ [CF]*Compiler*)
+         lt_prog_compiler_wl='-Wl,'
+         lt_prog_compiler_pic='-fPIC'
+         lt_prog_compiler_static='-static'
+         ;;
+       *Portland\ Group*)
+         lt_prog_compiler_wl='-Wl,'
+         lt_prog_compiler_pic='-fpic'
          lt_prog_compiler_static='-Bstatic'
-         lt_prog_compiler_wl=''
          ;;
        esac
        ;;
@@ -8694,7 +9427,7 @@ $as_echo_n "checking for $compiler option to produce PIC... " >&6; }
       lt_prog_compiler_pic='-KPIC'
       lt_prog_compiler_static='-Bstatic'
       case $cc_basename in
-      f77* | f90* | f95*)
+      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
        lt_prog_compiler_wl='-Qoption ld ';;
       *)
        lt_prog_compiler_wl='-Wl,';;
@@ -8751,13 +9484,17 @@ case $host_os in
     lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC"
     ;;
 esac
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5
-$as_echo "$lt_prog_compiler_pic" >&6; }
-
-
-
-
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5
+$as_echo_n "checking for $compiler option to produce PIC... " >&6; }
+if ${lt_cv_prog_compiler_pic+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler_pic=$lt_prog_compiler_pic
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5
+$as_echo "$lt_cv_prog_compiler_pic" >&6; }
+lt_prog_compiler_pic=$lt_cv_prog_compiler_pic
 
 #
 # Check to make sure the PIC flag actually works.
@@ -8765,7 +9502,7 @@ $as_echo "$lt_prog_compiler_pic" >&6; }
 if test -n "$lt_prog_compiler_pic"; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5
 $as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; }
-if test "${lt_cv_prog_compiler_pic_works+set}" = set; then :
+if ${lt_cv_prog_compiler_pic_works+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_prog_compiler_pic_works=no
@@ -8781,15 +9518,15 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8784: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:8788: \$? = $ac_status" >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
-     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
      $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
      if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
        lt_cv_prog_compiler_pic_works=yes
@@ -8818,13 +9555,18 @@ fi
 
 
 
+
+
+
+
+
 #
 # Check to make sure the static flag actually works.
 #
 wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\"
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5
 $as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; }
-if test "${lt_cv_prog_compiler_static_works+set}" = set; then :
+if ${lt_cv_prog_compiler_static_works+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_prog_compiler_static_works=no
@@ -8837,7 +9579,7 @@ else
      if test -s conftest.err; then
        # Append any errors to the config.log.
        cat conftest.err 1>&5
-       $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
        $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
        if diff conftest.exp conftest.er2 >/dev/null; then
          lt_cv_prog_compiler_static_works=yes
@@ -8867,7 +9609,7 @@ fi
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
-if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+if ${lt_cv_prog_compiler_c_o+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_prog_compiler_c_o=no
@@ -8886,16 +9628,16 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8889: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:8893: \$? = $ac_status" >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
-     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
      $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
      if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
        lt_cv_prog_compiler_c_o=yes
@@ -8922,7 +9664,7 @@ $as_echo "$lt_cv_prog_compiler_c_o" >&6; }
 
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5
 $as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; }
-if test "${lt_cv_prog_compiler_c_o+set}" = set; then :
+if ${lt_cv_prog_compiler_c_o+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   lt_cv_prog_compiler_c_o=no
@@ -8941,16 +9683,16 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8944: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:8948: \$? = $ac_status" >&5
+   echo "$as_me:$LINENO: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
-     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
      $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
      if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
        lt_cv_prog_compiler_c_o=yes
@@ -9016,7 +9758,6 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
   hardcode_direct=no
   hardcode_direct_absolute=no
   hardcode_libdir_flag_spec=
-  hardcode_libdir_flag_spec_ld=
   hardcode_libdir_separator=
   hardcode_minus_L=no
   hardcode_shlibpath_var=unsupported
@@ -9060,13 +9801,39 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
   openbsd*)
     with_gnu_ld=no
     ;;
-  linux* | k*bsd*-gnu)
+  linux* | k*bsd*-gnu | gnu*)
     link_all_deplibs=no
     ;;
   esac
 
   ld_shlibs=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
   if test "$with_gnu_ld" = yes; then
+    case $host_os in
+      aix*)
+       # The AIX port of GNU ld has always aspired to compatibility
+       # with the native linker.  However, as the warning in the GNU ld
+       # block says, versions before 2.19.5* couldn't really create working
+       # shared libraries, regardless of the interface used.
+       case `$LD -v 2>&1` in
+         *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+         *\ \(GNU\ Binutils\)\ 2.[2-9]*) ;;
+         *\ \(GNU\ Binutils\)\ [3-9]*) ;;
+         *)
+           lt_use_gnu_ld_interface=yes
+           ;;
+       esac
+       ;;
+      *)
+       lt_use_gnu_ld_interface=yes
+       ;;
+    esac
+  fi
+
+  if test "$lt_use_gnu_ld_interface" = yes; then
     # If archive_cmds runs LD, not CC, wlarc should be empty
     wlarc='${wl}'
 
@@ -9084,6 +9851,7 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
     fi
     supports_anon_versioning=no
     case `$LD -v 2>&1` in
+      *GNU\ gold*) supports_anon_versioning=yes ;;
       *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11
       *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
       *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
@@ -9099,11 +9867,12 @@ $as_echo_n "checking whether the $compiler linker ($LD) supports shared librarie
        ld_shlibs=no
        cat <<_LT_EOF 1>&2
 
-*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** Warning: the GNU linker, at least up to release 2.19, is reported
 *** to be unable to reliably create shared libraries on AIX.
 *** Therefore, libtool is disabling shared libraries support.  If you
-*** really care for shared libraries, you may want to modify your PATH
-*** so that a non-GNU linker is found, and then restart.
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
 
 _LT_EOF
       fi
@@ -9139,16 +9908,18 @@ _LT_EOF
       # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless,
       # as there is no search path for DLLs.
       hardcode_libdir_flag_spec='-L$libdir'
+      export_dynamic_flag_spec='${wl}--export-all-symbols'
       allow_undefined_flag=unsupported
       always_export_symbols=no
       enable_shared_with_static_runtimes=yes
-      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+      export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols'
+      exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'
 
       if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
         archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
        # If the export-symbols file already is a .def file (1st line
        # is EXPORTS), use it as is; otherwise, prepend...
-       archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+       archive_expsym_cmds='if test "x`$SED \"$sed_uncomment_deffile\" $export_symbols | $SED 1q`" = xEXPORTS; then
          cp $export_symbols $output_objdir/$soname.def;
        else
          echo EXPORTS > $output_objdir/$soname.def;
@@ -9160,6 +9931,11 @@ _LT_EOF
       fi
       ;;
 
+    haiku*)
+      archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      link_all_deplibs=yes
+      ;;
+
     interix[3-9]*)
       hardcode_direct=no
       hardcode_shlibpath_var=no
@@ -9175,7 +9951,7 @@ _LT_EOF
       archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
       ;;
 
-    gnu* | linux* | tpf* | k*bsd*-gnu)
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
       tmp_diet=no
       if test "$host_os" = linux-dietlibc; then
        case $cc_basename in
@@ -9185,15 +9961,16 @@ _LT_EOF
       if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
         && test "$tmp_diet" = no
       then
-       tmp_addflag=
+       tmp_addflag=' $pic_flag'
        tmp_sharedflag='-shared'
        case $cc_basename,$host_cpu in
         pgcc*)                         # Portland Group C compiler
-         whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+         whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
          tmp_addflag=' $pic_flag'
          ;;
-       pgf77* | pgf90* | pgf95*)       # Portland Group f77 and f90 compilers
-         whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+       pgf77* | pgf90* | pgf95* | pgfortran*)
+                                       # Portland Group f77 and f90 compilers
+         whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
          tmp_addflag=' $pic_flag -Mnomain' ;;
        ecc*,ia64* | icc*,ia64*)        # Intel C compiler on ia64
          tmp_addflag=' -i_dynamic' ;;
@@ -9204,13 +9981,17 @@ _LT_EOF
        lf95*)                          # Lahey Fortran 8.1
          whole_archive_flag_spec=
          tmp_sharedflag='--shared' ;;
-       xl[cC]*)                        # IBM XL C 8.0 on PPC (deal with xlf below)
+       xl[cC]* | bgxl[cC]* | mpixl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below)
          tmp_sharedflag='-qmkshrobj'
          tmp_addflag= ;;
+       nvcc*)  # Cuda Compiler Driver 2.2
+         whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+         compiler_needs_object=yes
+         ;;
        esac
        case `$CC -V 2>&1 | sed 5q` in
        *Sun\ C*)                       # Sun C 5.9
-         whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+         whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
          compiler_needs_object=yes
          tmp_sharedflag='-G' ;;
        *Sun\ F*)                       # Sun Fortran 8.3
@@ -9226,17 +10007,16 @@ _LT_EOF
         fi
 
        case $cc_basename in
-       xlf*)
+       xlf* | bgf* | bgxlf* | mpixlf*)
          # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
          whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive'
-         hardcode_libdir_flag_spec=
-         hardcode_libdir_flag_spec_ld='-rpath $libdir'
-         archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+         hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
+         archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
          if test "x$supports_anon_versioning" = xyes; then
            archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~
              cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
              echo "local: *; };" >> $output_objdir/$libname.ver~
-             $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+             $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
          fi
          ;;
        esac
@@ -9250,8 +10030,8 @@ _LT_EOF
        archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
        wlarc=
       else
-       archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-       archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       fi
       ;;
 
@@ -9269,8 +10049,8 @@ _LT_EOF
 
 _LT_EOF
       elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-       archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-       archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
        ld_shlibs=no
       fi
@@ -9316,8 +10096,8 @@ _LT_EOF
 
     *)
       if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-       archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-       archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
        ld_shlibs=no
       fi
@@ -9357,8 +10137,10 @@ _LT_EOF
       else
        # If we're using GNU nm, then we don't want the "-C" option.
        # -C means demangle to AIX nm, but means don't demangle with GNU nm
+       # Also, AIX nm treats weak defined symbols like other global
+       # defined symbols, whereas GNU nm marks them as "W".
        if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-         export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+         export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
        else
          export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
        fi
@@ -9446,7 +10228,13 @@ _LT_EOF
        allow_undefined_flag='-berok'
         # Determine the default libpath from the value encoded in an
         # empty executable.
-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+        if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
@@ -9459,25 +10247,32 @@ main ()
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
 
-lt_aix_libpath_sed='
-    /Import File Strings/,/^$/ {
-       /^0/ {
-           s/^0  *\(.*\)$/\1/
-           p
-       }
-    }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
-  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+         /^0/ {
+             s/^0  *\([^ ]*\) *$/\1/
+             p
+         }
+      }'
+  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+fi
 
         hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
-        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
       else
        if test "$host_cpu" = ia64; then
          hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
@@ -9486,7 +10281,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
        else
         # Determine the default libpath from the value encoded in an
         # empty executable.
-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+        if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  if ${lt_cv_aix_libpath_+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
@@ -9499,30 +10300,42 @@ main ()
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
 
-lt_aix_libpath_sed='
-    /Import File Strings/,/^$/ {
-       /^0/ {
-           s/^0  *\(.*\)$/\1/
-           p
-       }
-    }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
-  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi
+  lt_aix_libpath_sed='
+      /Import File Strings/,/^$/ {
+         /^0/ {
+             s/^0  *\([^ ]*\) *$/\1/
+             p
+         }
+      }'
+  lt_cv_aix_libpath_=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+  if test -z "$lt_cv_aix_libpath_"; then
+    lt_cv_aix_libpath_="/usr/lib:/lib"
+  fi
+
+fi
+
+  aix_libpath=$lt_cv_aix_libpath_
+fi
 
         hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
          # Warning - without using the other run time loading flags,
          # -berok will link without error, but may produce a broken library.
          no_undefined_flag=' ${wl}-bernotok'
          allow_undefined_flag=' ${wl}-berok'
-         # Exported symbols can be pulled into shared objects from archives
-         whole_archive_flag_spec='$convenience'
+         if test "$with_gnu_ld" = yes; then
+           # We only use this code for GNU lds that support --whole-archive.
+           whole_archive_flag_spec='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+         else
+           # Exported symbols can be pulled into shared objects from archives
+           whole_archive_flag_spec='$convenience'
+         fi
          archive_cmds_need_lc=yes
          # This is similar to how AIX traditionally builds its shared libraries.
          archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
@@ -9554,20 +10367,64 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
       # Microsoft Visual C++.
       # hardcode_libdir_flag_spec is actually meaningless, as there is
       # no search path for DLLs.
-      hardcode_libdir_flag_spec=' '
-      allow_undefined_flag=unsupported
-      # Tell ltmain to make .lib files, not .a files.
-      libext=lib
-      # Tell ltmain to make .dll files, not .so files.
-      shrext_cmds=".dll"
-      # FIXME: Setting linknames here is a bad hack.
-      archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
-      # The linker will automatically build a .lib file if we build a DLL.
-      old_archive_from_new_cmds='true'
-      # FIXME: Should let the user specify the lib program.
-      old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
-      fix_srcfile_path='`cygpath -w "$srcfile"`'
-      enable_shared_with_static_runtimes=yes
+      case $cc_basename in
+      cl*)
+       # Native MSVC
+       hardcode_libdir_flag_spec=' '
+       allow_undefined_flag=unsupported
+       always_export_symbols=yes
+       file_list_spec='@'
+       # Tell ltmain to make .lib files, not .a files.
+       libext=lib
+       # Tell ltmain to make .dll files, not .so files.
+       shrext_cmds=".dll"
+       # FIXME: Setting linknames here is a bad hack.
+       archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+       archive_expsym_cmds='if test "x`$SED \"$sed_uncomment_deffile\" $export_symbols | $SED 1q`" = xEXPORTS; then
+           sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+         else
+           sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+         fi~
+         $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+         linknames='
+       # The linker will not automatically build a static lib if we build a DLL.
+       # _LT_TAGVAR(old_archive_from_new_cmds, )='true'
+       enable_shared_with_static_runtimes=yes
+       exclude_expsyms='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+       export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1,DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols'
+       # Don't use ranlib
+       old_postinstall_cmds='chmod 644 $oldlib'
+       postlink_cmds='lt_outputfile="@OUTPUT@"~
+         lt_tool_outputfile="@TOOL_OUTPUT@"~
+         case $lt_outputfile in
+           *.exe|*.EXE) ;;
+           *)
+             lt_outputfile="$lt_outputfile.exe"
+             lt_tool_outputfile="$lt_tool_outputfile.exe"
+             ;;
+         esac~
+         if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+           $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+           $RM "$lt_outputfile.manifest";
+         fi'
+       ;;
+      *)
+       # Assume MSVC wrapper
+       hardcode_libdir_flag_spec=' '
+       allow_undefined_flag=unsupported
+       # Tell ltmain to make .lib files, not .a files.
+       libext=lib
+       # Tell ltmain to make .dll files, not .so files.
+       shrext_cmds=".dll"
+       # FIXME: Setting linknames here is a bad hack.
+       archive_cmds='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+       # The linker will automatically build a .lib file if we build a DLL.
+       old_archive_from_new_cmds='true'
+       # FIXME: Should let the user specify the lib program.
+       old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs'
+       enable_shared_with_static_runtimes=yes
+       ;;
+      esac
       ;;
 
     darwin* | rhapsody*)
@@ -9577,7 +10434,12 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
   hardcode_direct=no
   hardcode_automatic=yes
   hardcode_shlibpath_var=unsupported
-  whole_archive_flag_spec=''
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    whole_archive_flag_spec='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+
+  else
+    whole_archive_flag_spec=''
+  fi
   link_all_deplibs=yes
   allow_undefined_flag="$_lt_dar_allow_undefined"
   case $cc_basename in
@@ -9585,7 +10447,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
      *) _lt_dar_can_shared=$GCC ;;
   esac
   if test "$_lt_dar_can_shared" = "yes"; then
-    output_verbose_link_cmd=echo
+    output_verbose_link_cmd=func_echo_all
     archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
     module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
     archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
@@ -9603,10 +10465,6 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
       hardcode_shlibpath_var=no
       ;;
 
-    freebsd1*)
-      ld_shlibs=no
-      ;;
-
     # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
     # support.  Future versions do this automatically, but an explicit c++rt0.o
     # does not break anything, and helps significantly (at the cost of a little
@@ -9619,7 +10477,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
       ;;
 
     # Unfortunately, older versions of FreeBSD 2 do not have this feature.
-    freebsd2*)
+    freebsd2.*)
       archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
       hardcode_direct=yes
       hardcode_minus_L=yes
@@ -9628,7 +10486,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 
     # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
     freebsd* | dragonfly*)
-      archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
       hardcode_libdir_flag_spec='-R$libdir'
       hardcode_direct=yes
       hardcode_shlibpath_var=no
@@ -9636,7 +10494,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 
     hpux9*)
       if test "$GCC" = yes; then
-       archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+       archive_cmds='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
       else
        archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
       fi
@@ -9651,14 +10509,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
       ;;
 
     hpux10*)
-      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
-       archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+       archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
       else
        archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
       fi
       if test "$with_gnu_ld" = no; then
        hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
-       hardcode_libdir_flag_spec_ld='+b $libdir'
        hardcode_libdir_separator=:
        hardcode_direct=yes
        hardcode_direct_absolute=yes
@@ -9670,16 +10527,16 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
       ;;
 
     hpux11*)
-      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
        case $host_cpu in
        hppa*64*)
          archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
          ;;
        ia64*)
-         archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+         archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
          ;;
        *)
-         archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+         archive_cmds='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
          ;;
        esac
       else
@@ -9691,7 +10548,46 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
          archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
          ;;
        *)
-         archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+
+         # Older versions of the 11.00 compiler do not understand -b yet
+         # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+         { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $CC understands -b" >&5
+$as_echo_n "checking if $CC understands -b... " >&6; }
+if ${lt_cv_prog_compiler__b+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_prog_compiler__b=no
+   save_LDFLAGS="$LDFLAGS"
+   LDFLAGS="$LDFLAGS -b"
+   echo "$lt_simple_link_test_code" > conftest.$ac_ext
+   if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then
+     # The linker can only warn and ignore the option if not recognized
+     # So say no if there are warnings
+     if test -s conftest.err; then
+       # Append any errors to the config.log.
+       cat conftest.err 1>&5
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
+       $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
+       if diff conftest.exp conftest.er2 >/dev/null; then
+         lt_cv_prog_compiler__b=yes
+       fi
+     else
+       lt_cv_prog_compiler__b=yes
+     fi
+   fi
+   $RM -r conftest*
+   LDFLAGS="$save_LDFLAGS"
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler__b" >&5
+$as_echo "$lt_cv_prog_compiler__b" >&6; }
+
+if test x"$lt_cv_prog_compiler__b" = xyes; then
+    archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+else
+    archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
+fi
+
          ;;
        esac
       fi
@@ -9719,26 +10615,39 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
 
     irix5* | irix6* | nonstopux*)
       if test "$GCC" = yes; then
-       archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+       archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
        # Try to use the -exported_symbol ld option, if it does not
        # work, assume that -exports_file does not work either and
        # implicitly export all symbols.
-        save_LDFLAGS="$LDFLAGS"
-        LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
-        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+       # This should be the same for all languages, so no per-tag cache variable.
+       { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $host_os linker accepts -exported_symbol" >&5
+$as_echo_n "checking whether the $host_os linker accepts -exported_symbol... " >&6; }
+if ${lt_cv_irix_exported_symbol+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  save_LDFLAGS="$LDFLAGS"
+          LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-int foo(void) {}
+int foo (void) { return 0; }
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
-  archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
-
+  lt_cv_irix_exported_symbol=yes
+else
+  lt_cv_irix_exported_symbol=no
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-        LDFLAGS="$save_LDFLAGS"
+           LDFLAGS="$save_LDFLAGS"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_irix_exported_symbol" >&5
+$as_echo "$lt_cv_irix_exported_symbol" >&6; }
+       if test "$lt_cv_irix_exported_symbol" = yes; then
+          archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+       fi
       else
-       archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
-       archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+       archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+       archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
       fi
       archive_cmds_need_lc='no'
       hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
@@ -9800,17 +10709,17 @@ rm -f core conftest.err conftest.$ac_objext \
       hardcode_libdir_flag_spec='-L$libdir'
       hardcode_minus_L=yes
       allow_undefined_flag=unsupported
-      archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
       old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
       ;;
 
     osf3*)
       if test "$GCC" = yes; then
        allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
-       archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+       archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
       else
        allow_undefined_flag=' -expect_unresolved \*'
-       archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+       archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
       fi
       archive_cmds_need_lc='no'
       hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
@@ -9820,13 +10729,13 @@ rm -f core conftest.err conftest.$ac_objext \
     osf4* | osf5*)     # as osf3* with the addition of -msym flag
       if test "$GCC" = yes; then
        allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*'
-       archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+       archive_cmds='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
        hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
       else
        allow_undefined_flag=' -expect_unresolved \*'
-       archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+       archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
        archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
-       $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+       $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
 
        # Both c and cxx compiler support -rpath directly
        hardcode_libdir_flag_spec='-rpath $libdir'
@@ -9839,9 +10748,9 @@ rm -f core conftest.err conftest.$ac_objext \
       no_undefined_flag=' -z defs'
       if test "$GCC" = yes; then
        wlarc='${wl}'
-       archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       archive_cmds='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
        archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-         $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+         $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
       else
        case `$CC -V 2>&1` in
        *"Compilers 5.0"*)
@@ -10029,44 +10938,50 @@ x|xyes)
       # to ld, don't add -lc before -lgcc.
       { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5
 $as_echo_n "checking whether -lc should be explicitly linked in... " >&6; }
-      $RM conftest*
-      echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+if ${lt_cv_archive_cmds_need_lc+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  $RM conftest*
+       echo "$lt_simple_compile_test_code" > conftest.$ac_ext
 
-      if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+       if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; } 2>conftest.err; then
-        soname=conftest
-        lib=conftest
-        libobjs=conftest.$ac_objext
-        deplibs=
-        wl=$lt_prog_compiler_wl
-       pic_flag=$lt_prog_compiler_pic
-        compiler_flags=-v
-        linker_flags=-v
-        verstring=
-        output_objdir=.
-        libname=conftest
-        lt_save_allow_undefined_flag=$allow_undefined_flag
-        allow_undefined_flag=
-        if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
+         soname=conftest
+         lib=conftest
+         libobjs=conftest.$ac_objext
+         deplibs=
+         wl=$lt_prog_compiler_wl
+         pic_flag=$lt_prog_compiler_pic
+         compiler_flags=-v
+         linker_flags=-v
+         verstring=
+         output_objdir=.
+         libname=conftest
+         lt_save_allow_undefined_flag=$allow_undefined_flag
+         allow_undefined_flag=
+         if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5
   (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5
   ac_status=$?
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
   test $ac_status = 0; }
-        then
-         archive_cmds_need_lc=no
-        else
-         archive_cmds_need_lc=yes
-        fi
-        allow_undefined_flag=$lt_save_allow_undefined_flag
-      else
-        cat conftest.err 1>&5
-      fi
-      $RM conftest*
-      { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5
-$as_echo "$archive_cmds_need_lc" >&6; }
+         then
+           lt_cv_archive_cmds_need_lc=no
+         else
+           lt_cv_archive_cmds_need_lc=yes
+         fi
+         allow_undefined_flag=$lt_save_allow_undefined_flag
+       else
+         cat conftest.err 1>&5
+       fi
+       $RM conftest*
+
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_archive_cmds_need_lc" >&5
+$as_echo "$lt_cv_archive_cmds_need_lc" >&6; }
+      archive_cmds_need_lc=$lt_cv_archive_cmds_need_lc
       ;;
     esac
   fi
@@ -10224,11 +11139,6 @@ esac
 
 
 
-
-
-
-
-
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5
 $as_echo_n "checking dynamic linker characteristics... " >&6; }
 
@@ -10237,16 +11147,23 @@ if test "$GCC" = yes; then
     darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
     *) lt_awk_arg="/^libraries:/" ;;
   esac
-  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
-  if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([A-Za-z]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
     # if the path contains ";" then we assume it to be the separator
     # otherwise default to the standard path separator (i.e. ":") - it is
     # assumed that no part of a normal pathname contains ";" but that should
     # okay in the real world where ";" in dirpaths is itself problematic.
-    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
-  else
-    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
-  fi
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
   # Ok, now we have the path, separated by spaces, we can step through it
   # and add multilib dir if necessary.
   lt_tmp_lt_search_path_spec=
@@ -10259,7 +11176,7 @@ if test "$GCC" = yes; then
        lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
     fi
   done
-  lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
+  lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
 BEGIN {RS=" "; FS="/|\n";} {
   lt_foo="";
   lt_count=0;
@@ -10279,7 +11196,13 @@ BEGIN {RS=" "; FS="/|\n";} {
   if (lt_foo != "") { lt_freq[lt_foo]++; }
   if (lt_freq[lt_foo] == 1) { print lt_foo; }
 }'`
-  sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's,/\([A-Za-z]:\),\1,g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
 else
   sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
 fi
@@ -10305,7 +11228,7 @@ need_version=unknown
 
 case $host_os in
 aix3*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
   shlibpath_var=LIBPATH
 
@@ -10314,7 +11237,7 @@ aix3*)
   ;;
 
 aix[4-9]*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   hardcode_into_libs=yes
@@ -10367,7 +11290,7 @@ amigaos*)
   m68k)
     library_names_spec='$libname.ixlibrary $libname.a'
     # Create ${libname}_ixlibrary.a entries in /sys/libs.
-    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
     ;;
   esac
   ;;
@@ -10379,7 +11302,7 @@ beos*)
   ;;
 
 bsdi[45]*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
@@ -10398,8 +11321,9 @@ cygwin* | mingw* | pw32* | cegcc*)
   need_version=no
   need_lib_prefix=no
 
-  case $GCC,$host_os in
-  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+  case $GCC,$cc_basename in
+  yes,*)
+    # gcc
     library_names_spec='$libname.dll.a'
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
     postinstall_cmds='base_file=`basename \${file}`~
@@ -10420,36 +11344,83 @@ cygwin* | mingw* | pw32* | cegcc*)
     cygwin*)
       # Cygwin DLLs use 'cyg' prefix rather than 'lib'
       soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
-      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+
+      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"
       ;;
     mingw* | cegcc*)
       # MinGW DLLs use traditional 'lib' prefix
       soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
-      sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
-      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
-        # It is most probably a Windows format PATH printed by
-        # mingw gcc, but we are running on Cygwin. Gcc prints its search
-        # path with ; separators, and with drive letters. We can handle the
-        # drive letters (cygwin fileutils understands them), so leave them,
-        # especially as we might pass files found there to a mingw objdump,
-        # which wouldn't understand a cygwinified path. Ahh.
-        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
-      else
-        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
-      fi
       ;;
     pw32*)
       # pw32 DLLs use 'pw' prefix rather than 'lib'
       library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
       ;;
     esac
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then
+        # It is most probably a Windows format PATH.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
     ;;
 
   *)
+    # Assume MSVC wrapper
     library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
     ;;
   esac
-  dynamic_linker='Win32 ld.exe'
   # FIXME: first we should search . and the directory the executable is in
   shlibpath_var=PATH
   ;;
@@ -10470,7 +11441,7 @@ darwin* | rhapsody*)
   ;;
 
 dgux*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
@@ -10478,10 +11449,6 @@ dgux*)
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
-freebsd1*)
-  dynamic_linker=no
-  ;;
-
 freebsd* | dragonfly*)
   # DragonFly does not have aout.  When/if they implement a new
   # versioning mechanism, adjust this.
@@ -10489,7 +11456,7 @@ freebsd* | dragonfly*)
     objformat=`/usr/bin/objformat`
   else
     case $host_os in
-    freebsd[123]*) objformat=aout ;;
+    freebsd[23].*) objformat=aout ;;
     *) objformat=elf ;;
     esac
   fi
@@ -10507,7 +11474,7 @@ freebsd* | dragonfly*)
   esac
   shlibpath_var=LD_LIBRARY_PATH
   case $host_os in
-  freebsd2*)
+  freebsd2.*)
     shlibpath_overrides_runpath=yes
     ;;
   freebsd3.[01]* | freebsdelf3.[01]*)
@@ -10527,12 +11494,26 @@ freebsd* | dragonfly*)
   ;;
 
 gnu*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
   hardcode_into_libs=yes
   ;;
 
@@ -10578,12 +11559,14 @@ hpux9* | hpux10* | hpux11*)
     soname_spec='${libname}${release}${shared_ext}$major'
     ;;
   esac
-  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
   postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
   ;;
 
 interix[3-9]*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
@@ -10599,7 +11582,7 @@ irix5* | irix6* | nonstopux*)
     nonstopux*) version_type=nonstopux ;;
     *)
        if test "$lt_cv_prog_gnu_ld" = yes; then
-               version_type=linux
+               version_type=linux # correct to gnu/linux during the next big refactor
        else
                version_type=irix
        fi ;;
@@ -10636,9 +11619,29 @@ linux*oldld* | linux*aout* | linux*coff*)
   dynamic_linker=no
   ;;
 
-# This must be Linux ELF.
-linux* | k*bsd*-gnu)
-  version_type=linux
+linux*android*)
+  version_type=none # Android doesn't support versioned libraries.
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext'
+  soname_spec='$libname$release$shared_ext'
+  finish_cmds=
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  dynamic_linker='Android linker'
+  # Don't embed -rpath directories since the linker doesn't support them.
+  hardcode_libdir_flag_spec='-L$libdir'
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -10646,12 +11649,17 @@ linux* | k*bsd*-gnu)
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
+
   # Some binutils ld are patched to set DT_RUNPATH
-  save_LDFLAGS=$LDFLAGS
-  save_libdir=$libdir
-  eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
-       LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+  if ${lt_cv_shlibpath_overrides_runpath+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \
+        LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\""
+    cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
 int
@@ -10664,13 +11672,17 @@ main ()
 _ACEOF
 if ac_fn_c_try_link "$LINENO"; then :
   if  ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then :
-  shlibpath_overrides_runpath=yes
+  lt_cv_shlibpath_overrides_runpath=yes
 fi
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
-  LDFLAGS=$save_LDFLAGS
-  libdir=$save_libdir
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+
+fi
+
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
 
   # This implies no fast_install, which is unacceptable.
   # Some rework will be needed to allow for fast_install
@@ -10679,7 +11691,7 @@ rm -f core conftest.err conftest.$ac_objext \
 
   # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
-    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[      ]*hwcap[        ]/d;s/[:,      ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[      ]*hwcap[        ]/d;s/[:,      ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
     sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
   fi
 
@@ -10723,7 +11735,7 @@ netbsd*)
   ;;
 
 newsos6)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
@@ -10792,7 +11804,7 @@ rdos*)
   ;;
 
 solaris*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -10817,7 +11829,7 @@ sunos4*)
   ;;
 
 sysv4 | sysv4.3*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
@@ -10841,7 +11853,7 @@ sysv4 | sysv4.3*)
 
 sysv4*MP*)
   if test -d /usr/nec ;then
-    version_type=linux
+    version_type=linux # correct to gnu/linux during the next big refactor
     library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
     soname_spec='$libname${shared_ext}.$major'
     shlibpath_var=LD_LIBRARY_PATH
@@ -10872,7 +11884,7 @@ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
 
 tpf*)
   # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -10882,7 +11894,7 @@ tpf*)
   ;;
 
 uts4*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
 
 
 
+
+
+
+
+
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5
 $as_echo_n "checking how to hardcode library paths into programs... " >&6; }
 hardcode_action=
@@ -11066,7 +12083,7 @@ else
   # if libdl is installed we need to link against it
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
 $as_echo_n "checking for dlopen in -ldl... " >&6; }
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+if ${ac_cv_lib_dl_dlopen+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -11100,7 +12117,7 @@ LIBS=$ac_check_lib_save_LIBS
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
 $as_echo "$ac_cv_lib_dl_dlopen" >&6; }
-if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
   lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
 else
 
 
   *)
     ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load"
-if test "x$ac_cv_func_shl_load" = x""yes; then :
+if test "x$ac_cv_func_shl_load" = xyes; then :
   lt_cv_dlopen="shl_load"
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
 $as_echo_n "checking for shl_load in -ldld... " >&6; }
-if test "${ac_cv_lib_dld_shl_load+set}" = set; then :
+if ${ac_cv_lib_dld_shl_load+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -11153,16 +12170,16 @@ LIBS=$ac_check_lib_save_LIBS
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
 $as_echo "$ac_cv_lib_dld_shl_load" >&6; }
-if test "x$ac_cv_lib_dld_shl_load" = x""yes; then :
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
   lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"
 else
   ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen"
-if test "x$ac_cv_func_dlopen" = x""yes; then :
+if test "x$ac_cv_func_dlopen" = xyes; then :
   lt_cv_dlopen="dlopen"
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
 $as_echo_n "checking for dlopen in -ldl... " >&6; }
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then :
+if ${ac_cv_lib_dl_dlopen+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -11196,12 +12213,12 @@ LIBS=$ac_check_lib_save_LIBS
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
 $as_echo "$ac_cv_lib_dl_dlopen" >&6; }
-if test "x$ac_cv_lib_dl_dlopen" = x""yes; then :
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
   lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl"
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5
 $as_echo_n "checking for dlopen in -lsvld... " >&6; }
-if test "${ac_cv_lib_svld_dlopen+set}" = set; then :
+if ${ac_cv_lib_svld_dlopen+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -11235,12 +12252,12 @@ LIBS=$ac_check_lib_save_LIBS
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5
 $as_echo "$ac_cv_lib_svld_dlopen" >&6; }
-if test "x$ac_cv_lib_svld_dlopen" = x""yes; then :
+if test "x$ac_cv_lib_svld_dlopen" = xyes; then :
   lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5
 $as_echo_n "checking for dld_link in -ldld... " >&6; }
-if test "${ac_cv_lib_dld_dld_link+set}" = set; then :
+if ${ac_cv_lib_dld_dld_link+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -11274,7 +12291,7 @@ LIBS=$ac_check_lib_save_LIBS
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5
 $as_echo "$ac_cv_lib_dld_dld_link" >&6; }
-if test "x$ac_cv_lib_dld_dld_link" = x""yes; then :
+if test "x$ac_cv_lib_dld_dld_link" = xyes; then :
   lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"
 fi
 
@@ -11315,7 +12332,7 @@ fi
 
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5
 $as_echo_n "checking whether a program can dlopen itself... " >&6; }
-if test "${lt_cv_dlopen_self+set}" = set; then :
+if ${lt_cv_dlopen_self+:} false; then :
   $as_echo_n "(cached) " >&6
 else
          if test "$cross_compiling" = yes; then :
@@ -11324,7 +12341,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11327 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11365,7 +12382,13 @@ else
 #  endif
 #endif
 
-void fnord() { int i=42;}
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
 int main ()
 {
   void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
@@ -11374,7 +12397,11 @@ int main ()
   if (self)
     {
       if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
-      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      else
+        {
+         if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+       }
       /* dlclose (self); */
     }
   else
@@ -11411,7 +12438,7 @@ $as_echo "$lt_cv_dlopen_self" >&6; }
       wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\"
       { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5
 $as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; }
-if test "${lt_cv_dlopen_self_static+set}" = set; then :
+if ${lt_cv_dlopen_self_static+:} false; then :
   $as_echo_n "(cached) " >&6
 else
          if test "$cross_compiling" = yes; then :
@@ -11420,7 +12447,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11423 "configure"
+#line $LINENO "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11461,7 +12488,13 @@ else
 #  endif
 #endif
 
-void fnord() { int i=42;}
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
 int main ()
 {
   void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
@@ -11470,7 +12503,11 @@ int main ()
   if (self)
     {
       if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
-      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      else
+        {
+         if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+       }
       /* dlclose (self); */
     }
   else
@@ -11639,6 +12676,8 @@ CC="$lt_save_CC"
 
 
 
+
+
         ac_config_commands="$ac_config_commands libtool"
 
 
@@ -11652,7 +12691,7 @@ if test -n "$ac_tool_prefix"; then
 set dummy ${ac_tool_prefix}windres; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_RC+set}" = set; then :
+if ${ac_cv_prog_RC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$RC"; then
@@ -11664,7 +12703,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_RC="${ac_tool_prefix}windres"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -11692,7 +12731,7 @@ if test -z "$ac_cv_prog_RC"; then
 set dummy windres; ac_word=$2
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_RC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_RC+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -n "$ac_ct_RC"; then
@@ -11704,7 +12743,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_RC="windres"
     $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
@@ -11788,9 +12827,11 @@ $RM -r conftest*
 
 # Allow CC to be a program name with arguments.
 lt_save_CC="$CC"
+lt_save_CFLAGS=$CFLAGS
 lt_save_GCC=$GCC
 GCC=
 CC=${RC-"windres"}
+CFLAGS=
 compiler=$CC
 compiler_RC=$CC
 for cc_temp in $compiler""; do
@@ -11801,7 +12842,7 @@ for cc_temp in $compiler""; do
     *) break;;
   esac
 done
-cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
 
 lt_cv_prog_compiler_c_o_RC=yes
 
@@ -11819,7 +12860,8 @@ 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
 
-CC="$lt_save_CC"
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
 
 
 
@@ -11834,7 +12876,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"
+available_ciphers="$available_ciphers camellia idea salsa20 gost28147"
 enabled_ciphers=""
 
 # Definitions for public-key ciphers.
@@ -11842,10 +12884,15 @@ available_pubkey_ciphers="dsa elgamal rsa ecc"
 enabled_pubkey_ciphers=""
 
 # Definitions for message digests.
-available_digests="crc md4 md5 rmd160 sha1 sha256"
-available_digests_64="sha512 tiger whirlpool"
+available_digests="crc gostr3411-94 md4 md5 rmd160 sha1 sha256"
+available_digests_64="sha512 tiger whirlpool stribog"
 enabled_digests=""
 
+# Definitions for kdfs (optional ones)
+available_kdfs="s2k pkdf2"
+available_kdfs_64="scrypt"
+enabled_kdfs=""
+
 # Definitions for random modules.
 available_random_modules="linux egd unix"
 auto_random_modules="$available_random_modules"
@@ -11857,6 +12904,8 @@ LIBGCRYPT_THREAD_MODULES=""
 print_egd_notice=no
 have_w32_system=no
 have_w32ce_system=no
+have_pthread=no
+
 
 # Setup some stuff depending on host.
 case "${host}" in
@@ -11901,12 +12950,6 @@ $as_echo "#define HAVE_DOSISH_SYSTEM 1" >>confdefs.h
 
         ;;
 
-    *-*-freebsd*)
-       # FreeBSD
-       CPPFLAGS="$CPPFLAGS -I/usr/local/include"
-       LDFLAGS="$LDFLAGS -L/usr/local/lib"
-       ;;
-
     *-*-hpux*)
         if test -z "$GCC" ; then
             CFLAGS="$CFLAGS -Ae -D_HPUX_SOURCE"
@@ -12007,7 +13050,7 @@ fi
 if test x"$endiancheck" = xyes ; then
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
 $as_echo_n "checking whether byte ordering is bigendian... " >&6; }
-if test "${ac_cv_c_bigendian+set}" = set; then :
+if ${ac_cv_c_bigendian+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_cv_c_bigendian=unknown
@@ -12225,7 +13268,7 @@ $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
 
      ;; #(
    *)
-     as_fn_error "unknown endianness
+     as_fn_error $? "unknown endianness
  presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
  esac
 
@@ -12241,7 +13284,7 @@ fi
 # This bug is HP SR number 8606223364.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned short" >&5
 $as_echo_n "checking size of unsigned short... " >&6; }
-if test "${ac_cv_sizeof_unsigned_short+set}" = set; then :
+if ${ac_cv_sizeof_unsigned_short+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned short))" "ac_cv_sizeof_unsigned_short"        "$ac_includes_default"; then :
@@ -12250,9 +13293,8 @@ else
   if test "$ac_cv_type_unsigned_short" = 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_set_status 77
-as_fn_error "cannot compute sizeof (unsigned short)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (unsigned short)
+See \`config.log' for more details" "$LINENO" 5; }
    else
      ac_cv_sizeof_unsigned_short=0
    fi
@@ -12275,7 +13317,7 @@ _ACEOF
 # This bug is HP SR number 8606223364.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned int" >&5
 $as_echo_n "checking size of unsigned int... " >&6; }
-if test "${ac_cv_sizeof_unsigned_int+set}" = set; then :
+if ${ac_cv_sizeof_unsigned_int+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned int))" "ac_cv_sizeof_unsigned_int"        "$ac_includes_default"; then :
@@ -12284,9 +13326,8 @@ else
   if test "$ac_cv_type_unsigned_int" = 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_set_status 77
-as_fn_error "cannot compute sizeof (unsigned int)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (unsigned int)
+See \`config.log' for more details" "$LINENO" 5; }
    else
      ac_cv_sizeof_unsigned_int=0
    fi
@@ -12309,7 +13350,7 @@ _ACEOF
 # This bug is HP SR number 8606223364.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long" >&5
 $as_echo_n "checking size of unsigned long... " >&6; }
-if test "${ac_cv_sizeof_unsigned_long+set}" = set; then :
+if ${ac_cv_sizeof_unsigned_long+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long))" "ac_cv_sizeof_unsigned_long"        "$ac_includes_default"; then :
@@ -12318,9 +13359,8 @@ else
   if test "$ac_cv_type_unsigned_long" = 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_set_status 77
-as_fn_error "cannot compute sizeof (unsigned long)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (unsigned long)
+See \`config.log' for more details" "$LINENO" 5; }
    else
      ac_cv_sizeof_unsigned_long=0
    fi
@@ -12343,7 +13383,7 @@ _ACEOF
 # This bug is HP SR number 8606223364.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking size of unsigned long long" >&5
 $as_echo_n "checking size of unsigned long long... " >&6; }
-if test "${ac_cv_sizeof_unsigned_long_long+set}" = set; then :
+if ${ac_cv_sizeof_unsigned_long_long+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (unsigned long long))" "ac_cv_sizeof_unsigned_long_long"        "$ac_includes_default"; then :
@@ -12352,9 +13392,8 @@ else
   if test "$ac_cv_type_unsigned_long_long" = 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_set_status 77
-as_fn_error "cannot compute sizeof (unsigned long long)
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "cannot compute sizeof (unsigned long long)
+See \`config.log' for more details" "$LINENO" 5; }
    else
      ac_cv_sizeof_unsigned_long_long=0
    fi
@@ -12374,7 +13413,7 @@ _ACEOF
 
 
   ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default"
-if test "x$ac_cv_type_uintptr_t" = x""yes; then :
+if test "x$ac_cv_type_uintptr_t" = xyes; then :
 
 $as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h
 
@@ -12388,7 +13427,8 @@ int
 main ()
 {
 static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
 
   ;
   return 0;
@@ -12421,10 +13461,13 @@ 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, SHA-384, and SHA-512" >&5
-$as_echo "$as_me: WARNING: No 64-bit types.  Disabling TIGER/192, SHA-384, and SHA-512" >&2;}
+    { $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;}
 else
   available_digests="$available_digests $available_digests_64"
+  available_kdfs="$available_kdfs $available_kdfs_64"
 fi
 
 # If not specified otherwise, all available algorithms will be
@@ -12432,6 +13475,7 @@ fi
 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:'
@@ -12473,7 +13517,7 @@ for n in $list; do
 done
 
     if test "$found" = "0"; then
-       as_fn_error "unsupported cipher \"$cipher\" specified" "$LINENO" 5
+       as_fn_error $? "unsupported cipher \"$cipher\" specified" "$LINENO" 5
     fi
 done
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enabled_ciphers" >&5
@@ -12507,7 +13551,7 @@ for n in $list; do
 done
 
     if test "$found" = "0"; then
-       as_fn_error "unsupported public-key cipher specified" "$LINENO" 5
+       as_fn_error $? "unsupported public-key cipher specified" "$LINENO" 5
     fi
 done
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enabled_pubkey_ciphers" >&5
@@ -12541,12 +13585,46 @@ for n in $list; do
 done
 
     if test "$found" = "0"; then
-       as_fn_error "unsupported message digest specified" "$LINENO" 5
+       as_fn_error $? "unsupported message digest specified" "$LINENO" 5
     fi
 done
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enabled_digests" >&5
 $as_echo "$enabled_digests" >&6; }
 
+# Implementation of the --enable-kdfs switch.
+# Check whether --enable-kdfs was given.
+if test "${enable_kdfs+set}" = set; then :
+  enableval=$enable_kdfs; enabled_kdfs=`echo $enableval | tr ',:' '  ' | tr 'A-Z' 'a-z'`
+else
+  enabled_kdfs=""
+fi
+
+if test "x$enabled_kdfs" = "x" \
+   -o "$enabled_kdfs" = "yes"  \
+   -o "$enabled_kdfs" = "no"; then
+   enabled_kdfs=$default_kdfs
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking which key derivation functions to include" >&5
+$as_echo_n "checking which key derivation functions to include... " >&6; }
+for kdf in $enabled_kdfs; do
+
+name=$kdf
+list=$available_kdfs
+found=0
+
+for n in $list; do
+  if test "x$name" = "x$n"; then
+    found=1
+  fi
+done
+
+    if test "$found" = "0"; then
+       as_fn_error $? "unsupported key derivation function specified" "$LINENO" 5
+    fi
+done
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $enabled_kdfs" >&5
+$as_echo "$enabled_kdfs" >&6; }
+
 # Implementation of the --enable-random switch.
 # Check whether --enable-random was given.
 if test "${enable_random+set}" = set; then :
@@ -12571,7 +13649,7 @@ for n in $list; do
 done
 
     if test "$found" = "0"; then
-       as_fn_error "unsupported random module specified" "$LINENO" 5
+       as_fn_error $? "unsupported random module specified" "$LINENO" 5
     fi
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $random" >&5
@@ -12663,6 +13741,22 @@ $as_echo "#define M_GUARD 1" >>confdefs.h
 
 fi
 
+# Implementation of the --enable-large-data-tests switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to run large data tests" >&5
+$as_echo_n "checking whether to run large data tests... " >&6; }
+# Check whether --enable-large-data-tests was given.
+if test "${enable_large_data_tests+set}" = set; then :
+  enableval=$enable_large_data_tests; large_data_tests=$enableval
+else
+  large_data_tests=no
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $large_data_tests" >&5
+$as_echo "$large_data_tests" >&6; }
+RUN_LARGE_DATA_TESTS=$large_data_tests
+
+
+
 # Implementation of the --with-capabilities switch.
 # Check whether we want to use Linux capabilities
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether use of capabilities is requested" >&5
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $padlocksupport" >&5
 $as_echo "$padlocksupport" >&6; }
-if test x"$padlocksupport" = xyes ; then
-
-$as_echo "#define ENABLE_PADLOCK_SUPPORT 1" >>confdefs.h
-
-fi
 
 # Implementation of the --disable-aesni-support switch.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether AESNI support is requested" >&5
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $aesnisupport" >&5
 $as_echo "$aesnisupport" >&6; }
-if test x"$aesnisupport" = xyes ; then
 
-$as_echo "#define ENABLE_AESNI_SUPPORT 1" >>confdefs.h
+# Implementation of the --disable-pclmul-support switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether PCLMUL support is requested" >&5
+$as_echo_n "checking whether PCLMUL support is requested... " >&6; }
+# Check whether --enable-pclmul-support was given.
+if test "${enable_pclmul_support+set}" = set; then :
+  enableval=$enable_pclmul_support; pclmulsupport=$enableval
+else
+  pclmulsupport=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $pclmulsupport" >&5
+$as_echo "$pclmulsupport" >&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; }
+# Check whether --enable-drng-support was given.
+if test "${enable_drng_support+set}" = set; then :
+  enableval=$enable_drng_support; drngsupport=$enableval
+else
+  drngsupport=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $drngsupport" >&5
+$as_echo "$drngsupport" >&6; }
 
+# Implementation of the --disable-avx-support switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether AVX support is requested" >&5
+$as_echo_n "checking whether AVX support is requested... " >&6; }
+# Check whether --enable-avx-support was given.
+if test "${enable_avx_support+set}" = set; then :
+  enableval=$enable_avx_support; avxsupport=$enableval
+else
+  avxsupport=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $avxsupport" >&5
+$as_echo "$avxsupport" >&6; }
+
+# Implementation of the --disable-avx2-support switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether AVX2 support is requested" >&5
+$as_echo_n "checking whether AVX2 support is requested... " >&6; }
+# Check whether --enable-avx2-support was given.
+if test "${enable_avx2_support+set}" = set; then :
+  enableval=$enable_avx2_support; avx2support=$enableval
+else
+  avx2support=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $avx2support" >&5
+$as_echo "$avx2support" >&6; }
+
+# Implementation of the --disable-neon-support switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether NEON support is requested" >&5
+$as_echo_n "checking whether NEON support is requested... " >&6; }
+# Check whether --enable-neon-support was given.
+if test "${enable_neon_support+set}" = set; then :
+  enableval=$enable_neon_support; neonsupport=$enableval
+else
+  neonsupport=yes
 fi
 
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $neonsupport" >&5
+$as_echo "$neonsupport" >&6; }
+
 # Implementation of the --disable-O-flag-munging switch.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a -O flag munging is requested" >&5
 $as_echo_n "checking whether a -O flag munging is requested... " >&6; }
@@ -12754,6 +13903,18 @@ else
 fi
 
 
+# Implementation of the --disable-amd64-as-feature-detection switch.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable AMD64 as(1) feature detection" >&5
+$as_echo_n "checking whether to enable AMD64 as(1) feature detection... " >&6; }
+# Check whether --enable-amd64-as-feature-detection was given.
+if test "${enable_amd64_as_feature_detection+set}" = set; then :
+  enableval=$enable_amd64_as_feature_detection; amd64_as_feature_detection=$enableval
+else
+  amd64_as_feature_detection=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $amd64_as_feature_detection" >&5
+$as_echo "$amd64_as_feature_detection" >&6; }
 
 
 
@@ -12809,6 +13970,16 @@ _ACEOF
 # gpg-error is required.
 #
 
+
+# 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"
@@ -12816,6 +13987,7 @@ 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
@@ -12827,7 +13999,7 @@ fi
 set dummy ${ac_tool_prefix}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 test "${ac_cv_path_GPG_ERROR_CONFIG+set}" = set; then :
+if ${ac_cv_path_GPG_ERROR_CONFIG+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $GPG_ERROR_CONFIG in
@@ -12841,7 +14013,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_path_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
@@ -12870,7 +14042,7 @@ if test -z "$ac_cv_path_GPG_ERROR_CONFIG"; then
 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 test "${ac_cv_path_ac_pt_GPG_ERROR_CONFIG+set}" = set; then :
+if ${ac_cv_path_ac_pt_GPG_ERROR_CONFIG+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $ac_pt_GPG_ERROR_CONFIG in
@@ -12884,7 +14056,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  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
@@ -12984,7 +14156,7 @@ $as_echo "no" >&6; }
 
 
 if test "x$GPG_ERROR_LIBS" = "x"; then
-  as_fn_error "libgpg-error is needed.
+  as_fn_error $? "libgpg-error is needed.
                 See ftp://ftp.gnupg.org/gcrypt/libgpg-error/ ." "$LINENO" 5
 fi
 
@@ -13012,7 +14184,7 @@ if test "$use_random_daemon" = "yes"; then
 set dummy pth-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 test "${ac_cv_path_PTH_CONFIG+set}" = set; then :
+if ${ac_cv_path_PTH_CONFIG+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   case $PTH_CONFIG in
@@ -13026,7 +14198,7 @@ do
   IFS=$as_save_IFS
   test -z "$as_dir" && as_dir=.
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_path_PTH_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
@@ -13101,7 +14273,7 @@ $as_echo_n "checking for PTH - version >= $_req_version... " >&6; }
 $as_echo "yes" >&6; }
        { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether PTH installation is sane" >&5
 $as_echo_n "checking whether PTH installation is sane... " >&6; }
-       if test "${gnupg_cv_pth_is_sane+set}" = set; then :
+       if ${gnupg_cv_pth_is_sane+:} false; then :
   $as_echo_n "(cached) " >&6
 else
 
 
 
 
-# Solaris needs -lsocket and -lnsl. Unisys system includes
-# gethostbyname in libsocket but needs libnsl for socket.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing setsockopt" >&5
-$as_echo_n "checking for library containing setsockopt... " >&6; }
-if test "${ac_cv_search_setsockopt+set}" = set; then :
+#
+# See which thread system we have
+#
+# 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
-  ac_func_search_save_LIBS=$LIBS
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+  gl_cv_have_weak=no
+              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 setsockopt ();
+extern void xyzzy ();
+#pragma weak xyzzy
 int
 main ()
 {
-return setsockopt ();
+xyzzy();
   ;
   return 0;
 }
 _ACEOF
-for ac_lib in '' socket; do
-  if test -z "$ac_lib"; then
-    ac_res="none required"
-  else
-    ac_res=-l$ac_lib
-    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
-  fi
-  if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_search_setsockopt=$ac_res
+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
-  if test "${ac_cv_search_setsockopt+set}" = set; then :
-  break
+    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
-done
-if test "${ac_cv_search_setsockopt+set}" = set; then :
+rm -f conftest*
+
 
 else
-  ac_cv_search_setsockopt=no
+  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 conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_setsockopt" >&5
-$as_echo "$ac_cv_search_setsockopt" >&6; }
-ac_res=$ac_cv_search_setsockopt
-if test "$ac_res" != no; then :
-  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 
+       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
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing setsockopt" >&5
-$as_echo_n "checking for library containing setsockopt... " >&6; }
-if test "${ac_cv_search_setsockopt+set}" = set; then :
+  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_func_search_save_LIBS=$LIBS
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread  $LIBS"
 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
 
@@ -13235,42 +14543,378 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 #ifdef __cplusplus
 extern "C"
 #endif
-char setsockopt ();
+char pthread_kill ();
 int
 main ()
 {
-return setsockopt ();
+return pthread_kill ();
   ;
   return 0;
 }
 _ACEOF
-for ac_lib in '' socket; do
-  if test -z "$ac_lib"; then
-    ac_res="none required"
-  else
-    ac_res=-l$ac_lib
-    LIBS="-l$ac_lib -lnsl $ac_func_search_save_LIBS"
-  fi
-  if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_search_setsockopt=$ac_res
+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
-  if test "${ac_cv_search_setsockopt+set}" = set; then :
-  break
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
 fi
-done
-if test "${ac_cv_search_setsockopt+set}" = set; then :
+{ $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
 
-else
-  ac_cv_search_setsockopt=no
-fi
-rm conftest.$ac_ext
-LIBS=$ac_func_search_save_LIBS
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_setsockopt" >&5
-$as_echo "$ac_cv_search_setsockopt" >&6; }
-ac_res=$ac_cv_search_setsockopt
+
+        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 :
+  $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 :
+  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
+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 case "$gl_cv_have_weak" in *yes) true;; *) false;; esac; then
+
+$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
+
+
+# Solaris needs -lsocket and -lnsl. Unisys system includes
+# gethostbyname in libsocket but needs libnsl for socket.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing setsockopt" >&5
+$as_echo_n "checking for library containing setsockopt... " >&6; }
+if ${ac_cv_search_setsockopt+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$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 setsockopt ();
+int
+main ()
+{
+return setsockopt ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' socket; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib  $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_setsockopt=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_setsockopt+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_setsockopt+:} false; then :
+
+else
+  ac_cv_search_setsockopt=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_setsockopt" >&5
+$as_echo "$ac_cv_search_setsockopt" >&6; }
+ac_res=$ac_cv_search_setsockopt
+if test "$ac_res" != no; then :
+  test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing setsockopt" >&5
+$as_echo_n "checking for library containing setsockopt... " >&6; }
+if ${ac_cv_search_setsockopt+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_func_search_save_LIBS=$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 setsockopt ();
+int
+main ()
+{
+return setsockopt ();
+  ;
+  return 0;
+}
+_ACEOF
+for ac_lib in '' socket; do
+  if test -z "$ac_lib"; then
+    ac_res="none required"
+  else
+    ac_res=-l$ac_lib
+    LIBS="-l$ac_lib -lnsl $ac_func_search_save_LIBS"
+  fi
+  if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_search_setsockopt=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext
+  if ${ac_cv_search_setsockopt+:} false; then :
+  break
+fi
+done
+if ${ac_cv_search_setsockopt+:} false; then :
+
+else
+  ac_cv_search_setsockopt=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_setsockopt" >&5
+$as_echo "$ac_cv_search_setsockopt" >&6; }
+ac_res=$ac_cv_search_setsockopt
 if test "$ac_res" != no; then :
   test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
 
@@ -13280,7 +14924,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing setsockopt" >&5
 $as_echo_n "checking for library containing setsockopt... " >&6; }
-if test "${ac_cv_search_setsockopt+set}" = set; then :
+if ${ac_cv_search_setsockopt+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_func_search_save_LIBS=$LIBS
@@ -13314,11 +14958,11 @@ for ac_lib in '' nsl; do
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext
-  if test "${ac_cv_search_setsockopt+set}" = set; then :
+  if ${ac_cv_search_setsockopt+:} false; then :
   break
 fi
 done
-if test "${ac_cv_search_setsockopt+set}" = set; then :
+if ${ac_cv_search_setsockopt+:} false; then :
 
 else
   ac_cv_search_setsockopt=no
@@ -13341,7 +14985,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
 $as_echo_n "checking for ANSI C header files... " >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then :
+if ${ac_cv_header_stdc+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -13455,8 +15099,7 @@ for ac_header in unistd.h sys/select.h sys/msg.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-eval as_val=\$$as_ac_Header
-   if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
   cat >>confdefs.h <<_ACEOF
 #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
@@ -13479,7 +15122,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for an ANSI C-conforming const" >&5
 $as_echo_n "checking for an ANSI C-conforming const... " >&6; }
-if test "${ac_cv_c_const+set}" = set; then :
+if ${ac_cv_c_const+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -13488,11 +15131,11 @@ else
 int
 main ()
 {
-/* FIXME: Include the comments suggested by Paul. */
+
 #ifndef __cplusplus
-  /* Ultrix mips cc rejects this.  */
+  /* Ultrix mips cc rejects this sort of thing.  */
   typedef int charset[2];
-  const charset cs;
+  const charset cs = { 0, 0 };
   /* SunOS 4.1.1 cc rejects this.  */
   char const *const *pcpcc;
   char **ppc;
@@ -13509,8 +15152,9 @@ main ()
   ++pcpcc;
   ppc = (char**) pcpcc;
   pcpcc = (char const *const *) ppc;
-  { /* SCO 3.2v4 cc rejects this.  */
-    char *t;
+  { /* SCO 3.2v4 cc rejects this sort of thing.  */
+    char tx;
+    char *t = &tx;
     char const *s = 0 ? (char *) 0 : (char const *) 0;
 
     *t++ = 0;
@@ -13526,10 +15170,10 @@ main ()
     iptr p = 0;
     ++p;
   }
-  { /* AIX XL C 1.02.0.0 rejects this saying
+  { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
        "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
-    struct s { int j; const int *ap[3]; };
-    struct s *b; b->j = 5;
+    struct s { int j; const int *ap[3]; } bx;
+    struct s *b = &bx; b->j = 5;
   }
   { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
     const int foo = 10;
@@ -13559,7 +15203,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
 $as_echo_n "checking for inline... " >&6; }
-if test "${ac_cv_c_inline+set}" = set; then :
+if ${ac_cv_c_inline+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_cv_c_inline=no
@@ -13600,7 +15244,7 @@ _ACEOF
 esac
 
 ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
-if test "x$ac_cv_type_size_t" = x""yes; then :
+if test "x$ac_cv_type_size_t" = xyes; then :
 
 else
 
@@ -13612,7 +15256,7 @@ fi
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking return type of signal handlers" >&5
 $as_echo_n "checking return type of signal handlers... " >&6; }
-if test "${ac_cv_type_signal+set}" = set; then :
+if ${ac_cv_type_signal+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -13650,7 +15294,7 @@ ac_fn_c_check_decl "$LINENO" "sys_siglist" "ac_cv_have_decl_sys_siglist" "#inclu
 #endif
 
 "
-if test "x$ac_cv_have_decl_sys_siglist" = x""yes; then :
+if test "x$ac_cv_have_decl_sys_siglist" = xyes; then :
   ac_have_decl=1
 else
   ac_have_decl=0
@@ -13662,7 +15306,7 @@ _ACEOF
 
 
 ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
-if test "x$ac_cv_type_pid_t" = x""yes; then :
+if test "x$ac_cv_type_pid_t" = xyes; then :
 
 else
 
@@ -13675,7 +15319,7 @@ fi
 
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for byte typedef" >&5
 $as_echo_n "checking for byte typedef... " >&6; }
-    if test "${gnupg_cv_typedef_byte+set}" = set; then :
+    if ${gnupg_cv_typedef_byte+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -13712,7 +15356,7 @@ $as_echo "#define HAVE_BYTE_TYPEDEF 1" >>confdefs.h
 
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ushort typedef" >&5
 $as_echo_n "checking for ushort typedef... " >&6; }
-    if test "${gnupg_cv_typedef_ushort+set}" = set; then :
+    if ${gnupg_cv_typedef_ushort+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -13749,7 +15393,7 @@ $as_echo "#define HAVE_USHORT_TYPEDEF 1" >>confdefs.h
 
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ulong typedef" >&5
 $as_echo_n "checking for ulong typedef... " >&6; }
-    if test "${gnupg_cv_typedef_ulong+set}" = set; then :
+    if ${gnupg_cv_typedef_ulong+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -13786,7 +15430,7 @@ $as_echo "#define HAVE_ULONG_TYPEDEF 1" >>confdefs.h
 
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u16 typedef" >&5
 $as_echo_n "checking for u16 typedef... " >&6; }
-    if test "${gnupg_cv_typedef_u16+set}" = set; then :
+    if ${gnupg_cv_typedef_u16+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -13823,7 +15467,7 @@ $as_echo "#define HAVE_U16_TYPEDEF 1" >>confdefs.h
 
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for u32 typedef" >&5
 $as_echo_n "checking for u32 typedef... " >&6; }
-    if test "${gnupg_cv_typedef_u32+set}" = set; then :
+    if ${gnupg_cv_typedef_u32+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
@@ -13863,7 +15507,7 @@ $as_echo "#define HAVE_U32_TYPEDEF 1" >>confdefs.h
       for ac_header in sys/socket.h
 do :
   ac_fn_c_check_header_mongrel "$LINENO" "sys/socket.h" "ac_cv_header_sys_socket_h" "$ac_includes_default"
-if test "x$ac_cv_header_sys_socket_h" = x""yes; then :
+if test "x$ac_cv_header_sys_socket_h" = xyes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_SYS_SOCKET_H 1
 _ACEOF
@@ -13888,8 +15532,7 @@ done
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-eval as_val=\$$as_ac_Header
-   if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
   cat >>confdefs.h <<_ACEOF
 #define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
 _ACEOF
@@ -13909,12 +15552,12 @@ done
       # include <ws2tcpip.h>
       #endif
 "
-if test "x$ac_cv_type_socklen_t" = x""yes; then :
+if test "x$ac_cv_type_socklen_t" = xyes; then :
 
 else
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t equivalent" >&5
 $as_echo_n "checking for socklen_t equivalent... " >&6; }
-      if test "${gl_cv_gl_cv_socklen_t_equiv+set}" = set; then :
+      if ${gl_cv_gl_cv_socklen_t_equiv+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   # Systems have either "struct sockaddr *" or
@@ -13949,7 +15592,7 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
 
       if test "$gl_cv_socklen_t_equiv" = ""; then
-       as_fn_error "Cannot find a type to use in place of socklen_t" "$LINENO" 5
+       as_fn_error $? "Cannot find a type to use in place of socklen_t" "$LINENO" 5
       fi
       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gl_cv_socklen_t_equiv" >&5
 $as_echo "$gl_cv_socklen_t_equiv" >&6; }
@@ -13975,23 +15618,124 @@ case "${host}" in
 esac
 
 
+
 #
-# Check for ELF visibility support.
+# Check for __builtin_bswap32 intrinsic.
 #
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the visibility attribute is supported" >&5
-$as_echo_n "checking whether the visibility attribute is supported... " >&6; }
-if test "${gcry_cv_visibility_attribute+set}" = set; then :
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_bswap32" >&5
+$as_echo_n "checking for __builtin_bswap32... " >&6; }
+if ${gcry_cv_have_builtin_bswap32+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  gcry_cv_visibility_attribute=no
+  gcry_cv_have_builtin_bswap32=no
         cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-int foo __attribute__ ((visibility ("hidden"))) = 1;
-            int bar __attribute__ ((visibility ("protected"))) = 1;
 
+int
+main ()
+{
+int x = 0; int y = __builtin_bswap32(x); return y;
+  ;
+  return 0;
+}
 _ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  gcry_cv_have_builtin_bswap32=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_bswap32" >&5
+$as_echo "$gcry_cv_have_builtin_bswap32" >&6; }
+if test "$gcry_cv_have_builtin_bswap32" = "yes" ; then
 
-        if ${CC-cc} -Werror -S conftest.c -o conftest.s \
+$as_echo "#define HAVE_BUILTIN_BSWAP32 1" >>confdefs.h
+
+fi
+
+
+#
+# Check for __builtin_bswap64 intrinsic.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __builtin_bswap64" >&5
+$as_echo_n "checking for __builtin_bswap64... " >&6; }
+if ${gcry_cv_have_builtin_bswap64+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcry_cv_have_builtin_bswap64=no
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+int
+main ()
+{
+long long x = 0; long long y = __builtin_bswap64(x); return y;
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  gcry_cv_have_builtin_bswap64=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_bswap64" >&5
+$as_echo "$gcry_cv_have_builtin_bswap64" >&6; }
+if test "$gcry_cv_have_builtin_bswap64" = "yes" ; then
+
+$as_echo "#define HAVE_BUILTIN_BSWAP64 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
+$as_echo_n "checking whether the variable length arrays are supported... " >&6; }
+if ${gcry_cv_have_vla+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcry_cv_have_vla=no
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+void f1(char *, int);
+            char foo(int i) {
+              char b[(i < 0 ? 0 : i) + 1];
+              f1(b, sizeof b); return b[0];}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_have_vla=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_have_vla" >&5
+$as_echo "$gcry_cv_have_vla" >&6; }
+if test "$gcry_cv_have_vla" = "yes" ; then
+
+$as_echo "#define HAVE_VLA 1" >>confdefs.h
+
+fi
+
+
+#
+# Check for ELF visibility support.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the visibility attribute is supported" >&5
+$as_echo_n "checking whether the visibility attribute is supported... " >&6; }
+if ${gcry_cv_visibility_attribute+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcry_cv_visibility_attribute=no
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+int foo __attribute__ ((visibility ("hidden"))) = 1;
+            int bar __attribute__ ((visibility ("protected"))) = 1;
+
+_ACEOF
+
+        if ${CC-cc} -Werror -S conftest.c -o conftest.s \
                   1>&5 2>&5 ; then
             if grep '\.hidden.*foo' conftest.s >/dev/null 2>&1 ; then
                 if grep '\.protected.*bar' conftest.s >/dev/null 2>&1; then
@@ -14006,7 +15750,7 @@ $as_echo "$gcry_cv_visibility_attribute" >&6; }
 if test "$gcry_cv_visibility_attribute" = "yes"; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken visibility attribute" >&5
 $as_echo_n "checking for broken visibility attribute... " >&6; }
-if test "${gcry_cv_broken_visibility_attribute+set}" = set; then :
+if ${gcry_cv_broken_visibility_attribute+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   gcry_cv_broken_visibility_attribute=yes
@@ -14034,7 +15778,7 @@ fi
 if test "$gcry_cv_visibility_attribute" = "yes"; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for broken alias attribute" >&5
 $as_echo_n "checking for broken alias attribute... " >&6; }
-if test "${gcry_cv_broken_alias_attribute+set}" = set; then :
+if ${gcry_cv_broken_alias_attribute+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   gcry_cv_broken_alias_attribute=yes
@@ -14064,7 +15808,7 @@ fi
 if test "$gcry_cv_visibility_attribute" = "yes"; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking if gcc supports -fvisibility=hidden" >&5
 $as_echo_n "checking if gcc supports -fvisibility=hidden... " >&6; }
-if test "${gcry_cv_gcc_has_f_visibility+set}" = set; then :
+if ${gcry_cv_gcc_has_f_visibility+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   gcry_cv_gcc_has_f_visibility=no
@@ -14103,208 +15847,989 @@ $as_echo "#define GCRY_USE_VISIBILITY 1" >>confdefs.h
 fi
 
 
-#######################################
-#### Checks for library functions. ####
-#######################################
-
-for ac_func in vprintf
-do :
-  ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf"
-if test "x$ac_cv_func_vprintf" = x""yes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_VPRINTF 1
+#
+# Check whether the compiler supports the GCC style aligned attribute
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the GCC style aligned attribute is supported" >&5
+$as_echo_n "checking whether the GCC style aligned attribute is supported... " >&6; }
+if ${gcry_cv_gcc_attribute_aligned+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcry_cv_gcc_attribute_aligned=no
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+struct { int a; } foo __attribute__ ((aligned (16)));
 _ACEOF
-
-ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt"
-if test "x$ac_cv_func__doprnt" = x""yes; then :
-
-$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h
-
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_gcc_attribute_aligned=yes
 fi
-
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-done
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_gcc_attribute_aligned" >&5
+$as_echo "$gcry_cv_gcc_attribute_aligned" >&6; }
+if test "$gcry_cv_gcc_attribute_aligned" = "yes" ; then
 
-
-# We have replacements for these in src/missing-string.c
-for ac_func in stpcpy strcasecmp
-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"
-eval as_val=\$$as_ac_var
-   if test "x$as_val" = x""yes; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
+$as_echo "#define HAVE_GCC_ATTRIBUTE_ALIGNED 1" >>confdefs.h
 
 fi
-done
-
-# We have replacements for these in src/g10lib.h
-for ac_func in strtoul memmove stricmp atexit raise
-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"
-eval as_val=\$$as_ac_var
-   if test "x$as_val" = x""yes; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
 
-fi
-done
 
-# Other checks
-for ac_func in strerror rand mmap getpagesize sysconf waitpid wait4
-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"
-eval as_val=\$$as_ac_var
-   if test "x$as_val" = x""yes; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+#
+# Check whether the compiler supports 'asm' or '__asm__' keyword for
+# assembler blocks.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether 'asm' assembler keyword is supported" >&5
+$as_echo_n "checking whether 'asm' assembler keyword is supported... " >&6; }
+if ${gcry_cv_have_asm+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcry_cv_have_asm=no
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+void a(void) { asm("":::"memory"); }
 _ACEOF
-
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_have_asm=yes
 fi
-done
-
-for ac_func in gettimeofday getrusage gethrtime clock_gettime syslog
-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"
-eval as_val=\$$as_ac_var
-   if test "x$as_val" = x""yes; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-done
-
-for ac_func in fcntl ftruncate
-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"
-eval as_val=\$$as_ac_var
-   if test "x$as_val" = x""yes; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_have_asm" >&5
+$as_echo "$gcry_cv_have_asm" >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether '__asm__' assembler keyword is supported" >&5
+$as_echo_n "checking whether '__asm__' assembler keyword is supported... " >&6; }
+if ${gcry_cv_have___asm__+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcry_cv_have___asm__=no
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+void a(void) { __asm__("":::"memory"); }
 _ACEOF
-
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_have___asm__=yes
 fi
-done
-
-
- for ac_func in mlock
-do :
-  ac_fn_c_check_func "$LINENO" "mlock" "ac_cv_func_mlock"
-if test "x$ac_cv_func_mlock" = x""yes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_MLOCK 1
-_ACEOF
-
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-done
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_have___asm__" >&5
+$as_echo "$gcry_cv_have___asm__" >&6; }
+if test "$gcry_cv_have_asm" = "no" ; then
+   if test "$gcry_cv_have___asm__" = "yes" ; then
 
-    if test "$ac_cv_func_mlock" = "no"; then
-        for ac_header in sys/mman.h
-do :
-  ac_fn_c_check_header_mongrel "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h" "$ac_includes_default"
-if test "x$ac_cv_header_sys_mman_h" = x""yes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_SYS_MMAN_H 1
-_ACEOF
+$as_echo "#define asm __asm__" >>confdefs.h
 
+   fi
 fi
 
-done
 
-        if test "$ac_cv_header_sys_mman_h" = "yes"; then
-            # Add librt to LIBS:
-            { $as_echo "$as_me:${as_lineno-$LINENO}: checking for memlk in -lrt" >&5
-$as_echo_n "checking for memlk in -lrt... " >&6; }
-if test "${ac_cv_lib_rt_memlk+set}" = set; then :
+#
+# Check whether the compiler supports inline assembly memory barrier.
+#
+if test "$gcry_cv_have_asm" = "no" ; then
+   if test "$gcry_cv_have___asm__" = "yes" ; then
+      { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether inline assembly memory barrier is supported" >&5
+$as_echo_n "checking whether inline assembly memory barrier is supported... " >&6; }
+if ${gcry_cv_have_asm_volatile_memory+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  ac_check_lib_save_LIBS=$LIBS
-LIBS="-lrt  $LIBS"
-cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+  gcry_cv_have_asm_volatile_memory=no
+           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 memlk ();
-int
-main ()
-{
-return memlk ();
-  ;
-  return 0;
-}
+void a(void) { __asm__ volatile("":::"memory"); }
 _ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  ac_cv_lib_rt_memlk=yes
-else
-  ac_cv_lib_rt_memlk=no
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_have_asm_volatile_memory=yes
 fi
-rm -f core conftest.err conftest.$ac_objext \
-    conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_rt_memlk" >&5
-$as_echo "$ac_cv_lib_rt_memlk" >&6; }
-if test "x$ac_cv_lib_rt_memlk" = x""yes; then :
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_LIBRT 1
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_have_asm_volatile_memory" >&5
+$as_echo "$gcry_cv_have_asm_volatile_memory" >&6; }
+   fi
+else
+   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether inline assembly memory barrier is supported" >&5
+$as_echo_n "checking whether inline assembly memory barrier is supported... " >&6; }
+if ${gcry_cv_have_asm_volatile_memory+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  gcry_cv_have_asm_volatile_memory=no
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+void a(void) { asm volatile("":::"memory"); }
 _ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_have_asm_volatile_memory=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_have_asm_volatile_memory" >&5
+$as_echo "$gcry_cv_have_asm_volatile_memory" >&6; }
+fi
+if test "$gcry_cv_have_asm_volatile_memory" = "yes" ; then
 
-  LIBS="-lrt $LIBS"
+$as_echo "#define HAVE_GCC_ASM_VOLATILE_MEMORY 1" >>confdefs.h
 
 fi
 
-            { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mlock is in sys/mman.h" >&5
-$as_echo_n "checking whether mlock is in sys/mman.h... " >&6; }
-if test "${gnupg_cv_mlock_is_in_sys_mman+set}" = set; then :
+
+#
+# Check whether GCC assembler supports features needed for our ARM
+# implementations.  This needs to be done before setting up the
+# assembler stuff.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC assembler is compatible for ARM assembly implementations" >&5
+$as_echo_n "checking whether GCC assembler is compatible for ARM assembly implementations... " >&6; }
+if ${gcry_cv_gcc_arm_platform_as_ok+:} false; then :
   $as_echo_n "(cached) " >&6
 else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+  gcry_cv_gcc_arm_platform_as_ok=no
+        cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
+__asm__(
+                /* Test if assembler supports UAL syntax.  */
+                ".syntax unified\n\t"
+                ".arm\n\t" /* our assembly code is in ARM mode  */
+                /* Following causes error if assembler ignored '.syntax unified'.  */
+                "asmfunc:\n\t"
+                "add %r0, %r0, %r4, ror #12;\n\t"
+
+                /* Test if '.type' and '.size' are supported.  */
+                ".size asmfunc,.-asmfunc;\n\t"
+                ".type asmfunc,%function;\n\t"
+            );
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_gcc_arm_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_arm_platform_as_ok" >&5
+$as_echo "$gcry_cv_gcc_arm_platform_as_ok" >&6; }
+if test "$gcry_cv_gcc_arm_platform_as_ok" = "yes" ; then
 
-                    #include <assert.h>
-                    #ifdef HAVE_SYS_MMAN_H
-                    #include <sys/mman.h>
-                    #endif
+$as_echo "#define HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS 1" >>confdefs.h
 
-int
-main ()
-{
+fi
 
-int i;
 
-/* glibc defines this for functions which it implements
- * to always fail with ENOSYS.  Some functions are actually
- * named something starting with __ and the normal name
- * is an alias.  */
-#if defined (__stub_mlock) || defined (__stub___mlock)
-choke me
-#else
-mlock(&i, 4);
-#endif
-; return 0;
+#
+# Check whether underscores in symbols are required.  This needs to be
+# done before setting up the assembler stuff.
+#
 
-  ;
-  return 0;
-}
-_ACEOF
-if ac_fn_c_try_link "$LINENO"; then :
-  gnupg_cv_mlock_is_in_sys_mman=yes
-else
-  gnupg_cv_mlock_is_in_sys_mman=no
-fi
+tmp_do_check="no"
+case "${host}" in
+    *-mingw32msvc*)
+        ac_cv_sys_symbol_underscore=yes
+        ;;
+    i386-emx-os2 | i345686-pc-os2*emx | i386-pc-msdosdjgpp)
+        ac_cv_sys_symbol_underscore=yes
+        ;;
+    *)
+      if test "$cross_compiling" = yes; then
+        if test "x$ac_cv_sys_symbol_underscore" = x ; then
+           ac_cv_sys_symbol_underscore=yes
+        fi
+      else
+         tmp_do_check="yes"
+      fi
+       ;;
+esac
+if test "$tmp_do_check" = "yes"; then
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _ prefix in compiled symbols" >&5
+$as_echo_n "checking for _ prefix in compiled symbols... " >&6; }
+  if ${ac_cv_sys_symbol_underscore+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_cv_sys_symbol_underscore=no
+   cat > conftest.$ac_ext <<EOF
+      void nm_test_func(){}
+      int main(){nm_test_func;return 0;}
+EOF
+  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; then
+    # Now try to grab the symbols.
+    ac_nlist=conftest.nm
+    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \| cut -d \' \' -f 2 \> $ac_nlist\""; } >&5
+  (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \| cut -d \' \' -f 2 \> $ac_nlist) 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; } && test -s "$ac_nlist"; then
+      # See whether the symbols have a leading underscore.
+      if egrep '^_nm_test_func' "$ac_nlist" >/dev/null; then
+        ac_cv_sys_symbol_underscore=yes
+      else
+        if egrep '^nm_test_func ' "$ac_nlist" >/dev/null; then
+          :
+        else
+          echo "configure: cannot find nm_test_func in $ac_nlist" >&5
+        fi
+      fi
+    else
+      echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&5
+    fi
+  else
+    echo "configure: failed program was:" >&5
+    cat conftest.c >&5
+  fi
+  rm -rf conftest*
+
+fi
+
+  else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _ prefix in compiled symbols" >&5
+$as_echo_n "checking for _ prefix in compiled symbols... " >&6; }
+  fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_symbol_underscore" >&5
+$as_echo "$ac_cv_sys_symbol_underscore" >&6; }
+if test x$ac_cv_sys_symbol_underscore = xyes; then
+
+$as_echo "#define WITH_SYMBOL_UNDERSCORE 1" >>confdefs.h
+
+fi
+
+
+
+#################################
+####                         ####
+#### Setup assembler stuff.  ####
+#### Define mpi_cpu_arch.    ####
+####                         ####
+#################################
+# Check whether --enable-mpi-path was given.
+if test "${enable_mpi_path+set}" = set; then :
+  enableval=$enable_mpi_path; mpi_extra_path="$enableval"
+else
+  mpi_extra_path=""
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking architecture and mpi assembler functions" >&5
+$as_echo_n "checking architecture and mpi assembler functions... " >&6; }
+if test -f $srcdir/mpi/config.links ; then
+    . $srcdir/mpi/config.links
+    ac_config_links="$ac_config_links "$mpi_ln_list""
+
+    ac_cv_mpi_sflags="$mpi_sflags"
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: $mpi_cpu_arch" >&5
+$as_echo "$mpi_cpu_arch" >&6; }
+else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
+$as_echo "failed" >&6; }
+    as_fn_error $? "mpi/config.links missing!" "$LINENO" 5
+fi
+MPI_SFLAGS="$ac_cv_mpi_sflags"
+
+
+ if test "$mpi_mod_asm_mpih_add1" = yes; then
+  MPI_MOD_ASM_MPIH_ADD1_TRUE=
+  MPI_MOD_ASM_MPIH_ADD1_FALSE='#'
+else
+  MPI_MOD_ASM_MPIH_ADD1_TRUE='#'
+  MPI_MOD_ASM_MPIH_ADD1_FALSE=
+fi
+
+ if test "$mpi_mod_asm_mpih_sub1" = yes; then
+  MPI_MOD_ASM_MPIH_SUB1_TRUE=
+  MPI_MOD_ASM_MPIH_SUB1_FALSE='#'
+else
+  MPI_MOD_ASM_MPIH_SUB1_TRUE='#'
+  MPI_MOD_ASM_MPIH_SUB1_FALSE=
+fi
+
+ if test "$mpi_mod_asm_mpih_mul1" = yes; then
+  MPI_MOD_ASM_MPIH_MUL1_TRUE=
+  MPI_MOD_ASM_MPIH_MUL1_FALSE='#'
+else
+  MPI_MOD_ASM_MPIH_MUL1_TRUE='#'
+  MPI_MOD_ASM_MPIH_MUL1_FALSE=
+fi
+
+ if test "$mpi_mod_asm_mpih_mul2" = yes; then
+  MPI_MOD_ASM_MPIH_MUL2_TRUE=
+  MPI_MOD_ASM_MPIH_MUL2_FALSE='#'
+else
+  MPI_MOD_ASM_MPIH_MUL2_TRUE='#'
+  MPI_MOD_ASM_MPIH_MUL2_FALSE=
+fi
+
+ if test "$mpi_mod_asm_mpih_mul3" = yes; then
+  MPI_MOD_ASM_MPIH_MUL3_TRUE=
+  MPI_MOD_ASM_MPIH_MUL3_FALSE='#'
+else
+  MPI_MOD_ASM_MPIH_MUL3_TRUE='#'
+  MPI_MOD_ASM_MPIH_MUL3_FALSE=
+fi
+
+ if test "$mpi_mod_asm_mpih_lshift" = yes; then
+  MPI_MOD_ASM_MPIH_LSHIFT_TRUE=
+  MPI_MOD_ASM_MPIH_LSHIFT_FALSE='#'
+else
+  MPI_MOD_ASM_MPIH_LSHIFT_TRUE='#'
+  MPI_MOD_ASM_MPIH_LSHIFT_FALSE=
+fi
+
+ if test "$mpi_mod_asm_mpih_rshift" = yes; then
+  MPI_MOD_ASM_MPIH_RSHIFT_TRUE=
+  MPI_MOD_ASM_MPIH_RSHIFT_FALSE='#'
+else
+  MPI_MOD_ASM_MPIH_RSHIFT_TRUE='#'
+  MPI_MOD_ASM_MPIH_RSHIFT_FALSE=
+fi
+
+ if test "$mpi_mod_asm_udiv" = yes; then
+  MPI_MOD_ASM_UDIV_TRUE=
+  MPI_MOD_ASM_UDIV_FALSE='#'
+else
+  MPI_MOD_ASM_UDIV_TRUE='#'
+  MPI_MOD_ASM_UDIV_FALSE=
+fi
+
+ if test "$mpi_mod_asm_udiv_qrnnd" = yes; then
+  MPI_MOD_ASM_UDIV_QRNND_TRUE=
+  MPI_MOD_ASM_UDIV_QRNND_FALSE='#'
+else
+  MPI_MOD_ASM_UDIV_QRNND_TRUE='#'
+  MPI_MOD_ASM_UDIV_QRNND_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_add1" = yes; then
+  MPI_MOD_C_MPIH_ADD1_TRUE=
+  MPI_MOD_C_MPIH_ADD1_FALSE='#'
+else
+  MPI_MOD_C_MPIH_ADD1_TRUE='#'
+  MPI_MOD_C_MPIH_ADD1_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_sub1" = yes; then
+  MPI_MOD_C_MPIH_SUB1_TRUE=
+  MPI_MOD_C_MPIH_SUB1_FALSE='#'
+else
+  MPI_MOD_C_MPIH_SUB1_TRUE='#'
+  MPI_MOD_C_MPIH_SUB1_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_mul1" = yes; then
+  MPI_MOD_C_MPIH_MUL1_TRUE=
+  MPI_MOD_C_MPIH_MUL1_FALSE='#'
+else
+  MPI_MOD_C_MPIH_MUL1_TRUE='#'
+  MPI_MOD_C_MPIH_MUL1_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_mul2" = yes; then
+  MPI_MOD_C_MPIH_MUL2_TRUE=
+  MPI_MOD_C_MPIH_MUL2_FALSE='#'
+else
+  MPI_MOD_C_MPIH_MUL2_TRUE='#'
+  MPI_MOD_C_MPIH_MUL2_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_mul3" = yes; then
+  MPI_MOD_C_MPIH_MUL3_TRUE=
+  MPI_MOD_C_MPIH_MUL3_FALSE='#'
+else
+  MPI_MOD_C_MPIH_MUL3_TRUE='#'
+  MPI_MOD_C_MPIH_MUL3_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_lshift" = yes; then
+  MPI_MOD_C_MPIH_LSHIFT_TRUE=
+  MPI_MOD_C_MPIH_LSHIFT_FALSE='#'
+else
+  MPI_MOD_C_MPIH_LSHIFT_TRUE='#'
+  MPI_MOD_C_MPIH_LSHIFT_FALSE=
+fi
+
+ if test "$mpi_mod_c_mpih_rshift" = yes; then
+  MPI_MOD_C_MPIH_RSHIFT_TRUE=
+  MPI_MOD_C_MPIH_RSHIFT_FALSE='#'
+else
+  MPI_MOD_C_MPIH_RSHIFT_TRUE='#'
+  MPI_MOD_C_MPIH_RSHIFT_FALSE=
+fi
+
+ if test "$mpi_mod_c_udiv" = yes; then
+  MPI_MOD_C_UDIV_TRUE=
+  MPI_MOD_C_UDIV_FALSE='#'
+else
+  MPI_MOD_C_UDIV_TRUE='#'
+  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='#'
+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"
+   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.  ####
+####                                     ####
+#############################################
+
+#
+# Check whether GCC inline assembler supports SSSE3 instructions
+# This is required for the AES-NI instructions.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports SSSE3 instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports SSSE3 instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_ssse3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$mpi_cpu_arch" != "x86" ; then
+          gcry_cv_gcc_inline_asm_ssse3="n/a"
+        else
+          gcry_cv_gcc_inline_asm_ssse3=no
+          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+static unsigned char be_mask[16] __attribute__ ((aligned (16))) =
+              { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+            void a(void) {
+              __asm__("pshufb %[mask], %%xmm2\n\t"::[mask]"m"(*be_mask):);
+            }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_gcc_inline_asm_ssse3=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_ssse3" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_ssse3" >&6; }
+if test "$gcry_cv_gcc_inline_asm_ssse3" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_SSSE3 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC inline assembler supports PCLMUL instructions.
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports PCLMUL instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports PCLMUL instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_pclmul+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$mpi_cpu_arch" != "x86" ; then
+          gcry_cv_gcc_inline_asm_pclmul="n/a"
+        else
+          gcry_cv_gcc_inline_asm_pclmul=no
+          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+void a(void) {
+              __asm__("pclmulqdq \$0, %%xmm1, %%xmm3\n\t":::"cc");
+            }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_gcc_inline_asm_pclmul=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_pclmul" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_pclmul" >&6; }
+if test "$gcry_cv_gcc_inline_asm_pclmul" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_PCLMUL 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC inline assembler supports AVX instructions
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports AVX instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports AVX instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_avx+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$mpi_cpu_arch" != "x86" ; then
+          gcry_cv_gcc_inline_asm_avx="n/a"
+        else
+          gcry_cv_gcc_inline_asm_avx=no
+          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+void a(void) {
+              __asm__("xgetbv; vaesdeclast (%[mem]),%%xmm0,%%xmm7\n\t"::[mem]"r"(0):);
+            }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_gcc_inline_asm_avx=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_avx" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_avx" >&6; }
+if test "$gcry_cv_gcc_inline_asm_avx" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_AVX 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC inline assembler supports AVX2 instructions
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports AVX2 instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports AVX2 instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_avx2+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$mpi_cpu_arch" != "x86" ; then
+          gcry_cv_gcc_inline_asm_avx2="n/a"
+        else
+          gcry_cv_gcc_inline_asm_avx2=no
+          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+void a(void) {
+              __asm__("xgetbv; vpbroadcastb %%xmm7,%%ymm1\n\t":::"cc");
+            }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_gcc_inline_asm_avx2=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_avx2" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_avx2" >&6; }
+if test "$gcry_cv_gcc_inline_asm_avx2" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_AVX2 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC inline assembler supports BMI2 instructions
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports BMI2 instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports BMI2 instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_bmi2+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$mpi_cpu_arch" != "x86" ; then
+          gcry_cv_gcc_inline_asm_bmi2="n/a"
+        else
+          gcry_cv_gcc_inline_asm_bmi2=no
+          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+void a(void) {
+              __asm__("rorxl \$23, %%eax, %%edx\\n\\t":::"memory");
+            }
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_gcc_inline_asm_bmi2=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_bmi2" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_bmi2" >&6; }
+if test "$gcry_cv_gcc_inline_asm_bmi2" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_BMI2 1" >>confdefs.h
+
+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_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
+else
+  if test "$mpi_cpu_arch" != "x86" ; then
+          gcry_cv_gcc_amd64_platform_as_ok="n/a"
+        else
+          gcry_cv_gcc_amd64_platform_as_ok=no
+          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+__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"
+            );
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_gcc_amd64_platform_as_ok=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_amd64_platform_as_ok" >&5
+$as_echo "$gcry_cv_gcc_amd64_platform_as_ok" >&6; }
+  if test "$gcry_cv_gcc_amd64_platform_as_ok" = "yes" ; then
+
+$as_echo "#define HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS 1" >>confdefs.h
+
+  fi
+fi
+
+
+#
+# Check whether GCC assembler supports features needed for assembly
+# implementations that use Intel syntax
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC assembler is compatible for Intel syntax assembly implementations" >&5
+$as_echo_n "checking whether GCC assembler is compatible for Intel syntax assembly implementations... " >&6; }
+if ${gcry_cv_gcc_platform_as_ok_for_intel_syntax+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$mpi_cpu_arch" != "x86" ; then
+          gcry_cv_gcc_platform_as_ok_for_intel_syntax="n/a"
+        else
+          gcry_cv_gcc_platform_as_ok_for_intel_syntax=no
+          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+__asm__(
+                ".intel_syntax noprefix\n\t"
+                "pxor xmm1, xmm7;\n\t"
+                /* Intel syntax implementation also use GAS macros, so check
+                 * for them here. */
+                "VAL_A = xmm4\n\t"
+                "VAL_B = xmm2\n\t"
+                ".macro SET_VAL_A p1\n\t"
+                "  VAL_A = \\\\p1 \n\t"
+                ".endm\n\t"
+                ".macro SET_VAL_B p1\n\t"
+                "  VAL_B = \\\\p1 \n\t"
+                ".endm\n\t"
+                "vmovdqa VAL_A, VAL_B;\n\t"
+                "SET_VAL_A eax\n\t"
+                "SET_VAL_B ebp\n\t"
+                "add VAL_A, VAL_B;\n\t"
+                "add VAL_B, 0b10101;\n\t"
+            );
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_gcc_platform_as_ok_for_intel_syntax=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_platform_as_ok_for_intel_syntax" >&5
+$as_echo "$gcry_cv_gcc_platform_as_ok_for_intel_syntax" >&6; }
+if test "$gcry_cv_gcc_platform_as_ok_for_intel_syntax" = "yes" ; then
+
+$as_echo "#define HAVE_INTEL_SYNTAX_PLATFORM_AS 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether compiler is configured for ARMv6 or newer architecture
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether compiler is configured for ARMv6 or newer architecture" >&5
+$as_echo_n "checking whether compiler is configured for ARMv6 or newer architecture... " >&6; }
+if ${gcry_cv_cc_arm_arch_is_v6+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$mpi_cpu_arch" != "arm" ; then
+          gcry_cv_cc_arm_arch_is_v6="n/a"
+        else
+          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#if defined(__arm__) && \
+             ((defined(__ARM_ARCH) && __ARM_ARCH >= 6) \
+             || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+             || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \
+             || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) \
+             || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
+             || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
+             || defined(__ARM_ARCH_7EM__))
+            yes
+           #endif
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+  $EGREP "yes" >/dev/null 2>&1; then :
+  gcry_cv_cc_arm_arch_is_v6=yes
+else
+  gcry_cv_cc_arm_arch_is_v6=no
+fi
+rm -f conftest*
+
+        fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcry_cv_cc_arm_arch_is_v6" >&5
+$as_echo "$gcry_cv_cc_arm_arch_is_v6" >&6; }
+if test "$gcry_cv_cc_arm_arch_is_v6" = "yes" ; then
+
+$as_echo "#define HAVE_ARM_ARCH_V6 1" >>confdefs.h
+
+fi
+
+
+#
+# Check whether GCC inline assembler supports NEON instructions
+#
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether GCC inline assembler supports NEON instructions" >&5
+$as_echo_n "checking whether GCC inline assembler supports NEON instructions... " >&6; }
+if ${gcry_cv_gcc_inline_asm_neon+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  if test "$mpi_cpu_arch" != "arm" ; then
+          gcry_cv_gcc_inline_asm_neon="n/a"
+        else
+          gcry_cv_gcc_inline_asm_neon=no
+          cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+__asm__(
+                ".syntax unified\n\t"
+                ".thumb\n\t"
+                ".fpu neon\n\t"
+                "vld1.64 {%q0-%q1}, [%r0]!;\n\t"
+                "vrev64.8 %q0, %q3;\n\t"
+                "vadd.u64 %q0, %q1;\n\t"
+                "vadd.s64 %d3, %d2, %d3;\n\t"
+                );
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  gcry_cv_gcc_inline_asm_neon=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_neon" >&5
+$as_echo "$gcry_cv_gcc_inline_asm_neon" >&6; }
+if test "$gcry_cv_gcc_inline_asm_neon" = "yes" ; then
+
+$as_echo "#define HAVE_GCC_INLINE_ASM_NEON 1" >>confdefs.h
+
+fi
+
+
+#######################################
+#### Checks for library functions. ####
+#######################################
+
+for ac_func in vprintf
+do :
+  ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf"
+if test "x$ac_cv_func_vprintf" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_VPRINTF 1
+_ACEOF
+
+ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt"
+if test "x$ac_cv_func__doprnt" = xyes; then :
+
+$as_echo "#define HAVE_DOPRNT 1" >>confdefs.h
+
+fi
+
+fi
+done
+
+
+# We have replacements for these in src/missing-string.c
+for ac_func in stpcpy strcasecmp
+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"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+# We have replacements for these in src/g10lib.h
+for ac_func in strtoul memmove stricmp atexit raise
+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"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+# Other checks
+for ac_func in strerror rand mmap getpagesize sysconf waitpid wait4
+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"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in gettimeofday getrusage gethrtime clock_gettime syslog
+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"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in 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"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+
+ for ac_func in mlock
+do :
+  ac_fn_c_check_func "$LINENO" "mlock" "ac_cv_func_mlock"
+if test "x$ac_cv_func_mlock" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_MLOCK 1
+_ACEOF
+
+fi
+done
+
+    if test "$ac_cv_func_mlock" = "no"; then
+        for ac_header in sys/mman.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "sys/mman.h" "ac_cv_header_sys_mman_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_mman_h" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_SYS_MMAN_H 1
+_ACEOF
+
+fi
+
+done
+
+        if test "$ac_cv_header_sys_mman_h" = "yes"; then
+            # Add librt to LIBS:
+            { $as_echo "$as_me:${as_lineno-$LINENO}: checking for memlk in -lrt" >&5
+$as_echo_n "checking for memlk in -lrt... " >&6; }
+if ${ac_cv_lib_rt_memlk+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt  $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 memlk ();
+int
+main ()
+{
+return memlk ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_rt_memlk=yes
+else
+  ac_cv_lib_rt_memlk=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_rt_memlk" >&5
+$as_echo "$ac_cv_lib_rt_memlk" >&6; }
+if test "x$ac_cv_lib_rt_memlk" = xyes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBRT 1
+_ACEOF
+
+  LIBS="-lrt $LIBS"
+
+fi
+
+            { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mlock is in sys/mman.h" >&5
+$as_echo_n "checking whether mlock is in sys/mman.h... " >&6; }
+if ${gnupg_cv_mlock_is_in_sys_mman+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+                    #include <assert.h>
+                    #ifdef HAVE_SYS_MMAN_H
+                    #include <sys/mman.h>
+                    #endif
+
+int
+main ()
+{
+
+int i;
+
+/* glibc defines this for functions which it implements
+ * to always fail with ENOSYS.  Some functions are actually
+ * named something starting with __ and the normal name
+ * is an alias.  */
+#if defined (__stub_mlock) || defined (__stub___mlock)
+choke me
+#else
+mlock(&i, 4);
+#endif
+; return 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  gnupg_cv_mlock_is_in_sys_mman=yes
+else
+  gnupg_cv_mlock_is_in_sys_mman=no
+fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext conftest.$ac_ext
 fi
@@ -14322,8 +16847,7 @@ $as_echo "#define HAVE_MLOCK 1" >>confdefs.h
 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"
-eval as_val=\$$as_ac_var
-   if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
   cat >>confdefs.h <<_ACEOF
 #define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
@@ -14333,7 +16857,7 @@ done
 
         { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mlock is broken" >&5
 $as_echo_n "checking whether mlock is broken... " >&6; }
-          if test "${gnupg_cv_have_broken_mlock+set}" = set; then :
+          if ${gnupg_cv_have_broken_mlock+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test "$cross_compiling" = yes; then :
@@ -14414,25 +16938,31 @@ $as_echo "assuming no" >&6; }
 #
 # Replacement functions.
 #
-for ac_func in getpid clock
-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"
-eval as_val=\$$as_ac_var
-   if test "x$as_val" = x""yes; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
+ac_fn_c_check_func "$LINENO" "getpid" "ac_cv_func_getpid"
+if test "x$ac_cv_func_getpid" = xyes; then :
+  $as_echo "#define HAVE_GETPID 1" >>confdefs.h
 
 else
   case " $LIBOBJS " in
-  *" $ac_func.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext"
+  *" getpid.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS getpid.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "clock" "ac_cv_func_clock"
+if test "x$ac_cv_func_clock" = xyes; then :
+  $as_echo "#define HAVE_CLOCK 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" clock.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS clock.$ac_objext"
  ;;
 esac
 
 fi
-done
 
 
 
@@ -14446,7 +16976,7 @@ if test "$use_hmac_binary_check" = yes ; then
   LIBS=""
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5
 $as_echo_n "checking for library containing dlopen... " >&6; }
-if test "${ac_cv_search_dlopen+set}" = set; then :
+if ${ac_cv_search_dlopen+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_func_search_save_LIBS=$LIBS
@@ -14480,11 +17010,11 @@ for ac_lib in '' c dl; do
 fi
 rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext
-  if test "${ac_cv_search_dlopen+set}" = set; then :
+  if ${ac_cv_search_dlopen+:} false; then :
   break
 fi
 done
-if test "${ac_cv_search_dlopen+set}" = set; then :
+if ${ac_cv_search_dlopen+:} false; then :
 
 else
   ac_cv_search_dlopen=no
 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.
@@ -14515,7 +17052,7 @@ use_capabilities=no
 for ac_header in sys/capability.h
 do :
   ac_fn_c_check_header_mongrel "$LINENO" "sys/capability.h" "ac_cv_header_sys_capability_h" "$ac_includes_default"
-if test "x$ac_cv_header_sys_capability_h" = x""yes; then :
+if test "x$ac_cv_header_sys_capability_h" = xyes; then :
   cat >>confdefs.h <<_ACEOF
 #define HAVE_SYS_CAPABILITY_H 1
 _ACEOF
@@ -14527,7 +17064,7 @@ done
 if test "$ac_cv_header_sys_capability_h" = "yes" ; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cap_init in -lcap" >&5
 $as_echo_n "checking for cap_init in -lcap... " >&6; }
-if test "${ac_cv_lib_cap_cap_init+set}" = set; then :
+if ${ac_cv_lib_cap_cap_init+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   ac_check_lib_save_LIBS=$LIBS
@@ -14561,7 +17098,7 @@ LIBS=$ac_check_lib_save_LIBS
 fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_cap_cap_init" >&5
 $as_echo "$ac_cv_lib_cap_cap_init" >&6; }
-if test "x$ac_cv_lib_cap_cap_init" = x""yes; then :
+if test "x$ac_cv_lib_cap_cap_init" = xyes; then :
   ac_need_libcap=1
 fi
 
@@ -14601,7 +17138,7 @@ fi
 if test "$try_dev_random" = yes ; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: checking for random device" >&5
 $as_echo_n "checking for random device... " >&6; }
-if test "${ac_cv_have_dev_random+set}" = set; then :
+if ${ac_cv_have_dev_random+:} false; then :
   $as_echo_n "(cached) " >&6
 else
   if test -r "$NAME_OF_DEV_RANDOM" && test -r "$NAME_OF_DEV_URANDOM" ; then
@@ -14637,273 +17174,28 @@ if test "$random" = "default"; then
           ;;
         *-*-mingw32*|*-*-cygwin*)
           # Windows random device.
-          random_modules="w32"
-          ;;
-        *)
-          # Build everything, allow to select at runtime.
-          random_modules="$auto_random_modules"
-          ;;
-        esac
-    fi
-else
-    if test "$random" = "auto"; then
-        # Build everything, allow to select at runtime.
-        random_modules="$auto_random_modules"
-    else
-        random_modules="$random"
-    fi
-fi
-
-
-#
-# Setup assembler stuff.
-#
-
-tmp_do_check="no"
-case "${host}" in
-    *-mingw32msvc*)
-        ac_cv_sys_symbol_underscore=yes
-        ;;
-    i386-emx-os2 | i345686-pc-os2*emx | i386-pc-msdosdjgpp)
-        ac_cv_sys_symbol_underscore=yes
-        ;;
-    *)
-      if test "$cross_compiling" = yes; then
-        if test "x$ac_cv_sys_symbol_underscore" = x ; then
-           ac_cv_sys_symbol_underscore=yes
-        fi
-      else
-         tmp_do_check="yes"
-      fi
-       ;;
-esac
-if test "$tmp_do_check" = "yes"; then
-
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _ prefix in compiled symbols" >&5
-$as_echo_n "checking for _ prefix in compiled symbols... " >&6; }
-  if test "${ac_cv_sys_symbol_underscore+set}" = set; then :
-  $as_echo_n "(cached) " >&6
-else
-  ac_cv_sys_symbol_underscore=no
-   cat > conftest.$ac_ext <<EOF
-      void nm_test_func(){}
-      int main(){nm_test_func;return 0;}
-EOF
-  if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
-  (eval $ac_compile) 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; then
-    # Now try to grab the symbols.
-    ac_nlist=conftest.nm
-    if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \| cut -d \' \' -f 2 \> $ac_nlist\""; } >&5
-  (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \| cut -d \' \' -f 2 \> $ac_nlist) 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } && test -s "$ac_nlist"; then
-      # See whether the symbols have a leading underscore.
-      if egrep '^_nm_test_func' "$ac_nlist" >/dev/null; then
-        ac_cv_sys_symbol_underscore=yes
-      else
-        if egrep '^nm_test_func ' "$ac_nlist" >/dev/null; then
-          :
-        else
-          echo "configure: cannot find nm_test_func in $ac_nlist" >&5
-        fi
-      fi
-    else
-      echo "configure: cannot run $lt_cv_sys_global_symbol_pipe" >&5
-    fi
-  else
-    echo "configure: failed program was:" >&5
-    cat conftest.c >&5
-  fi
-  rm -rf conftest*
-
-fi
-
-  else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _ prefix in compiled symbols" >&5
-$as_echo_n "checking for _ prefix in compiled symbols... " >&6; }
-  fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_symbol_underscore" >&5
-$as_echo "$ac_cv_sys_symbol_underscore" >&6; }
-if test x$ac_cv_sys_symbol_underscore = xyes; then
-
-$as_echo "#define WITH_SYMBOL_UNDERSCORE 1" >>confdefs.h
-
-fi
-
-# Check whether --enable-mpi-path was given.
-if test "${enable_mpi_path+set}" = set; then :
-  enableval=$enable_mpi_path; mpi_extra_path="$enableval"
-else
-  mpi_extra_path=""
-fi
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for mpi assembler functions" >&5
-$as_echo_n "checking for mpi assembler functions... " >&6; }
-if test -f $srcdir/mpi/config.links ; then
-    . $srcdir/mpi/config.links
-    ac_config_links="$ac_config_links "$mpi_ln_list""
-
-    ac_cv_mpi_sflags="$mpi_sflags"
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: done" >&5
-$as_echo "done" >&6; }
-else
-    { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5
-$as_echo "failed" >&6; }
-    as_fn_error "mpi/config.links missing!" "$LINENO" 5
-fi
-MPI_SFLAGS="$ac_cv_mpi_sflags"
-
-
- if test "$mpi_mod_asm_mpih_add1" = yes; then
-  MPI_MOD_ASM_MPIH_ADD1_TRUE=
-  MPI_MOD_ASM_MPIH_ADD1_FALSE='#'
-else
-  MPI_MOD_ASM_MPIH_ADD1_TRUE='#'
-  MPI_MOD_ASM_MPIH_ADD1_FALSE=
-fi
-
- if test "$mpi_mod_asm_mpih_sub1" = yes; then
-  MPI_MOD_ASM_MPIH_SUB1_TRUE=
-  MPI_MOD_ASM_MPIH_SUB1_FALSE='#'
-else
-  MPI_MOD_ASM_MPIH_SUB1_TRUE='#'
-  MPI_MOD_ASM_MPIH_SUB1_FALSE=
-fi
-
- if test "$mpi_mod_asm_mpih_mul1" = yes; then
-  MPI_MOD_ASM_MPIH_MUL1_TRUE=
-  MPI_MOD_ASM_MPIH_MUL1_FALSE='#'
-else
-  MPI_MOD_ASM_MPIH_MUL1_TRUE='#'
-  MPI_MOD_ASM_MPIH_MUL1_FALSE=
-fi
-
- if test "$mpi_mod_asm_mpih_mul2" = yes; then
-  MPI_MOD_ASM_MPIH_MUL2_TRUE=
-  MPI_MOD_ASM_MPIH_MUL2_FALSE='#'
-else
-  MPI_MOD_ASM_MPIH_MUL2_TRUE='#'
-  MPI_MOD_ASM_MPIH_MUL2_FALSE=
-fi
-
- if test "$mpi_mod_asm_mpih_mul3" = yes; then
-  MPI_MOD_ASM_MPIH_MUL3_TRUE=
-  MPI_MOD_ASM_MPIH_MUL3_FALSE='#'
-else
-  MPI_MOD_ASM_MPIH_MUL3_TRUE='#'
-  MPI_MOD_ASM_MPIH_MUL3_FALSE=
-fi
-
- if test "$mpi_mod_asm_mpih_lshift" = yes; then
-  MPI_MOD_ASM_MPIH_LSHIFT_TRUE=
-  MPI_MOD_ASM_MPIH_LSHIFT_FALSE='#'
-else
-  MPI_MOD_ASM_MPIH_LSHIFT_TRUE='#'
-  MPI_MOD_ASM_MPIH_LSHIFT_FALSE=
-fi
-
- if test "$mpi_mod_asm_mpih_rshift" = yes; then
-  MPI_MOD_ASM_MPIH_RSHIFT_TRUE=
-  MPI_MOD_ASM_MPIH_RSHIFT_FALSE='#'
-else
-  MPI_MOD_ASM_MPIH_RSHIFT_TRUE='#'
-  MPI_MOD_ASM_MPIH_RSHIFT_FALSE=
-fi
-
- if test "$mpi_mod_asm_udiv" = yes; then
-  MPI_MOD_ASM_UDIV_TRUE=
-  MPI_MOD_ASM_UDIV_FALSE='#'
-else
-  MPI_MOD_ASM_UDIV_TRUE='#'
-  MPI_MOD_ASM_UDIV_FALSE=
-fi
-
- if test "$mpi_mod_asm_udiv_qrnnd" = yes; then
-  MPI_MOD_ASM_UDIV_QRNND_TRUE=
-  MPI_MOD_ASM_UDIV_QRNND_FALSE='#'
-else
-  MPI_MOD_ASM_UDIV_QRNND_TRUE='#'
-  MPI_MOD_ASM_UDIV_QRNND_FALSE=
-fi
-
- if test "$mpi_mod_c_mpih_add1" = yes; then
-  MPI_MOD_C_MPIH_ADD1_TRUE=
-  MPI_MOD_C_MPIH_ADD1_FALSE='#'
-else
-  MPI_MOD_C_MPIH_ADD1_TRUE='#'
-  MPI_MOD_C_MPIH_ADD1_FALSE=
-fi
-
- if test "$mpi_mod_c_mpih_sub1" = yes; then
-  MPI_MOD_C_MPIH_SUB1_TRUE=
-  MPI_MOD_C_MPIH_SUB1_FALSE='#'
-else
-  MPI_MOD_C_MPIH_SUB1_TRUE='#'
-  MPI_MOD_C_MPIH_SUB1_FALSE=
-fi
-
- if test "$mpi_mod_c_mpih_mul1" = yes; then
-  MPI_MOD_C_MPIH_MUL1_TRUE=
-  MPI_MOD_C_MPIH_MUL1_FALSE='#'
-else
-  MPI_MOD_C_MPIH_MUL1_TRUE='#'
-  MPI_MOD_C_MPIH_MUL1_FALSE=
-fi
-
- if test "$mpi_mod_c_mpih_mul2" = yes; then
-  MPI_MOD_C_MPIH_MUL2_TRUE=
-  MPI_MOD_C_MPIH_MUL2_FALSE='#'
-else
-  MPI_MOD_C_MPIH_MUL2_TRUE='#'
-  MPI_MOD_C_MPIH_MUL2_FALSE=
-fi
-
- if test "$mpi_mod_c_mpih_mul3" = yes; then
-  MPI_MOD_C_MPIH_MUL3_TRUE=
-  MPI_MOD_C_MPIH_MUL3_FALSE='#'
-else
-  MPI_MOD_C_MPIH_MUL3_TRUE='#'
-  MPI_MOD_C_MPIH_MUL3_FALSE=
-fi
-
- if test "$mpi_mod_c_mpih_lshift" = yes; then
-  MPI_MOD_C_MPIH_LSHIFT_TRUE=
-  MPI_MOD_C_MPIH_LSHIFT_FALSE='#'
-else
-  MPI_MOD_C_MPIH_LSHIFT_TRUE='#'
-  MPI_MOD_C_MPIH_LSHIFT_FALSE=
-fi
-
- if test "$mpi_mod_c_mpih_rshift" = yes; then
-  MPI_MOD_C_MPIH_RSHIFT_TRUE=
-  MPI_MOD_C_MPIH_RSHIFT_FALSE='#'
-else
-  MPI_MOD_C_MPIH_RSHIFT_TRUE='#'
-  MPI_MOD_C_MPIH_RSHIFT_FALSE=
-fi
-
- if test "$mpi_mod_c_udiv" = yes; then
-  MPI_MOD_C_UDIV_TRUE=
-  MPI_MOD_C_UDIV_FALSE='#'
-else
-  MPI_MOD_C_UDIV_TRUE='#'
-  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='#'
+          random_modules="w32"
+          ;;
+        *)
+          # Build everything, allow to select at runtime.
+          random_modules="$auto_random_modules"
+          ;;
+        esac
+    fi
 else
-  MPI_MOD_C_UDIV_QRNND_TRUE='#'
-  MPI_MOD_C_UDIV_QRNND_FALSE=
+    if test "$random" = "auto"; then
+        # Build everything, allow to select at runtime.
+        random_modules="$auto_random_modules"
+    else
+        random_modules="$random"
+    fi
 fi
 
 
-if test "$is_development_version" = "yes"; then
+#
+# Other defines
+#
+if test no = "yes"; then
 
 $as_echo "#define IS_DEVELOPMENT_VERSION 1" >>confdefs.h
 
@@ -15022,7 +17314,7 @@ $as_echo "$noexecstack_support" >&6; }
 
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether assembler supports --noexecstack option" >&5
 $as_echo_n "checking whether assembler supports --noexecstack option... " >&6; }
-if test "${cl_cv_as_noexecstack+set}" = set; then :
+if ${cl_cv_as_noexecstack+:} false; then :
   $as_echo_n "(cached) " >&6
 else
     cat > conftest.c <<EOF
@@ -15074,8 +17366,74 @@ ac_config_commands="$ac_config_commands gcrypt-conf"
 #### Conclusion. ####
 #####################
 
+# Check that requested feature can actually be used and define
+# ENABLE_foo_SUPPORT macros.
+
+if test x"$aesnisupport" = xyes ; then
+  if test "$gcry_cv_gcc_inline_asm_ssse3" != "yes" ; then
+    aesnisupport="no (unsupported by compiler)"
+  fi
+fi
+if test x"$pclmulsupport" = xyes ; then
+  if test "$gcry_cv_gcc_inline_asm_pclmul" != "yes" ; then
+    pclmulsupport="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)"
+  fi
+fi
+if test x"$avx2support" = xyes ; then
+  if test "$gcry_cv_gcc_inline_asm_avx2" != "yes" ; then
+    avx2support="no (unsupported by compiler)"
+  fi
+fi
+if test x"$neonsupport" = xyes ; then
+  if test "$gcry_cv_gcc_inline_asm_neon" != "yes" ; then
+    neonsupport="no (unsupported by compiler)"
+  fi
+fi
+
+if test x"$aesnisupport" = xyes ; then
+
+$as_echo "#define ENABLE_AESNI_SUPPORT 1" >>confdefs.h
+
+fi
+if test x"$pclmulsupport" = xyes ; then
+
+$as_echo "#define ENABLE_PCLMUL_SUPPORT 1" >>confdefs.h
+
+fi
+if test x"$avxsupport" = xyes ; then
+
+$as_echo "#define ENABLE_AVX_SUPPORT 1" >>confdefs.h
+
+fi
+if test x"$avx2support" = xyes ; then
+
+$as_echo "#define ENABLE_AVX2_SUPPORT 1" >>confdefs.h
+
+fi
+if test x"$neonsupport" = xyes ; then
+
+$as_echo "#define ENABLE_NEON_SUPPORT 1" >>confdefs.h
+
+fi
+if test x"$padlocksupport" = xyes ; then
+
+$as_echo "#define ENABLE_PADLOCK_SUPPORT 1" >>confdefs.h
+
+fi
+if test x"$drngsupport" = xyes ; then
+
+$as_echo "#define ENABLE_DRNG_SUPPORT 1" >>confdefs.h
+
+fi
+
+
 # Define conditional sources and config.h symbols depending on the
-# selected ciphers, pubkey-ciphers, digests and random modules.
+# selected ciphers, pubkey-ciphers, digests, kdfs, and random modules.
 
 
 name=arcfour
@@ -15111,6 +17469,17 @@ if test "$found" = "1" ; then
 
 $as_echo "#define USE_BLOWFISH 1" >>confdefs.h
 
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS blowfish-amd64.lo"
+      ;;
+      arm*-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS blowfish-arm.lo"
+      ;;
+   esac
 fi
 
 
@@ -15129,6 +17498,17 @@ if test "$found" = "1" ; then
 
 $as_echo "#define USE_CAST5 1" >>confdefs.h
 
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS cast5-amd64.lo"
+      ;;
+      arm*-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS cast5-arm.lo"
+      ;;
+   esac
 fi
 
 
@@ -15165,6 +17545,17 @@ if test "$found" = "1" ; then
 
 $as_echo "#define USE_AES 1" >>confdefs.h
 
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-amd64.lo"
+      ;;
+      arm*-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-arm.lo"
+      ;;
+   esac
 fi
 
 
@@ -15183,6 +17574,17 @@ if test "$found" = "1" ; then
 
 $as_echo "#define USE_TWOFISH 1" >>confdefs.h
 
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS twofish-amd64.lo"
+      ;;
+      arm*-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS twofish-arm.lo"
+      ;;
+   esac
 fi
 
 
@@ -15201,6 +17603,23 @@ if test "$found" = "1" ; then
 
 $as_echo "#define USE_SERPENT 1" >>confdefs.h
 
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the SSE2 implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent-sse2-amd64.lo"
+      ;;
+   esac
+
+   if test x"$avx2support" = xyes ; then
+      # Build with the AVX2 implementation
+      GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent-avx2-amd64.lo"
+   fi
+
+   if test x"$neonsupport" = xyes ; then
+      # Build with the NEON implementation
+      GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent-armv7-neon.lo"
+   fi
 fi
 
 
@@ -15255,6 +17674,93 @@ if test "$found" = "1" ; then
 
 $as_echo "#define USE_CAMELLIA 1" >>confdefs.h
 
+
+   case "${host}" in
+      arm*-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia-arm.lo"
+      ;;
+   esac
+
+   if test x"$avxsupport" = xyes ; then
+      if test x"$aesnisupport" = xyes ; then
+        # Build with the AES-NI/AVX implementation
+        GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia-aesni-avx-amd64.lo"
+      fi
+   fi
+
+   if test x"$avx2support" = xyes ; then
+      if test x"$aesnisupport" = xyes ; then
+        # Build with the AES-NI/AVX2 implementation
+        GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia-aesni-avx2-amd64.lo"
+      fi
+   fi
+fi
+
+
+name=idea
+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 idea.lo"
+
+$as_echo "#define USE_IDEA 1" >>confdefs.h
+
+fi
+
+
+name=salsa20
+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 salsa20.lo"
+
+$as_echo "#define USE_SALSA20 1" >>confdefs.h
+
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS salsa20-amd64.lo"
+      ;;
+   esac
+
+   if test x"$neonsupport" = xyes ; then
+     # Build with the NEON implementation
+     GCRYPT_CIPHERS="$GCRYPT_CIPHERS salsa20-armv7-neon.lo"
+   fi
+fi
+
+
+name=gost28147
+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 gost28147.lo"
+
+$as_echo "#define USE_GOST28147 1" >>confdefs.h
+
 fi
 
 
@@ -15323,7 +17829,9 @@ for n in $list; do
 done
 
 if test "$found" = "1" ; then
-   GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS ecc.lo"
+   GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS \
+                          ecc.lo ecc-curves.lo ecc-misc.lo \
+                          ecc-ecdsa.lo ecc-eddsa.lo ecc-gost.lo"
 
 $as_echo "#define USE_ECC 1" >>confdefs.h
 
@@ -15348,6 +17856,56 @@ $as_echo "#define USE_CRC 1" >>confdefs.h
 fi
 
 
+name=gostr3411-94
+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
+   # GOST R 34.11-94 internally uses GOST 28147-89
+
+name=gost28147
+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_DIGESTS="$GCRYPT_DIGESTS gostr3411-94.lo"
+
+$as_echo "#define USE_GOST_R_3411_94 1" >>confdefs.h
+
+   fi
+fi
+
+
+name=stribog
+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 stribog.lo"
+
+$as_echo "#define USE_GOST_R_3411_12 1" >>confdefs.h
+
+fi
+
+
 name=md4
 list=$enabled_digests
 found=0
@@ -15399,6 +17957,13 @@ if test "$found" = "1" ; then
 
 $as_echo "#define USE_SHA256 1" >>confdefs.h
 
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-ssse3-amd64.lo"
+      ;;
+   esac
 fi
 
 
@@ -15417,6 +17982,20 @@ if test "$found" = "1" ; then
 
 $as_echo "#define USE_SHA512 1" >>confdefs.h
 
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-ssse3-amd64.lo"
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-avx-amd64.lo"
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-avx2-bmi2-amd64.lo"
+      ;;
+   esac
+
+   if test x"$neonsupport" = xyes ; then
+     # Build with the NEON implementation
+     GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-armv7-neon.lo"
+   fi
 fi
 
 
@@ -15464,6 +18043,31 @@ $as_echo "#define USE_RMD160 1" >>confdefs.h
 $as_echo "#define USE_SHA1 1" >>confdefs.h
 
 
+case "${host}" in
+  x86_64-*-*)
+    # Build with the assembly implementation
+    GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha1-ssse3-amd64.lo"
+  ;;
+esac
+
+
+name=scrypt
+list=$enabled_kdfs
+found=0
+
+for n in $list; do
+  if test "x$name" = "x$n"; then
+    found=1
+  fi
+done
+
+if test "$found" = "1" ; then
+   GCRYPT_KDFS="$GCRYPT_KDFS scrypt.lo"
+
+$as_echo "#define USE_SCRYPT 1" >>confdefs.h
+
+fi
+
 
 name=linux
 list=$random_modules
@@ -15548,68 +18152,131 @@ for n in $list; do
   fi
 done
 
-if test "$found" = "1" ; then
-   GCRYPT_RANDOM="$GCRYPT_RANDOM rndw32ce.lo"
+if test "$found" = "1" ; then
+   GCRYPT_RANDOM="$GCRYPT_RANDOM rndw32ce.lo"
+
+$as_echo "#define USE_RNDW32CE 1" >>confdefs.h
+
+fi
+
+
+
+
+
+
+
+LIBGCRYPT_CIPHERS=$enabled_ciphers
+
+LIBGCRYPT_PUBKEY_CIPHERS=$enabled_pubkey_ciphers
+
+LIBGCRYPT_DIGESTS=$enabled_digests
+
+
+# For printing the configuration we need a colon separated list of
+# algorithm names.
+tmp=`echo "$enabled_ciphers" | tr ' ' : `
+
+cat >>confdefs.h <<_ACEOF
+#define LIBGCRYPT_CIPHERS "$tmp"
+_ACEOF
+
+tmp=`echo "$enabled_pubkey_ciphers" | tr ' ' : `
+
+cat >>confdefs.h <<_ACEOF
+#define LIBGCRYPT_PUBKEY_CIPHERS "$tmp"
+_ACEOF
+
+tmp=`echo "$enabled_digests" | tr ' ' : `
+
+cat >>confdefs.h <<_ACEOF
+#define LIBGCRYPT_DIGESTS "$tmp"
+_ACEOF
+
+tmp=`echo "$enabled_kdfs" | tr ' ' : `
+
+cat >>confdefs.h <<_ACEOF
+#define LIBGCRYPT_KDFS "$tmp"
+_ACEOF
+
+
+
+#
+# Define conditional sources depending on the used hardware platform.
+# Note that all possible modules must also be listed in
+# src/Makefile.am (EXTRA_libgcrypt_la_SOURCES).
+#
+GCRYPT_HWF_MODULES=
+case "$mpi_cpu_arch" in
+     x86)
+
+$as_echo "#define HAVE_CPU_ARCH_X86 1" >>confdefs.h
 
-$as_echo "#define USE_RNDW32CE 1" >>confdefs.h
+        GCRYPT_HWF_MODULES="hwf-x86.lo"
+        ;;
+     alpha)
 
-fi
+$as_echo "#define HAVE_CPU_ARCH_ALPHA 1" >>confdefs.h
 
+        ;;
+     sparc)
 
+$as_echo "#define HAVE_CPU_ARCH_SPARC 1" >>confdefs.h
 
+        ;;
+     mips)
 
+$as_echo "#define HAVE_CPU_ARCH_MIPS 1" >>confdefs.h
 
+        ;;
+     m68k)
 
-LIBGCRYPT_CIPHERS=$enabled_ciphers
+$as_echo "#define HAVE_CPU_ARCH_M68K 1" >>confdefs.h
 
-LIBGCRYPT_PUBKEY_CIPHERS=$enabled_pubkey_ciphers
+        ;;
+     ppc)
 
-LIBGCRYPT_DIGESTS=$enabled_digests
+$as_echo "#define HAVE_CPU_ARCH_PPC 1" >>confdefs.h
 
+        ;;
+     arm)
 
-# For printing the configuration we need a colon separated list of
-# algorithm names.
-tmp=`echo "$enabled_ciphers" | tr ' ' : `
+$as_echo "#define HAVE_CPU_ARCH_ARM 1" >>confdefs.h
 
-cat >>confdefs.h <<_ACEOF
-#define LIBGCRYPT_CIPHERS "$tmp"
-_ACEOF
+        GCRYPT_HWF_MODULES="hwf-arm.lo"
+        ;;
+esac
 
-tmp=`echo "$enabled_pubkey_ciphers" | tr ' ' : `
 
-cat >>confdefs.h <<_ACEOF
-#define LIBGCRYPT_PUBKEY_CIPHERS "$tmp"
-_ACEOF
 
-tmp=`echo "$enabled_digests" | tr ' ' : `
+#
+# Provide information about the build.
+#
+BUILD_REVISION="8804b9a"
+
 
 cat >>confdefs.h <<_ACEOF
-#define LIBGCRYPT_DIGESTS "$tmp"
+#define BUILD_REVISION "$BUILD_REVISION"
 _ACEOF
 
 
+BUILD_FILEVERSION=`echo "$VERSION" | sed 's/\([0-9.]*\).*/\1./;s/\./,/g'`
+BUILD_FILEVERSION="${BUILD_FILEVERSION}34820"
 
 
-# Generate extended version information for W32.
-if test "$have_w32_system" = yes; then
-   BUILD_TIMESTAMP=`date --iso-8601=minutes`
-      BUILD_FILEVERSION=`echo "$VERSION" | sed 's/\([0-9.]*\).*/\1./;s/\./,/g'`
-      BUILD_FILEVERSION="${BUILD_FILEVERSION}${BUILD_REVISION}"
-fi
-
-
+BUILD_TIMESTAMP=`date -u +%Y-%m-%dT%H:%M+0000 2>/dev/null || date`
 
 
 cat >>confdefs.h <<_ACEOF
-#define BUILD_REVISION "$BUILD_REVISION"
+#define BUILD_TIMESTAMP "$BUILD_TIMESTAMP"
 _ACEOF
 
 
 
-
 # And create the files.
 ac_config_files="$ac_config_files Makefile m4/Makefile compat/Makefile mpi/Makefile cipher/Makefile random/Makefile doc/Makefile src/Makefile src/gcrypt.h src/libgcrypt-config src/versioninfo.rc tests/Makefile"
 
+ac_config_files="$ac_config_files tests/hashtest-256g"
+
 cat >confcache <<\_ACEOF
 # This file is a shell script that caches the results of configure
 # tests run on this system so they can be shared between configure
@@ -15674,10 +18341,21 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
      :end' >>confcache
 if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
   if test -w "$cache_file"; then
-    test "x$cache_file" != "x/dev/null" &&
+    if test "x$cache_file" != "x/dev/null"; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
 $as_echo "$as_me: updating cache $cache_file" >&6;}
-    cat confcache >$cache_file
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+       cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+         mv -f confcache "$cache_file"$$ &&
+         mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+         mv -f confcache "$cache_file" ;;
+       esac
+      fi
+    fi
   else
     { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
 $as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
@@ -15693,6 +18371,7 @@ DEFS=-DHAVE_CONFIG_H
 
 ac_libobjs=
 ac_ltlibobjs=
+U=
 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
   # 1. Remove the extension, and $U if already installed.
   ac_script='s/\$U\././;s/\.o$//;s/\.obj$//'
 fi
 
 if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
-  as_fn_error "conditional \"MAINTAINER_MODE\" was never defined.
+  as_fn_error $? "conditional \"MAINTAINER_MODE\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
-  as_fn_error "conditional \"AMDEP\" was never defined.
+  as_fn_error $? "conditional \"AMDEP\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${am__fastdepCC_TRUE}" && test -z "${am__fastdepCC_FALSE}"; then
-  as_fn_error "conditional \"am__fastdepCC\" was never defined.
+  as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${am__fastdepCCAS_TRUE}" && test -z "${am__fastdepCCAS_FALSE}"; then
-  as_fn_error "conditional \"am__fastdepCCAS\" was never defined.
+  as_fn_error $? "conditional \"am__fastdepCCAS\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${HAVE_W32_SYSTEM_TRUE}" && test -z "${HAVE_W32_SYSTEM_FALSE}"; then
-  as_fn_error "conditional \"HAVE_W32_SYSTEM\" was never defined.
+  as_fn_error $? "conditional \"HAVE_W32_SYSTEM\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${HAVE_W32CE_SYSTEM_TRUE}" && test -z "${HAVE_W32CE_SYSTEM_FALSE}"; then
-  as_fn_error "conditional \"HAVE_W32CE_SYSTEM\" was never defined.
+  as_fn_error $? "conditional \"HAVE_W32CE_SYSTEM\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 
 if test -z "${USE_RANDOM_DAEMON_TRUE}" && test -z "${USE_RANDOM_DAEMON_FALSE}"; then
-  as_fn_error "conditional \"USE_RANDOM_DAEMON\" was never defined.
+  as_fn_error $? "conditional \"USE_RANDOM_DAEMON\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${ENABLE_O_FLAG_MUNGING_TRUE}" && test -z "${ENABLE_O_FLAG_MUNGING_FALSE}"; then
-  as_fn_error "conditional \"ENABLE_O_FLAG_MUNGING\" was never defined.
+  as_fn_error $? "conditional \"ENABLE_O_FLAG_MUNGING\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${HAVE_LD_VERSION_SCRIPT_TRUE}" && test -z "${HAVE_LD_VERSION_SCRIPT_FALSE}"; then
-  as_fn_error "conditional \"HAVE_LD_VERSION_SCRIPT\" was never defined.
+  as_fn_error $? "conditional \"HAVE_LD_VERSION_SCRIPT\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${MPI_MOD_ASM_MPIH_ADD1_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_ADD1_FALSE}"; then
-  as_fn_error "conditional \"MPI_MOD_ASM_MPIH_ADD1\" was never defined.
+  as_fn_error $? "conditional \"MPI_MOD_ASM_MPIH_ADD1\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${MPI_MOD_ASM_MPIH_SUB1_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_SUB1_FALSE}"; then
-  as_fn_error "conditional \"MPI_MOD_ASM_MPIH_SUB1\" was never defined.
+  as_fn_error $? "conditional \"MPI_MOD_ASM_MPIH_SUB1\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${MPI_MOD_ASM_MPIH_MUL1_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_MUL1_FALSE}"; then
-  as_fn_error "conditional \"MPI_MOD_ASM_MPIH_MUL1\" was never defined.
+  as_fn_error $? "conditional \"MPI_MOD_ASM_MPIH_MUL1\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${MPI_MOD_ASM_MPIH_MUL2_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_MUL2_FALSE}"; then
-  as_fn_error "conditional \"MPI_MOD_ASM_MPIH_MUL2\" was never defined.
+  as_fn_error $? "conditional \"MPI_MOD_ASM_MPIH_MUL2\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${MPI_MOD_ASM_MPIH_MUL3_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_MUL3_FALSE}"; then
-  as_fn_error "conditional \"MPI_MOD_ASM_MPIH_MUL3\" was never defined.
+  as_fn_error $? "conditional \"MPI_MOD_ASM_MPIH_MUL3\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${MPI_MOD_ASM_MPIH_LSHIFT_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_LSHIFT_FALSE}"; then
-  as_fn_error "conditional \"MPI_MOD_ASM_MPIH_LSHIFT\" was never defined.
+  as_fn_error $? "conditional \"MPI_MOD_ASM_MPIH_LSHIFT\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${MPI_MOD_ASM_MPIH_RSHIFT_TRUE}" && test -z "${MPI_MOD_ASM_MPIH_RSHIFT_FALSE}"; then
-  as_fn_error "conditional \"MPI_MOD_ASM_MPIH_RSHIFT\" was never defined.
+  as_fn_error $? "conditional \"MPI_MOD_ASM_MPIH_RSHIFT\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${MPI_MOD_ASM_UDIV_TRUE}" && test -z "${MPI_MOD_ASM_UDIV_FALSE}"; then
-  as_fn_error "conditional \"MPI_MOD_ASM_UDIV\" was never defined.
+  as_fn_error $? "conditional \"MPI_MOD_ASM_UDIV\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${MPI_MOD_ASM_UDIV_QRNND_TRUE}" && test -z "${MPI_MOD_ASM_UDIV_QRNND_FALSE}"; then
-  as_fn_error "conditional \"MPI_MOD_ASM_UDIV_QRNND\" was never defined.
+  as_fn_error $? "conditional \"MPI_MOD_ASM_UDIV_QRNND\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${MPI_MOD_C_MPIH_ADD1_TRUE}" && test -z "${MPI_MOD_C_MPIH_ADD1_FALSE}"; then
-  as_fn_error "conditional \"MPI_MOD_C_MPIH_ADD1\" was never defined.
+  as_fn_error $? "conditional \"MPI_MOD_C_MPIH_ADD1\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${MPI_MOD_C_MPIH_SUB1_TRUE}" && test -z "${MPI_MOD_C_MPIH_SUB1_FALSE}"; then
-  as_fn_error "conditional \"MPI_MOD_C_MPIH_SUB1\" was never defined.
+  as_fn_error $? "conditional \"MPI_MOD_C_MPIH_SUB1\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${MPI_MOD_C_MPIH_MUL1_TRUE}" && test -z "${MPI_MOD_C_MPIH_MUL1_FALSE}"; then
-  as_fn_error "conditional \"MPI_MOD_C_MPIH_MUL1\" was never defined.
+  as_fn_error $? "conditional \"MPI_MOD_C_MPIH_MUL1\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${MPI_MOD_C_MPIH_MUL2_TRUE}" && test -z "${MPI_MOD_C_MPIH_MUL2_FALSE}"; then
-  as_fn_error "conditional \"MPI_MOD_C_MPIH_MUL2\" was never defined.
+  as_fn_error $? "conditional \"MPI_MOD_C_MPIH_MUL2\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${MPI_MOD_C_MPIH_MUL3_TRUE}" && test -z "${MPI_MOD_C_MPIH_MUL3_FALSE}"; then
-  as_fn_error "conditional \"MPI_MOD_C_MPIH_MUL3\" was never defined.
+  as_fn_error $? "conditional \"MPI_MOD_C_MPIH_MUL3\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${MPI_MOD_C_MPIH_LSHIFT_TRUE}" && test -z "${MPI_MOD_C_MPIH_LSHIFT_FALSE}"; then
-  as_fn_error "conditional \"MPI_MOD_C_MPIH_LSHIFT\" was never defined.
+  as_fn_error $? "conditional \"MPI_MOD_C_MPIH_LSHIFT\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${MPI_MOD_C_MPIH_RSHIFT_TRUE}" && test -z "${MPI_MOD_C_MPIH_RSHIFT_FALSE}"; then
-  as_fn_error "conditional \"MPI_MOD_C_MPIH_RSHIFT\" was never defined.
+  as_fn_error $? "conditional \"MPI_MOD_C_MPIH_RSHIFT\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${MPI_MOD_C_UDIV_TRUE}" && test -z "${MPI_MOD_C_UDIV_FALSE}"; then
-  as_fn_error "conditional \"MPI_MOD_C_UDIV\" was never defined.
+  as_fn_error $? "conditional \"MPI_MOD_C_UDIV\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${MPI_MOD_C_UDIV_QRNND_TRUE}" && test -z "${MPI_MOD_C_UDIV_QRNND_FALSE}"; then
-  as_fn_error "conditional \"MPI_MOD_C_UDIV_QRNND\" was never defined.
+  as_fn_error $? "conditional \"MPI_MOD_C_UDIV_QRNND\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 if test -z "${CROSS_COMPILING_TRUE}" && test -z "${CROSS_COMPILING_FALSE}"; then
-  as_fn_error "conditional \"CROSS_COMPILING\" was never defined.
+  as_fn_error $? "conditional \"CROSS_COMPILING\" was never defined.
 Usually this means the macro was only invoked conditionally." "$LINENO" 5
 fi
 
-: ${CONFIG_STATUS=./config.status}
+: "${CONFIG_STATUS=./config.status}"
 ac_write_fail=0
 ac_clean_files_save=$ac_clean_files
 ac_clean_files="$ac_clean_files $CONFIG_STATUS"
@@ -15930,6 +18609,7 @@ fi
 IFS=" ""       $as_nl"
 
 # Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
 case $0 in #((
   *[\\/]* ) as_myself=$0 ;;
   *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
@@ -15975,19 +18655,19 @@ export LANGUAGE
 (unset CDPATH) >/dev/null 2>&1 && unset CDPATH
 
 
-# as_fn_error ERROR [LINENO LOG_FD]
-# ---------------------------------
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
 # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
 # provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with status $?, using 1 if that was 0.
+# script with STATUS, using 1 if that was 0.
 as_fn_error ()
 {
-  as_status=$?; test $as_status -eq 0 && as_status=1
-  if test "$3"; then
-    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-  $as_echo "$as_me: error: $1" >&2
+  $as_echo "$as_me: error: $2" >&2
   as_fn_exit $as_status
 } # as_fn_error
 
@@ -16125,16 +18805,16 @@ if (echo >conf$$.file) 2>/dev/null; then
     # ... but there are two gotchas:
     # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
     # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-    # In both cases, we have to default to `cp -p'.
+    # In both cases, we have to default to `cp -pR'.
     ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-      as_ln_s='cp -p'
+      as_ln_s='cp -pR'
   elif ln conf$$.file conf$$ 2>/dev/null; then
     as_ln_s=ln
   else
-    as_ln_s='cp -p'
+    as_ln_s='cp -pR'
   fi
 else
-  as_ln_s='cp -p'
+  as_ln_s='cp -pR'
 fi
 rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
 rmdir conf$$.dir 2>/dev/null
@@ -16183,7 +18863,7 @@ $as_echo X"$as_dir" |
       test -d "$as_dir" && break
     done
     test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
 
 
 } # as_fn_mkdir_p
@@ -16194,28 +18874,16 @@ else
   as_mkdir_p=false
 fi
 
-if test -x / >/dev/null 2>&1; then
-  as_test_x='test -x'
-else
-  if ls -dL / >/dev/null 2>&1; then
-    as_ls_L_option=L
-  else
-    as_ls_L_option=
-  fi
-  as_test_x='
-    eval sh -c '\''
-      if test -d "$1"; then
-       test -d "$1/.";
-      else
-       case $1 in #(
-       -*)set "./$1";;
-       esac;
-       case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
-       ???[sx]*):;;*)false;;esac;fi
-    '\'' sh
-  '
-fi
-as_executable_p=$as_test_x
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
 
 # Sed expression to map a string onto a valid CPP name.
 as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -16236,8 +18904,8 @@ 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.5.0, which was
-generated by GNU Autoconf 2.64.  Invocation command line was
+This file was extended by libgcrypt $as_me 1.6.1, which was
+generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
   CONFIG_HEADERS  = $CONFIG_HEADERS
@@ -16278,6 +18946,7 @@ Usage: $0 [OPTION]... [TAG]...
 
   -h, --help       print this help, then exit
   -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
   -q, --quiet, --silent
                    do not print progress messages
   -d, --debug      don't remove temporary files
@@ -16299,16 +18968,17 @@ $config_links
 Configuration commands:
 $config_commands
 
-Report bugs to <bug-libgcrypt@gnupg.org>."
+Report bugs to <http://bugs.gnupg.org>."
 
 _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.5.0
-configured by $0, generated by GNU Autoconf 2.64,
-  with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+libgcrypt config.status 1.6.1
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"
 
-Copyright (C) 2009 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
 gives unlimited permission to copy, distribute and modify it."
 
@@ -16326,11 +18996,16 @@ ac_need_defaults=:
 while test $# != 0
 do
   case $1 in
-  --*=*)
+  --*=?*)
     ac_option=`expr "X$1" : 'X\([^=]*\)='`
     ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
     ac_shift=:
     ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
   *)
     ac_option=$1
     ac_optarg=$2
     ac_cs_recheck=: ;;
   --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
     $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
   --debug | --debu | --deb | --de | --d | -d )
     debug=: ;;
   --file | --fil | --fi | --f )
     $ac_shift
     case $ac_optarg in
     *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
     esac
     as_fn_append CONFIG_FILES " '$ac_optarg'"
     ac_need_defaults=false;;
@@ -16362,7 +19040,7 @@ do
     ac_need_defaults=false;;
   --he | --h)
     # Conflict between --help and --header
-    as_fn_error "ambiguous option: \`$1'
+    as_fn_error $? "ambiguous option: \`$1'
 Try \`$0 --help' for more information.";;
   --help | --hel | -h )
     $as_echo "$ac_cs_usage"; exit ;;
@@ -16371,7 +19049,7 @@ Try \`$0 --help' for more information.";;
     ac_cs_silent=: ;;
 
   # This is an error.
-  -*) as_fn_error "unrecognized option: \`$1'
+  -*) as_fn_error $? "unrecognized option: \`$1'
 Try \`$0 --help' for more information." ;;
 
   *) as_fn_append ac_config_targets " $1"
@@ -16391,7 +19069,7 @@ fi
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 if \$ac_cs_recheck; then
-  set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
   shift
   \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
   CONFIG_SHELL='$SHELL'
@@ -16425,174 +19103,200 @@ AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
 sed_quote_subst='$sed_quote_subst'
 double_quote_subst='$double_quote_subst'
 delay_variable_subst='$delay_variable_subst'
-macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`'
-macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`'
-AS='`$ECHO "X$AS" | $Xsed -e "$delay_single_quote_subst"`'
-DLLTOOL='`$ECHO "X$DLLTOOL" | $Xsed -e "$delay_single_quote_subst"`'
-OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`'
-enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`'
-enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`'
-pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`'
-enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`'
-host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`'
-host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`'
-host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`'
-build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`'
-build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`'
-build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`'
-SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`'
-Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`'
-GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`'
-EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`'
-FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`'
-LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`'
-NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`'
-LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`'
-max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`'
-ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`'
-exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`'
-lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`'
-lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`'
-lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`'
-reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`'
-reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`'
-file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`'
-AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`'
-AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`'
-STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`'
-RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`'
-old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`'
-CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`'
-compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`'
-GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`'
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`'
-objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`'
-SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`'
-ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`'
-MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`'
-lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`'
-need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`'
-DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`'
-NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`'
-LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`'
-OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`'
-OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`'
-libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`'
-shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`'
-enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`'
-export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
-whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
-compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`'
-old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`'
-allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
-no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`'
-inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`'
-link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`'
-fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`'
-always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`'
-export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
-include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`'
-prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`'
-variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`'
-need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`'
-need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`'
-version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`'
-runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`'
-shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`'
-shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`'
-libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`'
-library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`'
-soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`'
-postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`'
-finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`'
-sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
-sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`'
-enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`'
-enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`'
-enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`'
-old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`'
-striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`'
-LD_RC='`$ECHO "X$LD_RC" | $Xsed -e "$delay_single_quote_subst"`'
-old_archive_cmds_RC='`$ECHO "X$old_archive_cmds_RC" | $Xsed -e "$delay_single_quote_subst"`'
-compiler_RC='`$ECHO "X$compiler_RC" | $Xsed -e "$delay_single_quote_subst"`'
-GCC_RC='`$ECHO "X$GCC_RC" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_no_builtin_flag_RC='`$ECHO "X$lt_prog_compiler_no_builtin_flag_RC" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_wl_RC='`$ECHO "X$lt_prog_compiler_wl_RC" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_pic_RC='`$ECHO "X$lt_prog_compiler_pic_RC" | $Xsed -e "$delay_single_quote_subst"`'
-lt_prog_compiler_static_RC='`$ECHO "X$lt_prog_compiler_static_RC" | $Xsed -e "$delay_single_quote_subst"`'
-lt_cv_prog_compiler_c_o_RC='`$ECHO "X$lt_cv_prog_compiler_c_o_RC" | $Xsed -e "$delay_single_quote_subst"`'
-archive_cmds_need_lc_RC='`$ECHO "X$archive_cmds_need_lc_RC" | $Xsed -e "$delay_single_quote_subst"`'
-enable_shared_with_static_runtimes_RC='`$ECHO "X$enable_shared_with_static_runtimes_RC" | $Xsed -e "$delay_single_quote_subst"`'
-export_dynamic_flag_spec_RC='`$ECHO "X$export_dynamic_flag_spec_RC" | $Xsed -e "$delay_single_quote_subst"`'
-whole_archive_flag_spec_RC='`$ECHO "X$whole_archive_flag_spec_RC" | $Xsed -e "$delay_single_quote_subst"`'
-compiler_needs_object_RC='`$ECHO "X$compiler_needs_object_RC" | $Xsed -e "$delay_single_quote_subst"`'
-old_archive_from_new_cmds_RC='`$ECHO "X$old_archive_from_new_cmds_RC" | $Xsed -e "$delay_single_quote_subst"`'
-old_archive_from_expsyms_cmds_RC='`$ECHO "X$old_archive_from_expsyms_cmds_RC" | $Xsed -e "$delay_single_quote_subst"`'
-archive_cmds_RC='`$ECHO "X$archive_cmds_RC" | $Xsed -e "$delay_single_quote_subst"`'
-archive_expsym_cmds_RC='`$ECHO "X$archive_expsym_cmds_RC" | $Xsed -e "$delay_single_quote_subst"`'
-module_cmds_RC='`$ECHO "X$module_cmds_RC" | $Xsed -e "$delay_single_quote_subst"`'
-module_expsym_cmds_RC='`$ECHO "X$module_expsym_cmds_RC" | $Xsed -e "$delay_single_quote_subst"`'
-with_gnu_ld_RC='`$ECHO "X$with_gnu_ld_RC" | $Xsed -e "$delay_single_quote_subst"`'
-allow_undefined_flag_RC='`$ECHO "X$allow_undefined_flag_RC" | $Xsed -e "$delay_single_quote_subst"`'
-no_undefined_flag_RC='`$ECHO "X$no_undefined_flag_RC" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_libdir_flag_spec_RC='`$ECHO "X$hardcode_libdir_flag_spec_RC" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_libdir_flag_spec_ld_RC='`$ECHO "X$hardcode_libdir_flag_spec_ld_RC" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_libdir_separator_RC='`$ECHO "X$hardcode_libdir_separator_RC" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_direct_RC='`$ECHO "X$hardcode_direct_RC" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_direct_absolute_RC='`$ECHO "X$hardcode_direct_absolute_RC" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_minus_L_RC='`$ECHO "X$hardcode_minus_L_RC" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_shlibpath_var_RC='`$ECHO "X$hardcode_shlibpath_var_RC" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_automatic_RC='`$ECHO "X$hardcode_automatic_RC" | $Xsed -e "$delay_single_quote_subst"`'
-inherit_rpath_RC='`$ECHO "X$inherit_rpath_RC" | $Xsed -e "$delay_single_quote_subst"`'
-link_all_deplibs_RC='`$ECHO "X$link_all_deplibs_RC" | $Xsed -e "$delay_single_quote_subst"`'
-fix_srcfile_path_RC='`$ECHO "X$fix_srcfile_path_RC" | $Xsed -e "$delay_single_quote_subst"`'
-always_export_symbols_RC='`$ECHO "X$always_export_symbols_RC" | $Xsed -e "$delay_single_quote_subst"`'
-export_symbols_cmds_RC='`$ECHO "X$export_symbols_cmds_RC" | $Xsed -e "$delay_single_quote_subst"`'
-exclude_expsyms_RC='`$ECHO "X$exclude_expsyms_RC" | $Xsed -e "$delay_single_quote_subst"`'
-include_expsyms_RC='`$ECHO "X$include_expsyms_RC" | $Xsed -e "$delay_single_quote_subst"`'
-prelink_cmds_RC='`$ECHO "X$prelink_cmds_RC" | $Xsed -e "$delay_single_quote_subst"`'
-file_list_spec_RC='`$ECHO "X$file_list_spec_RC" | $Xsed -e "$delay_single_quote_subst"`'
-hardcode_action_RC='`$ECHO "X$hardcode_action_RC" | $Xsed -e "$delay_single_quote_subst"`'
+macro_version='`$ECHO "$macro_version" | $SED "$delay_single_quote_subst"`'
+macro_revision='`$ECHO "$macro_revision" | $SED "$delay_single_quote_subst"`'
+AS='`$ECHO "$AS" | $SED "$delay_single_quote_subst"`'
+DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`'
+OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`'
+enable_static='`$ECHO "$enable_static" | $SED "$delay_single_quote_subst"`'
+enable_shared='`$ECHO "$enable_shared" | $SED "$delay_single_quote_subst"`'
+pic_mode='`$ECHO "$pic_mode" | $SED "$delay_single_quote_subst"`'
+enable_fast_install='`$ECHO "$enable_fast_install" | $SED "$delay_single_quote_subst"`'
+SHELL='`$ECHO "$SHELL" | $SED "$delay_single_quote_subst"`'
+ECHO='`$ECHO "$ECHO" | $SED "$delay_single_quote_subst"`'
+PATH_SEPARATOR='`$ECHO "$PATH_SEPARATOR" | $SED "$delay_single_quote_subst"`'
+host_alias='`$ECHO "$host_alias" | $SED "$delay_single_quote_subst"`'
+host='`$ECHO "$host" | $SED "$delay_single_quote_subst"`'
+host_os='`$ECHO "$host_os" | $SED "$delay_single_quote_subst"`'
+build_alias='`$ECHO "$build_alias" | $SED "$delay_single_quote_subst"`'
+build='`$ECHO "$build" | $SED "$delay_single_quote_subst"`'
+build_os='`$ECHO "$build_os" | $SED "$delay_single_quote_subst"`'
+SED='`$ECHO "$SED" | $SED "$delay_single_quote_subst"`'
+Xsed='`$ECHO "$Xsed" | $SED "$delay_single_quote_subst"`'
+GREP='`$ECHO "$GREP" | $SED "$delay_single_quote_subst"`'
+EGREP='`$ECHO "$EGREP" | $SED "$delay_single_quote_subst"`'
+FGREP='`$ECHO "$FGREP" | $SED "$delay_single_quote_subst"`'
+LD='`$ECHO "$LD" | $SED "$delay_single_quote_subst"`'
+NM='`$ECHO "$NM" | $SED "$delay_single_quote_subst"`'
+LN_S='`$ECHO "$LN_S" | $SED "$delay_single_quote_subst"`'
+max_cmd_len='`$ECHO "$max_cmd_len" | $SED "$delay_single_quote_subst"`'
+ac_objext='`$ECHO "$ac_objext" | $SED "$delay_single_quote_subst"`'
+exeext='`$ECHO "$exeext" | $SED "$delay_single_quote_subst"`'
+lt_unset='`$ECHO "$lt_unset" | $SED "$delay_single_quote_subst"`'
+lt_SP2NL='`$ECHO "$lt_SP2NL" | $SED "$delay_single_quote_subst"`'
+lt_NL2SP='`$ECHO "$lt_NL2SP" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_to_host_file_cmd" | $SED "$delay_single_quote_subst"`'
+lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`'
+reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`'
+reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`'
+deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`'
+file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`'
+file_magic_glob='`$ECHO "$file_magic_glob" | $SED "$delay_single_quote_subst"`'
+want_nocaseglob='`$ECHO "$want_nocaseglob" | $SED "$delay_single_quote_subst"`'
+sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`'
+AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`'
+AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`'
+archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`'
+STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`'
+RANLIB='`$ECHO "$RANLIB" | $SED "$delay_single_quote_subst"`'
+old_postinstall_cmds='`$ECHO "$old_postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_postuninstall_cmds='`$ECHO "$old_postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds='`$ECHO "$old_archive_cmds" | $SED "$delay_single_quote_subst"`'
+lock_old_archive_extraction='`$ECHO "$lock_old_archive_extraction" | $SED "$delay_single_quote_subst"`'
+CC='`$ECHO "$CC" | $SED "$delay_single_quote_subst"`'
+CFLAGS='`$ECHO "$CFLAGS" | $SED "$delay_single_quote_subst"`'
+compiler='`$ECHO "$compiler" | $SED "$delay_single_quote_subst"`'
+GCC='`$ECHO "$GCC" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_pipe='`$ECHO "$lt_cv_sys_global_symbol_pipe" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_cdecl='`$ECHO "$lt_cv_sys_global_symbol_to_cdecl" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address" | $SED "$delay_single_quote_subst"`'
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $SED "$delay_single_quote_subst"`'
+nm_file_list_spec='`$ECHO "$nm_file_list_spec" | $SED "$delay_single_quote_subst"`'
+lt_sysroot='`$ECHO "$lt_sysroot" | $SED "$delay_single_quote_subst"`'
+objdir='`$ECHO "$objdir" | $SED "$delay_single_quote_subst"`'
+MAGIC_CMD='`$ECHO "$MAGIC_CMD" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag='`$ECHO "$lt_prog_compiler_no_builtin_flag" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic='`$ECHO "$lt_prog_compiler_pic" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl='`$ECHO "$lt_prog_compiler_wl" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static='`$ECHO "$lt_prog_compiler_static" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o='`$ECHO "$lt_cv_prog_compiler_c_o" | $SED "$delay_single_quote_subst"`'
+need_locks='`$ECHO "$need_locks" | $SED "$delay_single_quote_subst"`'
+MANIFEST_TOOL='`$ECHO "$MANIFEST_TOOL" | $SED "$delay_single_quote_subst"`'
+DSYMUTIL='`$ECHO "$DSYMUTIL" | $SED "$delay_single_quote_subst"`'
+NMEDIT='`$ECHO "$NMEDIT" | $SED "$delay_single_quote_subst"`'
+LIPO='`$ECHO "$LIPO" | $SED "$delay_single_quote_subst"`'
+OTOOL='`$ECHO "$OTOOL" | $SED "$delay_single_quote_subst"`'
+OTOOL64='`$ECHO "$OTOOL64" | $SED "$delay_single_quote_subst"`'
+libext='`$ECHO "$libext" | $SED "$delay_single_quote_subst"`'
+shrext_cmds='`$ECHO "$shrext_cmds" | $SED "$delay_single_quote_subst"`'
+extract_expsyms_cmds='`$ECHO "$extract_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc='`$ECHO "$archive_cmds_need_lc" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes='`$ECHO "$enable_shared_with_static_runtimes" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec='`$ECHO "$export_dynamic_flag_spec" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec='`$ECHO "$whole_archive_flag_spec" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object='`$ECHO "$compiler_needs_object" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds='`$ECHO "$old_archive_from_new_cmds" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds='`$ECHO "$old_archive_from_expsyms_cmds" | $SED "$delay_single_quote_subst"`'
+archive_cmds='`$ECHO "$archive_cmds" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds='`$ECHO "$archive_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+module_cmds='`$ECHO "$module_cmds" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds='`$ECHO "$module_expsym_cmds" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld='`$ECHO "$with_gnu_ld" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag='`$ECHO "$allow_undefined_flag" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag='`$ECHO "$no_undefined_flag" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec='`$ECHO "$hardcode_libdir_flag_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator='`$ECHO "$hardcode_libdir_separator" | $SED "$delay_single_quote_subst"`'
+hardcode_direct='`$ECHO "$hardcode_direct" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute='`$ECHO "$hardcode_direct_absolute" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L='`$ECHO "$hardcode_minus_L" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var='`$ECHO "$hardcode_shlibpath_var" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic='`$ECHO "$hardcode_automatic" | $SED "$delay_single_quote_subst"`'
+inherit_rpath='`$ECHO "$inherit_rpath" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs='`$ECHO "$link_all_deplibs" | $SED "$delay_single_quote_subst"`'
+always_export_symbols='`$ECHO "$always_export_symbols" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds='`$ECHO "$export_symbols_cmds" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms='`$ECHO "$exclude_expsyms" | $SED "$delay_single_quote_subst"`'
+include_expsyms='`$ECHO "$include_expsyms" | $SED "$delay_single_quote_subst"`'
+prelink_cmds='`$ECHO "$prelink_cmds" | $SED "$delay_single_quote_subst"`'
+postlink_cmds='`$ECHO "$postlink_cmds" | $SED "$delay_single_quote_subst"`'
+file_list_spec='`$ECHO "$file_list_spec" | $SED "$delay_single_quote_subst"`'
+variables_saved_for_relink='`$ECHO "$variables_saved_for_relink" | $SED "$delay_single_quote_subst"`'
+need_lib_prefix='`$ECHO "$need_lib_prefix" | $SED "$delay_single_quote_subst"`'
+need_version='`$ECHO "$need_version" | $SED "$delay_single_quote_subst"`'
+version_type='`$ECHO "$version_type" | $SED "$delay_single_quote_subst"`'
+runpath_var='`$ECHO "$runpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_var='`$ECHO "$shlibpath_var" | $SED "$delay_single_quote_subst"`'
+shlibpath_overrides_runpath='`$ECHO "$shlibpath_overrides_runpath" | $SED "$delay_single_quote_subst"`'
+libname_spec='`$ECHO "$libname_spec" | $SED "$delay_single_quote_subst"`'
+library_names_spec='`$ECHO "$library_names_spec" | $SED "$delay_single_quote_subst"`'
+soname_spec='`$ECHO "$soname_spec" | $SED "$delay_single_quote_subst"`'
+install_override_mode='`$ECHO "$install_override_mode" | $SED "$delay_single_quote_subst"`'
+postinstall_cmds='`$ECHO "$postinstall_cmds" | $SED "$delay_single_quote_subst"`'
+postuninstall_cmds='`$ECHO "$postuninstall_cmds" | $SED "$delay_single_quote_subst"`'
+finish_cmds='`$ECHO "$finish_cmds" | $SED "$delay_single_quote_subst"`'
+finish_eval='`$ECHO "$finish_eval" | $SED "$delay_single_quote_subst"`'
+hardcode_into_libs='`$ECHO "$hardcode_into_libs" | $SED "$delay_single_quote_subst"`'
+sys_lib_search_path_spec='`$ECHO "$sys_lib_search_path_spec" | $SED "$delay_single_quote_subst"`'
+sys_lib_dlsearch_path_spec='`$ECHO "$sys_lib_dlsearch_path_spec" | $SED "$delay_single_quote_subst"`'
+hardcode_action='`$ECHO "$hardcode_action" | $SED "$delay_single_quote_subst"`'
+enable_dlopen='`$ECHO "$enable_dlopen" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self='`$ECHO "$enable_dlopen_self" | $SED "$delay_single_quote_subst"`'
+enable_dlopen_self_static='`$ECHO "$enable_dlopen_self_static" | $SED "$delay_single_quote_subst"`'
+old_striplib='`$ECHO "$old_striplib" | $SED "$delay_single_quote_subst"`'
+striplib='`$ECHO "$striplib" | $SED "$delay_single_quote_subst"`'
+LD_RC='`$ECHO "$LD_RC" | $SED "$delay_single_quote_subst"`'
+reload_flag_RC='`$ECHO "$reload_flag_RC" | $SED "$delay_single_quote_subst"`'
+reload_cmds_RC='`$ECHO "$reload_cmds_RC" | $SED "$delay_single_quote_subst"`'
+old_archive_cmds_RC='`$ECHO "$old_archive_cmds_RC" | $SED "$delay_single_quote_subst"`'
+compiler_RC='`$ECHO "$compiler_RC" | $SED "$delay_single_quote_subst"`'
+GCC_RC='`$ECHO "$GCC_RC" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_no_builtin_flag_RC='`$ECHO "$lt_prog_compiler_no_builtin_flag_RC" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_pic_RC='`$ECHO "$lt_prog_compiler_pic_RC" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_wl_RC='`$ECHO "$lt_prog_compiler_wl_RC" | $SED "$delay_single_quote_subst"`'
+lt_prog_compiler_static_RC='`$ECHO "$lt_prog_compiler_static_RC" | $SED "$delay_single_quote_subst"`'
+lt_cv_prog_compiler_c_o_RC='`$ECHO "$lt_cv_prog_compiler_c_o_RC" | $SED "$delay_single_quote_subst"`'
+archive_cmds_need_lc_RC='`$ECHO "$archive_cmds_need_lc_RC" | $SED "$delay_single_quote_subst"`'
+enable_shared_with_static_runtimes_RC='`$ECHO "$enable_shared_with_static_runtimes_RC" | $SED "$delay_single_quote_subst"`'
+export_dynamic_flag_spec_RC='`$ECHO "$export_dynamic_flag_spec_RC" | $SED "$delay_single_quote_subst"`'
+whole_archive_flag_spec_RC='`$ECHO "$whole_archive_flag_spec_RC" | $SED "$delay_single_quote_subst"`'
+compiler_needs_object_RC='`$ECHO "$compiler_needs_object_RC" | $SED "$delay_single_quote_subst"`'
+old_archive_from_new_cmds_RC='`$ECHO "$old_archive_from_new_cmds_RC" | $SED "$delay_single_quote_subst"`'
+old_archive_from_expsyms_cmds_RC='`$ECHO "$old_archive_from_expsyms_cmds_RC" | $SED "$delay_single_quote_subst"`'
+archive_cmds_RC='`$ECHO "$archive_cmds_RC" | $SED "$delay_single_quote_subst"`'
+archive_expsym_cmds_RC='`$ECHO "$archive_expsym_cmds_RC" | $SED "$delay_single_quote_subst"`'
+module_cmds_RC='`$ECHO "$module_cmds_RC" | $SED "$delay_single_quote_subst"`'
+module_expsym_cmds_RC='`$ECHO "$module_expsym_cmds_RC" | $SED "$delay_single_quote_subst"`'
+with_gnu_ld_RC='`$ECHO "$with_gnu_ld_RC" | $SED "$delay_single_quote_subst"`'
+allow_undefined_flag_RC='`$ECHO "$allow_undefined_flag_RC" | $SED "$delay_single_quote_subst"`'
+no_undefined_flag_RC='`$ECHO "$no_undefined_flag_RC" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_flag_spec_RC='`$ECHO "$hardcode_libdir_flag_spec_RC" | $SED "$delay_single_quote_subst"`'
+hardcode_libdir_separator_RC='`$ECHO "$hardcode_libdir_separator_RC" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_RC='`$ECHO "$hardcode_direct_RC" | $SED "$delay_single_quote_subst"`'
+hardcode_direct_absolute_RC='`$ECHO "$hardcode_direct_absolute_RC" | $SED "$delay_single_quote_subst"`'
+hardcode_minus_L_RC='`$ECHO "$hardcode_minus_L_RC" | $SED "$delay_single_quote_subst"`'
+hardcode_shlibpath_var_RC='`$ECHO "$hardcode_shlibpath_var_RC" | $SED "$delay_single_quote_subst"`'
+hardcode_automatic_RC='`$ECHO "$hardcode_automatic_RC" | $SED "$delay_single_quote_subst"`'
+inherit_rpath_RC='`$ECHO "$inherit_rpath_RC" | $SED "$delay_single_quote_subst"`'
+link_all_deplibs_RC='`$ECHO "$link_all_deplibs_RC" | $SED "$delay_single_quote_subst"`'
+always_export_symbols_RC='`$ECHO "$always_export_symbols_RC" | $SED "$delay_single_quote_subst"`'
+export_symbols_cmds_RC='`$ECHO "$export_symbols_cmds_RC" | $SED "$delay_single_quote_subst"`'
+exclude_expsyms_RC='`$ECHO "$exclude_expsyms_RC" | $SED "$delay_single_quote_subst"`'
+include_expsyms_RC='`$ECHO "$include_expsyms_RC" | $SED "$delay_single_quote_subst"`'
+prelink_cmds_RC='`$ECHO "$prelink_cmds_RC" | $SED "$delay_single_quote_subst"`'
+postlink_cmds_RC='`$ECHO "$postlink_cmds_RC" | $SED "$delay_single_quote_subst"`'
+file_list_spec_RC='`$ECHO "$file_list_spec_RC" | $SED "$delay_single_quote_subst"`'
+hardcode_action_RC='`$ECHO "$hardcode_action_RC" | $SED "$delay_single_quote_subst"`'
 
 LTCC='$LTCC'
 LTCFLAGS='$LTCFLAGS'
 compiler='$compiler_DEFAULT'
 
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$1
+_LTECHO_EOF'
+}
+
 # Quote evaled strings.
-for var in SED \
+for var in AS \
+DLLTOOL \
+OBJDUMP \
+SHELL \
+ECHO \
+PATH_SEPARATOR \
+SED \
 GREP \
 EGREP \
 FGREP \
@@ -16604,8 +19308,12 @@ lt_NL2SP \
 reload_flag \
 deplibs_check_method \
 file_magic_cmd \
+file_magic_glob \
+want_nocaseglob \
+sharedlib_from_linklib_cmd \
 AR \
 AR_FLAGS \
+archiver_list_spec \
 STRIP \
 RANLIB \
 CC \
@@ -16615,14 +19323,14 @@ lt_cv_sys_global_symbol_pipe \
 lt_cv_sys_global_symbol_to_cdecl \
 lt_cv_sys_global_symbol_to_c_name_address \
 lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \
-SHELL \
-ECHO \
+nm_file_list_spec \
 lt_prog_compiler_no_builtin_flag \
-lt_prog_compiler_wl \
 lt_prog_compiler_pic \
+lt_prog_compiler_wl \
 lt_prog_compiler_static \
 lt_cv_prog_compiler_c_o \
 need_locks \
+MANIFEST_TOOL \
 DSYMUTIL \
 NMEDIT \
 LIPO \
@@ -16636,9 +19344,7 @@ with_gnu_ld \
 allow_undefined_flag \
 no_undefined_flag \
 hardcode_libdir_flag_spec \
-hardcode_libdir_flag_spec_ld \
 hardcode_libdir_separator \
-fix_srcfile_path \
 exclude_expsyms \
 include_expsyms \
 file_list_spec \
@@ -16646,14 +19352,16 @@ variables_saved_for_relink \
 libname_spec \
 library_names_spec \
 soname_spec \
+install_override_mode \
 finish_eval \
 old_striplib \
 striplib \
 LD_RC \
+reload_flag_RC \
 compiler_RC \
 lt_prog_compiler_no_builtin_flag_RC \
-lt_prog_compiler_wl_RC \
 lt_prog_compiler_pic_RC \
+lt_prog_compiler_wl_RC \
 lt_prog_compiler_static_RC \
 lt_cv_prog_compiler_c_o_RC \
 export_dynamic_flag_spec_RC \
@@ -16663,15 +19371,13 @@ with_gnu_ld_RC \
 allow_undefined_flag_RC \
 no_undefined_flag_RC \
 hardcode_libdir_flag_spec_RC \
-hardcode_libdir_flag_spec_ld_RC \
 hardcode_libdir_separator_RC \
-fix_srcfile_path_RC \
 exclude_expsyms_RC \
 include_expsyms_RC \
 file_list_spec_RC; do
-    case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
     *[\\\\\\\`\\"\\\$]*)
-      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
       ;;
     *)
       eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -16693,11 +19399,13 @@ module_cmds \
 module_expsym_cmds \
 export_symbols_cmds \
 prelink_cmds \
+postlink_cmds \
 postinstall_cmds \
 postuninstall_cmds \
 finish_cmds \
 sys_lib_search_path_spec \
 sys_lib_dlsearch_path_spec \
+reload_cmds_RC \
 old_archive_cmds_RC \
 old_archive_from_new_cmds_RC \
 old_archive_from_expsyms_cmds_RC \
@@ -16706,10 +19414,11 @@ archive_expsym_cmds_RC \
 module_cmds_RC \
 module_expsym_cmds_RC \
 export_symbols_cmds_RC \
-prelink_cmds_RC; do
-    case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+prelink_cmds_RC \
+postlink_cmds_RC; do
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
     *[\\\\\\\`\\"\\\$]*)
-      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
       ;;
     *)
       eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -16717,12 +19426,6 @@ prelink_cmds_RC; do
     esac
 done
 
-# Fix-up fallback echo if it was mangled by the above quoting rules.
-case \$lt_ECHO in
-*'\\\$0 --fallback-echo"')  lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\`
-  ;;
-esac
-
 ac_aux_dir='$ac_aux_dir'
 xsi_shell='$xsi_shell'
 lt_shell_append='$lt_shell_append'
@@ -16777,8 +19480,9 @@ do
     "src/libgcrypt-config") CONFIG_FILES="$CONFIG_FILES src/libgcrypt-config" ;;
     "src/versioninfo.rc") CONFIG_FILES="$CONFIG_FILES src/versioninfo.rc" ;;
     "tests/Makefile") CONFIG_FILES="$CONFIG_FILES tests/Makefile" ;;
+    "tests/hashtest-256g") CONFIG_FILES="$CONFIG_FILES tests/hashtest-256g" ;;
 
-  *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   esac
 done
 
 # after its creation but before its name has been assigned to `$tmp'.
 $debug ||
 {
-  tmp=
+  tmp= ac_tmp=
   trap 'exit_status=$?
-  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
 ' 0
   trap 'as_fn_exit 1' 1 2 13 15
 }
@@ -16812,12 +19517,13 @@ $debug ||
 
 {
   tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
-  test -n "$tmp" && test -d "$tmp"
+  test -d "$tmp"
 }  ||
 {
   tmp=./conf$$-$RANDOM
   (umask 077 && mkdir "$tmp")
-} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
 
 # Set up the scripts for CONFIG_FILES section.
 # No need to generate them if there are no CONFIG_FILES.
@@ -16834,12 +19540,12 @@ if test "x$ac_cr" = x; then
 fi
 ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
 if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
-  ac_cs_awk_cr='\r'
+  ac_cs_awk_cr='\\r'
 else
   ac_cs_awk_cr=$ac_cr
 fi
 
-echo 'BEGIN {' >"$tmp/subs1.awk" &&
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
 _ACEOF
 
 
@@ -16848,18 +19554,18 @@ _ACEOF
   echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
   echo "_ACEOF"
 } >conf$$subs.sh ||
-  as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
-ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
 ac_delim='%!_!# '
 for ac_last_try in false false false false false :; do
   . ./conf$$subs.sh ||
-    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
 
   ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
   if test $ac_delim_n = $ac_delim_num; then
     break
   elif $ac_last_try; then
-    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
   else
     ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
   fi
@@ -16867,7 +19573,7 @@ done
 rm -f conf$$subs.sh
 
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
 _ACEOF
 sed -n '
 h
@@ -16881,7 +19587,7 @@ s/'"$ac_delim"'$//
 t delim
 :nl
 h
-s/\(.\{148\}\).*/\1/
+s/\(.\{148\}\)..*/\1/
 t more1
 s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
 p
@@ -16895,7 +19601,7 @@ s/.\{148\}//
 t nl
 :delim
 h
-s/\(.\{148\}\).*/\1/
+s/\(.\{148\}\)..*/\1/
 t more2
 s/["\\]/\\&/g; s/^/"/; s/$/"/
 p
@@ -16915,7 +19621,7 @@ t delim
 rm -f conf$$subs.awk
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 _ACAWK
-cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
   for (key in S) S_is_set[key] = 1
   FS = "\a"
 
@@ -16947,21 +19653,29 @@ if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
   sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
 else
   cat
-fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
-  || as_fn_error "could not setup config files machinery" "$LINENO" 5
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
 _ACEOF
 
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
 # trailing colons and then remove the whole line if VPATH becomes empty
 # (actually we leave an empty line to preserve line numbers).
 if test "x$srcdir" = x.; then
-  ac_vpsub='/^[         ]*VPATH[        ]*=/{
-s/:*\$(srcdir):*/:/
-s/:*\${srcdir}:*/:/
-s/:*@srcdir@:*/:/
-s/^\([^=]*=[    ]*\):*/\1/
+  ac_vpsub='/^[         ]*VPATH[        ]*=[    ]*/{
+h
+s///
+s/^/:/
+s/[     ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
 s/:*$//
+x
+s/\(=[  ]*\).*/\1/
+G
+s/\n//
 s/^[^=]*=[      ]*$//
 }'
 fi
@@ -16973,7 +19687,7 @@ fi # test -n "$CONFIG_FILES"
 # No need to generate them if there are no CONFIG_HEADERS.
 # This happens for instance with `./config.status Makefile'.
 if test -n "$CONFIG_HEADERS"; then
-cat >"$tmp/defines.awk" <<\_ACAWK ||
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
 BEGIN {
 _ACEOF
 
@@ -16985,11 +19699,11 @@ _ACEOF
 # handling of long lines.
 ac_delim='%!_!# '
 for ac_last_try in false false :; do
-  ac_t=`sed -n "/$ac_delim/p" confdefs.h`
-  if test -z "$ac_t"; then
+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; then
     break
   elif $ac_last_try; then
-    as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5
+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
   else
     ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
   fi
@@ -17074,7 +19788,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 _ACAWK
 _ACEOF
 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-  as_fn_error "could not setup config headers machinery" "$LINENO" 5
+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
 fi # test -n "$CONFIG_HEADERS"
 
 
@@ -17087,7 +19801,7 @@ do
   esac
   case $ac_mode$ac_tag in
   :[FHL]*:*);;
-  :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
   :[FH]-) ac_tag=-:-;;
   :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
   esac
@@ -17106,7 +19820,7 @@ do
     for ac_f
     do
       case $ac_f in
-      -) ac_f="$tmp/stdin";;
+      -) ac_f="$ac_tmp/stdin";;
       *) # Look for the file first in the build tree, then in the source tree
         # (if the path is not absolute).  The absolute path cannot be DOS-style,
         # because $ac_f cannot contain `:'.
@@ -17115,7 +19829,7 @@ do
           [\\/$]*) false;;
           *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
           esac ||
-          as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+          as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
       esac
       case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
       as_fn_append ac_file_inputs " '$ac_f'"
@@ -17141,8 +19855,8 @@ $as_echo "$as_me: creating $ac_file" >&6;}
     esac
 
     case $ac_tag in
-    *:-:* | *:-) cat >"$tmp/stdin" \
-      || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
     esac
     ;;
   esac
@@ -17278,23 +19992,24 @@ s&@INSTALL@&$ac_INSTALL&;t t
 s&@MKDIR_P@&$ac_MKDIR_P&;t t
 $ac_datarootdir_hack
 "
-eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
-  || as_fn_error "could not create $ac_file" "$LINENO" 5
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
 
 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
-  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
-  { ac_out=`sed -n '/^[         ]*datarootdir[  ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[         ]*datarootdir[  ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined.  Please make sure it is defined." >&5
+which seems to be undefined.  Please make sure it is defined" >&5
 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined.  Please make sure it is defined." >&2;}
+which seems to be undefined.  Please make sure it is defined" >&2;}
 
-  rm -f "$tmp/stdin"
+  rm -f "$ac_tmp/stdin"
   case $ac_file in
-  -) cat "$tmp/out" && rm -f "$tmp/out";;
-  *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
   esac \
-  || as_fn_error "could not create $ac_file" "$LINENO" 5
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
  ;;
   :H)
   #
@@ -17303,21 +20018,21 @@ which seems to be undefined.  Please make sure it is defined." >&2;}
   if test x"$ac_file" != x-; then
     {
       $as_echo "/* $configure_input  */" \
-      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
-    } >"$tmp/config.h" \
-      || as_fn_error "could not create $ac_file" "$LINENO" 5
-    if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
 $as_echo "$as_me: $ac_file is unchanged" >&6;}
     else
       rm -f "$ac_file"
-      mv "$tmp/config.h" "$ac_file" \
-       || as_fn_error "could not create $ac_file" "$LINENO" 5
+      mv "$ac_tmp/config.h" "$ac_file" \
+       || as_fn_error $? "could not create $ac_file" "$LINENO" 5
     fi
   else
     $as_echo "/* $configure_input  */" \
-      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
-      || as_fn_error "could not create -" "$LINENO" 5
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
   fi
 # Compute "$ac_file"'s index in $config_headers.
 _am_arg="$ac_file"
@@ -17371,19 +20086,19 @@ $as_echo X"$_am_arg" |
 $as_echo "$as_me: linking $ac_source to $ac_file" >&6;}
 
     if test ! -r "$ac_source"; then
-      as_fn_error "$ac_source: file not found" "$LINENO" 5
+      as_fn_error $? "$ac_source: file not found" "$LINENO" 5
     fi
     rm -f "$ac_file"
 
     # Try a relative symlink, then a hard link, then a copy.
-    case $srcdir in
+    case $ac_source in
     [\\/$]* | ?:[\\/]* ) ac_rel_source=$ac_source ;;
        *) ac_rel_source=$ac_top_build_prefix$ac_source ;;
     esac
     ln -s "$ac_rel_source" "$ac_file" 2>/dev/null ||
       ln "$ac_source" "$ac_file" 2>/dev/null ||
       cp -p "$ac_source" "$ac_file" ||
-      as_fn_error "cannot link or copy $ac_source to $ac_file" "$LINENO" 5
+      as_fn_error $? "cannot link or copy $ac_source to $ac_file" "$LINENO" 5
   fi
  ;;
   :C)  { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
@@ -17509,7 +20224,8 @@ $as_echo X"$file" |
 # NOTE: Changes made to this file will be lost: look at ltmain.sh.
 #
 #   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
-#                 2006, 2007, 2008 Free Software Foundation, Inc.
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
 #   Written by Gordon Matzigkeit, 1996
 #
 #   This file is part of GNU Libtool.
@@ -17546,13 +20262,13 @@ macro_version=$macro_version
 macro_revision=$macro_revision
 
 # Assembler program.
-AS=$AS
+AS=$lt_AS
 
 # DLL creation program.
-DLLTOOL=$DLLTOOL
+DLLTOOL=$lt_DLLTOOL
 
 # Object dumper program.
-OBJDUMP=$OBJDUMP
+OBJDUMP=$lt_OBJDUMP
 
 # Whether or not to build static libraries.
 build_old_libs=$enable_static
@@ -17566,6 +20282,15 @@ pic_mode=$pic_mode
 # Whether or not to optimize for fast installation.
 fast_install=$enable_fast_install
 
+# Shell to use when invoking shell scripts.
+SHELL=$lt_SHELL
+
+# An echo program that protects backslashes.
+ECHO=$lt_ECHO
+
+# The PATH separator for the build system.
+PATH_SEPARATOR=$lt_PATH_SEPARATOR
+
 # The host system.
 host_alias=$host_alias
 host=$host
@@ -17615,20 +20340,36 @@ SP2NL=$lt_lt_SP2NL
 # turn newlines into spaces.
 NL2SP=$lt_lt_NL2SP
 
-# How to create reloadable object files.
-reload_flag=$lt_reload_flag
-reload_cmds=$lt_reload_cmds
+# convert \$build file names to \$host format.
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+
+# convert \$build files to toolchain format.
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
 
 # Method to check whether dependent libraries are shared objects.
 deplibs_check_method=$lt_deplibs_check_method
 
-# Command to use when deplibs_check_method == "file_magic".
+# Command to use when deplibs_check_method = "file_magic".
 file_magic_cmd=$lt_file_magic_cmd
 
+# How to find potential files when deplibs_check_method = "file_magic".
+file_magic_glob=$lt_file_magic_glob
+
+# Find potential files using nocaseglob when deplibs_check_method = "file_magic".
+want_nocaseglob=$lt_want_nocaseglob
+
+# Command to associate shared and link libraries.
+sharedlib_from_linklib_cmd=$lt_sharedlib_from_linklib_cmd
+
 # The archiver.
 AR=$lt_AR
+
+# Flags to create an archive.
 AR_FLAGS=$lt_AR_FLAGS
 
+# How to feed a file listing to the archiver.
+archiver_list_spec=$lt_archiver_list_spec
+
 # A symbol stripping program.
 STRIP=$lt_STRIP
 
@@ -17637,6 +20378,9 @@ RANLIB=$lt_RANLIB
 old_postinstall_cmds=$lt_old_postinstall_cmds
 old_postuninstall_cmds=$lt_old_postuninstall_cmds
 
+# Whether to use a lock for old archive extraction.
+lock_old_archive_extraction=$lock_old_archive_extraction
+
 # A C compiler.
 LTCC=$lt_CC
 
@@ -17655,14 +20399,14 @@ global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address
 # Transform the output of nm in a C name address pair when lib prefix is needed.
 global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix
 
-# The name of the directory that contains temporary libtool files.
-objdir=$objdir
+# Specify filename containing input files for \$NM.
+nm_file_list_spec=$lt_nm_file_list_spec
 
-# Shell to use when invoking shell scripts.
-SHELL=$lt_SHELL
+# The root where to search for dependent libraries,and in which our libraries should be installed.
+lt_sysroot=$lt_sysroot
 
-# An echo program that does not interpret backslashes.
-ECHO=$lt_ECHO
+# The name of the directory that contains temporary libtool files.
+objdir=$objdir
 
 # Used to examine libraries when file_magic_cmd begins with "file".
 MAGIC_CMD=$MAGIC_CMD
@@ -17670,6 +20414,9 @@ MAGIC_CMD=$MAGIC_CMD
 # Must we lock files when doing compilation?
 need_locks=$lt_need_locks
 
+# Manifest tool.
+MANIFEST_TOOL=$lt_MANIFEST_TOOL
+
 # Tool to manipulate archived DWARF debug symbol files on Mac OS X.
 DSYMUTIL=$lt_DSYMUTIL
 
@@ -17726,6 +20473,9 @@ library_names_spec=$lt_library_names_spec
 # The coded name of the library, if different from the real name.
 soname_spec=$lt_soname_spec
 
+# Permission mode override for installation of shared libraries.
+install_override_mode=$lt_install_override_mode
+
 # Command to use after installation of a shared archive.
 postinstall_cmds=$lt_postinstall_cmds
 
@@ -17765,6 +20515,10 @@ striplib=$lt_striplib
 # The linker used to build libraries.
 LD=$lt_LD
 
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag
+reload_cmds=$lt_reload_cmds
+
 # Commands used to build an old-style archive.
 old_archive_cmds=$lt_old_archive_cmds
 
@@ -17777,12 +20531,12 @@ with_gcc=$GCC
 # Compiler flag to turn off builtin functions.
 no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag
 
-# How to pass a linker flag through the compiler.
-wl=$lt_lt_prog_compiler_wl
-
 # Additional compiler flags for building library objects.
 pic_flag=$lt_lt_prog_compiler_pic
 
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl
+
 # Compiler flag to prevent dynamic linking.
 link_static_flag=$lt_lt_prog_compiler_static
 
@@ -17832,10 +20586,6 @@ no_undefined_flag=$lt_no_undefined_flag
 # This must work even if \$libdir does not exist
 hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec
 
-# If ld is used when linking, flag to hardcode \$libdir into a binary
-# during linking.  This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld
-
 # Whether we need a single "-rpath" flag with a separated argument.
 hardcode_libdir_separator=$lt_hardcode_libdir_separator
 
@@ -17869,9 +20619,6 @@ inherit_rpath=$inherit_rpath
 # Whether libtool must link a program against all its dependency libraries.
 link_all_deplibs=$link_all_deplibs
 
-# Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path=$lt_fix_srcfile_path
-
 # Set to "yes" if exported symbols are required.
 always_export_symbols=$always_export_symbols
 
@@ -17887,6 +20634,9 @@ include_expsyms=$lt_include_expsyms
 # Commands necessary for linking programs (against libraries) with templates.
 prelink_cmds=$lt_prelink_cmds
 
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds
+
 # Specify filename containing input files.
 file_list_spec=$lt_file_list_spec
 
@@ -17919,212 +20669,169 @@ ltmain="$ac_aux_dir/ltmain.sh"
   # if finds mixed CR/LF and LF-only lines.  Since sed operates in
   # text mode, it properly converts lines to CR/LF.  This bash problem
   # is reportedly fixed, but why not run on old versions too?
-  sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
-    || (rm -f "$cfgfile"; exit 1)
-
-  case $xsi_shell in
-  yes)
-    cat << \_LT_EOF >> "$cfgfile"
-
-# func_dirname file append nondir_replacement
-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-func_dirname ()
-{
-  case ${1} in
-    */*) func_dirname_result="${1%/*}${2}" ;;
-    *  ) func_dirname_result="${3}" ;;
-  esac
-}
-
-# func_basename file
-func_basename ()
-{
-  func_basename_result="${1##*/}"
-}
-
-# func_dirname_and_basename file append nondir_replacement
-# perform func_basename and func_dirname in a single function
-# call:
-#   dirname:  Compute the dirname of FILE.  If nonempty,
-#             add APPEND to the result, otherwise set result
-#             to NONDIR_REPLACEMENT.
-#             value returned in "$func_dirname_result"
-#   basename: Compute filename of FILE.
-#             value retuned in "$func_basename_result"
-# Implementation must be kept synchronized with func_dirname
-# and func_basename. For efficiency, we do not delegate to
-# those functions but instead duplicate the functionality here.
-func_dirname_and_basename ()
-{
-  case ${1} in
-    */*) func_dirname_result="${1%/*}${2}" ;;
-    *  ) func_dirname_result="${3}" ;;
-  esac
-  func_basename_result="${1##*/}"
-}
-
-# func_stripname prefix suffix name
-# strip PREFIX and SUFFIX off of NAME.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-func_stripname ()
-{
-  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
-  # positional parameters, so assign one to ordinary parameter first.
-  func_stripname_result=${3}
-  func_stripname_result=${func_stripname_result#"${1}"}
-  func_stripname_result=${func_stripname_result%"${2}"}
-}
-
-# func_opt_split
-func_opt_split ()
-{
-  func_opt_split_opt=${1%%=*}
-  func_opt_split_arg=${1#*=}
-}
-
-# func_lo2o object
-func_lo2o ()
-{
-  case ${1} in
-    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
-    *)    func_lo2o_result=${1} ;;
-  esac
-}
-
-# func_xform libobj-or-source
-func_xform ()
-{
-  func_xform_result=${1%.*}.lo
-}
-
-# func_arith arithmetic-term...
-func_arith ()
-{
-  func_arith_result=$(( $* ))
-}
-
-# func_len string
-# STRING may not start with a hyphen.
-func_len ()
-{
-  func_len_result=${#1}
-}
-
-_LT_EOF
-    ;;
-  *) # Bourne compatible functions.
-    cat << \_LT_EOF >> "$cfgfile"
-
-# func_dirname file append nondir_replacement
-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-func_dirname ()
-{
-  # Extract subdirectory from the argument.
-  func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
-  if test "X$func_dirname_result" = "X${1}"; then
-    func_dirname_result="${3}"
-  else
-    func_dirname_result="$func_dirname_result${2}"
-  fi
-}
-
-# func_basename file
-func_basename ()
-{
-  func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
-}
-
-
-# func_stripname prefix suffix name
-# strip PREFIX and SUFFIX off of NAME.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-# func_strip_suffix prefix name
-func_stripname ()
-{
-  case ${2} in
-    .*) func_stripname_result=`$ECHO "X${3}" \
-           | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
-    *)  func_stripname_result=`$ECHO "X${3}" \
-           | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
-  esac
-}
-
-# sed scripts:
-my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q'
-my_sed_long_arg='1s/^-[^=]*=//'
-
-# func_opt_split
-func_opt_split ()
-{
-  func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
-  func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
-}
-
-# func_lo2o object
-func_lo2o ()
-{
-  func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
-}
-
-# func_xform libobj-or-source
-func_xform ()
-{
-  func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'`
-}
-
-# func_arith arithmetic-term...
-func_arith ()
-{
-  func_arith_result=`expr "$@"`
-}
-
-# func_len string
-# STRING may not start with a hyphen.
-func_len ()
-{
-  func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len`
-}
-
-_LT_EOF
-esac
-
-case $lt_shell_append in
-  yes)
-    cat << \_LT_EOF >> "$cfgfile"
-
-# func_append var value
-# Append VALUE to the end of shell variable VAR.
-func_append ()
-{
-  eval "$1+=\$2"
-}
-_LT_EOF
-    ;;
-  *)
-    cat << \_LT_EOF >> "$cfgfile"
-
-# func_append var value
-# Append VALUE to the end of shell variable VAR.
-func_append ()
-{
-  eval "$1=\$$1\$2"
-}
-
-_LT_EOF
-    ;;
-  esac
-
-
-  sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
-    || (rm -f "$cfgfile"; exit 1)
-
-  mv -f "$cfgfile" "$ofile" ||
+  sed '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
+
+  if test x"$xsi_shell" = xyes; then
+  sed -e '/^func_dirname ()$/,/^} # func_dirname /c\
+func_dirname ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+} # Extended-shell func_dirname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_basename ()$/,/^} # func_basename /c\
+func_basename ()\
+{\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_dirname_and_basename ()$/,/^} # func_dirname_and_basename /c\
+func_dirname_and_basename ()\
+{\
+\    case ${1} in\
+\      */*) func_dirname_result="${1%/*}${2}" ;;\
+\      *  ) func_dirname_result="${3}" ;;\
+\    esac\
+\    func_basename_result="${1##*/}"\
+} # Extended-shell func_dirname_and_basename implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_stripname ()$/,/^} # func_stripname /c\
+func_stripname ()\
+{\
+\    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are\
+\    # positional parameters, so assign one to ordinary parameter first.\
+\    func_stripname_result=${3}\
+\    func_stripname_result=${func_stripname_result#"${1}"}\
+\    func_stripname_result=${func_stripname_result%"${2}"}\
+} # Extended-shell func_stripname implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_long_opt ()$/,/^} # func_split_long_opt /c\
+func_split_long_opt ()\
+{\
+\    func_split_long_opt_name=${1%%=*}\
+\    func_split_long_opt_arg=${1#*=}\
+} # Extended-shell func_split_long_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_split_short_opt ()$/,/^} # func_split_short_opt /c\
+func_split_short_opt ()\
+{\
+\    func_split_short_opt_arg=${1#??}\
+\    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}\
+} # Extended-shell func_split_short_opt implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_lo2o ()$/,/^} # func_lo2o /c\
+func_lo2o ()\
+{\
+\    case ${1} in\
+\      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;\
+\      *)    func_lo2o_result=${1} ;;\
+\    esac\
+} # Extended-shell func_lo2o implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_xform ()$/,/^} # func_xform /c\
+func_xform ()\
+{\
+    func_xform_result=${1%.*}.lo\
+} # Extended-shell func_xform implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_arith ()$/,/^} # func_arith /c\
+func_arith ()\
+{\
+    func_arith_result=$(( $* ))\
+} # Extended-shell func_arith implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_len ()$/,/^} # func_len /c\
+func_len ()\
+{\
+    func_len_result=${#1}\
+} # Extended-shell func_len implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+fi
+
+if test x"$lt_shell_append" = xyes; then
+  sed -e '/^func_append ()$/,/^} # func_append /c\
+func_append ()\
+{\
+    eval "${1}+=\\${2}"\
+} # Extended-shell func_append implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  sed -e '/^func_append_quoted ()$/,/^} # func_append_quoted /c\
+func_append_quoted ()\
+{\
+\    func_quote_for_eval "${2}"\
+\    eval "${1}+=\\\\ \\$func_quote_for_eval_result"\
+} # Extended-shell func_append_quoted implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+
+
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([a-zA-Z_]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
+
+if test x"$_lt_function_replace_fail" = x":"; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Unable to substitute extended shell functions in $ofile" >&5
+$as_echo "$as_me: WARNING: Unable to substitute extended shell functions in $ofile" >&2;}
+fi
+
+
+   mv -f "$cfgfile" "$ofile" ||
     (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
   chmod +x "$ofile"
 
@@ -18136,6 +20843,10 @@ _LT_EOF
 # The linker used to build libraries.
 LD=$lt_LD_RC
 
+# How to create reloadable object files.
+reload_flag=$lt_reload_flag_RC
+reload_cmds=$lt_reload_cmds_RC
+
 # Commands used to build an old-style archive.
 old_archive_cmds=$lt_old_archive_cmds_RC
 
@@ -18148,12 +20859,12 @@ with_gcc=$GCC_RC
 # Compiler flag to turn off builtin functions.
 no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag_RC
 
-# How to pass a linker flag through the compiler.
-wl=$lt_lt_prog_compiler_wl_RC
-
 # Additional compiler flags for building library objects.
 pic_flag=$lt_lt_prog_compiler_pic_RC
 
+# How to pass a linker flag through the compiler.
+wl=$lt_lt_prog_compiler_wl_RC
+
 # Compiler flag to prevent dynamic linking.
 link_static_flag=$lt_lt_prog_compiler_static_RC
 
@@ -18203,10 +20914,6 @@ no_undefined_flag=$lt_no_undefined_flag_RC
 # This must work even if \$libdir does not exist
 hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec_RC
 
-# If ld is used when linking, flag to hardcode \$libdir into a binary
-# during linking.  This must work even if \$libdir does not exist.
-hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld_RC
-
 # Whether we need a single "-rpath" flag with a separated argument.
 hardcode_libdir_separator=$lt_hardcode_libdir_separator_RC
 
@@ -18240,9 +20947,6 @@ inherit_rpath=$inherit_rpath_RC
 # Whether libtool must link a program against all its dependency libraries.
 link_all_deplibs=$link_all_deplibs_RC
 
-# Fix the shell variable \$srcfile for the compiler.
-fix_srcfile_path=$lt_fix_srcfile_path_RC
-
 # Set to "yes" if exported symbols are required.
 always_export_symbols=$always_export_symbols_RC
 
@@ -18258,6 +20962,9 @@ include_expsyms=$lt_include_expsyms_RC
 # Commands necessary for linking programs (against libraries) with templates.
 prelink_cmds=$lt_prelink_cmds_RC
 
+# Commands necessary for finishing linking programs.
+postlink_cmds=$lt_postlink_cmds_RC
+
 # Specify filename containing input files.
 file_list_spec=$lt_file_list_spec_RC
 
@@ -18271,6 +20978,7 @@ _LT_EOF
     "gcrypt-conf":C)
 chmod +x src/libgcrypt-config
  ;;
+    "tests/hashtest-256g":F) chmod +x tests/hashtest-256g ;;
 
   esac
 done # for ac_tag
@@ -18281,7 +20989,7 @@ _ACEOF
 ac_clean_files=$ac_clean_files_save
 
 test $ac_write_fail = 0 ||
-  as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
 
 
 # configure is writing to config.log, and then calls config.status.
@@ -18302,7 +21010,7 @@ if test "$no_create" != yes; then
   exec 5>>config.log
   # Use ||, not &&, to avoid exiting from the if with $? = 1, which
   # would make configure fail if this is the last instruction.
-  $ac_cs_success || as_fn_exit $?
+  $ac_cs_success || as_fn_exit 1
 fi
 if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
@@ -18310,19 +21018,140 @@ $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
 fi
 
 
+
+detection_module="${GCRYPT_HWF_MODULES%.lo}"
+test -n "$detection_module" || detection_module="none"
+
 # Give some feedback
-echo "
-        Libgcrypt v${VERSION} has been configured as follows:
-
-        Platform:                  $PRINTABLE_OS_NAME ($host)
-        Enabled cipher algorithms: $enabled_ciphers
-        Enabled digest algorithms: $enabled_digests
-        Enabled pubkey algorithms: $enabled_pubkey_ciphers
-        Random number generator:   $random
-        Using linux capabilities:  $use_capabilities
-        Try using Padlock crypto:  $padlocksupport
-        Try using AES-NI crypto:   $aesnisupport
-"
+
+     echo "         " 1>&6
+
+
+     echo "        Libgcrypt v${VERSION} has been configured as follows:" 1>&6
+
+
+     echo "         " 1>&6
+
+
+     echo "        Platform:                  $PRINTABLE_OS_NAME ($host)" 1>&6
+
+
+     echo "        Hardware detection module: $detection_module" 1>&6
+
+
+    tmp="        Enabled cipher algorithms:"
+    tmpi="abc"
+    if test "${#tmpi}" -ne 3 >/dev/null 2>&1 ; then
+            echo "$tmp $enabled_ciphers" 1>&6
+    else
+      tmpi=`echo "$tmp"| sed 's/./ /g'`
+      echo $enabled_ciphers EOF | tr ' ' '\n' | \
+        while read word; do
+          if test "${#tmp}" -gt 70 ; then
+            echo "$tmp" 1>&6
+            tmp="$tmpi"
+          fi
+          if test "$word" = "EOF" ; then
+            echo "$tmp" 1>&6
+          else
+            tmp="$tmp $word"
+          fi
+        done
+    fi
+
+
+    tmp="        Enabled digest algorithms:"
+    tmpi="abc"
+    if test "${#tmpi}" -ne 3 >/dev/null 2>&1 ; then
+            echo "$tmp $enabled_digests" 1>&6
+    else
+      tmpi=`echo "$tmp"| sed 's/./ /g'`
+      echo $enabled_digests EOF | tr ' ' '\n' | \
+        while read word; do
+          if test "${#tmp}" -gt 70 ; then
+            echo "$tmp" 1>&6
+            tmp="$tmpi"
+          fi
+          if test "$word" = "EOF" ; then
+            echo "$tmp" 1>&6
+          else
+            tmp="$tmp $word"
+          fi
+        done
+    fi
+
+
+    tmp="        Enabled kdf algorithms:   "
+    tmpi="abc"
+    if test "${#tmpi}" -ne 3 >/dev/null 2>&1 ; then
+            echo "$tmp $enabled_kdfs" 1>&6
+    else
+      tmpi=`echo "$tmp"| sed 's/./ /g'`
+      echo $enabled_kdfs EOF | tr ' ' '\n' | \
+        while read word; do
+          if test "${#tmp}" -gt 70 ; then
+            echo "$tmp" 1>&6
+            tmp="$tmpi"
+          fi
+          if test "$word" = "EOF" ; then
+            echo "$tmp" 1>&6
+          else
+            tmp="$tmp $word"
+          fi
+        done
+    fi
+
+
+    tmp="        Enabled pubkey algorithms:"
+    tmpi="abc"
+    if test "${#tmpi}" -ne 3 >/dev/null 2>&1 ; then
+            echo "$tmp $enabled_pubkey_ciphers" 1>&6
+    else
+      tmpi=`echo "$tmp"| sed 's/./ /g'`
+      echo $enabled_pubkey_ciphers EOF | tr ' ' '\n' | \
+        while read word; do
+          if test "${#tmp}" -gt 70 ; then
+            echo "$tmp" 1>&6
+            tmp="$tmpi"
+          fi
+          if test "$word" = "EOF" ; then
+            echo "$tmp" 1>&6
+          else
+            tmp="$tmp $word"
+          fi
+        done
+    fi
+
+
+     echo "        Random number generator:   $random" 1>&6
+
+
+     echo "        Using linux capabilities:  $use_capabilities" 1>&6
+
+
+     echo "        Try using Padlock crypto:  $padlocksupport" 1>&6
+
+
+     echo "        Try using AES-NI crypto:   $aesnisupport" 1>&6
+
+
+     echo "        Try using Intel PCLMUL:    $pclmulsupport" 1>&6
+
+
+     echo "        Try using DRNG (RDRAND):   $drngsupport" 1>&6
+
+
+     echo "        Try using Intel AVX:       $avxsupport" 1>&6
+
+
+     echo "        Try using Intel AVX2:      $avx2support" 1>&6
+
+
+     echo "        Try using ARM NEON:        $neonsupport" 1>&6
+
+
+     echo "         " 1>&6
+
 
 if test "$print_egd_notice" = "yes"; then
 cat <<G10EOF
@@ -18344,6 +21173,15 @@ cat <<G10EOF
 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.
+
+G10EOF
+fi
+
 if test -n "$gpl"; then
   echo "Please note that you are building a version of Libgcrypt with"
   echo "  $gpl"
index 75e5a52..dfbccb7 100644 (file)
@@ -1,6 +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
 #
 # This file is part of Libgcrypt.
 #
@@ -22,48 +23,64 @@ AC_REVISION($Revision$)
 AC_PREREQ(2.60)
 min_automake_version="1.10"
 
+# 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
+# bump the version number immediately after the release and do another
+# 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, [1])
+
+# Below is m4 magic to extract and compute the revision number, the
+# decimalized short revision number, a beta version string, and a flag
+# indicating a development version (mym4_isgit). Note that the m4
+# processing is done by autoconf and not during the configure run.
+m4_define(mym4_version,
+          [mym4_version_major.mym4_version_minor.mym4_version_micro])
+m4_define([mym4_revision],
+          m4_esyscmd([git rev-parse --short HEAD | tr -d '\n\r']))
+m4_define([mym4_revision_dec],
+          m4_esyscmd_s([echo $((0x$(echo ]mym4_revision[|head -c 4)))]))
+m4_define([mym4_betastring],
+          m4_esyscmd_s([git describe --match 'libgcrypt-[0-9].*[0-9]' --long|\
+                        awk -F- '$3!=0{print"-beta"$3}']))
+m4_define([mym4_isgit],m4_if(mym4_betastring,[],[no],[yes]))
+m4_define([mym4_full_version],[mym4_version[]mym4_betastring])
+
+AC_INIT([libgcrypt],[mym4_full_version],[http://bugs.gnupg.org])
 
-# Remember to change the version number immediately *after* a release.
-# Set my_issvn to "yes" for non-released code.  Remember to run an
-# "svn up" and "autogen.sh" right before creating a distribution.
-m4_define([my_version], [1.5.0])
-m4_define([my_issvn], [no])
-
-m4_define([svn_revision], m4_esyscmd([printf "%d" $(svn info 2>/dev/null \
-          | sed -n '/^Revision:/ s/[^0-9]//gp'|head -1)]))
-m4_define([git_revision], m4_esyscmd([git branch -v 2>/dev/null \
-          | awk '/^\* / {printf "%s",$3}']))
-AC_INIT([libgcrypt],
-        [my_version[]m4_if(my_issvn,[yes],
-        [m4_if(git_revision,[],[-svn[]svn_revision],[-git[]git_revision])])],
-        [bug-libgcrypt@gnupg.org])
 # LT Version numbers, remember to change them just *before* a release.
 #   (Interfaces removed:    CURRENT++, AGE=0, REVISION=0)
 #   (Interfaces added:      CURRENT++, AGE++, REVISION=0)
 #   (No interfaces changed:                   REVISION++)
-LIBGCRYPT_LT_CURRENT=18
-LIBGCRYPT_LT_AGE=7
-LIBGCRYPT_LT_REVISION=0
+LIBGCRYPT_LT_CURRENT=20
+LIBGCRYPT_LT_AGE=0
+LIBGCRYPT_LT_REVISION=1
 
 
 # If the API is changed in an incompatible way: increment the next counter.
+#
+# 1.6: ABI and API change but the change is to most users irrelevant
+#      and thus the API version number has not been incremented.
 LIBGCRYPT_CONFIG_API_VERSION=1
 
-NEED_GPG_ERROR_VERSION=1.8
+# 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
 
-is_development_version=my_issvn
-m4_define([git_brevis],m4_esyscmd(printf "%u" 0x[]m4_substr(git_revision,0,4)))
-BUILD_REVISION=m4_if(git_revision,[],[svn_revision],[git_brevis])
 PACKAGE=$PACKAGE_NAME
 VERSION=$PACKAGE_VERSION
 
+AC_CONFIG_AUX_DIR([build-aux])
 AC_CONFIG_SRCDIR([src/libgcrypt.vers])
-AM_INIT_AUTOMAKE([])
-AM_CONFIG_HEADER(config.h)
+AM_INIT_AUTOMAKE
+AC_CONFIG_HEADER(config.h)
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_LIBOBJ_DIR([compat])
 AC_CANONICAL_HOST
 AM_MAINTAINER_MODE
+AM_SILENT_RULES
 
 AH_TOP([
 #ifndef _GCRYPT_CONFIG_H_INCLUDED
@@ -92,11 +109,6 @@ AH_BOTTOM([
    properly prefixed.  */
 #define CAMELLIA_EXT_SYM_PREFIX _gcry_
 
-/* This error code is only available with gpg-error 1.7.  Thus
-   we define it here with the usual gcry prefix.  */
-#define GCRY_GPG_ERR_NOT_OPERATIONAL  176
-
-
 #endif /*_GCRYPT_CONFIG_H_INCLUDED*/
 ])
 
@@ -116,6 +128,9 @@ AC_SUBST(PACKAGE)
 AC_SUBST(VERSION)
 AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of this package])
 AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version of this package])
+VERSION_NUMBER=m4_esyscmd(printf "0x%02x%02x%02x" mym4_version_major \
+                          mym4_version_minor mym4_version_micro)
+AC_SUBST(VERSION_NUMBER)
 
 
 ######################
@@ -139,6 +154,21 @@ AC_PROG_AWK
 
 AC_GNU_SOURCE
 
+# We need to compile and run a program on the build machine.  A
+# comment in libgpg-error says that the AC_PROG_CC_FOR_BUILD macro in
+# the AC archive is broken for autoconf 2.57.  Given that there is no
+# newer version of that macro, we assume that it is also broken for
+# autoconf 2.61 and thus we use a simple but usually sufficient
+# approach.
+AC_MSG_CHECKING(for cc for build)
+if test "$cross_compiling" = "yes"; then
+  CC_FOR_BUILD="${CC_FOR_BUILD-cc}"
+else
+  CC_FOR_BUILD="${CC_FOR_BUILD-$CC}"
+fi
+AC_MSG_RESULT($CC_FOR_BUILD)
+AC_ARG_VAR(CC_FOR_BUILD,[build system C compiler])
+
 
 LT_PREREQ([2.2.6])
 LT_INIT([win32-dll disable-static])
@@ -156,7 +186,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"
+available_ciphers="$available_ciphers camellia idea salsa20 gost28147"
 enabled_ciphers=""
 
 # Definitions for public-key ciphers.
@@ -164,10 +194,15 @@ available_pubkey_ciphers="dsa elgamal rsa ecc"
 enabled_pubkey_ciphers=""
 
 # Definitions for message digests.
-available_digests="crc md4 md5 rmd160 sha1 sha256"
-available_digests_64="sha512 tiger whirlpool"
+available_digests="crc gostr3411-94 md4 md5 rmd160 sha1 sha256"
+available_digests_64="sha512 tiger whirlpool stribog"
 enabled_digests=""
 
+# Definitions for kdfs (optional ones)
+available_kdfs="s2k pkdf2"
+available_kdfs_64="scrypt"
+enabled_kdfs=""
+
 # Definitions for random modules.
 available_random_modules="linux egd unix"
 auto_random_modules="$available_random_modules"
@@ -179,6 +214,8 @@ LIBGCRYPT_THREAD_MODULES=""
 print_egd_notice=no
 have_w32_system=no
 have_w32ce_system=no
+have_pthread=no
+
 
 # Setup some stuff depending on host.
 case "${host}" in
@@ -218,12 +255,6 @@ case "${host}" in
         AC_DEFINE(HAVE_DOSISH_SYSTEM)
         ;;
 
-    *-*-freebsd*)
-       # FreeBSD
-       CPPFLAGS="$CPPFLAGS -I/usr/local/include"
-       LDFLAGS="$LDFLAGS -L/usr/local/lib"
-       ;;
-
     *-*-hpux*)
         if test -z "$GCC" ; then
             CFLAGS="$CFLAGS -Ae -D_HPUX_SOURCE"
@@ -324,9 +355,11 @@ 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, SHA-384, and SHA-512])
+    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"
 fi
 
 # If not specified otherwise, all available algorithms will be
@@ -334,6 +367,7 @@ fi
 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.
 AC_SUBST(emacs_local_vars_begin, ['Local Variables:'])
@@ -404,6 +438,26 @@ for digest in $enabled_digests; do
 done
 AC_MSG_RESULT([$enabled_digests])
 
+# Implementation of the --enable-kdfs switch.
+AC_ARG_ENABLE(kdfs,
+      AC_HELP_STRING([--enable-kfds=kdfs],
+                    [select the KDFs to include]),
+      [enabled_kdfs=`echo $enableval | tr ',:' '  ' | tr '[A-Z]' '[a-z]'`],
+      [enabled_kdfs=""])
+if test "x$enabled_kdfs" = "x" \
+   -o "$enabled_kdfs" = "yes"  \
+   -o "$enabled_kdfs" = "no"; then
+   enabled_kdfs=$default_kdfs
+fi
+AC_MSG_CHECKING([which key derivation functions to include])
+for kdf in $enabled_kdfs; do
+    LIST_MEMBER($kdf, $available_kdfs)
+    if test "$found" = "0"; then
+       AC_MSG_ERROR([unsupported key derivation function specified])
+    fi
+done
+AC_MSG_RESULT([$enabled_kdfs])
+
 # Implementation of the --enable-random switch.
 AC_ARG_ENABLE(random,
              AC_HELP_STRING([--enable-random=name],
@@ -472,6 +526,16 @@ if test "$use_m_guard" = yes ; then
     AC_DEFINE(M_GUARD,1,[Define to use the (obsolete) malloc guarding feature])
 fi
 
+# Implementation of the --enable-large-data-tests switch.
+AC_MSG_CHECKING([whether to run large data tests])
+AC_ARG_ENABLE(large-data-tests,
+              AC_HELP_STRING([--enable-large-data-tests],
+                 [Enable the real long ruinning large data tests]),
+             large_data_tests=$enableval,large_data_tests=no)
+AC_MSG_RESULT($large_data_tests)
+AC_SUBST(RUN_LARGE_DATA_TESTS, $large_data_tests)
+
+
 # Implementation of the --with-capabilities switch.
 # Check whether we want to use Linux capabilities
 AC_MSG_CHECKING([whether use of capabilities is requested])
@@ -502,10 +566,6 @@ AC_ARG_ENABLE(padlock-support,
                         [Disable support for the PadLock Engine of VIA processors]),
              padlocksupport=$enableval,padlocksupport=yes)
 AC_MSG_RESULT($padlocksupport)
-if test x"$padlocksupport" = xyes ; then
-  AC_DEFINE(ENABLE_PADLOCK_SUPPORT, 1,
-            [Enable support for the PadLock engine.])
-fi
 
 # Implementation of the --disable-aesni-support switch.
 AC_MSG_CHECKING([whether AESNI support is requested])
@@ -514,10 +574,46 @@ AC_ARG_ENABLE(aesni-support,
                  [Disable support for the Intel AES-NI instructions]),
              aesnisupport=$enableval,aesnisupport=yes)
 AC_MSG_RESULT($aesnisupport)
-if test x"$aesnisupport" = xyes ; then
-  AC_DEFINE(ENABLE_AESNI_SUPPORT, 1,
-            [Enable support for Intel AES-NI instructions.])
-fi
+
+# Implementation of the --disable-pclmul-support switch.
+AC_MSG_CHECKING([whether PCLMUL support is requested])
+AC_ARG_ENABLE(pclmul-support,
+              AC_HELP_STRING([--disable-pclmul-support],
+                 [Disable support for the Intel PCLMUL instructions]),
+             pclmulsupport=$enableval,pclmulsupport=yes)
+AC_MSG_RESULT($pclmulsupport)
+
+# Implementation of the --disable-drng-support switch.
+AC_MSG_CHECKING([whether DRNG support is requested])
+AC_ARG_ENABLE(drng-support,
+              AC_HELP_STRING([--disable-drng-support],
+                 [Disable support for the Intel DRNG (RDRAND instruction)]),
+             drngsupport=$enableval,drngsupport=yes)
+AC_MSG_RESULT($drngsupport)
+
+# Implementation of the --disable-avx-support switch.
+AC_MSG_CHECKING([whether AVX support is requested])
+AC_ARG_ENABLE(avx-support,
+              AC_HELP_STRING([--disable-avx-support],
+                 [Disable support for the Intel AVX instructions]),
+             avxsupport=$enableval,avxsupport=yes)
+AC_MSG_RESULT($avxsupport)
+
+# Implementation of the --disable-avx2-support switch.
+AC_MSG_CHECKING([whether AVX2 support is requested])
+AC_ARG_ENABLE(avx2-support,
+              AC_HELP_STRING([--disable-avx2-support],
+                 [Disable support for the Intel AVX2 instructions]),
+             avx2support=$enableval,avx2support=yes)
+AC_MSG_RESULT($avx2support)
+
+# Implementation of the --disable-neon-support switch.
+AC_MSG_CHECKING([whether NEON support is requested])
+AC_ARG_ENABLE(neon-support,
+              AC_HELP_STRING([--disable-neon-support],
+                 [Disable support for the ARM NEON instructions]),
+             neonsupport=$enableval,neonsupport=yes)
+AC_MSG_RESULT($neonsupport)
 
 # Implementation of the --disable-O-flag-munging switch.
 AC_MSG_CHECKING([whether a -O flag munging is requested])
@@ -529,6 +625,14 @@ AC_ARG_ENABLE([O-flag-munging],
 AC_MSG_RESULT($enable_o_flag_munging)
 AM_CONDITIONAL(ENABLE_O_FLAG_MUNGING, test "$enable_o_flag_munging" = "yes")
 
+# Implementation of the --disable-amd64-as-feature-detection switch.
+AC_MSG_CHECKING([whether to enable AMD64 as(1) feature detection])
+AC_ARG_ENABLE(amd64-as-feature-detection,
+              AC_HELP_STRING([--disable-amd64-as-feature-detection],
+                 [Disable the auto-detection of AMD64 as(1) features]),
+             amd64_as_feature_detection=$enableval,
+              amd64_as_feature_detection=yes)
+AC_MSG_RESULT($amd64_as_feature_detection)
 
 
 AC_DEFINE_UNQUOTED(PRINTABLE_OS_NAME, "$PRINTABLE_OS_NAME",
@@ -614,6 +718,27 @@ AC_SUBST(PTH_CFLAGS)
 AC_SUBST(PTH_LIBS)
 
 
+#
+# See which thread system we have
+#
+# 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
+fi
+
+
 # Solaris needs -lsocket and -lnsl. Unisys system includes
 # gethostbyname in libsocket but needs libnsl for socket.
 AC_SEARCH_LIBS(setsockopt, [socket], ,
@@ -667,6 +792,54 @@ case "${host}" in
 esac
 AC_SUBST(FALLBACK_SOCKLEN_T)
 
+
+#
+# Check for __builtin_bswap32 intrinsic.
+#
+AC_CACHE_CHECK(for __builtin_bswap32,
+       [gcry_cv_have_builtin_bswap32],
+       [gcry_cv_have_builtin_bswap32=no
+        AC_LINK_IFELSE([AC_LANG_PROGRAM([],
+          [int x = 0; int y = __builtin_bswap32(x); return y;])],
+          [gcry_cv_have_builtin_bswap32=yes])])
+if test "$gcry_cv_have_builtin_bswap32" = "yes" ; then
+   AC_DEFINE(HAVE_BUILTIN_BSWAP32,1,
+             [Defined if compiler has '__builtin_bswap32' intrinsic])
+fi
+
+
+#
+# Check for __builtin_bswap64 intrinsic.
+#
+AC_CACHE_CHECK(for __builtin_bswap64,
+       [gcry_cv_have_builtin_bswap64],
+       [gcry_cv_have_builtin_bswap64=no
+        AC_LINK_IFELSE([AC_LANG_PROGRAM([],
+          [long long x = 0; long long y = __builtin_bswap64(x); return y;])],
+          [gcry_cv_have_builtin_bswap64=yes])])
+if test "$gcry_cv_have_builtin_bswap64" = "yes" ; then
+   AC_DEFINE(HAVE_BUILTIN_BSWAP64,1,
+             [Defined if compiler has '__builtin_bswap64' intrinsic])
+fi
+
+
+#
+# Check for VLA support (variable length arrays).
+#
+AC_CACHE_CHECK(whether the variable length arrays are supported,
+       [gcry_cv_have_vla],
+       [gcry_cv_have_vla=no
+        AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[void f1(char *, int);
+            char foo(int i) {
+              char b[(i < 0 ? 0 : i) + 1];
+              f1(b, sizeof b); return b[0];}]])],
+          [gcry_cv_have_vla=yes])])
+if test "$gcry_cv_have_vla" = "yes" ; then
+   AC_DEFINE(HAVE_VLA,1, [Defined if variable length arrays are supported])
+fi
+
+
 #
 # Check for ELF visibility support.
 #
@@ -735,7 +908,7 @@ if test "$gcry_cv_visibility_attribute" = "yes"; then
        [gcry_cv_gcc_has_f_visibility=no
         _gcc_cflags_save=$CFLAGS
         CFLAGS="-fvisibility=hidden"
-        AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]),
+        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],
                           gcry_cv_gcc_has_f_visibility=yes)
         CFLAGS=$_gcc_cflags_save;
        ])
@@ -751,6 +924,402 @@ if test "$gcry_cv_visibility_attribute" = "yes" \
 fi
 
 
+#
+# Check whether the compiler supports the GCC style aligned attribute
+#
+AC_CACHE_CHECK([whether the GCC style aligned attribute is supported],
+       [gcry_cv_gcc_attribute_aligned],
+       [gcry_cv_gcc_attribute_aligned=no
+        AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[struct { int a; } foo __attribute__ ((aligned (16)));]])],
+          [gcry_cv_gcc_attribute_aligned=yes])])
+if test "$gcry_cv_gcc_attribute_aligned" = "yes" ; then
+   AC_DEFINE(HAVE_GCC_ATTRIBUTE_ALIGNED,1,
+     [Defined if a GCC style "__attribute__ ((aligned (n))" is supported])
+fi
+
+
+#
+# Check whether the compiler supports 'asm' or '__asm__' keyword for
+# assembler blocks.
+#
+AC_CACHE_CHECK([whether 'asm' assembler keyword is supported],
+       [gcry_cv_have_asm],
+       [gcry_cv_have_asm=no
+        AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[void a(void) { asm("":::"memory"); }]])],
+          [gcry_cv_have_asm=yes])])
+AC_CACHE_CHECK([whether '__asm__' assembler keyword is supported],
+       [gcry_cv_have___asm__],
+       [gcry_cv_have___asm__=no
+        AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[void a(void) { __asm__("":::"memory"); }]])],
+          [gcry_cv_have___asm__=yes])])
+if test "$gcry_cv_have_asm" = "no" ; then
+   if test "$gcry_cv_have___asm__" = "yes" ; then
+      AC_DEFINE(asm,__asm__,
+        [Define to supported assembler block keyword, if plain 'asm' was not
+         supported])
+   fi
+fi
+
+
+#
+# Check whether the compiler supports inline assembly memory barrier.
+#
+if test "$gcry_cv_have_asm" = "no" ; then
+   if test "$gcry_cv_have___asm__" = "yes" ; then
+      AC_CACHE_CHECK([whether inline assembly memory barrier is supported],
+          [gcry_cv_have_asm_volatile_memory],
+          [gcry_cv_have_asm_volatile_memory=no
+           AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+             [[void a(void) { __asm__ volatile("":::"memory"); }]])],
+             [gcry_cv_have_asm_volatile_memory=yes])])
+   fi
+else
+   AC_CACHE_CHECK([whether inline assembly memory barrier is supported],
+       [gcry_cv_have_asm_volatile_memory],
+       [gcry_cv_have_asm_volatile_memory=no
+        AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[void a(void) { asm volatile("":::"memory"); }]])],
+          [gcry_cv_have_asm_volatile_memory=yes])])
+fi
+if test "$gcry_cv_have_asm_volatile_memory" = "yes" ; then
+   AC_DEFINE(HAVE_GCC_ASM_VOLATILE_MEMORY,1,
+     [Define if inline asm memory barrier is supported])
+fi
+
+
+#
+# Check whether GCC assembler supports features needed for our ARM
+# implementations.  This needs to be done before setting up the
+# assembler stuff.
+#
+AC_CACHE_CHECK([whether GCC assembler is compatible for ARM assembly implementations],
+       [gcry_cv_gcc_arm_platform_as_ok],
+       [gcry_cv_gcc_arm_platform_as_ok=no
+        AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[__asm__(
+                /* Test if assembler supports UAL syntax.  */
+                ".syntax unified\n\t"
+                ".arm\n\t" /* our assembly code is in ARM mode  */
+                /* Following causes error if assembler ignored '.syntax unified'.  */
+                "asmfunc:\n\t"
+                "add %r0, %r0, %r4, ror #12;\n\t"
+
+                /* Test if '.type' and '.size' are supported.  */
+                ".size asmfunc,.-asmfunc;\n\t"
+                ".type asmfunc,%function;\n\t"
+            );]])],
+          [gcry_cv_gcc_arm_platform_as_ok=yes])])
+if test "$gcry_cv_gcc_arm_platform_as_ok" = "yes" ; then
+   AC_DEFINE(HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS,1,
+     [Defined if underlying assembler is compatible with ARM assembly implementations])
+fi
+
+
+#
+# Check whether underscores in symbols are required.  This needs to be
+# done before setting up the assembler stuff.
+#
+GNUPG_SYS_SYMBOL_UNDERSCORE()
+
+
+#################################
+####                         ####
+#### Setup assembler stuff.  ####
+#### Define mpi_cpu_arch.    ####
+####                         ####
+#################################
+AC_ARG_ENABLE(mpi-path,
+              AC_HELP_STRING([--enable-mpi-path=EXTRA_PATH],
+             [prepend EXTRA_PATH to list of CPU specific optimizations]),
+             mpi_extra_path="$enableval",mpi_extra_path="")
+AC_MSG_CHECKING(architecture and mpi assembler functions)
+if test -f $srcdir/mpi/config.links ; then
+    . $srcdir/mpi/config.links
+    AC_CONFIG_LINKS("$mpi_ln_list")
+    ac_cv_mpi_sflags="$mpi_sflags"
+    AC_MSG_RESULT($mpi_cpu_arch)
+else
+    AC_MSG_RESULT(failed)
+    AC_MSG_ERROR([mpi/config.links missing!])
+fi
+MPI_SFLAGS="$ac_cv_mpi_sflags"
+AC_SUBST(MPI_SFLAGS)
+
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_ADD1, test "$mpi_mod_asm_mpih_add1" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_SUB1, test "$mpi_mod_asm_mpih_sub1" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_MUL1, test "$mpi_mod_asm_mpih_mul1" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_MUL2, test "$mpi_mod_asm_mpih_mul2" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_MUL3, test "$mpi_mod_asm_mpih_mul3" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_LSHIFT, test "$mpi_mod_asm_mpih_lshift" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_MPIH_RSHIFT, test "$mpi_mod_asm_mpih_rshift" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_UDIV, test "$mpi_mod_asm_udiv" = yes)
+AM_CONDITIONAL(MPI_MOD_ASM_UDIV_QRNND, test "$mpi_mod_asm_udiv_qrnnd" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_ADD1, test "$mpi_mod_c_mpih_add1" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_SUB1, test "$mpi_mod_c_mpih_sub1" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_MUL1, test "$mpi_mod_c_mpih_mul1" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_MUL2, test "$mpi_mod_c_mpih_mul2" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_MUL3, test "$mpi_mod_c_mpih_mul3" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_LSHIFT, test "$mpi_mod_c_mpih_lshift" = yes)
+AM_CONDITIONAL(MPI_MOD_C_MPIH_RSHIFT, test "$mpi_mod_c_mpih_rshift" = yes)
+AM_CONDITIONAL(MPI_MOD_C_UDIV, test "$mpi_mod_c_udiv" = yes)
+AM_CONDITIONAL(MPI_MOD_C_UDIV_QRNND, test "$mpi_mod_c_udiv_qrnnd" = yes)
+
+# 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
+
+if test "$mpi_cpu_arch" != "arm" ; then
+   neonsupport="n/a"
+fi
+
+
+#############################################
+####                                     ####
+#### Platform specific compiler checks.  ####
+####                                     ####
+#############################################
+
+#
+# Check whether GCC inline assembler supports SSSE3 instructions
+# This is required for the AES-NI instructions.
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports SSSE3 instructions],
+       [gcry_cv_gcc_inline_asm_ssse3],
+       [if test "$mpi_cpu_arch" != "x86" ; then
+          gcry_cv_gcc_inline_asm_ssse3="n/a"
+        else
+          gcry_cv_gcc_inline_asm_ssse3=no
+          AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[static unsigned char be_mask[16] __attribute__ ((aligned (16))) =
+              { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+            void a(void) {
+              __asm__("pshufb %[mask], %%xmm2\n\t"::[mask]"m"(*be_mask):);
+            }]])],
+          [gcry_cv_gcc_inline_asm_ssse3=yes])
+        fi])
+if test "$gcry_cv_gcc_inline_asm_ssse3" = "yes" ; then
+   AC_DEFINE(HAVE_GCC_INLINE_ASM_SSSE3,1,
+     [Defined if inline assembler supports SSSE3 instructions])
+fi
+
+
+#
+# Check whether GCC inline assembler supports PCLMUL instructions.
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports PCLMUL instructions],
+       [gcry_cv_gcc_inline_asm_pclmul],
+       [if test "$mpi_cpu_arch" != "x86" ; then
+          gcry_cv_gcc_inline_asm_pclmul="n/a"
+        else
+          gcry_cv_gcc_inline_asm_pclmul=no
+          AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[void a(void) {
+              __asm__("pclmulqdq \$0, %%xmm1, %%xmm3\n\t":::"cc");
+            }]])],
+          [gcry_cv_gcc_inline_asm_pclmul=yes])
+        fi])
+if test "$gcry_cv_gcc_inline_asm_pclmul" = "yes" ; then
+   AC_DEFINE(HAVE_GCC_INLINE_ASM_PCLMUL,1,
+     [Defined if inline assembler supports PCLMUL instructions])
+fi
+
+
+#
+# Check whether GCC inline assembler supports AVX instructions
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports AVX instructions],
+       [gcry_cv_gcc_inline_asm_avx],
+       [if test "$mpi_cpu_arch" != "x86" ; then
+          gcry_cv_gcc_inline_asm_avx="n/a"
+        else
+          gcry_cv_gcc_inline_asm_avx=no
+          AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[void a(void) {
+              __asm__("xgetbv; vaesdeclast (%[mem]),%%xmm0,%%xmm7\n\t"::[mem]"r"(0):);
+            }]])],
+          [gcry_cv_gcc_inline_asm_avx=yes])
+        fi])
+if test "$gcry_cv_gcc_inline_asm_avx" = "yes" ; then
+   AC_DEFINE(HAVE_GCC_INLINE_ASM_AVX,1,
+     [Defined if inline assembler supports AVX instructions])
+fi
+
+
+#
+# Check whether GCC inline assembler supports AVX2 instructions
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports AVX2 instructions],
+       [gcry_cv_gcc_inline_asm_avx2],
+       [if test "$mpi_cpu_arch" != "x86" ; then
+          gcry_cv_gcc_inline_asm_avx2="n/a"
+        else
+          gcry_cv_gcc_inline_asm_avx2=no
+          AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[void a(void) {
+              __asm__("xgetbv; vpbroadcastb %%xmm7,%%ymm1\n\t":::"cc");
+            }]])],
+          [gcry_cv_gcc_inline_asm_avx2=yes])
+        fi])
+if test "$gcry_cv_gcc_inline_asm_avx2" = "yes" ; then
+   AC_DEFINE(HAVE_GCC_INLINE_ASM_AVX2,1,
+     [Defined if inline assembler supports AVX2 instructions])
+fi
+
+
+#
+# Check whether GCC inline assembler supports BMI2 instructions
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports BMI2 instructions],
+       [gcry_cv_gcc_inline_asm_bmi2],
+       [if test "$mpi_cpu_arch" != "x86" ; then
+          gcry_cv_gcc_inline_asm_bmi2="n/a"
+        else
+          gcry_cv_gcc_inline_asm_bmi2=no
+          AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[void a(void) {
+              __asm__("rorxl \$23, %%eax, %%edx\\n\\t":::"memory");
+            }]])],
+          [gcry_cv_gcc_inline_asm_bmi2=yes])
+        fi])
+if test "$gcry_cv_gcc_inline_asm_bmi2" = "yes" ; then
+   AC_DEFINE(HAVE_GCC_INLINE_ASM_BMI2,1,
+     [Defined if inline assembler supports BMI2 instructions])
+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],
+       [gcry_cv_gcc_amd64_platform_as_ok],
+       [if test "$mpi_cpu_arch" != "x86" ; then
+          gcry_cv_gcc_amd64_platform_as_ok="n/a"
+        else
+          gcry_cv_gcc_amd64_platform_as_ok=no
+          AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[__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"
+            );]])],
+          [gcry_cv_gcc_amd64_platform_as_ok=yes])
+        fi])
+  if test "$gcry_cv_gcc_amd64_platform_as_ok" = "yes" ; then
+     AC_DEFINE(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS,1,
+              [Defined if underlying assembler is compatible with amd64 assembly implementations])
+  fi
+fi
+
+
+#
+# Check whether GCC assembler supports features needed for assembly
+# implementations that use Intel syntax
+#
+AC_CACHE_CHECK([whether GCC assembler is compatible for Intel syntax assembly implementations],
+       [gcry_cv_gcc_platform_as_ok_for_intel_syntax],
+       [if test "$mpi_cpu_arch" != "x86" ; then
+          gcry_cv_gcc_platform_as_ok_for_intel_syntax="n/a"
+        else
+          gcry_cv_gcc_platform_as_ok_for_intel_syntax=no
+          AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[__asm__(
+                ".intel_syntax noprefix\n\t"
+                "pxor xmm1, xmm7;\n\t"
+                /* Intel syntax implementation also use GAS macros, so check
+                 * for them here. */
+                "VAL_A = xmm4\n\t"
+                "VAL_B = xmm2\n\t"
+                ".macro SET_VAL_A p1\n\t"
+                "  VAL_A = \\\\p1 \n\t"
+                ".endm\n\t"
+                ".macro SET_VAL_B p1\n\t"
+                "  VAL_B = \\\\p1 \n\t"
+                ".endm\n\t"
+                "vmovdqa VAL_A, VAL_B;\n\t"
+                "SET_VAL_A eax\n\t"
+                "SET_VAL_B ebp\n\t"
+                "add VAL_A, VAL_B;\n\t"
+                "add VAL_B, 0b10101;\n\t"
+            );]])],
+          [gcry_cv_gcc_platform_as_ok_for_intel_syntax=yes])
+        fi])
+if test "$gcry_cv_gcc_platform_as_ok_for_intel_syntax" = "yes" ; then
+  AC_DEFINE(HAVE_INTEL_SYNTAX_PLATFORM_AS,1,
+            [Defined if underlying assembler is compatible with Intel syntax assembly implementations])
+fi
+
+
+#
+# Check whether compiler is configured for ARMv6 or newer architecture
+#
+AC_CACHE_CHECK([whether compiler is configured for ARMv6 or newer architecture],
+       [gcry_cv_cc_arm_arch_is_v6],
+       [if test "$mpi_cpu_arch" != "arm" ; then
+          gcry_cv_cc_arm_arch_is_v6="n/a"
+        else
+          AC_EGREP_CPP(yes,
+          [#if defined(__arm__) && \
+             ((defined(__ARM_ARCH) && __ARM_ARCH >= 6) \
+             || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+             || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \
+             || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) \
+             || defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
+             || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
+             || defined(__ARM_ARCH_7EM__))
+            yes
+           #endif
+          ], gcry_cv_cc_arm_arch_is_v6=yes, gcry_cv_cc_arm_arch_is_v6=no)
+        fi])
+if test "$gcry_cv_cc_arm_arch_is_v6" = "yes" ; then
+   AC_DEFINE(HAVE_ARM_ARCH_V6,1,
+     [Defined if ARM architecture is v6 or newer])
+fi
+
+
+#
+# Check whether GCC inline assembler supports NEON instructions
+#
+AC_CACHE_CHECK([whether GCC inline assembler supports NEON instructions],
+       [gcry_cv_gcc_inline_asm_neon],
+       [if test "$mpi_cpu_arch" != "arm" ; then
+          gcry_cv_gcc_inline_asm_neon="n/a"
+        else
+          gcry_cv_gcc_inline_asm_neon=no
+          AC_COMPILE_IFELSE([AC_LANG_SOURCE(
+          [[__asm__(
+                ".syntax unified\n\t"
+                ".thumb\n\t"
+                ".fpu neon\n\t"
+                "vld1.64 {%q0-%q1}, [%r0]!;\n\t"
+                "vrev64.8 %q0, %q3;\n\t"
+                "vadd.u64 %q0, %q1;\n\t"
+                "vadd.s64 %d3, %d2, %d3;\n\t"
+                );
+            ]])],
+          [gcry_cv_gcc_inline_asm_neon=yes])
+        fi])
+if test "$gcry_cv_gcc_inline_asm_neon" = "yes" ; then
+   AC_DEFINE(HAVE_GCC_INLINE_ASM_NEON,1,
+     [Defined if inline assembler supports NEON instructions])
+fi
+
+
 #######################################
 #### Checks for library functions. ####
 #######################################
@@ -763,7 +1332,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)
+AC_CHECK_FUNCS(fcntl ftruncate flockfile)
 
 GNUPG_CHECK_MLOCK
 
@@ -787,6 +1356,13 @@ 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.
@@ -866,46 +1442,9 @@ fi
 
 
 #
-# Setup assembler stuff.
+# Other defines
 #
-GNUPG_SYS_SYMBOL_UNDERSCORE()
-AC_ARG_ENABLE(mpi-path,
-              AC_HELP_STRING([--enable-mpi-path=EXTRA_PATH],
-             [prepend EXTRA_PATH to list of CPU specific optimizations]),
-             mpi_extra_path="$enableval",mpi_extra_path="")
-AC_MSG_CHECKING(for mpi assembler functions)
-if test -f $srcdir/mpi/config.links ; then
-    . $srcdir/mpi/config.links
-    AC_CONFIG_LINKS("$mpi_ln_list")
-    ac_cv_mpi_sflags="$mpi_sflags"
-    AC_MSG_RESULT(done)
-else
-    AC_MSG_RESULT(failed)
-    AC_MSG_ERROR([mpi/config.links missing!])
-fi
-MPI_SFLAGS="$ac_cv_mpi_sflags"
-AC_SUBST(MPI_SFLAGS)
-
-AM_CONDITIONAL(MPI_MOD_ASM_MPIH_ADD1, test "$mpi_mod_asm_mpih_add1" = yes)
-AM_CONDITIONAL(MPI_MOD_ASM_MPIH_SUB1, test "$mpi_mod_asm_mpih_sub1" = yes)
-AM_CONDITIONAL(MPI_MOD_ASM_MPIH_MUL1, test "$mpi_mod_asm_mpih_mul1" = yes)
-AM_CONDITIONAL(MPI_MOD_ASM_MPIH_MUL2, test "$mpi_mod_asm_mpih_mul2" = yes)
-AM_CONDITIONAL(MPI_MOD_ASM_MPIH_MUL3, test "$mpi_mod_asm_mpih_mul3" = yes)
-AM_CONDITIONAL(MPI_MOD_ASM_MPIH_LSHIFT, test "$mpi_mod_asm_mpih_lshift" = yes)
-AM_CONDITIONAL(MPI_MOD_ASM_MPIH_RSHIFT, test "$mpi_mod_asm_mpih_rshift" = yes)
-AM_CONDITIONAL(MPI_MOD_ASM_UDIV, test "$mpi_mod_asm_udiv" = yes)
-AM_CONDITIONAL(MPI_MOD_ASM_UDIV_QRNND, test "$mpi_mod_asm_udiv_qrnnd" = yes)
-AM_CONDITIONAL(MPI_MOD_C_MPIH_ADD1, test "$mpi_mod_c_mpih_add1" = yes)
-AM_CONDITIONAL(MPI_MOD_C_MPIH_SUB1, test "$mpi_mod_c_mpih_sub1" = yes)
-AM_CONDITIONAL(MPI_MOD_C_MPIH_MUL1, test "$mpi_mod_c_mpih_mul1" = yes)
-AM_CONDITIONAL(MPI_MOD_C_MPIH_MUL2, test "$mpi_mod_c_mpih_mul2" = yes)
-AM_CONDITIONAL(MPI_MOD_C_MPIH_MUL3, test "$mpi_mod_c_mpih_mul3" = yes)
-AM_CONDITIONAL(MPI_MOD_C_MPIH_LSHIFT, test "$mpi_mod_c_mpih_lshift" = yes)
-AM_CONDITIONAL(MPI_MOD_C_MPIH_RSHIFT, test "$mpi_mod_c_mpih_rshift" = yes)
-AM_CONDITIONAL(MPI_MOD_C_UDIV, test "$mpi_mod_c_udiv" = yes)
-AM_CONDITIONAL(MPI_MOD_C_UDIV_QRNND, test "$mpi_mod_c_udiv_qrnnd" = yes)
-
-if test "$is_development_version" = "yes"; then
+if test mym4_isgit = "yes"; then
     AC_DEFINE(IS_DEVELOPMENT_VERSION,1,
               [Defined if this is not a regular release])
 fi
@@ -935,7 +1474,7 @@ if test "$GCC" = yes; then
         AC_MSG_CHECKING([if gcc supports -Wno-missing-field-initializers])
         _gcc_cflags_save=$CFLAGS
         CFLAGS="-Wno-missing-field-initializers"
-        AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]),_gcc_wopt=yes,_gcc_wopt=no)
+        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],_gcc_wopt=yes,_gcc_wopt=no)
         AC_MSG_RESULT($_gcc_wopt)
         CFLAGS=$_gcc_cflags_save;
         if test x"$_gcc_wopt" = xyes ; then
@@ -949,7 +1488,7 @@ if test "$GCC" = yes; then
         AC_MSG_CHECKING([if gcc supports -Wpointer-arith])
         _gcc_cflags_save=$CFLAGS
         CFLAGS="-Wpointer-arith"
-        AC_COMPILE_IFELSE(AC_LANG_PROGRAM([]),_gcc_wopt=yes,_gcc_wopt=no)
+        AC_COMPILE_IFELSE([AC_LANG_PROGRAM([],[])],_gcc_wopt=yes,_gcc_wopt=no)
         AC_MSG_RESULT($_gcc_wopt)
         CFLAGS=$_gcc_cflags_save;
         if test x"$_gcc_wopt" = xyes ; then
@@ -984,8 +1523,67 @@ DATADIRNAME=$DATADIRNAME
 #### Conclusion. ####
 #####################
 
+# Check that requested feature can actually be used and define
+# ENABLE_foo_SUPPORT macros.
+
+if test x"$aesnisupport" = xyes ; then
+  if test "$gcry_cv_gcc_inline_asm_ssse3" != "yes" ; then
+    aesnisupport="no (unsupported by compiler)"
+  fi
+fi
+if test x"$pclmulsupport" = xyes ; then
+  if test "$gcry_cv_gcc_inline_asm_pclmul" != "yes" ; then
+    pclmulsupport="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)"
+  fi
+fi
+if test x"$avx2support" = xyes ; then
+  if test "$gcry_cv_gcc_inline_asm_avx2" != "yes" ; then
+    avx2support="no (unsupported by compiler)"
+  fi
+fi
+if test x"$neonsupport" = xyes ; then
+  if test "$gcry_cv_gcc_inline_asm_neon" != "yes" ; then
+    neonsupport="no (unsupported by compiler)"
+  fi
+fi
+
+if test x"$aesnisupport" = xyes ; then
+  AC_DEFINE(ENABLE_AESNI_SUPPORT, 1,
+            [Enable support for Intel AES-NI instructions.])
+fi
+if test x"$pclmulsupport" = xyes ; then
+  AC_DEFINE(ENABLE_PCLMUL_SUPPORT, 1,
+            [Enable support for Intel PCLMUL instructions.])
+fi
+if test x"$avxsupport" = xyes ; then
+  AC_DEFINE(ENABLE_AVX_SUPPORT,1,
+            [Enable support for Intel AVX instructions.])
+fi
+if test x"$avx2support" = xyes ; then
+  AC_DEFINE(ENABLE_AVX2_SUPPORT,1,
+            [Enable support for Intel AVX2 instructions.])
+fi
+if test x"$neonsupport" = xyes ; then
+  AC_DEFINE(ENABLE_NEON_SUPPORT,1,
+            [Enable support for ARM NEON instructions.])
+fi
+if test x"$padlocksupport" = xyes ; then
+  AC_DEFINE(ENABLE_PADLOCK_SUPPORT, 1,
+            [Enable support for the PadLock engine.])
+fi
+if test x"$drngsupport" = xyes ; then
+  AC_DEFINE(ENABLE_DRNG_SUPPORT, 1,
+            [Enable support for Intel DRNG (RDRAND instruction).])
+fi
+
+
 # Define conditional sources and config.h symbols depending on the
-# selected ciphers, pubkey-ciphers, digests and random modules.
+# selected ciphers, pubkey-ciphers, digests, kdfs, and random modules.
 
 LIST_MEMBER(arcfour, $enabled_ciphers)
 if test "$found" = "1"; then
@@ -997,12 +1595,34 @@ LIST_MEMBER(blowfish, $enabled_ciphers)
 if test "$found" = "1" ; then
    GCRYPT_CIPHERS="$GCRYPT_CIPHERS blowfish.lo"
    AC_DEFINE(USE_BLOWFISH, 1, [Defined if this module should be included])
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS blowfish-amd64.lo"
+      ;;
+      arm*-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS blowfish-arm.lo"
+      ;;
+   esac
 fi
 
 LIST_MEMBER(cast5, $enabled_ciphers)
 if test "$found" = "1" ; then
    GCRYPT_CIPHERS="$GCRYPT_CIPHERS cast5.lo"
    AC_DEFINE(USE_CAST5, 1, [Defined if this module should be included])
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS cast5-amd64.lo"
+      ;;
+      arm*-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS cast5-arm.lo"
+      ;;
+   esac
 fi
 
 LIST_MEMBER(des, $enabled_ciphers)
@@ -1015,18 +1635,57 @@ LIST_MEMBER(aes, $enabled_ciphers)
 if test "$found" = "1" ; then
    GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael.lo"
    AC_DEFINE(USE_AES, 1, [Defined if this module should be included])
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-amd64.lo"
+      ;;
+      arm*-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-arm.lo"
+      ;;
+   esac
 fi
 
 LIST_MEMBER(twofish, $enabled_ciphers)
 if test "$found" = "1" ; then
    GCRYPT_CIPHERS="$GCRYPT_CIPHERS twofish.lo"
    AC_DEFINE(USE_TWOFISH, 1, [Defined if this module should be included])
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS twofish-amd64.lo"
+      ;;
+      arm*-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS twofish-arm.lo"
+      ;;
+   esac
 fi
 
 LIST_MEMBER(serpent, $enabled_ciphers)
 if test "$found" = "1" ; then
    GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent.lo"
    AC_DEFINE(USE_SERPENT, 1, [Defined if this module should be included])
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the SSE2 implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent-sse2-amd64.lo"
+      ;;
+   esac
+
+   if test x"$avx2support" = xyes ; then
+      # Build with the AVX2 implementation
+      GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent-avx2-amd64.lo"
+   fi
+
+   if test x"$neonsupport" = xyes ; then
+      # Build with the NEON implementation
+      GCRYPT_CIPHERS="$GCRYPT_CIPHERS serpent-armv7-neon.lo"
+   fi
 fi
 
 LIST_MEMBER(rfc2268, $enabled_ciphers)
@@ -1045,6 +1704,57 @@ LIST_MEMBER(camellia, $enabled_ciphers)
 if test "$found" = "1" ; then
    GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia.lo camellia-glue.lo"
    AC_DEFINE(USE_CAMELLIA, 1, [Defined if this module should be included])
+
+   case "${host}" in
+      arm*-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia-arm.lo"
+      ;;
+   esac
+
+   if test x"$avxsupport" = xyes ; then
+      if test x"$aesnisupport" = xyes ; then
+        # Build with the AES-NI/AVX implementation
+        GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia-aesni-avx-amd64.lo"
+      fi
+   fi
+
+   if test x"$avx2support" = xyes ; then
+      if test x"$aesnisupport" = xyes ; then
+        # Build with the AES-NI/AVX2 implementation
+        GCRYPT_CIPHERS="$GCRYPT_CIPHERS camellia-aesni-avx2-amd64.lo"
+      fi
+   fi
+fi
+
+LIST_MEMBER(idea, $enabled_ciphers)
+if test "$found" = "1" ; then
+   GCRYPT_CIPHERS="$GCRYPT_CIPHERS idea.lo"
+   AC_DEFINE(USE_IDEA, 1, [Defined if this module should be included])
+fi
+
+LIST_MEMBER(salsa20, $enabled_ciphers)
+if test "$found" = "1" ; then
+   GCRYPT_CIPHERS="$GCRYPT_CIPHERS salsa20.lo"
+   AC_DEFINE(USE_SALSA20, 1, [Defined if this module should be included])
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_CIPHERS="$GCRYPT_CIPHERS salsa20-amd64.lo"
+      ;;
+   esac
+
+   if test x"$neonsupport" = xyes ; then
+     # Build with the NEON implementation
+     GCRYPT_CIPHERS="$GCRYPT_CIPHERS salsa20-armv7-neon.lo"
+   fi
+fi
+
+LIST_MEMBER(gost28147, $enabled_ciphers)
+if test "$found" = "1" ; then
+   GCRYPT_CIPHERS="$GCRYPT_CIPHERS gost28147.lo"
+   AC_DEFINE(USE_GOST28147, 1, [Defined if this module should be included])
 fi
 
 LIST_MEMBER(dsa, $enabled_pubkey_ciphers)
@@ -1067,7 +1777,9 @@ fi
 
 LIST_MEMBER(ecc, $enabled_pubkey_ciphers)
 if test "$found" = "1" ; then
-   GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS ecc.lo"
+   GCRYPT_PUBKEY_CIPHERS="$GCRYPT_PUBKEY_CIPHERS \
+                          ecc.lo ecc-curves.lo ecc-misc.lo \
+                          ecc-ecdsa.lo ecc-eddsa.lo ecc-gost.lo"
    AC_DEFINE(USE_ECC, 1, [Defined if this module should be included])
 fi
 
@@ -1077,6 +1789,22 @@ if test "$found" = "1" ; then
    AC_DEFINE(USE_CRC, 1, [Defined if this module should be included])
 fi
 
+LIST_MEMBER(gostr3411-94, $enabled_digests)
+if test "$found" = "1" ; then
+   # GOST R 34.11-94 internally uses GOST 28147-89
+   LIST_MEMBER(gost28147, $enabled_ciphers)
+   if test "$found" = "1" ; then
+      GCRYPT_DIGESTS="$GCRYPT_DIGESTS gostr3411-94.lo"
+      AC_DEFINE(USE_GOST_R_3411_94, 1, [Defined if this module should be included])
+   fi
+fi
+
+LIST_MEMBER(stribog, $enabled_digests)
+if test "$found" = "1" ; then
+   GCRYPT_DIGESTS="$GCRYPT_DIGESTS stribog.lo"
+   AC_DEFINE(USE_GOST_R_3411_12, 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"
@@ -1093,12 +1821,33 @@ LIST_MEMBER(sha256, $enabled_digests)
 if test "$found" = "1" ; then
    GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256.lo"
    AC_DEFINE(USE_SHA256, 1, [Defined if this module should be included])
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha256-ssse3-amd64.lo"
+      ;;
+   esac
 fi
 
 LIST_MEMBER(sha512, $enabled_digests)
 if test "$found" = "1" ; then
    GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512.lo"
    AC_DEFINE(USE_SHA512, 1, [Defined if this module should be included])
+
+   case "${host}" in
+      x86_64-*-*)
+         # Build with the assembly implementation
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-ssse3-amd64.lo"
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-avx-amd64.lo"
+         GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-avx2-bmi2-amd64.lo"
+      ;;
+   esac
+
+   if test x"$neonsupport" = xyes ; then
+     # Build with the NEON implementation
+     GCRYPT_DIGESTS="$GCRYPT_DIGESTS sha512-armv7-neon.lo"
+   fi
 fi
 
 LIST_MEMBER(tiger, $enabled_digests)
@@ -1118,6 +1867,19 @@ GCRYPT_DIGESTS="$GCRYPT_DIGESTS rmd160.lo sha1.lo"
 AC_DEFINE(USE_RMD160, 1, [Defined if this module should be included])
 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"
+  ;;
+esac
+
+LIST_MEMBER(scrypt, $enabled_kdfs)
+if test "$found" = "1" ; then
+   GCRYPT_KDFS="$GCRYPT_KDFS scrypt.lo"
+   AC_DEFINE(USE_SCRYPT, 1, [Defined if this module should be included])
+fi
+
 LIST_MEMBER(linux, $random_modules)
 if test "$found" = "1" ; then
    GCRYPT_RANDOM="$GCRYPT_RANDOM rndlinux.lo"
@@ -1154,6 +1916,7 @@ fi
 AC_SUBST([GCRYPT_CIPHERS])
 AC_SUBST([GCRYPT_PUBKEY_CIPHERS])
 AC_SUBST([GCRYPT_DIGESTS])
+AC_SUBST([GCRYPT_KDFS])
 AC_SUBST([GCRYPT_RANDOM])
 
 AC_SUBST(LIBGCRYPT_CIPHERS, $enabled_ciphers)
@@ -1171,23 +1934,63 @@ AC_DEFINE_UNQUOTED(LIBGCRYPT_PUBKEY_CIPHERS, "$tmp",
 tmp=`echo "$enabled_digests" | tr ' ' : `
 AC_DEFINE_UNQUOTED(LIBGCRYPT_DIGESTS, "$tmp",
                    [List of available digest algorithms])
+tmp=`echo "$enabled_kdfs" | tr ' ' : `
+AC_DEFINE_UNQUOTED(LIBGCRYPT_KDFS, "$tmp",
+                   [List of available KDF algorithms])
 
 
+#
+# Define conditional sources depending on the used hardware platform.
+# Note that all possible modules must also be listed in
+# src/Makefile.am (EXTRA_libgcrypt_la_SOURCES).
+#
+GCRYPT_HWF_MODULES=
+case "$mpi_cpu_arch" in
+     x86)
+        AC_DEFINE(HAVE_CPU_ARCH_X86, 1,   [Defined for the x86 platforms])
+        GCRYPT_HWF_MODULES="hwf-x86.lo"
+        ;;
+     alpha)
+        AC_DEFINE(HAVE_CPU_ARCH_ALPHA, 1, [Defined for Alpha platforms])
+        ;;
+     sparc)
+        AC_DEFINE(HAVE_CPU_ARCH_SPARC, 1, [Defined for SPARC platforms])
+        ;;
+     mips)
+        AC_DEFINE(HAVE_CPU_ARCH_MIPS, 1,  [Defined for MIPS platforms])
+        ;;
+     m68k)
+        AC_DEFINE(HAVE_CPU_ARCH_M68K, 1,  [Defined for M68k platforms])
+        ;;
+     ppc)
+        AC_DEFINE(HAVE_CPU_ARCH_PPC, 1,   [Defined for PPC platforms])
+        ;;
+     arm)
+        AC_DEFINE(HAVE_CPU_ARCH_ARM, 1,   [Defined for ARM platforms])
+        GCRYPT_HWF_MODULES="hwf-arm.lo"
+        ;;
+esac
+AC_SUBST([GCRYPT_HWF_MODULES])
 
-# Generate extended version information for W32.
-if test "$have_w32_system" = yes; then
-   BUILD_TIMESTAMP=`date --iso-8601=minutes`
-   changequote(,)dnl
-   BUILD_FILEVERSION=`echo "$VERSION" | sed 's/\([0-9.]*\).*/\1./;s/\./,/g'`
-   changequote([,])dnl
-   BUILD_FILEVERSION="${BUILD_FILEVERSION}${BUILD_REVISION}"
-fi
+
+#
+# Provide information about the build.
+#
+BUILD_REVISION="mym4_revision"
 AC_SUBST(BUILD_REVISION)
-AC_SUBST(BUILD_TIMESTAMP)
-AC_SUBST(BUILD_FILEVERSION)
 AC_DEFINE_UNQUOTED(BUILD_REVISION, "$BUILD_REVISION",
-                   [Subversion revision used to build this package])
+                   [GIT commit id revision used to build this package])
 
+changequote(,)dnl
+BUILD_FILEVERSION=`echo "$VERSION" | sed 's/\([0-9.]*\).*/\1./;s/\./,/g'`
+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_SUBST(BUILD_TIMESTAMP)
+AC_DEFINE_UNQUOTED(BUILD_TIMESTAMP, "$BUILD_TIMESTAMP",
+                   [The time this package was configured for a build])
 
 
 # And create the files.
@@ -1205,21 +2008,33 @@ src/libgcrypt-config
 src/versioninfo.rc
 tests/Makefile
 ])
+AC_CONFIG_FILES([tests/hashtest-256g], [chmod +x tests/hashtest-256g])
 AC_OUTPUT
 
+
+detection_module="${GCRYPT_HWF_MODULES%.lo}"
+test -n "$detection_module" || detection_module="none"
+
 # Give some feedback
-echo "
-        Libgcrypt v${VERSION} has been configured as follows:
-
-        Platform:                  $PRINTABLE_OS_NAME ($host)
-        Enabled cipher algorithms: $enabled_ciphers
-        Enabled digest algorithms: $enabled_digests
-        Enabled pubkey algorithms: $enabled_pubkey_ciphers
-        Random number generator:   $random
-        Using linux capabilities:  $use_capabilities
-        Try using Padlock crypto:  $padlocksupport
-        Try using AES-NI crypto:   $aesnisupport
-"
+GCRY_MSG_SHOW([],[])
+GCRY_MSG_SHOW([Libgcrypt],[v${VERSION} has been configured as follows:])
+GCRY_MSG_SHOW([],[])
+GCRY_MSG_SHOW([Platform:                 ],[$PRINTABLE_OS_NAME ($host)])
+GCRY_MSG_SHOW([Hardware detection module:],[$detection_module])
+GCRY_MSG_WRAP([Enabled cipher algorithms:],[$enabled_ciphers])
+GCRY_MSG_WRAP([Enabled digest algorithms:],[$enabled_digests])
+GCRY_MSG_WRAP([Enabled kdf algorithms:   ],[$enabled_kdfs])
+GCRY_MSG_WRAP([Enabled pubkey algorithms:],[$enabled_pubkey_ciphers])
+GCRY_MSG_SHOW([Random number generator:  ],[$random])
+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 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
 cat <<G10EOF
@@ -1241,6 +2056,15 @@ cat <<G10EOF
 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.
+
+G10EOF
+fi
+
 if test -n "$gpl"; then
   echo "Please note that you are building a version of Libgcrypt with"
   echo "  $gpl"
similarity index 95%
rename from doc/ChangeLog
rename to doc/ChangeLog-2011
index 992c63b..de837a0 100644 (file)
@@ -1,3 +1,20 @@
+2011-12-01  Werner Koch  <wk@g10code.com>
+
+       NB: ChangeLog files are no longer manually maintained.  Starting
+       on December 1st, 2011 we put change information only in the GIT
+       commit log, and generate a top-level ChangeLog file from logs at
+       "make dist".  See doc/HACKING for details.
+
+2011-09-15  Werner Koch  <wk@g10code.com>
+
+       * gcrypt.texi: Remove the gcry_ac interface
+
+2009-10-28  Werner Koch  <wk@g10code.com>
+
+       * Makefile.am: Add code to build a man page for hmac256.
+       * yat2m.c: New.  Taken from GnuPG.
+       * gcrypt.text (hmac256): New section.
+
 2009-10-28  Werner Koch  <wk@g10code.com>
 
        * gcrypt.texi (Multi-Threading): Add examples.
@@ -465,3 +482,7 @@ Wed Feb 10 17:15:39 CET 1999  Werner Koch  <wk@isil.d.shuttle.de>
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
diff --git a/doc/DCO b/doc/DCO
new file mode 100644 (file)
index 0000000..ee460f6
--- /dev/null
+++ b/doc/DCO
@@ -0,0 +1,29 @@
+Libgcrypt Developer's Certificate of Origin.  Version 1.0
+=========================================================
+
+By making a contribution to the Libgcrypt project, I certify that:
+
+(a) The contribution was created in whole or in part by me and I
+    have the right to submit it under the free software license
+    indicated in the file; or
+
+(b) The contribution is based upon previous work that, to the
+    best of my knowledge, is covered under an appropriate free
+    software license and I have the right under that license to
+    submit that work with modifications, whether created in whole
+    or in part by me, under the same free software license
+    (unless I am permitted to submit under a different license),
+    as indicated in the file; or
+
+(c) The contribution was provided directly to me by some other
+    person who certified (a), (b) or (c) and I have not modified
+    it.
+
+(d) I understand and agree that this project and the contribution
+    are public and that a record of the contribution (including
+    all personal information I submit with it, including my
+    sign-off) is maintained indefinitely and may be redistributed
+    consistent with this project or the free software license(s)
+    involved.
+
+Signed-off-by: [Your name and mail address]
index 3f94772..0cb8d56 100644 (file)
@@ -1,9 +1,86 @@
-                        Various hacking notes                  -*- text -*-
-                       =======================
+# HACKING                                                       -*- org -*-
+#+TITLE: Hacking notes for Libgcrypt
+#+STARTUP: showall
 
+* How to contribute
 
-Taking optimized MPI code out of GMP:
--------------------------------------
+  The following stuff explains some basic procedures you need to
+  follow if you want to contribute code or documentation.
+
+** No more ChangeLog files
+
+  Do not modify any of the ChangeLog files in Libgcrypt.  Starting on
+  December 1st, 2011 we put change information only in the GIT commit
+  log, and generate a top-level ChangeLog file from logs at "make
+  dist" time.  As such, there are strict requirements on the form of
+  the commit log messages.  The old ChangeLog files have all be
+  renamed to ChangeLog-2011
+
+** Commit log requirements
+
+  Your commit log should always start with a one-line summary, the
+  second line should be blank, and the remaining lines are usually
+  ChangeLog-style entries for all affected files.  However, it's fine
+  -- even recommended -- to write a few lines of prose describing the
+  change, when the summary and ChangeLog entries don't give enough of
+  the big picture.  Omit the leading TABs that you're used to seeing
+  in a "real" ChangeLog file, but keep the maximum line length at 72
+  or smaller, so that the generated ChangeLog lines, each with its
+  leading TAB, will not exceed 80 columns.
+
+** License policy
+
+  Libgcrypt is currently licensed under the LGPLv2+ with tools and the
+  manual being under the GPLv2+.  We may eventually update to a newer
+  version of the licenses or a combination of them.  It is thus
+  important, that all contributed code allows for an update of the
+  license; for example we can't accept code under the LGPLv2(only).
+
+  Libgcrypt used to have a strict policy of requiring copyright
+  assignments to the FSF.  To avoid this major organizational overhead
+  and to allow inclusion of code, not copyrighted by the FSF, this
+  policy has been relaxed.  It is now also possible to contribute code
+  by asserting that the contribution is in accordance to the
+  "Libgcrypt Developer's Certificate of Origin" as found in the file
+  "DCO".  (Except for a slight wording change, this DCO is identical
+  to the one used by the Linux kernel.)
+
+  If your want to contribute code or documentation to Libgcrypt and
+  you didn't signed a copyright assignment with the FSF in the past,
+  you need to take these simple steps:
+
+  - Decide which mail address you want to use.  Please have your real
+    name in the address and not a pseudonym.  Anonymous contributions
+    can only be done if you find a proxy who certifies for you.
+
+  - If your employer or school might claim ownership of code written
+    by you; you need to talk to them to make sure that you have the
+    right to contribute under the DCO.
+
+  - Send an OpenPGP signed mail to the gcrypt-devel@gnupg.org mailing
+    list from your mail address.  Include a copy of the DCO as found
+    in the official master branch.  Insert your name and email address
+    into the DCO in the same way you want to use it later.  Example:
+
+      Signed-off-by: Joe R. Hacker <joe@example.org>
+
+    (If you really need it, you may perform simple transformations of
+    the mail address: Replacing "@" by " at " or "." by " dot ".)
+
+  - That's it.  From now on you only need to add a "Signed-off-by:"
+    line with your name and mail address to the commit message.  It is
+    recommended to send the patches using a PGP/MIME signed mail.
+
+** Coding standards
+
+  Please follow the GNU coding standards.  If you are in doubt consult
+  the existing code as an example.  Do no re-indent code without a
+  need.  If you really need to do it, use a separate commit for such a
+  change.
+
+
+* Porting hints
+** Taking optimized MPI code out of GMP:
 
   I generated the pentium4/* files by glueing the existing assembler
   prologues to the GMP 4.2.1 assembler files generated with the m4
@@ -18,8 +95,9 @@ Taking optimized MPI code out of GMP:
   tedious work.
 
 
-Debugging math stuff:
----------------------
+* Debug hints
+
+** Debugging math stuff:
 
   While debugging the ECC code in libgcrypt, I was in need for some
   computer algebra system which would allow me to verify the numbers
index fc12745..30330bb 100644 (file)
 # License along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 
-EXTRA_DIST = README.apichanges HACKING \
+EXTRA_DIST = README.apichanges HACKING DCO \
             libgcrypt-modules.eps fips-fsm.eps \
             libgcrypt-modules.png fips-fsm.png \
-             libgcrypt-modules.pdf fips-fsm.pdf
+             libgcrypt-modules.pdf fips-fsm.pdf \
+            yat2m.c
 
-DISTCLEANFILES = gcrypt.cps
+DISTCLEANFILES = gcrypt.cps yat2m-stamp.tmp yat2m-stamp $(myman_pages)
+CLEANFILES = yat2m
 
 BUILT_SOURCES = libgcrypt-modules.eps fips-fsm.eps \
                 libgcrypt-modules.png fips-fsm.png \
@@ -31,6 +33,16 @@ BUILT_SOURCES = libgcrypt-modules.eps fips-fsm.eps \
 info_TEXINFOS = gcrypt.texi
 gcrypt_TEXINFOS = lgpl.texi gpl.texi libgcrypt-modules.fig fips-fsm.fig
 
+YAT2M_OPTIONS = -I $(srcdir) \
+       --release "Libgcrypt @PACKAGE_VERSION@" --source "Libgcrypt"
+
+myman_sources = gcrypt.texi
+myman_pages   = hmac256.1
+
+man_MANS = $(myman_pages)
+
+yat2m: yat2m.c
+       $(CC_FOR_BUILD) -o $@ $(srcdir)/yat2m.c
 
 .fig.png:
        fig2dev -L png `test -f '$<' || echo '$(srcdir)/'`$< $@
@@ -44,6 +56,29 @@ gcrypt_TEXINFOS = lgpl.texi gpl.texi libgcrypt-modules.fig fips-fsm.fig
 .fig.pdf:
        fig2dev -L pdf `test -f '$<' || echo '$(srcdir)/'`$< $@
 
+yat2m-stamp: $(myman_sources)
+       @rm -f yat2m-stamp.tmp
+       @touch yat2m-stamp.tmp
+       for file in $(myman_sources) ; do \
+              ./yat2m $(YAT2M_OPTIONS) --store \
+                 `test -f '$$file' || echo '$(srcdir)/'`$$file ; done
+       @mv -f yat2m-stamp.tmp $@
+
+yat2m-stamp: yat2m
+
+$(myman_pages) : yat2m-stamp
+       @if test -f $@; then :; else \
+            trap 'rm -rf yat2m-stamp yat2m-lock' 1 2 13 15; \
+               if mkdir yat2m-lock 2>/dev/null; then \
+                 rm -f yat2m-stamp; \
+                 $(MAKE) $(AM_MAKEFLAGS) yat2m-stamp; \
+                 rmdir yat2m-lock; \
+               else \
+                 while test -d yat2m-lock; do sleep 1; done; \
+                 test -f yat2m-stamp; exit $$?; \
+               fi; \
+             fi
+
 
 # Make sure that gcrypt.texi is touched if any other source file has
 # been modified.  This is required so that the version.texi magic
index 52cb7c3..08ef3e8 100644 (file)
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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; \
+    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;; \
+    esac; \
+    test $$am__dry = yes; \
+  }
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -54,25 +71,33 @@ host_triplet = @host@
 subdir = doc
 DIST_COMMON = $(gcrypt_TEXINFOS) $(srcdir)/Makefile.am \
        $(srcdir)/Makefile.in $(srcdir)/stamp-vti \
-       $(srcdir)/version.texi ChangeLog mdate-sh texinfo.tex
+       $(srcdir)/version.texi
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.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/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/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
        $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
-       $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+       $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/acinclude.m4 \
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
+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_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
 SOURCES =
 DIST_SOURCES =
 INFO_DEPS = $(srcdir)/gcrypt.info
-am__TEXINFO_TEX_DIR = $(srcdir)
+TEXINFO_TEX = $(top_srcdir)/build-aux/texinfo.tex
+am__TEXINFO_TEX_DIR = $(top_srcdir)/build-aux
 DVIS = gcrypt.dvi
 PDFS = gcrypt.pdf
 PSS = gcrypt.ps
@@ -83,7 +108,12 @@ TEXI2PDF = $(TEXI2DVI) --pdf --batch
 MAKEINFOHTML = $(MAKEINFO) --html
 AM_MAKEINFOHTMLFLAGS = $(AM_MAKEINFOFLAGS)
 DVIPS = dvips
-am__installdirs = "$(DESTDIR)$(infodir)"
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
+am__installdirs = "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)"
 am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
 am__vpath_adj = case $$p in \
     $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
@@ -105,9 +135,19 @@ am__nobase_list = $(am__nobase_strip_setup); \
 am__base_list = \
   sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
   sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
+man1dir = $(mandir)/man1
+NROFF = nroff
+MANS = $(man_MANS)
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AR = @AR@
 AS = @AS@
 AUTOCONF = @AUTOCONF@
@@ -122,6 +162,7 @@ CCAS = @CCAS@
 CCASDEPMODE = @CCASDEPMODE@
 CCASFLAGS = @CCASFLAGS@
 CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
@@ -141,6 +182,8 @@ FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
 FGREP = @FGREP@
 GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
 GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_HWF_MODULES = @GCRYPT_HWF_MODULES@
+GCRYPT_KDFS = @GCRYPT_KDFS@
 GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
 GCRYPT_RANDOM = @GCRYPT_RANDOM@
 GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
@@ -166,14 +209,19 @@ 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@
 MKDIR_P = @MKDIR_P@
 MPI_SFLAGS = @MPI_SFLAGS@
 NM = @NM@
@@ -196,16 +244,19 @@ PTH_CONFIG = @PTH_CONFIG@
 PTH_LIBS = @PTH_LIBS@
 RANLIB = @RANLIB@
 RC = @RC@
+RUN_LARGE_DATA_TESTS = @RUN_LARGE_DATA_TESTS@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
 SYS_SOCKET_H = @SYS_SOCKET_H@
 VERSION = @VERSION@
+VERSION_NUMBER = @VERSION_NUMBER@
 abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
@@ -241,7 +292,6 @@ libdir = @libdir@
 libexecdir = @libexecdir@
 localedir = @localedir@
 localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 oldincludedir = @oldincludedir@
@@ -257,18 +307,26 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
-EXTRA_DIST = README.apichanges HACKING \
+EXTRA_DIST = README.apichanges HACKING DCO \
             libgcrypt-modules.eps fips-fsm.eps \
             libgcrypt-modules.png fips-fsm.png \
-             libgcrypt-modules.pdf fips-fsm.pdf
+             libgcrypt-modules.pdf fips-fsm.pdf \
+            yat2m.c
 
-DISTCLEANFILES = gcrypt.cps
+DISTCLEANFILES = gcrypt.cps yat2m-stamp.tmp yat2m-stamp $(myman_pages)
+CLEANFILES = yat2m
 BUILT_SOURCES = libgcrypt-modules.eps fips-fsm.eps \
                 libgcrypt-modules.png fips-fsm.png \
                 libgcrypt-modules.pdf fips-fsm.pdf
 
 info_TEXINFOS = gcrypt.texi
 gcrypt_TEXINFOS = lgpl.texi gpl.texi libgcrypt-modules.fig fips-fsm.fig
+YAT2M_OPTIONS = -I $(srcdir) \
+       --release "Libgcrypt @PACKAGE_VERSION@" --source "Libgcrypt"
+
+myman_sources = gcrypt.texi
+myman_pages = hmac256.1
+man_MANS = $(myman_pages)
 all: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) all-am
 
@@ -363,7 +421,7 @@ gcrypt.html: gcrypt.texi $(srcdir)/version.texi $(gcrypt_TEXINFOS)
 $(srcdir)/version.texi: @MAINTAINER_MODE_TRUE@ $(srcdir)/stamp-vti
 $(srcdir)/stamp-vti: gcrypt.texi $(top_srcdir)/configure
        @(dir=.; test -f ./gcrypt.texi || dir=$(srcdir); \
-       set `$(SHELL) $(srcdir)/mdate-sh $$dir/gcrypt.texi`; \
+       set `$(SHELL) $(top_srcdir)/build-aux/mdate-sh $$dir/gcrypt.texi`; \
        echo "@set UPDATED $$1 $$2 $$3"; \
        echo "@set UPDATED-MONTH $$2 $$3"; \
        echo "@set EDITION $(VERSION)"; \
@@ -403,9 +461,7 @@ uninstall-html-am:
 
 uninstall-info-am:
        @$(PRE_UNINSTALL)
-       @if test -d '$(DESTDIR)$(infodir)' && \
-           (install-info --version && \
-            install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+       @if test -d '$(DESTDIR)$(infodir)' && $(am__can_run_installinfo); then \
          list='$(INFO_DEPS)'; \
          for file in $$list; do \
            relfile=`echo "$$file" | sed 's|^.*/||'`; \
@@ -476,6 +532,49 @@ maintainer-clean-aminfo:
          echo " rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]"; \
          rm -f $$i $$i-[0-9] $$i-[0-9][0-9] $$i_i[0-9] $$i_i[0-9][0-9]; \
        done
+install-man1: $(man_MANS)
+       @$(NORMAL_INSTALL)
+       @list1=''; \
+       list2='$(man_MANS)'; \
+       test -n "$(man1dir)" \
+         && test -n "`echo $$list1$$list2`" \
+         || exit 0; \
+       echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
+       $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
+       { for i in $$list1; do echo "$$i"; done;  \
+       if test -n "$$list2"; then \
+         for i in $$list2; do echo "$$i"; done \
+           | sed -n '/\.1[a-z]*$$/p'; \
+       fi; \
+       } | while read p; do \
+         if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
+         echo "$$d$$p"; echo "$$p"; \
+       done | \
+       sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
+             -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
+       sed 'N;N;s,\n, ,g' | { \
+       list=; while read file base inst; do \
+         if test "$$base" = "$$inst"; then list="$$list $$file"; else \
+           echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+           $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
+         fi; \
+       done; \
+       for i in $$list; do echo "$$i"; done | $(am__base_list) | \
+       while read files; do \
+         test -z "$$files" || { \
+           echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
+           $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
+       done; }
+
+uninstall-man1:
+       @$(NORMAL_UNINSTALL)
+       @list=''; test -n "$(man1dir)" || exit 0; \
+       files=`{ for i in $$list; do echo "$$i"; done; \
+       l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
+         sed -n '/\.1[a-z]*$$/p'; \
+       } | 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:
 
@@ -484,6 +583,19 @@ CTAGS:
 
 
 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)'; \
@@ -519,9 +631,9 @@ distdir: $(DISTFILES)
 check-am: all-am
 check: $(BUILT_SOURCES)
        $(MAKE) $(AM_MAKEFLAGS) check-am
-all-am: Makefile $(INFO_DEPS)
+all-am: Makefile $(INFO_DEPS) $(MANS)
 installdirs:
-       for dir in "$(DESTDIR)$(infodir)"; do \
+       for dir in "$(DESTDIR)$(infodir)" "$(DESTDIR)$(man1dir)"; do \
          test -z "$$dir" || $(MKDIR_P) "$$dir"; \
        done
 install: $(BUILT_SOURCES)
@@ -535,13 +647,19 @@ install-am: all-am
 
 installcheck: installcheck-am
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-         `test -z '$(STRIP)' || \
-           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+       if test -z '$(STRIP)'; then \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+             install; \
+       else \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+           "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+       fi
 mostlyclean-generic:
 
 clean-generic:
+       -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
 
 distclean-generic:
        -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
@@ -572,14 +690,17 @@ info: info-am
 
 info-am: $(INFO_DEPS)
 
-install-data-am: install-info-am
+install-data-am: install-info-am install-man
 
 install-dvi: install-dvi-am
 
 install-dvi-am: $(DVIS)
        @$(NORMAL_INSTALL)
-       test -z "$(dvidir)" || $(MKDIR_P) "$(DESTDIR)$(dvidir)"
        @list='$(DVIS)'; test -n "$(dvidir)" || list=; \
+       if test -n "$$list"; then \
+         echo " $(MKDIR_P) '$(DESTDIR)$(dvidir)'"; \
+         $(MKDIR_P) "$(DESTDIR)$(dvidir)" || exit 1; \
+       fi; \
        for p in $$list; do \
          if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
          echo "$$d$$p"; \
@@ -594,18 +715,22 @@ install-html: install-html-am
 
 install-html-am: $(HTMLS)
        @$(NORMAL_INSTALL)
-       test -z "$(htmldir)" || $(MKDIR_P) "$(DESTDIR)$(htmldir)"
        @list='$(HTMLS)'; list2=; test -n "$(htmldir)" || list=; \
+       if test -n "$$list"; then \
+         echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)'"; \
+         $(MKDIR_P) "$(DESTDIR)$(htmldir)" || exit 1; \
+       fi; \
        for p in $$list; do \
          if test -f "$$p" || test -d "$$p"; then d=; else d="$(srcdir)/"; fi; \
          $(am__strip_dir) \
-         if test -d "$$d$$p"; then \
+         d2=$$d$$p; \
+         if test -d "$$d2"; then \
            echo " $(MKDIR_P) '$(DESTDIR)$(htmldir)/$$f'"; \
            $(MKDIR_P) "$(DESTDIR)$(htmldir)/$$f" || exit 1; \
-           echo " $(INSTALL_DATA) '$$d$$p'/* '$(DESTDIR)$(htmldir)/$$f'"; \
-           $(INSTALL_DATA) "$$d$$p"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \
+           echo " $(INSTALL_DATA) '$$d2'/* '$(DESTDIR)$(htmldir)/$$f'"; \
+           $(INSTALL_DATA) "$$d2"/* "$(DESTDIR)$(htmldir)/$$f" || exit $$?; \
          else \
-           list2="$$list2 $$d$$p"; \
+           list2="$$list2 $$d2"; \
          fi; \
        done; \
        test -z "$$list2" || { echo "$$list2" | $(am__base_list) | \
@@ -617,9 +742,12 @@ install-info: install-info-am
 
 install-info-am: $(INFO_DEPS)
        @$(NORMAL_INSTALL)
-       test -z "$(infodir)" || $(MKDIR_P) "$(DESTDIR)$(infodir)"
        @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
        list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
+       if test -n "$$list"; then \
+         echo " $(MKDIR_P) '$(DESTDIR)$(infodir)'"; \
+         $(MKDIR_P) "$(DESTDIR)$(infodir)" || exit 1; \
+       fi; \
        for file in $$list; do \
          case $$file in \
            $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
@@ -637,8 +765,7 @@ install-info-am: $(INFO_DEPS)
          echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(infodir)'"; \
          $(INSTALL_DATA) $$files "$(DESTDIR)$(infodir)" || exit $$?; done
        @$(POST_INSTALL)
-       @if (install-info --version && \
-            install-info --version 2>&1 | sed 1q | grep -i -v debian) >/dev/null 2>&1; then \
+       @if $(am__can_run_installinfo); then \
          list='$(INFO_DEPS)'; test -n "$(infodir)" || list=; \
          for file in $$list; do \
            relfile=`echo "$$file" | sed 's|^.*/||'`; \
@@ -646,14 +773,17 @@ install-info-am: $(INFO_DEPS)
            install-info --info-dir="$(DESTDIR)$(infodir)" "$(DESTDIR)$(infodir)/$$relfile" || :;\
          done; \
        else : ; fi
-install-man:
+install-man: install-man1
 
 install-pdf: install-pdf-am
 
 install-pdf-am: $(PDFS)
        @$(NORMAL_INSTALL)
-       test -z "$(pdfdir)" || $(MKDIR_P) "$(DESTDIR)$(pdfdir)"
        @list='$(PDFS)'; test -n "$(pdfdir)" || list=; \
+       if test -n "$$list"; then \
+         echo " $(MKDIR_P) '$(DESTDIR)$(pdfdir)'"; \
+         $(MKDIR_P) "$(DESTDIR)$(pdfdir)" || exit 1; \
+       fi; \
        for p in $$list; do \
          if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
          echo "$$d$$p"; \
@@ -665,8 +795,11 @@ install-ps: install-ps-am
 
 install-ps-am: $(PSS)
        @$(NORMAL_INSTALL)
-       test -z "$(psdir)" || $(MKDIR_P) "$(DESTDIR)$(psdir)"
        @list='$(PSS)'; test -n "$(psdir)" || list=; \
+       if test -n "$$list"; then \
+         echo " $(MKDIR_P) '$(DESTDIR)$(psdir)'"; \
+         $(MKDIR_P) "$(DESTDIR)$(psdir)" || exit 1; \
+       fi; \
        for p in $$list; do \
          if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
          echo "$$d$$p"; \
@@ -695,7 +828,9 @@ ps: ps-am
 ps-am: $(PSS)
 
 uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \
-       uninstall-pdf-am uninstall-ps-am
+       uninstall-man uninstall-pdf-am uninstall-ps-am
+
+uninstall-man: uninstall-man1
 
 .MAKE: all check install install-am install-strip
 
@@ -705,16 +840,19 @@ uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-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-aminfo \
+       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 \
        uninstall-dvi-am uninstall-html-am uninstall-info-am \
-       uninstall-pdf-am uninstall-ps-am
+       uninstall-man uninstall-man1 uninstall-pdf-am uninstall-ps-am
 
 
+yat2m: yat2m.c
+       $(CC_FOR_BUILD) -o $@ $(srcdir)/yat2m.c
+
 .fig.png:
        fig2dev -L png `test -f '$<' || echo '$(srcdir)/'`$< $@
 
@@ -727,6 +865,29 @@ uninstall-am: uninstall-dvi-am uninstall-html-am uninstall-info-am \
 .fig.pdf:
        fig2dev -L pdf `test -f '$<' || echo '$(srcdir)/'`$< $@
 
+yat2m-stamp: $(myman_sources)
+       @rm -f yat2m-stamp.tmp
+       @touch yat2m-stamp.tmp
+       for file in $(myman_sources) ; do \
+              ./yat2m $(YAT2M_OPTIONS) --store \
+                 `test -f '$$file' || echo '$(srcdir)/'`$$file ; done
+       @mv -f yat2m-stamp.tmp $@
+
+yat2m-stamp: yat2m
+
+$(myman_pages) : yat2m-stamp
+       @if test -f $@; then :; else \
+            trap 'rm -rf yat2m-stamp yat2m-lock' 1 2 13 15; \
+               if mkdir yat2m-lock 2>/dev/null; then \
+                 rm -f yat2m-stamp; \
+                 $(MAKE) $(AM_MAKEFLAGS) yat2m-stamp; \
+                 rmdir yat2m-lock; \
+               else \
+                 while test -d yat2m-lock; do sleep 1; done; \
+                 test -f yat2m-stamp; exit $$?; \
+               fi; \
+             fi
+
 # 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.
index b1223ca..9006b13 100644 (file)
@@ -1,11 +1,11 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/wk/w/libgcrypt/doc/fips-fsm.fig
-%%Creator: fig2dev Version 3.2 Patchlevel 4
-%%CreationDate: Mon Mar 28 14:04:57 2011
-%%For: wk@vigenere (Werner Koch,,,)
+%!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
 %%BoundingBox: 0 0 497 579
-%%Magnification: 1.0000
+%Magnification: 1.0000
 %%EndComments
+%%BeginProlog
 /$F2psDict 200 dict def
 $F2psDict begin
 $F2psDict /mtrx matrix put
@@ -42,24 +42,20 @@ $F2psDict /mtrx matrix put
 /col29 {1.000 0.750 0.750 srgb} bind def
 /col30 {1.000 0.880 0.880 srgb} bind def
 /col31 {1.000 0.840 0.000 srgb} bind def
-/col32 {0.609 0.000 0.000 srgb} bind def
-/col33 {0.547 0.547 0.547 srgb} bind def
-/col34 {0.547 0.547 0.547 srgb} bind def
-/col35 {0.258 0.258 0.258 srgb} bind def
-/col36 {0.547 0.547 0.547 srgb} bind def
-/col37 {0.258 0.258 0.258 srgb} bind def
-/col38 {0.547 0.547 0.547 srgb} bind def
-/col39 {0.258 0.258 0.258 srgb} bind def
-/col40 {0.547 0.547 0.547 srgb} bind def
-/col41 {0.258 0.258 0.258 srgb} bind def
-/col42 {0.547 0.547 0.547 srgb} bind def
-/col43 {0.258 0.258 0.258 srgb} bind def
+/col32 {0.612 0.000 0.000 srgb} bind def
+/col33 {0.549 0.549 0.549 srgb} bind def
+/col34 {0.549 0.549 0.549 srgb} bind def
+/col35 {0.259 0.259 0.259 srgb} bind def
+/col36 {0.549 0.549 0.549 srgb} bind def
+/col37 {0.259 0.259 0.259 srgb} bind def
+/col38 {0.549 0.549 0.549 srgb} bind def
+/col39 {0.259 0.259 0.259 srgb} bind def
+/col40 {0.549 0.549 0.549 srgb} bind def
+/col41 {0.259 0.259 0.259 srgb} bind def
+/col42 {0.549 0.549 0.549 srgb} bind def
+/col43 {0.259 0.259 0.259 srgb} bind def
 
 end
-save
-newpath 0 579 moveto 0 0 lineto 497 0 lineto 497 579 lineto closepath clip newpath
--56.9 596.0 translate
-1 -1 scale
 
 /cp {closepath} bind def
 /ef {eofill} bind def
@@ -147,10 +143,22 @@ newfontname newfont definefont pop end } def
 /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
 /$F2psEnd {$F2psEnteredState restore end} def
 
+/pageheader {
+save
+newpath 0 579 moveto 0 0 lineto 497 0 lineto 497 579 lineto closepath clip newpath
+-56.9 596.0 translate
+1 -1 scale
 $F2psBegin
 10 setmiterlimit
 0 slj 0 slc
  0.06299 0.06299 sc
+} bind def
+/pagefooter {
+$F2psEnd
+restore
+} bind def
+%%EndProlog
+pageheader
 %
 % Fig objects follow
 %
@@ -160,202 +168,120 @@ $F2psBegin
 7.500 slw
 n 3238 1735 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-3157 1805 m
-gs 1 -1 sc (1) col0 sh gr
 % Ellipse
 n 2408 3749 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-2327 3819 m
-gs 1 -1 sc (2) col0 sh gr
 % Ellipse
 n 1708 5809 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-1627 5879 m
-gs 1 -1 sc (3) col0 sh gr
 % Ellipse
 n 5848 1685 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-5767 1755 m
-gs 1 -1 sc (6) col0 sh gr
 % Ellipse
 n 6128 7899 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-6047 7969 m
-gs 1 -1 sc (7) col0 sh gr
 % Ellipse
 n 7568 4889 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-7487 4959 m
-gs 1 -1 sc (8) col0 sh gr
 % Ellipse
 n 6008 3879 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-5882 3940 m
-gs 1 -1 sc (10) col0 sh gr
 % Ellipse
 n 5418 2659 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-5292 2720 m
-gs 1 -1 sc (11) col0 sh gr
 % Ellipse
 n 4268 3715 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-4142 3776 m
-gs 1 -1 sc (12) col0 sh gr
 % Ellipse
 n 3208 5865 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-3082 5926 m
-gs 1 -1 sc (13) col0 sh gr
 % Ellipse
 n 4178 6765 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-4052 6826 m
-gs 1 -1 sc (14) col0 sh gr
 % Ellipse
 n 4558 7355 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-4432 7416 m
-gs 1 -1 sc (15) col0 sh gr
 % Ellipse
 n 5208 7365 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-5127 7435 m
-gs 1 -1 sc (5) col0 sh gr
 % Ellipse
 n 3708 7715 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-3582 7776 m
-gs 1 -1 sc (16) col0 sh gr
 % Ellipse
 n 3038 7925 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-2957 7995 m
-gs 1 -1 sc (4) col0 sh gr
 % Ellipse
 n 6568 5895 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-6487 5965 m
-gs 1 -1 sc (9) col0 sh gr
 % Polyline
+0 slj
+0 slc
 n 3900 8370 m 3600 8370 3600 9150 300 arcto 4 {pop} repeat
   3600 9450 5670 9450 300 arcto 4 {pop} repeat
   5970 9450 5970 8670 300 arcto 4 {pop} repeat
   5970 8370 3900 8370 300 arcto 4 {pop} repeat
  cp gs col0 s gr 
-/Times-Roman-iso ff 360.00 scf sf
-3870 9000 m
-gs 1 -1 sc (Operational) col0 sh gr
 % Polyline
 n 1215 4335 m 915 4335 915 5145 300 arcto 4 {pop} repeat
   915 5445 2640 5445 300 arcto 4 {pop} repeat
   2940 5445 2940 4635 300 arcto 4 {pop} repeat
   2940 4335 1215 4335 300 arcto 4 {pop} repeat
  cp gs col0 s gr 
-/Times-Roman-iso ff 360.00 scf sf
-1620 4995 m
-gs 1 -1 sc (Init) col0 sh gr
 % Polyline
 n 1230 6345 m 930 6345 930 7155 300 arcto 4 {pop} repeat
   930 7455 2655 7455 300 arcto 4 {pop} repeat
   2955 7455 2955 6645 300 arcto 4 {pop} repeat
   2955 6345 1230 6345 300 arcto 4 {pop} repeat
  cp gs col0 s gr 
-/Times-Roman-iso ff 360.00 scf sf
-1215 7020 m
-gs 1 -1 sc (Self-Test) col0 sh gr
 % Polyline
 n 7050 6360 m 6750 6360 6750 7170 300 arcto 4 {pop} repeat
   6750 7470 8475 7470 300 arcto 4 {pop} repeat
   8775 7470 8775 6660 300 arcto 4 {pop} repeat
   8775 6360 7050 6360 300 arcto 4 {pop} repeat
  cp gs col0 s gr 
-/Times-Roman-iso ff 360.00 scf sf
-7335 7020 m
-gs 1 -1 sc (Error) col0 sh gr
 % Polyline
 n 4125 4335 m 3825 4335 3825 5145 300 arcto 4 {pop} repeat
   3825 5445 5550 5445 300 arcto 4 {pop} repeat
   5850 5445 5850 4635 300 arcto 4 {pop} repeat
   5850 4335 4125 4335 300 arcto 4 {pop} repeat
  cp gs col0 s gr 
-/Times-Roman-iso ff 360.00 scf sf
-3915 4995 m
-gs 1 -1 sc (Fatal-Error) col0 sh gr
 % Polyline
 n 7050 2310 m 6750 2310 6750 3120 300 arcto 4 {pop} repeat
   6750 3420 8475 3420 300 arcto 4 {pop} repeat
   8775 3420 8775 2610 300 arcto 4 {pop} repeat
   8775 2310 7050 2310 300 arcto 4 {pop} repeat
  cp gs col0 s gr 
-/Times-Roman-iso ff 360.00 scf sf
-6930 2970 m
-gs 1 -1 sc (Shutdown) col0 sh gr
 % Polyline
 n 2775 2295 m 2475 2295 2475 3105 300 arcto 4 {pop} repeat
   2475 3405 4200 3405 300 arcto 4 {pop} repeat
   4500 3405 4500 2595 300 arcto 4 {pop} repeat
   4500 2295 2775 2295 300 arcto 4 {pop} repeat
  cp gs col0 s gr 
-/Times-Roman-iso ff 360.00 scf sf
-2655 2970 m
-gs 1 -1 sc (Power-On) col0 sh gr
 % Polyline
 n 2775 285 m 2475 285 2475 1095 300 arcto 4 {pop} repeat
   2475 1395 4200 1395 300 arcto 4 {pop} repeat
   4500 1395 4500 585 300 arcto 4 {pop} repeat
   4500 285 2775 285 300 arcto 4 {pop} repeat
  cp gs col0 s gr 
-/Times-Roman-iso ff 360.00 scf sf
-2565 945 m
-gs 1 -1 sc (Power-Off) col0 sh gr
 % Ellipse
 n 4192 6338 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-4066 6399 m
-gs 1 -1 sc (17) col0 sh gr
 % Ellipse
 n 3202 4507 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-3076 4568 m
-gs 1 -1 sc (19) col0 sh gr
 % Ellipse
 n 3181 5161 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-3055 5222 m
-gs 1 -1 sc (18) col0 sh gr
 % Ellipse
 n 7709 7996 142 142 0 360 DrawEllipse gs col0 s gr
 
-/Courier-Oblique-iso ff 180.00 scf sf
-7612 8047 m
-gs 1 -1 sc (20) col0 sh gr
 % Arc
 15.000 slw
 1 slc
 gs  clippath
-2899 6648 m 2920 6766 l 3203 6716 l 2957 6699 l 3182 6598 l cp
+3182 6598 m 2899 6648 l 2920 6766 l 3203 6716 l 3203 6716 l 2957 6699 l 3182 6598 l cp
 eoclip
-n 4837.5 16740.0 10215.6 -79.2 -100.8 arcn
+n 4837.5 16740.0 10215.6 -79.2098 -100.7902 arcn
 gs col0 s gr
  gr
 
@@ -365,9 +291,9 @@ n 3182 6598 m 2957 6699 l 3203 6716 l 3182 6598 l  cp gs 0.00 setgray ef gr  col
 % Arc
 1 slc
 gs  clippath
-2911 7184 m 2908 7304 l 3195 7313 l 2957 7246 l 3198 7193 l cp
+3198 7193 m 2911 7184 l 2908 7304 l 3195 7313 l 3195 7313 l 2957 7246 l 3198 7193 l cp
 eoclip
-n 3026.1 8399.8 1159.2 -1.5 -95.0 arcn
+n 3026.1 8399.8 1159.2 -1.4743 -95.0051 arcn
 gs col0 s gr
  gr
 
@@ -377,9 +303,9 @@ n 3198 7193 m 2957 7246 l 3195 7313 l 3198 7193 l  cp gs 0.00 setgray ef gr  col
 % Arc
 1 slc
 gs  clippath
-6757 6631 m 6772 6512 l 6487 6477 l 6718 6566 l 6472 6596 l cp
+6472 6596 m 6757 6631 l 6772 6512 l 6487 6477 l 6487 6477 l 6718 6566 l 6472 6596 l cp
 eoclip
-n 7663.1 -2028.8 8647.1 123.6 96.1 arcn
+n 7663.1 -2028.8 8647.1 123.5832 96.0617 arcn
 gs col0 s gr
  gr
 
@@ -389,9 +315,9 @@ n 6472 6596 m 6718 6566 l 6487 6477 l 6472 6596 l  cp gs 0.00 setgray ef gr  col
 % Arc
 1 slc
 gs  clippath
-8336 7494 m 8241 7421 l 8066 7650 l 8260 7496 l 8162 7723 l cp
+8162 7723 m 8336 7494 l 8241 7421 l 8066 7650 l 8066 7650 l 8260 7496 l 8162 7723 l cp
 eoclip
-n 7717.5 7211.2 619.2 155.3 24.7 arcn
+n 7717.5 7211.2 619.2 155.2976 24.7024 arcn
 gs col0 s gr
  gr
 
@@ -401,7 +327,7 @@ n 8162 7723 m 8260 7496 l 8066 7650 l 8162 7723 l  cp gs 0.00 setgray ef gr  col
 % Polyline
 1 slc
 gs  clippath
-3360 2310 m 3480 2310 l 3480 2023 l 3420 2263 l 3360 2023 l cp
+3360 2023 m 3360 2310 l 3480 2310 l 3480 2023 l 3480 2023 l 3420 2263 l 3360 2023 l cp
 eoclip
 n 3420 1395 m
  3420 2295 l gs col0 s gr gr
@@ -412,7 +338,7 @@ n 3360 2023 m 3420 2263 l 3480 2023 l 3360 2023 l  cp gs 0.00 setgray ef gr  col
 % Polyline
 1 slc
 gs  clippath
-4794 4378 m 4860 4278 l 4621 4118 l 4788 4302 l 4555 4218 l cp
+4555 4218 m 4794 4378 l 4860 4278 l 4621 4118 l 4621 4118 l 4788 4302 l 4555 4218 l cp
 eoclip
 n 3465 3420 m
  4815 4320 l gs col0 s gr gr
@@ -423,7 +349,7 @@ n 4555 4218 m 4788 4302 l 4621 4118 l 4555 4218 l  cp gs 0.00 setgray ef gr  col
 % Polyline
 1 slc
 gs  clippath
-1830 6360 m 1950 6360 l 1950 6073 l 1890 6313 l 1830 6073 l cp
+1830 6073 m 1830 6360 l 1950 6360 l 1950 6073 l 1950 6073 l 1890 6313 l 1830 6073 l cp
 eoclip
 n 1890 5445 m
  1890 6345 l gs col0 s gr gr
@@ -434,7 +360,7 @@ n 1830 6073 m 1890 6313 l 1950 6073 l 1830 6073 l  cp gs 0.00 setgray ef gr  col
 % Polyline
 1 slc
 gs  clippath
-3699 8465 m 3790 8386 l 3601 8170 l 3714 8391 l 3511 8249 l cp
+3511 8249 m 3699 8465 l 3790 8386 l 3601 8170 l 3601 8170 l 3714 8391 l 3511 8249 l cp
 eoclip
 n 2835 7380 m
  3735 8415 l gs col0 s gr gr
@@ -445,7 +371,7 @@ n 3511 8249 m 3714 8391 l 3601 8170 l 3511 8249 l  cp gs 0.00 setgray ef gr  col
 % Polyline
 1 slc
 gs  clippath
-4785 5475 m 4665 5475 l 4665 5762 l 4725 5522 l 4785 5762 l cp
+4785 5762 m 4785 5475 l 4665 5475 l 4665 5762 l 4665 5762 l 4725 5522 l 4785 5762 l cp
 eoclip
 n 4725 8370 m
  4725 5490 l gs col0 s gr gr
@@ -456,7 +382,7 @@ n 4785 5762 m 4725 5522 l 4665 5762 l 4785 5762 l  cp gs 0.00 setgray ef gr  col
 % Polyline
 1 slc
 gs  clippath
-7395 3432 m 7287 3380 l 7162 3639 l 7321 3449 l 7270 3691 l cp
+7270 3691 m 7395 3432 l 7287 3380 l 7162 3639 l 7162 3639 l 7321 3449 l 7270 3691 l cp
 eoclip
 n 4950 8370 m
  7335 3420 l gs col0 s gr gr
@@ -467,7 +393,7 @@ n 7270 3691 m 7321 3449 l 7162 3639 l 7270 3691 l  cp gs 0.00 setgray ef gr  col
 % Polyline
 1 slc
 gs  clippath
-6765 6990 m 6765 6870 l 6478 6870 l 6718 6930 l 6478 6990 l cp
+6478 6990 m 6765 6990 l 6765 6870 l 6478 6870 l 6478 6870 l 6718 6930 l 6478 6990 l cp
 eoclip
 n 2925 6930 m
  6750 6930 l gs col0 s gr gr
@@ -478,7 +404,7 @@ n 6478 6990 m 6718 6930 l 6478 6870 l 6478 6990 l  cp gs 0.00 setgray ef gr  col
 % Polyline
 1 slc
 gs  clippath
-3969 5384 m 3880 5303 l 3686 5515 l 3893 5379 l 3774 5596 l cp
+3774 5596 m 3969 5384 l 3880 5303 l 3686 5515 l 3686 5515 l 3893 5379 l 3774 5596 l cp
 eoclip
 n 2880 6480 m
  3915 5355 l gs col0 s gr gr
@@ -489,7 +415,7 @@ n 3774 5596 m 3893 5379 l 3686 5515 l 3774 5596 l  cp gs 0.00 setgray ef gr  col
 % Polyline
 1 slc
 gs  clippath
-6765 2895 m 6765 2775 l 6478 2775 l 6718 2835 l 6478 2895 l cp
+6478 2895 m 6765 2895 l 6765 2775 l 6478 2775 l 6478 2775 l 6718 2835 l 6478 2895 l cp
 eoclip
 n 4500 2835 m
  6750 2835 l gs col0 s gr gr
@@ -500,7 +426,7 @@ n 6478 2895 m 6718 2835 l 6478 2775 l 6478 2895 l  cp gs 0.00 setgray ef gr  col
 % Polyline
 1 slc
 gs  clippath
-7800 3405 m 7680 3405 l 7680 3692 l 7740 3452 l 7800 3692 l cp
+7800 3692 m 7800 3405 l 7680 3405 l 7680 3692 l 7680 3692 l 7740 3452 l 7800 3692 l cp
 eoclip
 n 7740 6345 m
  7740 3420 l gs col0 s gr gr
@@ -511,7 +437,7 @@ n 7800 3692 m 7740 3452 l 7680 3692 l 7800 3692 l  cp gs 0.00 setgray ef gr  col
 % Polyline
 1 slc
 gs  clippath
-1846 4276 m 1908 4379 l 2154 4229 l 1918 4303 l 2092 4127 l cp
+2092 4127 m 1846 4276 l 1908 4379 l 2154 4229 l 2154 4229 l 1918 4303 l 2092 4127 l cp
 eoclip
 n 3375 3420 m
  1890 4320 l gs col0 s gr gr
@@ -522,7 +448,7 @@ n 2092 4127 m 1918 4303 l 2154 4229 l 2092 4127 l  cp gs 0.00 setgray ef gr  col
 % Polyline
 1 slc
 gs  clippath
-6893 3361 m 6808 3276 l 6604 3480 l 6817 3353 l 6689 3565 l cp
+6689 3565 m 6893 3361 l 6808 3276 l 6604 3480 l 6604 3480 l 6817 3353 l 6689 3565 l cp
 eoclip
 n 5760 4410 m
  6840 3330 l gs col0 s gr gr
@@ -533,7 +459,7 @@ n 6689 3565 m 6817 3353 l 6604 3480 l 6689 3565 l  cp gs 0.00 setgray ef gr  col
 % Polyline
 1 slc
 gs  clippath
-4510 794 m 4461 903 l 4724 1020 l 4530 868 l 4773 910 l cp
+4773 910 m 4510 794 l 4461 903 l 4724 1020 l 4724 1020 l 4530 868 l 4773 910 l cp
 eoclip
 n 7740 2295 m
  4500 855 l gs col0 s gr gr
@@ -544,7 +470,7 @@ n 4773 910 m 4530 868 l 4724 1020 l 4773 910 l  cp gs 0.00 setgray ef gr  col0 s
 % Polyline
 1 slc
 gs  clippath
-5791 5301 m 5706 5386 l 5910 5590 l 5783 5378 l 5995 5505 l cp
+5995 5505 m 5791 5301 l 5706 5386 l 5910 5590 l 5910 5590 l 5783 5378 l 5995 5505 l cp
 eoclip
 n 6840 6435 m
  5760 5355 l gs col0 s gr gr
@@ -555,7 +481,7 @@ n 5995 5505 m 5783 5378 l 5910 5590 l 5995 5505 l  cp gs 0.00 setgray ef gr  col
 % Polyline
 1 slc
 gs  clippath
-6895 7408 m 6804 7329 l 6615 7545 l 6819 7404 l 6706 7624 l cp
+6706 7624 m 6895 7408 l 6804 7329 l 6615 7545 l 6615 7545 l 6819 7404 l 6706 7624 l cp
 eoclip
 n 5895 8460 m
  6840 7380 l gs col0 s gr gr
@@ -566,7 +492,7 @@ n 6706 7624 m 6819 7404 l 6615 7545 l 6706 7624 l  cp gs 0.00 setgray ef gr  col
 % Polyline
 1 slc
 gs  clippath
-3840 4740 m 3840 4620 l 3553 4620 l 3793 4680 l 3553 4740 l cp
+3553 4740 m 3840 4740 l 3840 4620 l 3553 4620 l 3553 4620 l 3793 4680 l 3553 4740 l cp
 eoclip
 n 2925 4680 m
  3825 4680 l gs col0 s gr gr
@@ -574,7 +500,92 @@ n 2925 4680 m
 % arrowhead
 0 slc
 n 3553 4740 m 3793 4680 l 3553 4620 l 3553 4740 l  cp gs 0.00 setgray ef gr  col0 s
+/Courier-Oblique-iso ff 180.00 scf sf
+3157 1805 m
+gs 1 -1 sc (1) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+2327 3819 m
+gs 1 -1 sc (2) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+1627 5879 m
+gs 1 -1 sc (3) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+5767 1755 m
+gs 1 -1 sc (6) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+6047 7969 m
+gs 1 -1 sc (7) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+7487 4959 m
+gs 1 -1 sc (8) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+5882 3940 m
+gs 1 -1 sc (10) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+5292 2720 m
+gs 1 -1 sc (11) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+4142 3776 m
+gs 1 -1 sc (12) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+3082 5926 m
+gs 1 -1 sc (13) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+4052 6826 m
+gs 1 -1 sc (14) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+4432 7416 m
+gs 1 -1 sc (15) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+5127 7435 m
+gs 1 -1 sc (5) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+3582 7776 m
+gs 1 -1 sc (16) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+2957 7995 m
+gs 1 -1 sc (4) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+6487 5965 m
+gs 1 -1 sc (9) col0 sh gr
+/Times-Roman-iso ff 360.00 scf sf
+3870 9000 m
+gs 1 -1 sc (Operational) col0 sh gr
+/Times-Roman-iso ff 360.00 scf sf
+1620 4995 m
+gs 1 -1 sc (Init) col0 sh gr
+/Times-Roman-iso ff 360.00 scf sf
+1215 7020 m
+gs 1 -1 sc (Self-Test) col0 sh gr
+/Times-Roman-iso ff 360.00 scf sf
+7335 7020 m
+gs 1 -1 sc (Error) col0 sh gr
+/Times-Roman-iso ff 360.00 scf sf
+3915 4995 m
+gs 1 -1 sc (Fatal-Error) col0 sh gr
+/Times-Roman-iso ff 360.00 scf sf
+6930 2970 m
+gs 1 -1 sc (Shutdown) col0 sh gr
+/Times-Roman-iso ff 360.00 scf sf
+2655 2970 m
+gs 1 -1 sc (Power-On) col0 sh gr
+/Times-Roman-iso ff 360.00 scf sf
+2565 945 m
+gs 1 -1 sc (Power-Off) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+4066 6399 m
+gs 1 -1 sc (17) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+3076 4568 m
+gs 1 -1 sc (19) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+3055 5222 m
+gs 1 -1 sc (18) col0 sh gr
+/Courier-Oblique-iso ff 180.00 scf sf
+7612 8047 m
+gs 1 -1 sc (20) col0 sh gr
 % here ends figure;
-$F2psEnd
-rs
+pagefooter
 showpage
+%%Trailer
+%EOF
index a8bd445..9e24e22 100644 (file)
Binary files a/doc/fips-fsm.pdf and b/doc/fips-fsm.pdf differ
index 990b8b2..515072c 100644 (file)
Binary files a/doc/fips-fsm.png and b/doc/fips-fsm.png differ
index 9eed5ce..79f8b6c 100644 (file)
@@ -1,11 +1,12 @@
-This is /home/wk/w/libgcrypt/doc/gcrypt.info, produced by makeinfo
-version 4.13 from /home/wk/w/libgcrypt/doc/gcrypt.texi.
+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.5.0, 29 June 2011), which is
+This manual is for Libgcrypt (version 1.6.1, 29 January 2014), which is
 GNU's library of cryptographic building blocks.
 
-   Copyright (C) 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011
-Free Software Foundation, Inc.
+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
@@ -21,108 +22,110 @@ END-INFO-DIR-ENTRY
 
 \1f
 Indirect:
-gcrypt.info-1: 832
+gcrypt.info-1: 877
+gcrypt.info-2: 283260
 \1f
 Tag Table:
 (Indirect)
-Node: Top\7f832
-Node: Introduction\7f3123
-Node: Getting Started\7f3495
-Node: Features\7f4376
-Node: Overview\7f5160
-Node: Preparation\7f5791
-Node: Header\7f6648
-Node: Building sources\7f7719
-Node: Building sources using Automake\7f9633
-Node: Initializing the library\7f10815
-Ref: sample-use-suspend-secmem\7f13990
-Ref: sample-use-resume-secmem\7f14610
-Node: Multi-Threading\7f15506
-Ref: Multi-Threading-Footnote-1\7f20134
-Node: Enabling FIPS mode\7f20542
-Node: Generalities\7f22408
-Node: Controlling the library\7f22733
-Node: Modules\7f35470
-Node: Error Handling\7f36249
-Node: Error Values\7f38772
-Node: Error Sources\7f43712
-Node: Error Codes\7f45983
-Node: Error Strings\7f49468
-Node: Handler Functions\7f50651
-Node: Progress handler\7f51210
-Node: Allocation handler\7f53206
-Node: Error handler\7f54757
-Node: Logging handler\7f56324
-Node: Symmetric cryptography\7f56916
-Node: Available ciphers\7f57721
-Node: Cipher modules\7f60228
-Node: Available cipher modes\7f64841
-Node: Working with cipher handles\7f66516
-Node: General cipher functions\7f74831
-Node: Public Key cryptography\7f77349
-Node: Available algorithms\7f78264
-Node: Used S-expressions\7f78613
-Node: RSA key parameters\7f79725
-Node: DSA key parameters\7f81000
-Node: ECC key parameters\7f81658
-Node: Public key modules\7f83423
-Node: Cryptographic Functions\7f89093
-Node: General public-key related Functions\7f96945
-Node: AC Interface\7f109262
-Node: Available asymmetric algorithms\7f110397
-Node: Working with sets of data\7f111066
-Node: Working with IO objects\7f115568
-Node: Working with handles\7f118288
-Node: Working with keys\7f119235
-Node: Using cryptographic functions\7f123317
-Node: Handle-independent functions\7f130224
-Node: Hashing\7f130972
-Node: Available hash algorithms\7f131763
-Node: Hash algorithm modules\7f135212
-Node: Working with hash algorithms\7f139149
-Node: Key Derivation\7f150451
-Node: Random Numbers\7f152520
-Node: Quality of random numbers\7f152801
-Node: Retrieving random numbers\7f153485
-Node: S-expressions\7f154969
-Node: Data types for S-expressions\7f155613
-Node: Working with S-expressions\7f155939
-Node: MPI library\7f165835
-Node: Data types\7f166793
-Node: Basic functions\7f166987
-Node: MPI formats\7f169055
-Node: Calculations\7f171938
-Node: Comparisons\7f174192
-Node: Bit manipulations\7f175067
-Node: Miscellaneous\7f176382
-Node: Prime numbers\7f178351
-Node: Generation\7f178621
-Node: Checking\7f179905
-Node: Utilities\7f180318
-Node: Memory allocation\7f180511
-Node: Architecture\7f181838
-Ref: fig:subsystems\7f183358
-Ref: Architecture-Footnote-1\7f184443
-Ref: Architecture-Footnote-2\7f184505
-Node: Public-Key Subsystem Architecture\7f184589
-Node: Symmetric Encryption Subsystem Architecture\7f187530
-Node: Hashing and MACing Subsystem Architecture\7f188977
-Node: Multi-Precision-Integer Subsystem Architecture\7f190901
-Node: Prime-Number-Generator Subsystem Architecture\7f192342
-Ref: Prime-Number-Generator Subsystem Architecture-Footnote-1\7f194273
-Node: Random-Number Subsystem Architecture\7f194560
-Node: CSPRNG Description\7f197049
-Ref: CSPRNG Description-Footnote-1\7f198611
-Node: FIPS PRNG Description\7f198734
-Node: Self-Tests\7f200869
-Node: FIPS Mode\7f212561
-Ref: fig:fips-fsm\7f216541
-Ref: tbl:fips-states\7f216643
-Ref: tbl:fips-state-transitions\7f217896
-Node: Library Copying\7f221510
-Node: Copying\7f249628
-Node: Figures and Tables\7f268802
-Node: Concept Index\7f269212
-Node: Function and Data Index\7f274915
+Node: Top\7f877
+Node: Introduction\7f3312
+Node: Getting Started\7f3684
+Node: Features\7f4565
+Node: Overview\7f5349
+Node: Preparation\7f5980
+Node: Header\7f6903
+Node: Building sources\7f7974
+Node: Building sources using Automake\7f9888
+Node: Initializing the library\7f11070
+Ref: sample-use-suspend-secmem\7f14246
+Ref: sample-use-resume-secmem\7f14867
+Node: Multi-Threading\7f15763
+Ref: Multi-Threading-Footnote-1\7f20391
+Node: Enabling FIPS mode\7f20799
+Node: Hardware features\7f22791
+Ref: Hardware features-Footnote-1\7f24019
+Node: Generalities\7f24180
+Node: Controlling the library\7f24439
+Node: Error Handling\7f41157
+Node: Error Values\7f43696
+Node: Error Sources\7f48636
+Node: Error Codes\7f50907
+Node: Error Strings\7f54392
+Node: Handler Functions\7f55576
+Node: Progress handler\7f56135
+Node: Allocation handler\7f58280
+Node: Error handler\7f59831
+Node: Logging handler\7f61398
+Node: Symmetric cryptography\7f61990
+Node: Available ciphers\7f62730
+Node: Available cipher modes\7f65347
+Node: Working with cipher handles\7f67440
+Node: General cipher functions\7f77418
+Node: Public Key cryptography\7f80936
+Node: Available algorithms\7f81702
+Node: Used S-expressions\7f82051
+Node: RSA key parameters\7f83168
+Node: DSA key parameters\7f84443
+Node: ECC key parameters\7f85101
+Ref: ecc_keyparam\7f85252
+Node: Cryptographic Functions\7f86997
+Node: General public-key related Functions\7f98416
+Node: Hashing\7f111927
+Node: Available hash algorithms\7f112660
+Node: Working with hash algorithms\7f116552
+Node: Message Authentication Codes\7f129166
+Node: Available MAC algorithms\7f129834
+Node: Working with MAC algorithms\7f133757
+Node: Key Derivation\7f139119
+Node: Random Numbers\7f141513
+Node: Quality of random numbers\7f141796
+Node: Retrieving random numbers\7f142482
+Node: S-expressions\7f143968
+Node: Data types for S-expressions\7f144612
+Node: Working with S-expressions\7f144938
+Node: MPI library\7f158338
+Node: Data types\7f159362
+Node: Basic functions\7f159671
+Node: MPI formats\7f162125
+Node: Calculations\7f165510
+Node: Comparisons\7f167764
+Node: Bit manipulations\7f168763
+Node: EC functions\7f170077
+Ref: gcry_mpi_ec_new\7f172775
+Node: Miscellaneous\7f177536
+Node: Prime numbers\7f181679
+Node: Generation\7f181949
+Node: Checking\7f183233
+Node: Utilities\7f183647
+Node: Memory allocation\7f183959
+Node: Context management\7f185313
+Ref: gcry_ctx_release\7f185750
+Node: Buffer description\7f185911
+Node: Tools\7f186673
+Node: hmac256\7f186839
+Node: Architecture\7f187846
+Ref: fig:subsystems\7f189362
+Ref: Architecture-Footnote-1\7f190447
+Ref: Architecture-Footnote-2\7f190509
+Node: Public-Key Subsystem Architecture\7f190593
+Node: Symmetric Encryption Subsystem Architecture\7f192868
+Node: Hashing and MACing Subsystem Architecture\7f194315
+Node: Multi-Precision-Integer Subsystem Architecture\7f196239
+Node: Prime-Number-Generator Subsystem Architecture\7f197680
+Ref: Prime-Number-Generator Subsystem Architecture-Footnote-1\7f199611
+Node: Random-Number Subsystem Architecture\7f199899
+Node: CSPRNG Description\7f202388
+Ref: CSPRNG Description-Footnote-1\7f203950
+Node: FIPS PRNG Description\7f204073
+Node: Self-Tests\7f206206
+Node: FIPS Mode\7f217716
+Ref: fig:fips-fsm\7f221523
+Ref: tbl:fips-states\7f221625
+Ref: tbl:fips-state-transitions\7f222878
+Node: Library Copying\7f226501
+Node: Copying\7f254620
+Node: Figures and Tables\7f273795
+Node: Concept Index\7f274205
+Node: Function and Data Index\7f283260
 \1f
 End Tag Table
index 2b669b9..97095ea 100644 (file)
@@ -1,11 +1,12 @@
-This is /home/wk/w/libgcrypt/doc/gcrypt.info, produced by makeinfo
-version 4.13 from /home/wk/w/libgcrypt/doc/gcrypt.texi.
+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.5.0, 29 June 2011), which is
+This manual is for Libgcrypt (version 1.6.1, 29 January 2014), which is
 GNU's library of cryptographic building blocks.
 
-   Copyright (C) 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011
-Free Software Foundation, Inc.
+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
@@ -25,11 +26,12 @@ File: gcrypt.info,  Node: Top,  Next: Introduction,  Up: (dir)
 The Libgcrypt Library
 *********************
 
-This manual is for Libgcrypt (version 1.5.0, 29 June 2011), which is
+This manual is for Libgcrypt (version 1.6.1, 29 January 2014), which is
 GNU's library of cryptographic building blocks.
 
-   Copyright (C) 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011
-Free Software Foundation, Inc.
+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
@@ -46,13 +48,15 @@ Free Software Foundation, Inc.
 * 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 and MAC algorithms.
+* 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
@@ -164,6 +168,7 @@ verified.
 * 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
@@ -327,7 +332,7 @@ 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 intialized. */
+          makes sure that important subsystems are initialized. */
        if (!gcry_check_version (GCRYPT_VERSION))
          {
            fputs ("libgcrypt version mismatch\n", stderr);
@@ -341,7 +346,7 @@ of used and freed memory, you need to initialize Libgcrypt this way:
 
        /* ... 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 intialized.  */
+          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.  */
@@ -478,7 +483,7 @@ 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,  Prev: Multi-Threading,  Up: Preparation
+File: gcrypt.info,  Node: Enabling FIPS mode,  Next: Hardware features,  Prev: Multi-Threading,  Up: Preparation
 
 2.6 How to enable the FIPS mode
 ===============================
@@ -509,9 +514,10 @@ Libgcrypt into this mode:
 
    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'.  The Enforced FIPS mode helps to detect
-applications which don't fulfill all requirements for using Libgcrypt
-in FIPS mode (*note FIPS Mode::).
+`/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
@@ -519,6 +525,64 @@ 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
@@ -527,11 +591,10 @@ File: gcrypt.info,  Node: Generalities,  Next: Handler Functions,  Prev: Prepara
 * Menu:
 
 * Controlling the library::     Controlling Libgcrypt's behavior.
-* Modules::                     Description of extension modules.
 * Error Handling::              Error codes and such.
 
 \1f
-File: gcrypt.info,  Node: Controlling the library,  Next: Modules,  Up: Generalities
+File: gcrypt.info,  Node: Controlling the library,  Next: Error Handling,  Up: Generalities
 
 3.1 Controlling the library
 ===========================
@@ -553,29 +616,29 @@ File: gcrypt.info,  Node: Controlling the library,  Next: Modules,  Up: Generali
           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
-          recommened.  However, for some applications the extra quality
-          random Libgcrypt tries to create is not justified and this
-          option may help to get better performace.  Please check with
-          a crypto expert whether this option can be used for your
+          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 randum number generator related statistics
+          This command dumps random number generator related statistics
           to the library's logging stream.
 
     `GCRYCTL_DUMP_MEMORY_STATS; Arguments: none'
-          This command dumps memory managment related statistics to the
-          library's logging stream.
+          This command dumps memory management related statistics to
+          the library's logging stream.
 
     `GCRYCTL_DUMP_SECMEM_STATS; Arguments: none'
-          This command dumps secure memory manamgent related statistics
-          to the library's logging stream.
+          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
-          priviliges of the current process.  This command has not much
+          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.
 
@@ -589,6 +652,25 @@ File: gcrypt.info,  Node: Controlling the library,  Next: Modules,  Up: Generali
           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
@@ -656,7 +738,7 @@ File: gcrypt.info,  Node: Controlling the library,  Next: Modules,  Up: Generali
           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
-          inital states of the pools are completely known.  Note that
+          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
@@ -664,6 +746,15 @@ File: gcrypt.info,  Node: Controlling the library,  Next: Modules,  Up: Generali
           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
@@ -698,11 +789,11 @@ File: gcrypt.info,  Node: Controlling the library,  Next: Modules,  Up: Generali
           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
-          intialization is by calling gcry_check_version.
+          initialization is by calling gcry_check_version.
 
     `GCRYCTL_INITIALIZATION_FINISHED; Arguments: none'
           This command tells the library that the application has
-          finished the intialization.
+          finished the initialization.
 
     `GCRYCTL_INITIALIZATION_FINISHED_P; Arguments: none'
           This command returns true if the command
@@ -730,23 +821,23 @@ File: gcrypt.info,  Node: Controlling the library,  Next: Modules,  Up: Generali
           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 intialization has been finished but not
-          before a gcry_version_check.
+          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 intialization has
-          been finished but not before a gcry_version_check.
+          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
-          intialization has been finished but not before a
-          gcry_version_check.  An application may use this command or
+          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.
 
@@ -758,11 +849,55 @@ File: gcrypt.info,  Node: Controlling the library,  Next: Modules,  Up: Generali
           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
+          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
-          intialization.
+          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
@@ -771,8 +906,8 @@ File: gcrypt.info,  Node: Controlling the library,  Next: Modules,  Up: Generali
 
     `GCRYCTL_DISABLE_HWF; Arguments: const char *name'
           Libgcrypt detects certain features of the CPU at startup
-          time.  For performace tests it is sometimes required not to
-          use such a feature.  This option may be used to disabale a
+          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
@@ -782,29 +917,9 @@ File: gcrypt.info,  Node: Controlling the library,  Next: Modules,  Up: Generali
 
 
 \1f
-File: gcrypt.info,  Node: Modules,  Next: Error Handling,  Prev: Controlling the library,  Up: Generalities
-
-3.2 Modules
-===========
-
-Libgcrypt supports the use of `extension modules', which implement
-algorithms in addition to those already built into the library directly.
-
- -- Data type: gcry_module_t
-     This data type represents a `module'.
-
-   Functions registering modules provided by the user take a `module
-specification structure' as input and return a value of `gcry_module_t'
-and an ID that is unique in the modules' category.  This ID can be used
-to reference the newly registered module.  After registering a module
-successfully, the new functionality should be able to be used through
-the normal functions provided by Libgcrypt until it is unregistered
-again.
-
-\1f
-File: gcrypt.info,  Node: Error Handling,  Prev: Modules,  Up: Generalities
+File: gcrypt.info,  Node: Error Handling,  Prev: Controlling the library,  Up: Generalities
 
-3.3 Error Handling
+3.2 Error Handling
 ==================
 
 Many functions in Libgcrypt can return an error if they fail.  For this
@@ -856,7 +971,7 @@ information on libgpg-error, see the according manual.
 \1f
 File: gcrypt.info,  Node: Error Values,  Next: Error Sources,  Up: Error Handling
 
-3.3.1 Error Values
+3.2.1 Error Values
 ------------------
 
  -- Data type: gcry_err_code_t
@@ -961,7 +1076,7 @@ system error number.  The following functions can be used to do that.
 \1f
 File: gcrypt.info,  Node: Error Sources,  Next: Error Codes,  Prev: Error Values,  Up: Error Handling
 
-3.3.2 Error Sources
+3.2.2 Error Sources
 -------------------
 
 The library `libgpg-error' defines an error source for every component
@@ -1029,7 +1144,7 @@ Libgcrypt is:
 \1f
 File: gcrypt.info,  Node: Error Codes,  Next: Error Strings,  Prev: Error Sources,  Up: Error Handling
 
-3.3.3 Error Codes
+3.2.3 Error Codes
 -----------------
 
 The library `libgpg-error' defines many error values.  The following
@@ -1130,7 +1245,7 @@ list includes the most important error codes.
 \1f
 File: gcrypt.info,  Node: Error Strings,  Prev: Error Codes,  Up: Error Handling
 
-3.3.4 Error Strings
+3.2.4 Error Strings
 -------------------
 
  -- Function: const char * gcry_strerror (gcry_error_t ERR)
@@ -1140,7 +1255,7 @@ File: gcrypt.info,  Node: Error Strings,  Prev: Error Codes,  Up: Error Handling
      output a diagnostic message to the user.
 
  -- Function: const char * gcry_strsource (gcry_error_t ERR)
-     The function `gcry_strerror' returns a pointer to a statically
+     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.
@@ -1225,6 +1340,10 @@ this purpose.
                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'
@@ -1359,13 +1478,12 @@ blocks provided by Libgcrypt.
 * Menu:
 
 * Available ciphers::           List of ciphers supported by the library.
-* Cipher modules::              How to work with cipher modules.
 * 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: Cipher modules,  Up: Symmetric cryptography
+File: gcrypt.info,  Node: Available ciphers,  Next: Available cipher modes,  Up: Symmetric cryptography
 
 5.1 Available ciphers
 =====================
@@ -1375,9 +1493,7 @@ File: gcrypt.info,  Node: Available ciphers,  Next: Cipher modules,  Up: Symmetr
      return.  The value always evaluates to false.
 
 `GCRY_CIPHER_IDEA'
-     This is the IDEA algorithm.  The constant is provided but there is
-     currently no implementation for it because the algorithm is
-     patented.
+     This is the IDEA algorithm.
 
 `GCRY_CIPHER_3DES'
      Triple-DES with 3 Keys as EDE.  The key size of this algorithm is
@@ -1435,9 +1551,7 @@ File: gcrypt.info,  Node: Available ciphers,  Next: Cipher modules,  Up: Symmetr
 
 `GCRY_CIPHER_RFC2268_40'
 `GCRY_CIPHER_RFC2268_128'
-     Ron's Cipher 2 in the 40 and 128 bit variants.  Note, that we
-     currently only support the 40 bit variant.  The identifier for 128
-     is reserved for future use.
+     Ron's Cipher 2 in the 40 and 128 bit variants.
 
 `GCRY_CIPHER_SEED'
      A 128 bit cipher as described by RFC4269.
@@ -1448,126 +1562,22 @@ File: gcrypt.info,  Node: Available ciphers,  Next: Cipher modules,  Up: Symmetr
      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.
 
-\1f
-File: gcrypt.info,  Node: Cipher modules,  Next: Available cipher modes,  Prev: Available ciphers,  Up: Symmetric cryptography
+`GCRY_CIPHER_SALSA20R12'
+     This is the Salsa20/12 - reduced round version of Salsa20 stream
+     cipher.
 
-5.2 Cipher modules
-==================
+`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.
 
-Libgcrypt makes it possible to load additional `cipher modules'; these
-ciphers can be used just like the cipher algorithms that are built into
-the library directly.  For an introduction into extension modules, see
-*Note Modules::.
-
- -- Data type: gcry_cipher_spec_t
-     This is the `module specification structure' needed for registering
-     cipher modules, which has to be filled in by the user before it
-     can be used to register a module.  It contains the following
-     members:
-
-    `const char *name'
-          The primary name of the algorithm.
-
-    `const char **aliases'
-          A list of strings that are `aliases' for the algorithm.  The
-          list must be terminated with a NULL element.
-
-    `gcry_cipher_oid_spec_t *oids'
-          A list of OIDs that are to be associated with the algorithm.
-          The list's last element must have it's `oid' member set to
-          NULL.  See below for an explanation of this type.
-
-    `size_t blocksize'
-          The block size of the algorithm, in bytes.
-
-    `size_t keylen'
-          The length of the key, in bits.
-
-    `size_t contextsize'
-          The size of the algorithm-specific `context', that should be
-          allocated for each handle.
-
-    `gcry_cipher_setkey_t setkey'
-          The function responsible for initializing a handle with a
-          provided key.  See below for a description of this type.
-
-    `gcry_cipher_encrypt_t encrypt'
-          The function responsible for encrypting a single block.  See
-          below for a description of this type.
-
-    `gcry_cipher_decrypt_t decrypt'
-          The function responsible for decrypting a single block.  See
-          below for a description of this type.
-
-    `gcry_cipher_stencrypt_t stencrypt'
-          Like `encrypt', for stream ciphers.  See below for a
-          description of this type.
-
-    `gcry_cipher_stdecrypt_t stdecrypt'
-          Like `decrypt', for stream ciphers.  See below for a
-          description of this type.
-
- -- Data type: gcry_cipher_oid_spec_t
-     This type is used for associating a user-provided algorithm
-     implementation with certain OIDs.  It contains the following
-     members:
-    `const char *oid'
-          Textual representation of the OID.
-
-    `int mode'
-          Cipher mode for which this OID is valid.
-
- -- Data type: gcry_cipher_setkey_t
-     Type for the `setkey' function, defined as: gcry_err_code_t
-     (*gcry_cipher_setkey_t) (void *c, const unsigned char *key,
-     unsigned keylen)
-
- -- Data type: gcry_cipher_encrypt_t
-     Type for the `encrypt' function, defined as: gcry_err_code_t
-     (*gcry_cipher_encrypt_t) (void *c, const unsigned char *outbuf,
-     const unsigned char *inbuf)
-
- -- Data type: gcry_cipher_decrypt_t
-     Type for the `decrypt' function, defined as: gcry_err_code_t
-     (*gcry_cipher_decrypt_t) (void *c, const unsigned char *outbuf,
-     const unsigned char *inbuf)
-
- -- Data type: gcry_cipher_stencrypt_t
-     Type for the `stencrypt' function, defined as: gcry_err_code_t
-     (*gcry_cipher_stencrypt_t) (void *c, const unsigned char *outbuf,
-     const unsigned char *, unsigned int n)
-
- -- Data type: gcry_cipher_stdecrypt_t
-     Type for the `stdecrypt' function, defined as: gcry_err_code_t
-     (*gcry_cipher_stdecrypt_t) (void *c, const unsigned char *outbuf,
-     const unsigned char *, unsigned int n)
-
- -- Function: gcry_error_t gcry_cipher_register (gcry_cipher_spec_t
-          *CIPHER, unsigned int *algorithm_id, gcry_module_t *MODULE)
-     Register a new cipher module whose specification can be found in
-     CIPHER.  On success, a new algorithm ID is stored in ALGORITHM_ID
-     and a pointer representing this module is stored in MODULE.
-     Deprecated; the module register interface will be removed in a
-     future version.
-
- -- Function: void gcry_cipher_unregister (gcry_module_t MODULE)
-     Unregister the cipher identified by MODULE, which must have been
-     registered with gcry_cipher_register.
-
- -- Function: gcry_error_t gcry_cipher_list (int *LIST, int
-          *LIST_LENGTH)
-     Get a list consisting of the IDs of the loaded cipher modules.  If
-     LIST is zero, write the number of loaded cipher modules to
-     LIST_LENGTH and return.  If LIST is non-zero, the first
-     *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
-     according size.  In case there are less cipher modules than
-     *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.
 
 \1f
-File: gcrypt.info,  Node: Available cipher modes,  Next: Working with cipher handles,  Prev: Cipher modules,  Up: Symmetric cryptography
+File: gcrypt.info,  Node: Available cipher modes,  Next: Working with cipher handles,  Prev: Available ciphers,  Up: Symmetric cryptography
 
-5.3 Available cipher modes
+5.2 Available cipher modes
 ==========================
 
 `GCRY_CIPHER_MODE_NONE'
@@ -1608,11 +1618,21 @@ File: gcrypt.info,  Node: Available cipher modes,  Next: Working with cipher han
      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.4 Working with cipher handles
+5.3 Working with cipher handles
 ===============================
 
 To use a cipher algorithm, you must first allocate an according handle.
@@ -1636,10 +1656,13 @@ This is to be done using the open function:
      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. Any
-     block cipher mode (`GCRY_CIPHER_MODE_ECB', `GCRY_CIPHER_MODE_CBC',
-     `GCRY_CIPHER_MODE_CFB', `GCRY_CIPHER_MODE_OFB' or
-     `GCRY_CIPHER_MODE_CTR') will work with any block cipher algorithm.
+     (`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.
@@ -1697,6 +1720,14 @@ To set the IV or CTR, use these functions:
      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
@@ -1712,6 +1743,33 @@ To set the IV or CTR, use these functions:
 
      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.
@@ -1785,7 +1843,7 @@ directly but there is nothing which would inhibit it:
 \1f
 File: gcrypt.info,  Node: General cipher functions,  Prev: Working with cipher handles,  Up: Symmetric cryptography
 
-5.5 General cipher functions
+5.4 General cipher functions
 ============================
 
 To work with the algorithms, several functions are available to map
@@ -1809,10 +1867,14 @@ retrieve information about an algorithm or the current cipher context.
           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.
+          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.
@@ -1820,6 +1882,22 @@ retrieve information about an algorithm or the current cipher context.
 
 
 
+ -- 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
@@ -1852,12 +1930,9 @@ cryptography, this chapter explains the one based on S-expressions.
 
 * Available algorithms::        Algorithms supported by the library.
 * Used S-expressions::          Introduction into the used S-expression.
-* Public key modules::          How to work with public key modules.
 * Cryptographic Functions::     Functions for performing the cryptographic actions.
 * General public-key related Functions::  General functions, not implementing any cryptography.
 
-* AC Interface::                Alternative interface to public key functions.
-
 \1f
 File: gcrypt.info,  Node: Available algorithms,  Next: Used S-expressions,  Up: Public Key cryptography
 
@@ -1869,7 +1944,7 @@ 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: Public key modules,  Prev: Available algorithms,  Up: Public Key cryptography
+File: gcrypt.info,  Node: Used S-expressions,  Next: Cryptographic Functions,  Prev: Available algorithms,  Up: Public Key cryptography
 
 6.2 Used S-expressions
 ======================
@@ -1881,13 +1956,13 @@ contexts as most of the other building blocks of Libgcrypt do.
 
 The following information are stored in S-expressions:
 
-     keys
+   * keys
 
-     plain text data
+   * plain text data
 
-     encrypted data
+   * encrypted data
 
-     signatures
+   * signatures
 
 
 To describe how Libgcrypt expect keys, we use examples. Note that words
@@ -2027,14 +2102,15 @@ N-MPI
      Order of g
 
 Q-POINT
-     The point representing the public key Q = dP.
+     The point representing the public key Q = dG.
 
 D-MPI
      The private key d
 
-   All point values are encoded in standard format; Libgcrypt does
-currently only support uncompressed points, thus the first byte needs to
-be `0x04'.
+   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 public key is similar with "private-key" replaced by "public-key"
 and no D-MPI.
@@ -2048,8 +2124,9 @@ be used.  For example
          (q Q-POINT)
          (d D-MPI)))
 
-   The `curve' parameter may be given in any case and is used to replace
-missing parameters.
+   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'
@@ -2080,157 +2157,24 @@ Currently implemented curves are:
 or `oid.'.
 
 \1f
-File: gcrypt.info,  Node: Public key modules,  Next: Cryptographic Functions,  Prev: Used S-expressions,  Up: Public Key cryptography
-
-6.3 Public key modules
-======================
-
-Libgcrypt makes it possible to load additional `public key modules';
-these public key algorithms can be used just like the algorithms that
-are built into the library directly.  For an introduction into
-extension modules, see *Note Modules::.
-
- -- Data type: gcry_pk_spec_t
-     This is the `module specification structure' needed for registering
-     public key modules, which has to be filled in by the user before it
-     can be used to register a module.  It contains the following
-     members:
-
-    `const char *name'
-          The primary name of this algorithm.
-
-    `char **aliases'
-          A list of strings that are `aliases' for the algorithm.  The
-          list must be terminated with a NULL element.
-
-    `const char *elements_pkey'
-          String containing the one-letter names of the MPI values
-          contained in a public key.
-
-    `const char *element_skey'
-          String containing the one-letter names of the MPI values
-          contained in a secret key.
-
-    `const char *elements_enc'
-          String containing the one-letter names of the MPI values that
-          are the result of an encryption operation using this
-          algorithm.
-
-    `const char *elements_sig'
-          String containing the one-letter names of the MPI values that
-          are the result of a sign operation using this algorithm.
-
-    `const char *elements_grip'
-          String containing the one-letter names of the MPI values that
-          are to be included in the `key grip'.
-
-    `int use'
-          The bitwise-OR of the following flags, depending on the
-          abilities of the algorithm:
-         `GCRY_PK_USAGE_SIGN'
-               The algorithm supports signing and verifying of data.
-
-         `GCRY_PK_USAGE_ENCR'
-               The algorithm supports the encryption and decryption of
-               data.
-
-    `gcry_pk_generate_t generate'
-          The function responsible for generating a new key pair.  See
-          below for a description of this type.
-
-    `gcry_pk_check_secret_key_t check_secret_key'
-          The function responsible for checking the sanity of a
-          provided secret key.  See below for a description of this
-          type.
-
-    `gcry_pk_encrypt_t encrypt'
-          The function responsible for encrypting data.  See below for a
-          description of this type.
-
-    `gcry_pk_decrypt_t decrypt'
-          The function responsible for decrypting data.  See below for a
-          description of this type.
-
-    `gcry_pk_sign_t sign'
-          The function responsible for signing data.  See below for a
-          description of this type.
-
-    `gcry_pk_verify_t verify'
-          The function responsible for verifying that the provided
-          signature matches the provided data.  See below for a
-          description of this type.
-
-    `gcry_pk_get_nbits_t get_nbits'
-          The function responsible for returning the number of bits of
-          a provided key.  See below for a description of this type.
-
- -- Data type: gcry_pk_generate_t
-     Type for the `generate' function, defined as: gcry_err_code_t
-     (*gcry_pk_generate_t) (int algo, unsigned int nbits, unsigned long
-     use_e, gcry_mpi_t *skey, gcry_mpi_t **retfactors)
-
- -- Data type: gcry_pk_check_secret_key_t
-     Type for the `check_secret_key' function, defined as:
-     gcry_err_code_t (*gcry_pk_check_secret_key_t) (int algo,
-     gcry_mpi_t *skey)
-
- -- Data type: gcry_pk_encrypt_t
-     Type for the `encrypt' function, defined as: gcry_err_code_t
-     (*gcry_pk_encrypt_t) (int algo, gcry_mpi_t *resarr, gcry_mpi_t
-     data, gcry_mpi_t *pkey, int flags)
-
- -- Data type: gcry_pk_decrypt_t
-     Type for the `decrypt' function, defined as: gcry_err_code_t
-     (*gcry_pk_decrypt_t) (int algo, gcry_mpi_t *result, gcry_mpi_t
-     *data, gcry_mpi_t *skey, int flags)
-
- -- Data type: gcry_pk_sign_t
-     Type for the `sign' function, defined as: gcry_err_code_t
-     (*gcry_pk_sign_t) (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
-     gcry_mpi_t *skey)
-
- -- Data type: gcry_pk_verify_t
-     Type for the `verify' function, defined as: gcry_err_code_t
-     (*gcry_pk_verify_t) (int algo, gcry_mpi_t hash, gcry_mpi_t *data,
-     gcry_mpi_t *pkey, int (*cmp) (void *, gcry_mpi_t), void *opaquev)
-
- -- Data type: gcry_pk_get_nbits_t
-     Type for the `get_nbits' function, defined as: unsigned
-     (*gcry_pk_get_nbits_t) (int algo, gcry_mpi_t *pkey)
-
- -- Function: gcry_error_t gcry_pk_register (gcry_pk_spec_t *PUBKEY,
-          unsigned int *algorithm_id, gcry_module_t *MODULE)
-     Register a new public key module whose specification can be found
-     in PUBKEY.  On success, a new algorithm ID is stored in
-     ALGORITHM_ID and a pointer representing this module is stored in
-     MODULE.  Deprecated; the module register interface will be removed
-     in a future version.
-
-
- -- Function: void gcry_pk_unregister (gcry_module_t MODULE)
-     Unregister the public key module identified by MODULE, which must
-     have been registered with gcry_pk_register.
-
- -- Function: gcry_error_t gcry_pk_list (int *LIST, int *LIST_LENGTH)
-     Get a list consisting of the IDs of the loaded pubkey modules.  If
-     LIST is zero, write the number of loaded pubkey modules to
-     LIST_LENGTH and return.  If LIST is non-zero, the first
-     *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
-     according size.  In case there are less pubkey modules than
-     *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.
-
-\1f
-File: gcrypt.info,  Node: Cryptographic Functions,  Next: General public-key related Functions,  Prev: Public key modules,  Up: Public Key cryptography
+File: gcrypt.info,  Node: Cryptographic Functions,  Next: General public-key related Functions,  Prev: Used S-expressions,  Up: Public Key cryptography
 
-6.4 Cryptographic Functions
+6.3 Cryptographic Functions
 ===========================
 
-Note that we will in future allow to use keys without p,q and u
-specified and may also support other parameters for performance reasons.
+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:
 
-Some functions operating on S-expressions support `flags', that
-influence the operation.  These flags have to be listed in a
-sub-S-expression named `flags'; 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.
 
 `pkcs1'
      Use PKCS#1 block type 2 padding for encryption, block type 1
@@ -2242,12 +2186,55 @@ sub-S-expression named `flags'; the following flags are known:
 `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
@@ -2377,6 +2364,28 @@ functions, similar to the encryption functions:
 
      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:
 
@@ -2393,9 +2402,25 @@ functions, similar to the encryption functions:
               (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".
+     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:
@@ -2411,14 +2436,14 @@ signature.  Libgcrypt provides this function:
 
      The result is 0 for success (i.e. the data matches the signature),
      or an error code where the most relevant code is
-     `GCRYERR_BAD_SIGNATURE' to indicate that the signature does not
+     `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,  Next: AC Interface,  Prev: Cryptographic Functions,  Up: Public Key cryptography
+File: gcrypt.info,  Node: General public-key related Functions,  Prev: Cryptographic Functions,  Up: Public Key cryptography
 
-6.5 General public-key related Functions
+6.4 General public-key related Functions
 ========================================
 
 A couple of utility functions are available to retrieve the length of
@@ -2523,7 +2548,9 @@ the key, map algorithm identifiers and perform sanity checks:
     `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)'.
+          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:
@@ -2548,9 +2575,11 @@ Libgcrypt also provides a function to generate public key pairs:
      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.
+          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
@@ -2559,9 +2588,9 @@ Libgcrypt also provides a function to generate public key pairs:
           taken if `nbits' has been given.  The available names are
           listed with the description of the ECC public key parameters.
 
-    `rsa-use-e'
+    `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
+          exponent. The VALUE will be used as a base to test for a
           usable exponent. Some values are special:
 
          `0'
@@ -2581,9 +2610,9 @@ Libgcrypt also provides a function to generate public key pairs:
           If this parameter is not used, Libgcrypt uses for historic
           reasons 65537.
 
-    `qbits'
+    `qbits N'
           This is only meanigful for DSA keys.  If it is given the DSA
-          key is generated with a Q parameyer of this size.  If it is
+          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
@@ -2604,15 +2633,7 @@ Libgcrypt also provides a function to generate public key pairs:
           range 512 to 15680 are valid as long as they are multiples of
           8.
 
-    `transient-key'
-          This is only meaningful for RSA, DSA, ECDSA, and ECDH keys.
-          This is a flag with no value.  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.
-
-    `domain'
+    `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
@@ -2629,7 +2650,7 @@ Libgcrypt also provides a function to generate public key pairs:
           `nbits' and `qbits' may not be specified because they are
           derived from the domain parameters.
 
-    `derive-parms'
+    `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
@@ -2664,35 +2685,32 @@ Libgcrypt also provides a function to generate public key pairs:
                    (derive-parms
                      (seed SEED-MPI))))
 
-    `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 and usually not required.  Note that this
-          algorithm is implicitly used if either `derive-parms' is
-          given or Libgcrypt is in FIPS mode.
+    `flags FLAGLIST'
+          This is preferred way to define flags.  FLAGLIST may contain
+          any number of flags.  See above for a specification of these
+          flags.
 
-    `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.
+          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'
-          Force the use of the FIPS 186-2 key generation algorithm
-          instead of the default algorithm.  This algorithm is slighlty
-          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.
+          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.
 
-     As an example, here is what the Elgamal key generation returns:
+     Here are two examples; the first for Elgamal and the second for
+     elliptic curve key generation:
 
           (key-data
             (public-key
@@ -2709,6 +2727,19 @@ Libgcrypt also provides a function to generate public key pairs:
             (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
@@ -2717,550 +2748,48 @@ Libgcrypt also provides a function to generate public key pairs:
      not a very useful information and only available if the key
      generation algorithm provides them.
 
-\1f
-File: gcrypt.info,  Node: AC Interface,  Prev: General public-key related Functions,  Up: Public Key cryptography
-
-6.6 Alternative Public Key Interface
-====================================
-
-This section documents the alternative interface to asymmetric
-cryptography (ac) that is not based on S-expressions, but on native C
-data structures.  As opposed to the pk interface described in the
-former chapter, this one follows an open/use/close paradigm like other
-building blocks of the library.
-
-   *This interface has a few known problems; most noteworthy an
-inherent tendency to leak memory.  It might not be available in
-forthcoming versions of Libgcrypt.*
-
-* Menu:
-
-* Available asymmetric algorithms::  List of algorithms supported by the library.
-* Working with sets of data::   How to work with sets of data.
-* Working with IO objects::     How to work with IO objects.
-* Working with handles::        How to use handles.
-* Working with keys::           How to work with keys.
-* Using cryptographic functions::  How to perform cryptographic operations.
-* Handle-independent functions::  General functions independent of handles.
-
-\1f
-File: gcrypt.info,  Node: Available asymmetric algorithms,  Next: Working with sets of data,  Up: AC Interface
-
-6.6.1 Available asymmetric 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.
-
- -- Data type: gcry_ac_id_t
-     The following constants are defined for this type:
-
-    `GCRY_AC_RSA'
-          Rivest-Shamir-Adleman
-
-    `GCRY_AC_DSA'
-          Digital Signature Algorithm
-
-    `GCRY_AC_ELG'
-          Elgamal
-
-    `GCRY_AC_ELG_E'
-          Elgamal, encryption only.
-
-\1f
-File: gcrypt.info,  Node: Working with sets of data,  Next: Working with IO objects,  Prev: Available asymmetric algorithms,  Up: AC Interface
-
-6.6.2 Working with sets of data
--------------------------------
-
-In the context of this interface the term `data set' refers to a list
-of `named MPI values' that is used by functions performing
-cryptographic operations; a named MPI value is a an MPI value,
-associated with a label.
-
-   Such data sets are used for representing keys, since keys simply
-consist of a variable amount of numbers.  Furthermore some functions
-return data sets to the caller that are to be provided to other
-functions.
-
-   This section documents the data types, symbols and functions that are
-relevant for working with data sets.
-
- -- Data type: gcry_ac_data_t
-     A single data set.
-
-   The following flags are supported:
-
-`GCRY_AC_FLAG_DEALLOC'
-     Used for storing data in a data set.  If given, the data will be
-     released by the library.  Note that whenever one of the ac
-     functions is about to release objects because of this flag, the
-     objects are expected to be stored in memory allocated through the
-     Libgcrypt memory management.  In other words: gcry_free() is used
-     instead of free().
-
-`GCRY_AC_FLAG_COPY'
-     Used for storing/retrieving data in/from a data set.  If given, the
-     library will create copies of the provided/contained data, which
-     will then be given to the user/associated with the data set.
-
- -- Function: gcry_error_t gcry_ac_data_new (gcry_ac_data_t *DATA)
-     Creates a new, empty data set and stores it in DATA.
-
- -- Function: void gcry_ac_data_destroy (gcry_ac_data_t DATA)
-     Destroys the data set DATA.
-
- -- Function: gcry_error_t gcry_ac_data_set (gcry_ac_data_t DATA,
-          unsigned int FLAGS, char *NAME, gcry_mpi_t MPI)
-     Add the value MPI to DATA with the label NAME.  If FLAGS contains
-     GCRY_AC_FLAG_COPY, the data set will contain copies of NAME and
-     MPI.  If FLAGS contains GCRY_AC_FLAG_DEALLOC or GCRY_AC_FLAG_COPY,
-     the values contained in the data set will be deallocated when they
-     are to be removed from the data set.
-
- -- Function: gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *DATA_CP,
-          gcry_ac_data_t DATA)
-     Create a copy of the data set DATA and store it in DATA_CP.
-     FIXME: exact semantics undefined.
-
- -- Function: unsigned int gcry_ac_data_length (gcry_ac_data_t DATA)
-     Returns the number of named MPI values inside of the data set DATA.
-
- -- Function: gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t DATA,
-          unsigned int FLAGS, char *NAME, gcry_mpi_t *MPI)
-     Store the value labelled with NAME found in DATA in MPI.  If FLAGS
-     contains GCRY_AC_FLAG_COPY, store a copy of the MPI value
-     contained in the data set.  MPI may be NULL (this might be useful
-     for checking the existence of an MPI with extracting it).
-
- -- Function: gcry_error_t gcry_ac_data_get_index (gcry_ac_data_t DATA,
-          unsigned int flags, unsigned int INDEX, const char **NAME,
-          gcry_mpi_t *MPI)
-     Stores in NAME and MPI the named MPI value contained in the data
-     set DATA with the index IDX.  If FLAGS contains GCRY_AC_FLAG_COPY,
-     store copies of the values contained in the data set. NAME or MPI
-     may be NULL.
-
- -- Function: void gcry_ac_data_clear (gcry_ac_data_t DATA)
-     Destroys any values contained in the data set DATA.
-
- -- Function: gcry_error_t gcry_ac_data_to_sexp (gcry_ac_data_t DATA,
-          gcry_sexp_t *SEXP, const char **IDENTIFIERS)
-     This function converts the data set DATA into a newly created
-     S-Expression, which is to be stored in SEXP; IDENTIFIERS is a NULL
-     terminated list of C strings, which specifies the structure of the
-     S-Expression.
-
-     Example:
-
-     If IDENTIFIERS is a list of pointers to the strings "foo" and
-     "bar" and if DATA is a data set containing the values "val1 =
-     0x01" and "val2 = 0x02", then the resulting S-Expression will look
-     like this: (foo (bar ((val1 0x01) (val2 0x02))).
-
- -- Function: gcry_error gcry_ac_data_from_sexp (gcry_ac_data_t *DATA,
-          gcry_sexp_t SEXP, const char **IDENTIFIERS)
-     This function converts the S-Expression SEXP into a newly created
-     data set, which is to be stored in DATA; IDENTIFIERS is a NULL
-     terminated list of C strings, which specifies the structure of the
-     S-Expression.  If the list of identifiers does not match the
-     structure of the S-Expression, the function fails.
-
-\1f
-File: gcrypt.info,  Node: Working with IO objects,  Next: Working with handles,  Prev: Working with sets of data,  Up: AC Interface
-
-6.6.3 Working with IO objects
------------------------------
-
-Note: IO objects are currently only used in the context of message
-encoding/decoding and encryption/signature schemes.
-
- -- Data type: gcry_ac_io_t
-     `gcry_ac_io_t' is the type to be used for IO objects.
-
-   IO objects provide an uniform IO layer on top of different underlying
-IO mechanisms; either they can be used for providing data to the
-library (mode is GCRY_AC_IO_READABLE) or they can be used for
-retrieving data from the library (mode is GCRY_AC_IO_WRITABLE).
-
-   IO object need to be initialized by calling on of the following
-functions:
-
- -- Function: void gcry_ac_io_init (gcry_ac_io_t *AC_IO,
-          gcry_ac_io_mode_t MODE, gcry_ac_io_type_t TYPE, ...);
-     Initialize AC_IO according to MODE, TYPE and the variable list of
-     arguments.  The list of variable arguments to specify depends on
-     the given TYPE.
-
- -- Function: void gcry_ac_io_init_va (gcry_ac_io_t *AC_IO,
-          gcry_ac_io_mode_t MODE, gcry_ac_io_type_t TYPE, va_list AP);
-     Initialize AC_IO according to MODE, TYPE and the variable list of
-     arguments AP.  The list of variable arguments to specify depends
-     on the given TYPE.
-
-   The following types of IO objects exist:
-
-`GCRY_AC_IO_STRING'
-     In case of GCRY_AC_IO_READABLE the IO object will provide data
-     from a memory string.  Arguments to specify at initialization time:
-    `unsigned char *'
-          Pointer to the beginning of the memory string
-
-    `size_t'
-          Size of the memory string
-     In case of GCRY_AC_IO_WRITABLE the object will store retrieved
-     data in a newly allocated memory string.  Arguments to specify at
-     initialization time:
-    `unsigned char **'
-          Pointer to address, at which the pointer to the newly created
-          memory string is to be stored
-
-    `size_t *'
-          Pointer to address, at which the size of the newly created
-          memory string is to be stored
-
-`GCRY_AC_IO_CALLBACK'
-     In case of GCRY_AC_IO_READABLE the object will forward read
-     requests to a provided callback function.  Arguments to specify at
-     initialization time:
-    `gcry_ac_data_read_cb_t'
-          Callback function to use
-
-    `void *'
-          Opaque argument to provide to the callback function
-     In case of GCRY_AC_IO_WRITABLE the object will forward write
-     requests to a provided callback function.  Arguments to specify at
-     initialization time:
-    `gcry_ac_data_write_cb_t'
-          Callback function to use
-
-    `void *'
-          Opaque argument to provide to the callback function
-
-\1f
-File: gcrypt.info,  Node: Working with handles,  Next: Working with keys,  Prev: Working with IO objects,  Up: AC Interface
-
-6.6.4 Working with handles
---------------------------
-
-In order to use an algorithm, an according handle must be created.
-This is done using the following function:
-
- -- Function: gcry_error_t gcry_ac_open (gcry_ac_handle_t *HANDLE, int
-          ALGORITHM, int FLAGS)
-     Creates a new handle for the algorithm ALGORITHM and stores it in
-     HANDLE.  FLAGS is not used currently.
-
-     ALGORITHM must be a valid algorithm ID, see *Note Available
-     asymmetric algorithms::, for a list of supported algorithms and the
-     according constants.  Besides using the listed constants directly,
-     the functions `gcry_pk_name_to_id' may be used to convert the
-     textual name of an algorithm into the according numeric ID.
-
- -- Function: void gcry_ac_close (gcry_ac_handle_t HANDLE)
-     Destroys the handle HANDLE.
-
-\1f
-File: gcrypt.info,  Node: Working with keys,  Next: Using cryptographic functions,  Prev: Working with handles,  Up: AC Interface
-
-6.6.5 Working with keys
------------------------
-
- -- Data type: gcry_ac_key_type_t
-     Defined constants:
-
-    `GCRY_AC_KEY_SECRET'
-          Specifies a secret key.
-
-    `GCRY_AC_KEY_PUBLIC'
-          Specifies a public key.
-
- -- Data type: gcry_ac_key_t
-     This type represents a single `key', either a secret one or a
-     public one.
-
- -- Data type: gcry_ac_key_pair_t
-     This type represents a `key pair' containing a secret and a public
-     key.
-
-   Key data structures can be created in two different ways; a new key
-pair can be generated, resulting in ready-to-use key.  Alternatively a
-key can be initialized from a given data set.
-
- -- Function: gcry_error_t gcry_ac_key_init (gcry_ac_key_t *KEY,
-          gcry_ac_handle_t HANDLE, gcry_ac_key_type_t TYPE,
-          gcry_ac_data_t DATA)
-     Creates a new key of type TYPE, consisting of the MPI values
-     contained in the data set DATA and stores it in KEY.
-
- -- Function: gcry_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t
-          HANDLE, unsigned int NBITS, void *KEY_SPEC,
-          gcry_ac_key_pair_t *KEY_PAIR, gcry_mpi_t **MISC_DATA)
-     Generates a new key pair via the handle HANDLE of NBITS bits and
-     stores it in KEY_PAIR.
-
-     In case non-standard settings are wanted, a pointer to a structure
-     of type `gcry_ac_key_spec_<algorithm>_t', matching the selected
-     algorithm, can be given as KEY_SPEC.  MISC_DATA is not used yet.
-     Such a structure does only exist for RSA.  A description of the
-     members of the supported structures follows.
-
-    `gcry_ac_key_spec_rsa_t'
-
-         `gcry_mpi_t e'
-               Generate the key pair using a special `e'.  The value of
-               `e' has the following meanings:
-              `= 0'
-                    Let Libgcrypt decide what exponent should be used.
-
-              `= 1'
-                    Request the use of a "secure" exponent; this is
-                    required by some specification to be 65537.
-
-              `> 2'
-                    Try starting at this value until a working exponent
-                    is found.  Note that the current implementation
-                    leaks some information about the private key
-                    because the incrementation used is not randomized.
-                    Thus, this function will be changed in the future
-                    to return a random exponent of the given size.
-
-     Example code:
-          {
-            gcry_ac_key_pair_t key_pair;
-            gcry_ac_key_spec_rsa_t rsa_spec;
-
-            rsa_spec.e = gcry_mpi_new (0);
-            gcry_mpi_set_ui (rsa_spec.e, 1);
-
-            err = gcry_ac_open  (&handle, GCRY_AC_RSA, 0);
-            assert (! err);
-
-            err = gcry_ac_key_pair_generate (handle, 1024, &rsa_spec,
-                                             &key_pair, NULL);
-            assert (! err);
-          }
-
- -- Function: gcry_ac_key_t gcry_ac_key_pair_extract
-          (gcry_ac_key_pair_t KEY_PAIR, gcry_ac_key_type_t WHICH)
-     Returns the key of type WHICH out of the key pair KEY_PAIR.
-
- -- Function: void gcry_ac_key_destroy (gcry_ac_key_t KEY)
-     Destroys the key KEY.
-
- -- Function: void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t
-          KEY_PAIR)
-     Destroys the key pair KEY_PAIR.
-
- -- Function: gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t KEY)
-     Returns the data set contained in the key KEY.
-
- -- Function: gcry_error_t gcry_ac_key_test (gcry_ac_handle_t HANDLE,
-          gcry_ac_key_t KEY)
-     Verifies that the private key KEY is sane via HANDLE.
-
- -- Function: gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t
-          HANDLE, gcry_ac_key_t KEY, unsigned int *NBITS)
-     Stores the number of bits of the key KEY in NBITS via HANDLE.
-
- -- Function: gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t
-          HANDLE, gcry_ac_key_t KEY, unsigned char *KEY_GRIP)
-     Writes the 20 byte long key grip of the key KEY to KEY_GRIP via
-     HANDLE.
+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:
 
-\1f
-File: gcrypt.info,  Node: Using cryptographic functions,  Next: Handle-independent functions,  Prev: Working with keys,  Up: AC Interface
-
-6.6.6 Using cryptographic functions
------------------------------------
-
-The following flags might be relevant:
-
-`GCRY_AC_FLAG_NO_BLINDING'
-     Disable any blinding, which might be supported by the chosen
-     algorithm; blinding is the default.
-
-   There exist two kinds of cryptographic functions available through
-the ac interface: primitives, and high-level functions.
+ -- 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:
 
-   Primitives deal with MPIs (data sets) directly; what they provide is
-direct access to the cryptographic operations provided by an algorithm
-implementation.
+    `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.
 
-   High-level functions deal with octet strings, according to a
-specified "scheme".  Schemes make use of "encoding methods", which are
-responsible for converting the provided octet strings into MPIs, which
-are then forwared to the cryptographic primitives.  Since schemes are
-to be used for a special purpose in order to achieve a particular
-security goal, there exist "encryption schemes" and "signature
-schemes".  Encoding methods can be used seperately or implicitly
-through schemes.
+    `GCRY_PK_GET_PUBKEY'
+          Return the public key even if the context has the private key
+          parameter.
 
-   What follows is a description of the cryptographic primitives.
+    `GCRY_PK_GET_SECKEY'
+          Return the private key or the error `GPG_ERR_NO_SECKEY' if it
+          is not possible.
 
- -- Function: gcry_error_t gcry_ac_data_encrypt (gcry_ac_handle_t
-          HANDLE, unsigned int FLAGS, gcry_ac_key_t KEY, gcry_mpi_t
-          DATA_PLAIN, gcry_ac_data_t *DATA_ENCRYPTED)
-     Encrypts the plain text MPI value DATA_PLAIN with the key public
-     KEY under the control of the flags FLAGS and stores the resulting
-     data set into DATA_ENCRYPTED.
+     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.
 
- -- Function: gcry_error_t gcry_ac_data_decrypt (gcry_ac_handle_t
-          HANDLE, unsigned int FLAGS, gcry_ac_key_t KEY, gcry_mpi_t
-          *DATA_PLAIN, gcry_ac_data_t DATA_ENCRYPTED)
-     Decrypts the encrypted data contained in the data set
-     DATA_ENCRYPTED with the secret key KEY under the control of the
-     flags FLAGS and stores the resulting plain text MPI value in
-     DATA_PLAIN.
-
- -- Function: gcry_error_t gcry_ac_data_sign (gcry_ac_handle_t HANDLE,
-          gcry_ac_key_t KEY, gcry_mpi_t DATA, gcry_ac_data_t
-          *DATA_SIGNATURE)
-     Signs the data contained in DATA with the secret key KEY and
-     stores the resulting signature in the data set DATA_SIGNATURE.
-
- -- Function: gcry_error_t gcry_ac_data_verify (gcry_ac_handle_t
-          HANDLE, gcry_ac_key_t KEY, gcry_mpi_t DATA, gcry_ac_data_t
-          DATA_SIGNATURE)
-     Verifies that the signature contained in the data set
-     DATA_SIGNATURE is indeed the result of signing the data contained
-     in DATA with the secret key belonging to the public key KEY.
-
-   What follows is a description of the high-level functions.
-
-   The type "gcry_ac_em_t" is used for specifying encoding methods; the
-following methods are supported:
-
-`GCRY_AC_EME_PKCS_V1_5'
-     PKCS-V1_5 Encoding Method for Encryption.  Options must be provided
-     through a pointer to a correctly initialized object of type
-     gcry_ac_eme_pkcs_v1_5_t.
-
-`GCRY_AC_EMSA_PKCS_V1_5'
-     PKCS-V1_5 Encoding Method for Signatures with Appendix.  Options
-     must be provided through a pointer to a correctly initialized
-     object of type gcry_ac_emsa_pkcs_v1_5_t.
-
-   Option structure types:
-
-`gcry_ac_eme_pkcs_v1_5_t'
-
-    `gcry_ac_key_t key'
-
-    `gcry_ac_handle_t handle'
-
-`gcry_ac_emsa_pkcs_v1_5_t'
-
-    `gcry_md_algo_t md'
-
-    `size_t em_n'
-
-   Encoding methods can be used directly through the following
-functions:
-
- -- Function: gcry_error_t gcry_ac_data_encode (gcry_ac_em_t METHOD,
-          unsigned int FLAGS, void *OPTIONS, unsigned char *M, size_t
-          M_N, unsigned char **EM, size_t *EM_N)
-     Encodes the message contained in M of size M_N according to
-     METHOD, FLAGS and OPTIONS.  The newly created encoded message is
-     stored in EM and EM_N.
-
- -- Function: gcry_error_t gcry_ac_data_decode (gcry_ac_em_t METHOD,
-          unsigned int FLAGS, void *OPTIONS, unsigned char *EM, size_t
-          EM_N, unsigned char **M, size_t *M_N)
-     Decodes the message contained in EM of size EM_N according to
-     METHOD, FLAGS and OPTIONS.  The newly created decoded message is
-     stored in M and M_N.
-
-   The type "gcry_ac_scheme_t" is used for specifying schemes; the
-following schemes are supported:
-
-`GCRY_AC_ES_PKCS_V1_5'
-     PKCS-V1_5 Encryption Scheme.  No options can be provided.
-
-`GCRY_AC_SSA_PKCS_V1_5'
-     PKCS-V1_5 Signature Scheme (with Appendix).  Options can be
-     provided through a pointer to a correctly initialized object of
-     type gcry_ac_ssa_pkcs_v1_5_t.
-
-   Option structure types:
-
-`gcry_ac_ssa_pkcs_v1_5_t'
-
-    `gcry_md_algo_t md'
-
-   The functions implementing schemes:
-
- -- Function: gcry_error_t gcry_ac_data_encrypt_scheme
-          (gcry_ac_handle_t HANDLE, gcry_ac_scheme_t SCHEME, unsigned
-          int FLAGS, void *OPTS, gcry_ac_key_t KEY, gcry_ac_io_t
-          *IO_MESSAGE, gcry_ac_io_t *IO_CIPHER)
-     Encrypts the plain text readable from IO_MESSAGE through HANDLE
-     with the public key KEY according to SCHEME, FLAGS and OPTS.  If
-     OPTS is not NULL, it has to be a pointer to a structure specific
-     to the chosen scheme (gcry_ac_es_*_t).  The encrypted message is
-     written to IO_CIPHER.
-
- -- Function: gcry_error_t gcry_ac_data_decrypt_scheme
-          (gcry_ac_handle_t HANDLE, gcry_ac_scheme_t SCHEME, unsigned
-          int FLAGS, void *OPTS, gcry_ac_key_t KEY, gcry_ac_io_t
-          *IO_CIPHER, gcry_ac_io_t *IO_MESSAGE)
-     Decrypts the cipher text readable from IO_CIPHER through HANDLE
-     with the secret key KEY according to SCHEME, FLAGS and OPTS.  If
-     OPTS is not NULL, it has to be a pointer to a structure specific
-     to the chosen scheme (gcry_ac_es_*_t).  The decrypted message is
-     written to IO_MESSAGE.
-
- -- Function: gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t
-          HANDLE, gcry_ac_scheme_t SCHEME, unsigned int FLAGS, void
-          *OPTS, gcry_ac_key_t KEY, gcry_ac_io_t *IO_MESSAGE,
-          gcry_ac_io_t *IO_SIGNATURE)
-     Signs the message readable from IO_MESSAGE through HANDLE with the
-     secret key KEY according to SCHEME, FLAGS and OPTS.  If OPTS is
-     not NULL, it has to be a pointer to a structure specific to the
-     chosen scheme (gcry_ac_ssa_*_t).  The signature is written to
-     IO_SIGNATURE.
-
- -- Function: gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t
-          HANDLE, gcry_ac_scheme_t SCHEME, unsigned int FLAGS, void
-          *OPTS, gcry_ac_key_t KEY, gcry_ac_io_t *IO_MESSAGE,
-          gcry_ac_io_t *IO_SIGNATURE)
-     Verifies through HANDLE that the signature readable from
-     IO_SIGNATURE is indeed the result of signing the message readable
-     from IO_MESSAGE with the secret key belonging to the public key
-     KEY according to SCHEME and OPTS.  If OPTS is not NULL, it has to
-     be an anonymous structure (gcry_ac_ssa_*_t) specific to the chosen
-     scheme.
 
 \1f
-File: gcrypt.info,  Node: Handle-independent functions,  Prev: Using cryptographic functions,  Up: AC Interface
-
-6.6.7 Handle-independent functions
-----------------------------------
-
-These two functions are deprecated; do not use them for new code.
-
- -- Function: gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t ALGORITHM,
-          const char **NAME)
-     Stores the textual representation of the algorithm whose id is
-     given in ALGORITHM in NAME.  Deprecated; use `gcry_pk_algo_name'.
-
- -- Function: gcry_error_t gcry_ac_name_to_id (const char *NAME,
-          gcry_ac_id_t *ALGORITHM)
-     Stores the numeric ID of the algorithm whose textual
-     representation is contained in NAME in ALGORITHM. Deprecated; use
-     `gcry_pk_map_name'.
-
-\1f
-File: gcrypt.info,  Node: Hashing,  Next: Key Derivation,  Prev: Public Key cryptography,  Up: Top
+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 MAC using the same routines.  The
+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.
 
@@ -3270,11 +2799,10 @@ operations are also supported.
 * Menu:
 
 * Available hash algorithms::   List of hash algorithms supported by the library.
-* Hash algorithm modules::      How to work with hash algorithm modules.
 * Working with hash algorithms::  List of functions related to hashing.
 
 \1f
-File: gcrypt.info,  Node: Available hash algorithms,  Next: Hash algorithm modules,  Up: Hashing
+File: gcrypt.info,  Node: Available hash algorithms,  Next: Working with hash algorithms,  Up: Hashing
 
 7.1 Available hash algorithms
 =============================
@@ -3304,7 +2832,7 @@ File: gcrypt.info,  Node: Available hash algorithms,  Next: Hash algorithm modul
 
 `GCRY_MD_MD4'
      This is the MD4 algorithm, which yields a message digest of 16
-     bytes.  This algorithms ha severe weaknesses and should not be
+     bytes.  This algorithm has severe weaknesses and should not be
      used.
 
 `GCRY_MD_MD2'
@@ -3364,112 +2892,23 @@ File: gcrypt.info,  Node: Available hash algorithms,  Next: Hash algorithm modul
      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.
 
-\1f
-File: gcrypt.info,  Node: Hash algorithm modules,  Next: Working with hash algorithms,  Prev: Available hash algorithms,  Up: Hashing
+`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.
 
-7.2 Hash algorithm modules
-==========================
+`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.
 
-Libgcrypt makes it possible to load additional `message digest
-modules'; these digests can be used just like the message digest
-algorithms that are built into the library directly.  For an
-introduction into extension modules, see *Note Modules::.
-
- -- Data type: gcry_md_spec_t
-     This is the `module specification structure' needed for registering
-     message digest modules, which has to be filled in by the user
-     before it can be used to register a module.  It contains the
-     following members:
-
-    `const char *name'
-          The primary name of this algorithm.
-
-    `unsigned char *asnoid'
-          Array of bytes that form the ASN OID.
-
-    `int asnlen'
-          Length of bytes in `asnoid'.
-
-    `gcry_md_oid_spec_t *oids'
-          A list of OIDs that are to be associated with the algorithm.
-          The list's last element must have it's `oid' member set to
-          NULL.  See below for an explanation of this type.  See below
-          for an explanation of this type.
-
-    `int mdlen'
-          Length of the message digest algorithm.  See below for an
-          explanation of this type.
-
-    `gcry_md_init_t init'
-          The function responsible for initializing a handle.  See
-          below for an explanation of this type.
-
-    `gcry_md_write_t write'
-          The function responsible for writing data into a message
-          digest context.  See below for an explanation of this type.
-
-    `gcry_md_final_t final'
-          The function responsible for `finalizing' a message digest
-          context.  See below for an explanation of this type.
-
-    `gcry_md_read_t read'
-          The function responsible for reading out a message digest
-          result.  See below for an explanation of this type.
-
-    `size_t contextsize'
-          The size of the algorithm-specific `context', that should be
-          allocated for each handle.
-
- -- Data type: gcry_md_oid_spec_t
-     This type is used for associating a user-provided algorithm
-     implementation with certain OIDs.  It contains the following
-     members:
-
-    `const char *oidstring'
-          Textual representation of the OID.
-
- -- Data type: gcry_md_init_t
-     Type for the `init' function, defined as: void (*gcry_md_init_t)
-     (void *c)
-
- -- Data type: gcry_md_write_t
-     Type for the `write' function, defined as: void (*gcry_md_write_t)
-     (void *c, unsigned char *buf, size_t nbytes)
-
- -- Data type: gcry_md_final_t
-     Type for the `final' function, defined as: void (*gcry_md_final_t)
-     (void *c)
-
- -- Data type: gcry_md_read_t
-     Type for the `read' function, defined as: unsigned char
-     *(*gcry_md_read_t) (void *c)
-
- -- Function: gcry_error_t gcry_md_register (gcry_md_spec_t *DIGEST,
-          unsigned int *algorithm_id, gcry_module_t *MODULE)
-     Register a new digest module whose specification can be found in
-     DIGEST.  On success, a new algorithm ID is stored in ALGORITHM_ID
-     and a pointer representing this module is stored in MODULE.
-     Deprecated; the module register interface will be removed in a
-     future version.
-
- -- Function: void gcry_md_unregister (gcry_module_t MODULE)
-     Unregister the digest identified by MODULE, which must have been
-     registered with gcry_md_register.
-
- -- Function: gcry_error_t gcry_md_list (int *LIST, int *LIST_LENGTH)
-     Get a list consisting of the IDs of the loaded message digest
-     modules.  If LIST is zero, write the number of loaded message
-     digest modules to LIST_LENGTH and return.  If LIST is non-zero,
-     the first *LIST_LENGTH algorithm IDs are stored in LIST, which
-     must be of according size.  In case there are less message digests
-     modules than *LIST_LENGTH, *LIST_LENGTH is updated to the correct
-     number.
 
 \1f
-File: gcrypt.info,  Node: Working with hash algorithms,  Prev: Hash algorithm modules,  Up: Hashing
+File: gcrypt.info,  Node: Working with hash algorithms,  Prev: Available hash algorithms,  Up: Hashing
 
-7.3 Working with hash algorithms
+7.2 Working with hash algorithms
 ================================
 
 To use most of these function it is necessary to create a context; this
@@ -3501,6 +2940,21 @@ is done using:
           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.
@@ -3598,8 +3052,33 @@ function:
      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 one block
-of memory, a fast convenience function is available for this task:
+   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);
@@ -3611,8 +3090,8 @@ of memory, a fast convenience function is available for this task:
      ALGO.  This required size may be obtained by using the function
      `gcry_md_get_algo_dlen'.
 
-     Note that this function will abort the process if an unavailable
-     algorithm is used.
+     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
@@ -3693,27 +3172,277 @@ written to files on request.
      stopped and the file closed.  This is only rarely required because
      `gcry_md_close' implicitly stops debugging.
 
-   The following two deprecated macros are used for debugging by old
-code.  They shopuld be replaced by `gcry_md_debug'.
+\1f
+File: gcrypt.info,  Node: Message Authentication Codes,  Next: Key Derivation,  Prev: Hashing,  Up: Top
 
- -- Function: void gcry_md_start_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'.
+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.
 
- -- Function: void gcry_md_stop_debug (gcry_md_hd_t H, int RESERVED)
-     Stop debugging on handle H.  RESERVED should be specified as 0.
-     This function is usually not required because `gcry_md_close' does
-     implicitly stop debugging.
+   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: Hashing,  Up: Top
+File: gcrypt.info,  Node: Key Derivation,  Next: Random Numbers,  Prev: Message Authentication Codes,  Up: Top
 
-8 Key Derivation
+9 Key Derivation
 ****************
 
 Libgcypt provides a general purpose function to derive keys from
@@ -3758,12 +3487,18 @@ strings.
     `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
 
-9 Random Numbers
-****************
+10 Random Numbers
+*****************
 
 * Menu:
 
@@ -3773,8 +3508,8 @@ File: gcrypt.info,  Node: Random Numbers,  Next: S-expressions,  Prev: Key Deriv
 \1f
 File: gcrypt.info,  Node: Quality of random numbers,  Next: Retrieving random numbers,  Up: Random Numbers
 
-9.1 Quality of random numbers
-=============================
+10.1 Quality of random numbers
+==============================
 
 Libgcypt offers random numbers of different quality levels:
 
@@ -3795,8 +3530,8 @@ Libgcypt offers random numbers of different quality levels:
 \1f
 File: gcrypt.info,  Node: Retrieving random numbers,  Prev: Quality of random numbers,  Up: Random Numbers
 
-9.2 Retrieving random numbers
-=============================
+10.2 Retrieving random numbers
+==============================
 
  -- Function: void gcry_randomize (unsigned char *BUFFER, size_t
           LENGTH, enum gcry_random_level LEVEL)
@@ -3829,7 +3564,7 @@ File: gcrypt.info,  Node: Retrieving random numbers,  Prev: Quality of random nu
 \1f
 File: gcrypt.info,  Node: S-expressions,  Next: MPI library,  Prev: Random Numbers,  Up: Top
 
-10 S-expressions
+11 S-expressions
 ****************
 
 S-expressions are used by the public key functions to pass complex data
@@ -3847,7 +3582,7 @@ Rivest, code and description of S-expressions,
 \1f
 File: gcrypt.info,  Node: Data types for S-expressions,  Next: Working with S-expressions,  Up: S-expressions
 
-10.1 Data types for S-expressions
+11.1 Data types for S-expressions
 =================================
 
  -- Data type: gcry_sexp_t
@@ -3857,7 +3592,7 @@ File: gcrypt.info,  Node: Data types for S-expressions,  Next: Working with S-ex
 \1f
 File: gcrypt.info,  Node: Working with S-expressions,  Prev: Data types for S-expressions,  Up: S-expressions
 
-10.2 Working with S-expressions
+11.2 Working with S-expressions
 ===============================
 
 There are several functions to create an Libgcrypt S-expression object
@@ -4019,8 +3754,9 @@ There are functions to parse S-expressions and retrieve elements:
 
  -- 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 called the "type" and should always exist and be a
-     string. `NULL' is returned in case of a problem.
+     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
@@ -4047,6 +3783,26 @@ There are functions to parse S-expressions and retrieve elements:
           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
@@ -4065,10 +3821,69 @@ There are functions to parse S-expressions and retrieve elements:
      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
 
-11 MPI library
+12 MPI library
 **************
 
 * Menu:
@@ -4079,6 +3894,7 @@ File: gcrypt.info,  Node: MPI library,  Next: Prime numbers,  Prev: S-expression
 * 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.
@@ -4091,16 +3907,20 @@ called MPIs (multi-precision-integers).
 \1f
 File: gcrypt.info,  Node: Data types,  Next: Basic functions,  Up: MPI library
 
-11.1 Data types
+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
 
-11.2 Basic functions
+12.2 Basic functions
 ====================
 
 To work with MPIs, storage must be allocated and released for the
@@ -4120,7 +3940,8 @@ numbers.  This can be done with one of these functions:
      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.
+     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
@@ -4143,10 +3964,20 @@ The simplest operations are used to assign a new value to an MPI:
  -- 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
 
-11.3 MPI formats
+12.3 MPI formats
 ================
 
 The following functions are used to convert between an external
@@ -4164,7 +3995,8 @@ representation of an MPI and the internal one of Libgcrypt.
      `NULL'. FORMAT describes the format of the MPI as stored in BUFFER:
 
     `GCRYMPI_FMT_STD'
-          2-complement stored without a length header.
+          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
@@ -4176,8 +4008,11 @@ representation of an MPI and the internal one of Libgcrypt.
           `GCRYMPI_FMT_STD' with a 4 byte big endian header.
 
     `GCRYMPI_FMT_HEX'
-          Stored as a C style string with each byte of the MPI encoded
-          as 2 hex digits.  When using this format, BUFLEN must be zero.
+          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.
@@ -4203,6 +4038,12 @@ representation of an MPI and the internal one of Libgcrypt.
      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
@@ -4212,7 +4053,7 @@ representation of an MPI and the internal one of Libgcrypt.
 \1f
 File: gcrypt.info,  Node: Calculations,  Next: Comparisons,  Prev: MPI formats,  Up: MPI library
 
-11.4 Calculations
+12.4 Calculations
 =================
 
 Basic arithmetic operations:
@@ -4283,7 +4124,7 @@ Basic arithmetic operations:
 \1f
 File: gcrypt.info,  Node: Comparisons,  Next: Bit manipulations,  Prev: Calculations,  Up: MPI library
 
-11.5 Comparisons
+12.5 Comparisons
 ================
 
 The next 2 functions are used to compare MPIs:
@@ -4301,10 +4142,13 @@ The next 2 functions are used to compare MPIs:
      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: Miscellaneous,  Prev: Comparisons,  Up: MPI library
+File: gcrypt.info,  Node: Bit manipulations,  Next: EC functions,  Prev: Comparisons,  Up: MPI library
 
-11.6 Bit manipulations
+12.6 Bit manipulations
 ======================
 
 There are a couple of functions to get information on arbitrary bits in
@@ -4339,22 +4183,180 @@ an MPI and to set or clear them:
      X.
 
 \1f
-File: gcrypt.info,  Node: Miscellaneous,  Prev: Bit manipulations,  Up: MPI library
+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
 
-11.7 Miscellaneous
+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)
@@ -4362,33 +4364,73 @@ File: gcrypt.info,  Node: Miscellaneous,  Prev: Bit manipulations,  Up: MPI libr
      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.  Currently only the flag
-     `GCRYMPI_FLAG_SECURE' is allowed to convert A into an MPI stored
-     in "secure memory".
+     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.  Note that this
-     function is currently useless as no flags are allowed.
+     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 when the FLAG is set for A.
+     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 value 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'.
+     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
 
-12 Prime numbers
+13 Prime numbers
 ****************
 
 * Menu:
@@ -4399,7 +4441,7 @@ File: gcrypt.info,  Node: Prime numbers,  Next: Utilities,  Prev: MPI library,
 \1f
 File: gcrypt.info,  Node: Generation,  Next: Checking,  Up: Prime numbers
 
-12.1 Generation
+13.1 Generation
 ===============
 
  -- Function: gcry_error_t gcry_prime_generate (gcry_mpi_t
@@ -4426,30 +4468,32 @@ File: gcrypt.info,  Node: Generation,  Next: Checking,  Up: Prime numbers
 \1f
 File: gcrypt.info,  Node: Checking,  Prev: Generation,  Up: Prime numbers
 
-12.2 Checking
+13.2 Checking
 =============
 
  -- Function: gcry_error_t gcry_prime_check (gcry_mpi_t P, unsigned int
           FLAGS)
-     Check wether the number P is prime.  Returns zero in case P is
+     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: Architecture,  Prev: Prime numbers,  Up: Top
+File: gcrypt.info,  Node: Utilities,  Next: Tools,  Prev: Prime numbers,  Up: Top
 
-13 Utilities
+14 Utilities
 ************
 
 * Menu:
 
-* Memory allocation:: Functions related with memory allocation.
+* 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,  Up: Utilities
+File: gcrypt.info,  Node: Memory allocation,  Next: Context management,  Up: Utilities
 
-13.1 Memory allocation
+14.1 Memory allocation
 ======================
 
  -- Function: void * gcry_malloc (size_t N)
@@ -4480,9 +4524,96 @@ File: gcrypt.info,  Node: Memory allocation,  Up: Utilities
      Release the memory area pointed to by P.
 
 \1f
-File: gcrypt.info,  Node: Architecture,  Next: Self-Tests,  Prev: Utilities,  Up: Top
+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
 
-14 Architecture
+16 Architecture
 ***************
 
 This chapter describes the internal architecture of Libgcrypt.
@@ -4511,9 +4642,9 @@ 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 14.1: Libgcrypt subsystems
+Figure 16.1: Libgcrypt subsystems
 
-   Libgcrypt consists of several subsystems (*note Figure 14.1:
+   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
@@ -4541,18 +4672,12 @@ for details.
 \1f
 File: gcrypt.info,  Node: Public-Key Subsystem Architecture,  Next: Symmetric Encryption Subsystem Architecture,  Up: Architecture
 
-14.1 Public-Key Architecture
+16.1 Public-Key Architecture
 ============================
 
-Libgcrypt implements two interfaces for public key cryptography: The
-standard interface is PK interface using functions in the `gcry_pk_'
-name space.  The AC interface in an alternative one which is now
-deprecated and will not be further described.  The AC interface is also
-disabled in FIPS mode.
-
-   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
+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
@@ -4581,18 +4706,12 @@ following main functions are available:
      Create a new public/private key pair.
 
 
-   With the help of the module registration system 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.  The interface to the modules is published
-(`gcrypt-modules.h') so that it can used to register external
-implementations of algorithms with Libgcrypt.  However, for some
-algorithms this module interface is to limited and thus for the
-internal modules an extra interface is sometimes used to convey more
-information.
+   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
@@ -4610,7 +4729,7 @@ 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
 
-14.2 Symmetric Encryption Subsystem Architecture
+16.2 Symmetric Encryption Subsystem Architecture
 ================================================
 
 The interface to work with symmetric encryption algorithms is made up
@@ -4651,7 +4770,7 @@ 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
 
-14.3 Hashing and MACing Subsystem Architecture
+16.3 Hashing and MACing Subsystem Architecture
 ==============================================
 
 The interface to work with message digests and CRC algorithms is made
@@ -4703,7 +4822,7 @@ 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
 
-14.4 Multi-Precision-Integer Subsystem Architecture
+16.4 Multi-Precision-Integer Subsystem Architecture
 ===================================================
 
 The implementation of Libgcrypt's big integer computation code is based
@@ -4736,7 +4855,7 @@ GMP are:
 \1f
 File: gcrypt.info,  Node: Prime-Number-Generator Subsystem Architecture,  Next: Random-Number Subsystem Architecture,  Prev: Multi-Precision-Integer Subsystem Architecture,  Up: Architecture
 
-14.5 Prime-Number-Generator Subsystem Architecture
+16.5 Prime-Number-Generator Subsystem Architecture
 ==================================================
 
 Libgcrypt provides an interface to its prime number generator.  These
@@ -4776,7 +4895,7 @@ available through the public API.
    ---------- Footnotes ----------
 
    (1) Chae Hoon Lim and Pil Joong Lee. A key recovery attack on
-discrete log-based shemes using a prime order subgroup. In Burton S.
+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.
@@ -4784,7 +4903,7 @@ Described on page 260.
 \1f
 File: gcrypt.info,  Node: Random-Number Subsystem Architecture,  Prev: Prime-Number-Generator Subsystem Architecture,  Up: Architecture
 
-14.6 Random-Number Subsystem Architecture
+16.6 Random-Number Subsystem Architecture
 =========================================
 
 Libgcrypt provides 3 levels or random quality: The level
@@ -4847,7 +4966,7 @@ rndhw
 \1f
 File: gcrypt.info,  Node: CSPRNG Description,  Next: FIPS PRNG Description,  Up: Random-Number Subsystem Architecture
 
-14.6.1 Description of the CSPRNG
+16.6.1 Description of the CSPRNG
 --------------------------------
 
 This random number generator is loosely modelled after the one
@@ -4884,7 +5003,7 @@ 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
 
-14.6.2 Description of the FIPS X9.31 PRNG
+16.6.2 Description of the FIPS X9.31 PRNG
 -----------------------------------------
 
 The core of this deterministic random number generator is implemented
@@ -4903,7 +5022,7 @@ 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/radnom' device. Thus these generators may block
+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.
 
@@ -4918,7 +5037,7 @@ 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 stucked generator.
+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
@@ -5066,8 +5185,8 @@ RSA
           (`cipher/rsa.c:selftest_sign_1024')
 
        4. A 1000 bit random value is encrypted and checked that it does
-          not match the orginal random value.  The encrtypted result is
-          then decrypted and checked that it macthes the original
+          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
@@ -5104,7 +5223,7 @@ keys.  The table itself is protected using a SHA-1 hash.
 A.2 Conditional Tests
 =====================
 
-The conditional tests are performed if a certain contidion is met.
+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.
@@ -5139,9 +5258,7 @@ DSA
 A.2.2 Software Load Tests
 -------------------------
 
-Loading of extra modules into libgcrypt is disabled in FIPS mode and
-thus no tests are implemented. (`cipher/cipher.c:_gcry_cipher_register',
-`cipher/md.c:_gcry_md_register', `cipher/pubkey.c:_gcry_pk_register')
+No code is loaded at runtime.
 
 A.2.3 Manual Key Entry Tests
 ----------------------------
@@ -5341,11 +5458,6 @@ If Libgcrypt is used in FIPS mode these restrictions are effective:
 
    * The command `GCRYCTL_ENABLE_QUICK_RANDOM' is ignored.
 
-   * The Alternative Public Key Interface (`gcry_ac_xxx') is not
-     supported and all API calls return an error.
-
-   * Registration of external modules is not supported.
-
    * Message digest debugging is disabled.
 
    * All debug output related to cryptographic data is suppressed.
@@ -5391,7 +5503,7 @@ Power-Off
 
 Power-On
      Libgcrypt is loaded into memory and API calls may be made.
-     Compiler introducted constructor functions may be run.  Note that
+     Compiler introduced constructor functions may be run.  Note that
      Libgcrypt does not implement any arbitrary constructor functions
      to be called by the operating system
 
@@ -5417,7 +5529,7 @@ Fatal-Error
 
 Shutdown
      Libgcrypt is about to be terminated and removed from the memory.
-     The application may at this point still runing cleanup handlers.
+     The application may at this point still running cleanup handlers.
 
 
 Table B.1: FIPS mode states
@@ -5430,18 +5542,18 @@ The valid state transitions (*note Figure B.1: fig:fips-fsm.) are:
 
 `2'
      Power-On to Init is triggered by the application calling the
-     Libgcrypt intialization function `gcry_check_version'.
+     Libgcrypt initialization function `gcry_check_version'.
 
 `3'
-     Init to Self-Test is either triggred by a dedicated API call or
-     implicit by invoking a libgrypt service conrolled by the FSM.
+     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 artifical state without any direct
+     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.
 
@@ -5462,35 +5574,35 @@ The valid state transitions (*note Figure B.1: fig:fips-fsm.) are:
      transition (5).
 
 `9'
-     Error to Fatal-Error is triggred if Libgrypt detects an fatal error
-     while already being in Error state.
+     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 artifical state to document that
-     Libgcrypt has not ye been initializaed but the process is about to
+     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 triggerd if certain Libgcrypt
+     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 triggred by severe errors in Libgcrypt
-     while running self-tests.
+     Self-Test to Fatal-Error is triggered by severe errors in
+     Libgcrypt while running self-tests.
 
 `14'
-     Self-Test to Error is triggred by a failed self-test.
+     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 triggred if the application requested
+     Operational to Self-Test is triggered if the application requested
      to run the self-tests again.
 
 `17'
@@ -5982,6 +6094,7 @@ be combined with the library in order to run.
      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
@@ -6325,6 +6438,7 @@ modification follow.
      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
@@ -6422,7 +6536,7 @@ List of Figures and Tables
 
 * Menu:
 
-* Figure 14.1: Libgcrypt subsystems:     fig:subsystems.
+* Figure 16.1: Libgcrypt subsystems:     fig:subsystems.
 * Figure B.1: FIPS mode state ...:       fig:fips-fsm.
 
 * Menu:
@@ -6439,434 +6553,129 @@ Concept Index
 \0\b[index\0\b]
 * Menu:
 
-* 3DES:                                  Available ciphers.   (line  16)
-* Advanced Encryption Standard:          Available ciphers.   (line  37)
-* AES:                                   Available ciphers.   (line  37)
+* 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  54)
-* Blowfish:                              Available ciphers.   (line  24)
-* Camellia:                              Available ciphers.   (line  81)
-* CAST5:                                 Available ciphers.   (line  21)
+                                                               (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)
+                                                               (line 20)
 * CBC-MAC:                               Working with cipher handles.
-                                                              (line  52)
+                                                               (line 55)
+* CCM, Counter with CBC-MAC mode:        Available cipher modes.
+                                                               (line 45)
 * CFB, Cipher Feedback mode:             Available cipher modes.
-                                                              (line  16)
+                                                               (line 16)
 * cipher text stealing:                  Working with cipher handles.
-                                                              (line  45)
+                                                               (line 48)
+* comp:                                  Cryptographic Functions.
+                                                               (line 13)
 * CRC32:                                 Available hash algorithms.
-                                                              (line   6)
+                                                               (line  6)
 * CTR, Counter mode:                     Available cipher modes.
-                                                              (line  29)
-* DES:                                   Available ciphers.   (line  59)
-* DES-EDE:                               Available ciphers.   (line  16)
-* Digital Encryption Standard:           Available ciphers.   (line  16)
+                                                               (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)
-* 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)
+                                                               (line 13)
+* EdDSA:                                 Cryptographic Functions.
+                                                               (line 31)
+* 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  63)
-* FIPS 186:                              General public-key related Functions.
-                                                              (line 257)
-* FIPS mode:                             Enabling FIPS mode.  (line   6)
-* GPL, GNU General Public License:       Copying.             (line   6)
+                                                               (line 51)
+* FIPS 186:                              Cryptographic Functions.
+                                                               (line 64)
+* FIPS 186-2:                            Cryptographic Functions.
+                                                               (line 72)
+* 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)
+                                                               (line  6)
 * HMAC:                                  Working with hash algorithms.
-                                                              (line  27)
-* IDEA:                                  Available ciphers.   (line  11)
-* LGPL, GNU Lesser General Public License: Library Copying.   (line   6)
+                                                               (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)
+                                                               (line  6)
+* no-blinding:                           Cryptographic Functions.
+                                                               (line 39)
+* nocomp:                                Cryptographic Functions.
+                                                               (line 13)
+* OAEP:                                  Cryptographic Functions.
+                                                               (line 25)
 * OFB, Output Feedback mode:             Available cipher modes.
-                                                              (line  26)
-* RC2:                                   Available ciphers.   (line  71)
-* RC4:                                   Available ciphers.   (line  54)
-* rfc-2268:                              Available ciphers.   (line  71)
-* Rijndael:                              Available ciphers.   (line  37)
+                                                               (line 26)
+* param:                                 Cryptographic Functions.
+                                                               (line 45)
+* PKCS1:                                 Cryptographic Functions.
+                                                               (line 21)
+* PSS:                                   Cryptographic Functions.
+                                                               (line 28)
+* RC2:                                   Available ciphers.    (line 69)
+* RC4:                                   Available ciphers.    (line 52)
+* rfc-2268:                              Available ciphers.    (line 69)
+* RFC6979:                               Cryptographic Functions.
+                                                               (line 36)
+* Rijndael:                              Available ciphers.    (line 35)
 * RIPE-MD-160:                           Available hash algorithms.
-                                                              (line   6)
-* Seed (cipher):                         Available ciphers.   (line  76)
-* Serpent:                               Available ciphers.   (line  67)
+                                                               (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)
+                                                               (line  6)
 * SHA-224, SHA-256, SHA-384, SHA-512:    Available hash algorithms.
-                                                              (line   6)
+                                                               (line  6)
 * sync mode (OpenPGP):                   Working with cipher handles.
-                                                              (line  40)
+                                                               (line 43)
 * TIGER, TIGER1, TIGER2:                 Available hash algorithms.
-                                                              (line   6)
-* Triple-DES:                            Available ciphers.   (line  16)
-* Twofish:                               Available ciphers.   (line  48)
+                                                               (line  6)
+* transient-key:                         Cryptographic Functions.
+                                                               (line 50)
+* Triple-DES:                            Available ciphers.    (line 14)
+* Twofish:                               Available ciphers.    (line 46)
 * Whirlpool:                             Available hash algorithms.
-                                                              (line   6)
+                                                               (line  6)
 * X9.31 <1>:                             Public-Key Subsystem Architecture.
-                                                              (line  63)
-* X9.31:                                 General public-key related Functions.
-                                                              (line 250)
-
-\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  13)
-* gcry_ac_close:                         Working with handles.
-                                                              (line  21)
-* gcry_ac_data_clear:                    Working with sets of data.
-                                                              (line  75)
-* gcry_ac_data_copy:                     Working with sets of data.
-                                                              (line  53)
-* gcry_ac_data_decode:                   Using cryptographic functions.
-                                                              (line 100)
-* gcry_ac_data_decrypt:                  Using cryptographic functions.
-                                                              (line  40)
-* gcry_ac_data_decrypt_scheme:           Using cryptographic functions.
-                                                              (line 137)
-* gcry_ac_data_destroy:                  Working with sets of data.
-                                                              (line  41)
-* gcry_ac_data_encode:                   Using cryptographic functions.
-                                                              (line  93)
-* gcry_ac_data_encrypt:                  Using cryptographic functions.
-                                                              (line  33)
-* gcry_ac_data_encrypt_scheme:           Using cryptographic functions.
-                                                              (line 127)
-* gcry_ac_data_from_sexp:                Working with sets of data.
-                                                              (line  93)
-* gcry_ac_data_get_index:                Working with sets of data.
-                                                              (line  69)
-* gcry_ac_data_get_name:                 Working with sets of data.
-                                                              (line  61)
-* gcry_ac_data_length:                   Working with sets of data.
-                                                              (line  57)
-* gcry_ac_data_new:                      Working with sets of data.
-                                                              (line  38)
-* gcry_ac_data_set:                      Working with sets of data.
-                                                              (line  45)
-* gcry_ac_data_sign:                     Using cryptographic functions.
-                                                              (line  48)
-* gcry_ac_data_sign_scheme:              Using cryptographic functions.
-                                                              (line 147)
-* gcry_ac_data_t:                        Working with sets of data.
-                                                              (line  20)
-* gcry_ac_data_to_sexp:                  Working with sets of data.
-                                                              (line  79)
-* gcry_ac_data_verify:                   Using cryptographic functions.
-                                                              (line  54)
-* gcry_ac_data_verify_scheme:            Using cryptographic functions.
-                                                              (line 157)
-* gcry_ac_id_t:                          Available asymmetric algorithms.
-                                                              (line  11)
-* gcry_ac_id_to_name:                    Handle-independent functions.
-                                                              (line  10)
-* gcry_ac_io_init:                       Working with IO objects.
-                                                              (line  22)
-* gcry_ac_io_init_va:                    Working with IO objects.
-                                                              (line  28)
-* gcry_ac_io_t:                          Working with IO objects.
-                                                              (line  10)
-* gcry_ac_key_data_get:                  Working with keys.   (line  93)
-* gcry_ac_key_destroy:                   Working with keys.   (line  86)
-* gcry_ac_key_get_grip:                  Working with keys.   (line 105)
-* gcry_ac_key_get_nbits:                 Working with keys.   (line 101)
-* gcry_ac_key_init:                      Working with keys.   (line  30)
-* gcry_ac_key_pair_destroy:              Working with keys.   (line  90)
-* gcry_ac_key_pair_extract:              Working with keys.   (line  83)
-* gcry_ac_key_pair_generate:             Working with keys.   (line  36)
-* gcry_ac_key_pair_t:                    Working with keys.   (line  20)
-* gcry_ac_key_t:                         Working with keys.   (line  16)
-* gcry_ac_key_test:                      Working with keys.   (line  97)
-* gcry_ac_key_type_t:                    Working with keys.   (line   7)
-* gcry_ac_name_to_id:                    Handle-independent functions.
-                                                              (line  15)
-* gcry_ac_open:                          Working with handles.
-                                                              (line  11)
-* gcry_calloc:                           Memory allocation.   (line  15)
-* gcry_calloc_secure:                    Memory allocation.   (line  21)
-* gcry_check_version:                    Initializing the library.
-                                                              (line  17)
-* gcry_cipher_algo_info:                 General cipher functions.
-                                                              (line  12)
-* gcry_cipher_algo_name:                 General cipher functions.
-                                                              (line  39)
-* gcry_cipher_close:                     Working with cipher handles.
-                                                              (line  59)
-* gcry_cipher_ctl:                       Working with cipher handles.
-                                                              (line 159)
-* gcry_cipher_decrypt:                   Working with cipher handles.
-                                                              (line 129)
-* gcry_cipher_decrypt_t:                 Cipher modules.      (line  80)
-* gcry_cipher_encrypt:                   Working with cipher handles.
-                                                              (line 110)
-* gcry_cipher_encrypt_t:                 Cipher modules.      (line  75)
-* gcry_cipher_info:                      Working with cipher handles.
-                                                              (line 168)
-* gcry_cipher_list:                      Cipher modules.      (line 108)
-* gcry_cipher_map_name:                  General cipher functions.
-                                                              (line  45)
-* gcry_cipher_mode_from_oid:             General cipher functions.
-                                                              (line  50)
-* gcry_cipher_oid_spec_t:                Cipher modules.      (line  60)
-* gcry_cipher_open:                      Working with cipher handles.
-                                                              (line  11)
-* gcry_cipher_register:                  Cipher modules.      (line  96)
-* gcry_cipher_reset:                     Working with cipher handles.
-                                                              (line  97)
-* gcry_cipher_setctr:                    Working with cipher handles.
-                                                              (line  90)
-* gcry_cipher_setiv:                     Working with cipher handles.
-                                                              (line  83)
-* gcry_cipher_setkey:                    Working with cipher handles.
-                                                              (line  68)
-* gcry_cipher_setkey_t:                  Cipher modules.      (line  70)
-* gcry_cipher_spec_t:                    Cipher modules.      (line  12)
-* gcry_cipher_stdecrypt_t:               Cipher modules.      (line  90)
-* gcry_cipher_stencrypt_t:               Cipher modules.      (line  85)
-* gcry_cipher_sync:                      Working with cipher handles.
-                                                              (line 149)
-* gcry_cipher_unregister:                Cipher modules.      (line 103)
-* gcry_control:                          Controlling the library.
-                                                              (line   7)
-* gcry_create_nonce:                     Retrieving random numbers.
-                                                              (line  26)
-* gcry_err_code:                         Error Values.        (line  43)
-* gcry_err_code_from_errno:              Error Values.        (line  95)
-* gcry_err_code_t:                       Error Values.        (line   7)
-* gcry_err_code_to_errno:                Error Values.        (line 100)
-* gcry_err_make:                         Error Values.        (line  57)
-* gcry_err_make_from_errno:              Error Values.        (line  81)
-* gcry_err_source:                       Error Values.        (line  49)
-* gcry_err_source_t:                     Error Values.        (line  14)
-* gcry_error:                            Error Values.        (line  64)
-* gcry_error_from_errno:                 Error Values.        (line  86)
-* gcry_error_t:                          Error Values.        (line  25)
-* gcry_fips_mode_active:                 Controlling the library.
-                                                              (line 221)
-* gcry_free:                             Memory allocation.   (line  31)
-* gcry_handler_alloc_t:                  Allocation handler.  (line  12)
-* gcry_handler_error_t:                  Error handler.       (line  27)
-* gcry_handler_free_t:                   Allocation handler.  (line  24)
-* gcry_handler_log_t:                    Logging handler.     (line   7)
-* gcry_handler_no_mem_t:                 Error handler.       (line  11)
-* gcry_handler_progress_t:               Progress handler.    (line  10)
-* gcry_handler_realloc_t:                Allocation handler.  (line  20)
-* gcry_handler_secure_check_t:           Allocation handler.  (line  16)
-* gcry_kdf_derive:                       Key Derivation.      (line  13)
-* gcry_malloc:                           Memory allocation.   (line   7)
-* gcry_malloc_secure:                    Memory allocation.   (line  12)
-* gcry_md_algo_name:                     Working with hash algorithms.
-                                                              (line 154)
-* gcry_md_close:                         Working with hash algorithms.
-                                                              (line  61)
-* gcry_md_copy:                          Working with hash algorithms.
-                                                              (line  84)
-* gcry_md_debug:                         Working with hash algorithms.
-                                                              (line 218)
-* gcry_md_enable:                        Working with hash algorithms.
-                                                              (line  44)
-* gcry_md_final:                         Working with hash algorithms.
-                                                              (line 112)
-* gcry_md_final_t:                       Hash algorithm modules.
-                                                              (line  73)
-* gcry_md_get_algo:                      Working with hash algorithms.
-                                                              (line 198)
-* gcry_md_get_algo_dlen:                 Working with hash algorithms.
-                                                              (line 189)
-* gcry_md_get_asnoid:                    Working with hash algorithms.
-                                                              (line 170)
-* gcry_md_hash_buffer:                   Working with hash algorithms.
-                                                              (line 137)
-* gcry_md_init_t:                        Hash algorithm modules.
-                                                              (line  65)
-* gcry_md_is_enabled:                    Working with hash algorithms.
-                                                              (line 209)
-* gcry_md_is_secure:                     Working with hash algorithms.
-                                                              (line 204)
-* gcry_md_list:                          Hash algorithm modules.
-                                                              (line  93)
-* gcry_md_map_name:                      Working with hash algorithms.
-                                                              (line 160)
-* gcry_md_oid_spec_t:                    Hash algorithm modules.
-                                                              (line  57)
-* gcry_md_open:                          Working with hash algorithms.
-                                                              (line  11)
-* gcry_md_putc:                          Working with hash algorithms.
-                                                              (line 102)
-* gcry_md_read:                          Working with hash algorithms.
-                                                              (line 122)
-* gcry_md_read_t:                        Hash algorithm modules.
-                                                              (line  77)
-* gcry_md_register:                      Hash algorithm modules.
-                                                              (line  82)
-* gcry_md_reset:                         Working with hash algorithms.
-                                                              (line  72)
-* gcry_md_setkey:                        Working with hash algorithms.
-                                                              (line  53)
-* gcry_md_spec_t:                        Hash algorithm modules.
-                                                              (line  12)
-* gcry_md_start_debug:                   Working with hash algorithms.
-                                                              (line 232)
-* gcry_md_stop_debug:                    Working with hash algorithms.
-                                                              (line 240)
-* gcry_md_test_algo:                     Working with hash algorithms.
-                                                              (line 183)
-* gcry_md_unregister:                    Hash algorithm modules.
-                                                              (line  89)
-* gcry_md_write:                         Working with hash algorithms.
-                                                              (line  97)
-* gcry_md_write_t:                       Hash algorithm modules.
-                                                              (line  69)
-* gcry_module_t:                         Modules.             (line  10)
-* gcry_mpi_add:                          Calculations.        (line  10)
-* gcry_mpi_add_ui:                       Calculations.        (line  14)
-* gcry_mpi_addm:                         Calculations.        (line  18)
-* gcry_mpi_aprint:                       MPI formats.         (line  54)
-* gcry_mpi_clear_bit:                    Bit manipulations.   (line  19)
-* gcry_mpi_clear_flag:                   Miscellaneous.       (line  32)
-* gcry_mpi_clear_highbit:                Bit manipulations.   (line  25)
-* gcry_mpi_cmp:                          Comparisons.         (line   9)
-* gcry_mpi_cmp_ui:                       Comparisons.         (line  17)
-* gcry_mpi_copy:                         Basic functions.     (line  23)
-* gcry_mpi_div:                          Calculations.        (line  50)
-* gcry_mpi_dump:                         MPI formats.         (line  61)
-* gcry_mpi_gcd:                          Calculations.        (line  63)
-* gcry_mpi_get_flag:                     Miscellaneous.       (line  37)
-* gcry_mpi_get_nbits:                    Bit manipulations.   (line  10)
-* gcry_mpi_get_opaque:                   Miscellaneous.       (line  20)
-* gcry_mpi_invm:                         Calculations.        (line  68)
-* gcry_mpi_lshift:                       Bit manipulations.   (line  34)
-* gcry_mpi_mod:                          Calculations.        (line  55)
-* gcry_mpi_mul:                          Calculations.        (line  34)
-* gcry_mpi_mul_2exp:                     Calculations.        (line  46)
-* gcry_mpi_mul_ui:                       Calculations.        (line  38)
-* gcry_mpi_mulm:                         Calculations.        (line  42)
-* gcry_mpi_new:                          Basic functions.     (line  10)
-* gcry_mpi_powm:                         Calculations.        (line  59)
-* gcry_mpi_print:                        MPI formats.         (line  45)
-* gcry_mpi_randomize:                    Miscellaneous.       (line  41)
-* gcry_mpi_release:                      Basic functions.     (line  26)
-* gcry_mpi_rshift:                       Bit manipulations.   (line  29)
-* gcry_mpi_scan:                         MPI formats.         (line  12)
-* gcry_mpi_set:                          Basic functions.     (line  33)
-* gcry_mpi_set_bit:                      Bit manipulations.   (line  16)
-* gcry_mpi_set_flag:                     Miscellaneous.       (line  26)
-* gcry_mpi_set_highbit:                  Bit manipulations.   (line  22)
-* gcry_mpi_set_opaque:                   Miscellaneous.       (line   8)
-* gcry_mpi_set_ui:                       Basic functions.     (line  37)
-* gcry_mpi_snew:                         Basic functions.     (line  17)
-* gcry_mpi_sub:                          Calculations.        (line  22)
-* gcry_mpi_sub_ui:                       Calculations.        (line  26)
-* gcry_mpi_subm:                         Calculations.        (line  30)
-* gcry_mpi_swap:                         Basic functions.     (line  44)
-* gcry_mpi_t:                            Data types.          (line   7)
-* gcry_mpi_test_bit:                     Bit manipulations.   (line  13)
-* gcry_pk_algo_info:                     General public-key related Functions.
-                                                              (line  47)
-* gcry_pk_algo_name:                     General public-key related Functions.
-                                                              (line  10)
-* gcry_pk_check_secret_key_t:            Public key modules.  (line  91)
-* gcry_pk_ctl:                           General public-key related Functions.
-                                                              (line 100)
-* gcry_pk_decrypt:                       Cryptographic Functions.
-                                                              (line  92)
-* gcry_pk_decrypt_t:                     Public key modules.  (line 101)
-* gcry_pk_encrypt:                       Cryptographic Functions.
-                                                              (line  36)
-* gcry_pk_encrypt_t:                     Public key modules.  (line  96)
-* gcry_pk_generate_t:                    Public key modules.  (line  86)
-* gcry_pk_genkey:                        General public-key related Functions.
-                                                              (line 115)
-* gcry_pk_get_keygrip:                   General public-key related Functions.
-                                                              (line  29)
-* gcry_pk_get_nbits:                     General public-key related Functions.
-                                                              (line  24)
-* gcry_pk_get_nbits_t:                   Public key modules.  (line 116)
-* gcry_pk_list:                          Public key modules.  (line 133)
-* gcry_pk_map_name:                      General public-key related Functions.
-                                                              (line  16)
-* gcry_pk_register:                      Public key modules.  (line 121)
-* gcry_pk_sign:                          Cryptographic Functions.
-                                                              (line 130)
-* gcry_pk_sign_t:                        Public key modules.  (line 106)
-* gcry_pk_spec_t:                        Public key modules.  (line  12)
-* gcry_pk_test_algo:                     General public-key related Functions.
-                                                              (line  20)
-* gcry_pk_testkey:                       General public-key related Functions.
-                                                              (line  40)
-* gcry_pk_unregister:                    Public key modules.  (line 129)
-* gcry_pk_verify:                        Cryptographic Functions.
-                                                              (line 183)
-* gcry_pk_verify_t:                      Public key modules.  (line 111)
-* gcry_prime_check:                      Checking.            (line   8)
-* gcry_prime_generate:                   Generation.          (line  10)
-* gcry_prime_group_generator:            Generation.          (line  19)
-* gcry_prime_release_factors:            Generation.          (line  25)
-* gcry_random_bytes:                     Retrieving random numbers.
-                                                              (line  13)
-* gcry_random_bytes_secure:              Retrieving random numbers.
-                                                              (line  19)
-* gcry_random_level_t:                   Quality of random numbers.
-                                                              (line   9)
-* gcry_randomize:                        Retrieving random numbers.
-                                                              (line   8)
-* gcry_realloc:                          Memory allocation.   (line  24)
-* gcry_set_allocation_handler:           Allocation handler.  (line  34)
-* gcry_set_fatalerror_handler:           Error handler.       (line  32)
-* gcry_set_log_handler:                  Logging handler.     (line  12)
-* gcry_set_outofcore_handler:            Error handler.       (line  16)
-* gcry_set_progress_handler:             Progress handler.    (line  21)
-* gcry_sexp_build:                       Working with S-expressions.
-                                                              (line  43)
-* gcry_sexp_canon_len:                   Working with S-expressions.
-                                                              (line 135)
-* gcry_sexp_car:                         Working with S-expressions.
-                                                              (line 164)
-* gcry_sexp_cdr:                         Working with S-expressions.
-                                                              (line 169)
-* gcry_sexp_create:                      Working with S-expressions.
-                                                              (line  26)
-* gcry_sexp_dump:                        Working with S-expressions.
-                                                              (line 126)
-* gcry_sexp_find_token:                  Working with S-expressions.
-                                                              (line 147)
-* gcry_sexp_length:                      Working with S-expressions.
-                                                              (line 154)
-* gcry_sexp_new:                         Working with S-expressions.
-                                                              (line  13)
-* gcry_sexp_nth:                         Working with S-expressions.
-                                                              (line 159)
-* gcry_sexp_nth_data:                    Working with S-expressions.
-                                                              (line 177)
-* gcry_sexp_nth_mpi:                     Working with S-expressions.
-                                                              (line 202)
-* gcry_sexp_nth_string:                  Working with S-expressions.
-                                                              (line 194)
-* gcry_sexp_release:                     Working with S-expressions.
-                                                              (line  92)
-* gcry_sexp_sprint:                      Working with S-expressions.
-                                                              (line 103)
-* gcry_sexp_sscan:                       Working with S-expressions.
-                                                              (line  37)
-* gcry_sexp_t:                           Data types for S-expressions.
-                                                              (line   7)
-* gcry_strerror:                         Error Strings.       (line   7)
-* gcry_strsource:                        Error Strings.       (line  13)
-
+                                                               (line 51)
+* X9.31:                                 Cryptographic Functions.
+                                                               (line 57)
 
diff --git a/doc/gcrypt.info-2 b/doc/gcrypt.info-2
new file mode 100644 (file)
index 0000000..aba9f6c
Binary files /dev/null and b/doc/gcrypt.info-2 differ
index e172ca8..58491fb 100644 (file)
@@ -12,7 +12,9 @@ This manual is for Libgcrypt
 (version @value{VERSION}, @value{UPDATED}),
 which is GNU's library of cryptographic building blocks.
 
-Copyright @copyright{} 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
+@noindent
+Copyright @copyright{} 2000, 2002, 2003, 2004, 2006, 2007, 2008, 2009, 2011, 2012 Free Software Foundation, Inc. @*
+Copyright @copyright{} 2012, 2013 g10 Code GmbH
 
 @quotation
 Permission is granted to copy, distribute and/or modify this document
@@ -28,6 +30,23 @@ section entitled ``GNU General Public License''.
 * libgcrypt: (gcrypt).  Cryptographic function library.
 @end direntry
 
+@c A couple of macros with no effect on texinfo
+@c but used by the yat2m processor.
+@macro manpage {a}
+@end macro
+@macro mansect {a}
+@end macro
+@macro manpause
+@end macro
+@macro mancont
+@end macro
+
+@c
+@c Printing stuff taken from gcc.
+@c
+@macro gnupgtabopt{body}
+@code{\body\}
+@end macro
 
 
 @c
@@ -67,13 +86,15 @@ section entitled ``GNU General Public License''.
 * 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 and MAC algorithms.
+* 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
@@ -189,6 +210,7 @@ of the library are verified.
 * 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.
 @end menu
 
 
@@ -370,7 +392,7 @@ and freed memory, you need to 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);
@@ -385,7 +407,7 @@ and freed memory, you need to initialize Libgcrypt this way:
 
   /* ... 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 intialized.  */
+     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.  */
@@ -577,8 +599,10 @@ initialization (i.e. before @code{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
-@file{/etc/gcrypt/fips_enabled}.  The Enforced FIPS mode helps to
-detect applications which don't fulfill all requirements for using
+@file{/etc/gcrypt/fips_enabled} or by using the control command
+@code{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 (@pxref{FIPS Mode}).
 
 Once Libgcrypt has been put into FIPS mode, it is not possible to
@@ -586,6 +610,53 @@ 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.
 
+@node Hardware features
+@section How to disable hardware features
+@cindex 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
+
+@table @code
+@item padlock-rng
+@item padlock-aes
+@item padlock-sha
+@item padlock-mmul
+@item intel-cpu
+@item intel-bmi2
+@item intel-ssse3
+@item intel-pclmul
+@item intel-aesni
+@item intel-rdrand
+@item intel-avx
+@item intel-avx2
+@item arm-neon
+@end table
+
+To disable a feature for all processes using Libgcrypt 1.6 or newer,
+create the file @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 @code{gcry_check_version}.
+Example:@footnote{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}
+
+@example
+  gcry_control (GCRYCTL_DISABLE_HWF, "intel-rdrand", NULL);
+@end example
+
+@noindent
+To print the list of active features you may use this command:
+
+@example
+  mpicalc --print-config | grep ^hwflist: | tr : '\n' | tail -n +2
+@end example
 
 
 @c **********************************************************
@@ -596,7 +667,6 @@ If the logging verbosity level of Libgcrypt has been set to at least
 
 @menu
 * Controlling the library::     Controlling Libgcrypt's behavior.
-* Modules::                     Description of extension modules.
 * Error Handling::              Error codes and such.
 @end menu
 
@@ -621,9 +691,9 @@ callbacks.
 @item GCRYCTL_ENABLE_QUICK_RANDOM; Arguments: none
 This command inhibits the use the very secure random quality level
 (@code{GCRY_VERY_STRONG_RANDOM}) and degrades all request down to
-@code{GCRY_STRONG_RANDOM}.  In general this is not recommened.  However,
+@code{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 performace.
+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.
 
@@ -631,19 +701,19 @@ This option can only be used at initialization time.
 
 
 @item GCRYCTL_DUMP_RANDOM_STATS; Arguments: none
-This command dumps randum number generator related statistics to the
+This command dumps random number generator related statistics to the
 library's logging stream.
 
 @item GCRYCTL_DUMP_MEMORY_STATS; Arguments: none
-This command dumps memory managment related statistics to the library's
+This command dumps memory management related statistics to the library's
 logging stream.
 
 @item GCRYCTL_DUMP_SECMEM_STATS; Arguments: none
-This command dumps secure memory manamgent related statistics to the
+This command dumps secure memory management related statistics to the
 library's logging stream.
 
 @item GCRYCTL_DROP_PRIVS; Arguments: none
-This command disables the use of secure memory and drops the priviliges
+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 @code{GCRYCTL_DISABLE_SECMEM} right
 after initialization.
@@ -658,6 +728,24 @@ Many applications do not require secure memory, so they should disable
 it right away.  This command should be executed right after
 @code{gcry_check_version}.
 
+@item 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
+@code{gcry_check_version}.
+
+@item 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
+@code{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.
+
 @item 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
@@ -719,13 +807,21 @@ 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
-inital states of the pools are completely known.  Note that this is not
+initial states of the pools are completely known.  Note that this is not
 an issue if random of @code{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.
 
+@item 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.
+
 @item 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.
@@ -756,11 +852,11 @@ This command does nothing.  It exists only for backward compatibility.
 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 intialization is by calling gcry_check_version.
+do this basic initialization is by calling gcry_check_version.
 
 @item GCRYCTL_INITIALIZATION_FINISHED; Arguments: none
 This command tells the library that the application has finished the
-intialization.
+initialization.
 
 @item GCRYCTL_INITIALIZATION_FINISHED_P; Arguments: none
 This command returns true if the command@*
@@ -786,21 +882,21 @@ proper random device.
 @item 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 @var{stream}, the log
-system is used.  This command may be used before the intialization has
-been finished but not before a gcry_version_check.
+system is used.  This command may be used before the initialization has
+been finished but not before a @code{gcry_check_version}.
 
 @item 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 intialization has been finished but not before a gcry_version_check.
+the initialization has been finished but not before a @code{gcry_check_version}.
 
 @item 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 intialization has been finished but not
-before a gcry_version_check.  An application may use this command or
+command may be used before the initialization has been finished but not
+before a @code{gcry_check_version}.  An application may use this command or
 the convenience macro below to check whether FIPS mode is actually
 active.
 
@@ -816,9 +912,49 @@ implemented as a macro.
 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
+to @code{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 intialization.
+reject an attempt to switch to fips mode during or after the initialization.
+
+@item 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 @code{gcry_check_version}. Note that Libgcrypt will
+reject an attempt to switch to the enforced fips mode during or after
+the initialization.
+
+@item 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
+@code{gcry_check_version}.  The available generators are:
+@table @code
+@item GCRY_RNG_TYPE_STANDARD
+A conservative standard generator based on the ``Continuously Seeded
+Pseudo Random Number Generator'' designed by Peter Gutmann.
+@item 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.
+@item 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.
+@end table
+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 *
+This command stores the type of the currently used RNG as an integer
+value at the provided address.
+
 
 @item GCRYCTL_SELFTEST; Arguments: none
 This may be used at anytime to have the library run all implemented
@@ -828,8 +964,8 @@ success or an error code on failure.
 @item GCRYCTL_DISABLE_HWF; Arguments: const char *name
 
 Libgcrypt detects certain features of the CPU at startup time.  For
-performace tests it is sometimes required not to use such a feature.
-This option may be used to disabale a certain feature; i.e. Libgcrypt
+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
@@ -839,25 +975,6 @@ command must be used at initialization time; i.e. before calling
 
 @end deftypefun
 
-@node Modules
-@section Modules
-
-Libgcrypt supports the use of `extension modules', which
-implement algorithms in addition to those already built into the library
-directly.
-
-@deftp {Data type} gcry_module_t
-This data type represents a `module'.
-@end deftp
-
-Functions registering modules provided by the user take a `module
-specification structure' as input and return a value of
-@code{gcry_module_t} and an ID that is unique in the modules'
-category.  This ID can be used to reference the newly registered
-module.  After registering a module successfully, the new functionality
-should be able to be used through the normal functions provided by
-Libgcrypt until it is unregistered again.
-
 @c **********************************************************
 @c *******************  Errors  ****************************
 @c **********************************************************
@@ -1208,7 +1325,7 @@ diagnostic message to the user.
 
 
 @deftypefun {const char *} gcry_strsource (@w{gcry_error_t @var{err}})
-The function @code{gcry_strerror} returns a pointer to a statically
+The function @code{gcry_strsource} returns a pointer to a statically
 allocated string containing a description of the error source
 contained in the error value @var{err}.  This string can be used to
 output a diagnostic message to the user.
@@ -1294,6 +1411,10 @@ values for @var{what} are defined:
 Not enough entropy is available.  @var{total} holds the number of
 required bytes.
 
+@item wait_dev_random
+Waiting to re-open a random device.  @var{total} gives the number of
+seconds until the next try.
+
 @item primegen
 Values for @var{printchar}:
 @table @code
@@ -1412,7 +1533,6 @@ building blocks provided by Libgcrypt.
 
 @menu
 * Available ciphers::           List of ciphers supported by the library.
-* Cipher modules::              How to work with cipher modules.
 * 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.
@@ -1428,8 +1548,7 @@ The value always evaluates to false.
 
 @item GCRY_CIPHER_IDEA
 @cindex IDEA
-This is the IDEA algorithm.  The constant is provided but there is
-currently no implementation for it because the algorithm is patented.
+This is the IDEA algorithm.
 
 @item GCRY_CIPHER_3DES
 @cindex 3DES
@@ -1502,9 +1621,7 @@ The Serpent cipher from the AES contest.
 @itemx GCRY_CIPHER_RFC2268_128
 @cindex rfc-2268
 @cindex RC2
-Ron's Cipher 2 in the 40 and 128 bit variants.  Note, that we currently
-only support the 40 bit variant.  The identifier for 128 is reserved for
-future use.
+Ron's Cipher 2 in the 40 and 128 bit variants.
 
 @item GCRY_CIPHER_SEED
 @cindex Seed (cipher)
@@ -1517,120 +1634,20 @@ A 128 bit cipher as described by RFC4269.
 The Camellia cipher by NTT.  See
 @uref{http://info.isl.ntt.co.jp/@/crypt/@/eng/@/camellia/@/specifications.html}.
 
-@end table
-
-@node Cipher modules
-@section Cipher modules
-
-Libgcrypt makes it possible to load additional `cipher modules'; these
-ciphers can be used just like the cipher algorithms that are built
-into the library directly.  For an introduction into extension
-modules, see @xref{Modules}.
+@item GCRY_CIPHER_SALSA20
+@cindex Salsa20
+This is the Salsa20 stream cipher.
 
-@deftp {Data type} gcry_cipher_spec_t
-This is the `module specification structure' needed for registering
-cipher modules, which has to be filled in by the user before it can be
-used to register a module.  It contains the following members:
+@item GCRY_CIPHER_SALSA20R12
+@cindex Salsa20/12
+This is the Salsa20/12 - reduced round version of Salsa20 stream cipher.
 
-@table @code
-@item const char *name
-The primary name of the algorithm.
-@item const char **aliases
-A list of strings that are `aliases' for the algorithm.  The list must
-be terminated with a NULL element.
-@item gcry_cipher_oid_spec_t *oids
-A list of OIDs that are to be associated with the algorithm.  The
-list's last element must have it's `oid' member set to NULL.  See
-below for an explanation of this type.
-@item size_t blocksize
-The block size of the algorithm, in bytes.
-@item size_t keylen
-The length of the key, in bits.
-@item size_t contextsize
-The size of the algorithm-specific `context', that should be allocated
-for each handle.
-@item gcry_cipher_setkey_t setkey
-The function responsible for initializing a handle with a provided
-key.  See below for a description of this type.
-@item gcry_cipher_encrypt_t encrypt
-The function responsible for encrypting a single block.  See below for
-a description of this type.
-@item gcry_cipher_decrypt_t decrypt
-The function responsible for decrypting a single block.  See below for
-a description of this type.
-@item gcry_cipher_stencrypt_t stencrypt
-Like `encrypt', for stream ciphers.  See below for a description of
-this type.
-@item gcry_cipher_stdecrypt_t stdecrypt
-Like `decrypt', for stream ciphers.  See below for a description of
-this type.
-@end table
-@end deftp
+@item GCRY_CIPHER_GOST28147
+@cindex GOST 28147-89
+The GOST 28147-89 cipher, defined in the respective GOST standard.
+Translation of this GOST into English is provided in the RFC-5830.
 
-@deftp {Data type} gcry_cipher_oid_spec_t
-This type is used for associating a user-provided algorithm
-implementation with certain OIDs.  It contains the following members:
-@table @code
-@item const char *oid
-Textual representation of the OID.
-@item int mode
-Cipher mode for which this OID is valid.
 @end table
-@end deftp
-
-@deftp {Data type} gcry_cipher_setkey_t
-Type for the `setkey' function, defined as: gcry_err_code_t
-(*gcry_cipher_setkey_t) (void *c, const unsigned char *key, unsigned
-keylen)
-@end deftp
-
-@deftp {Data type} gcry_cipher_encrypt_t
-Type for the `encrypt' function, defined as: gcry_err_code_t
-(*gcry_cipher_encrypt_t) (void *c, const unsigned char *outbuf, const
-unsigned char *inbuf)
-@end deftp
-
-@deftp {Data type} gcry_cipher_decrypt_t
-Type for the `decrypt' function, defined as: gcry_err_code_t
-(*gcry_cipher_decrypt_t) (void *c, const unsigned char *outbuf, const
-unsigned char *inbuf)
-@end deftp
-
-@deftp {Data type} gcry_cipher_stencrypt_t
-Type for the `stencrypt' function, defined as: gcry_err_code_t
-(*gcry_@/cipher_@/stencrypt_@/t) (void *c, const unsigned char *outbuf, const
-unsigned char *, unsigned int n)
-@end deftp
-
-@deftp {Data type} gcry_cipher_stdecrypt_t
-Type for the `stdecrypt' function, defined as: gcry_err_code_t
-(*gcry_@/cipher_@/stdecrypt_@/t) (void *c, const unsigned char *outbuf, const
-unsigned char *, unsigned int n)
-@end deftp
-
-@deftypefun gcry_error_t gcry_cipher_register (gcry_cipher_spec_t *@var{cipher}, unsigned int *algorithm_id, gcry_module_t *@var{module})
-
-Register a new cipher module whose specification can be found in
-@var{cipher}.  On success, a new algorithm ID is stored in
-@var{algorithm_id} and a pointer representing this module is stored
-in @var{module}.  Deprecated; the module register interface will be
-removed in a future version.
-@end deftypefun
-
-@deftypefun void gcry_cipher_unregister (gcry_module_t @var{module})
-Unregister the cipher identified by @var{module}, which must have been
-registered with gcry_cipher_register.
-@end deftypefun
-
-@deftypefun gcry_error_t gcry_cipher_list (int *@var{list}, int *@var{list_length})
-Get a list consisting of the IDs of the loaded cipher modules.  If
-@var{list} is zero, write the number of loaded cipher modules to
-@var{list_length} and return.  If @var{list} is non-zero, the first
-*@var{list_length} algorithm IDs are stored in @var{list}, which must
-be of according size.  In case there are less cipher modules than
-*@var{list_length}, *@var{list_length} is updated to the correct
-number.
-@end deftypefun
 
 @node Available cipher modes
 @section Available cipher modes
@@ -1679,6 +1696,18 @@ 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.
 
+@item  GCRY_CIPHER_MODE_CCM
+@cindex CCM, Counter with CBC-MAC mode
+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.
+
+@item  GCRY_CIPHER_MODE_GCM
+@cindex GCM, Galois/Counter Mode
+Galois/Counter Mode (GCM) is an Authenticated Encryption with
+Associated Data (AEAD) block cipher mode, which is specified in
+'NIST Special Publication 800-38D'.
+
 @end table
 
 @node Working with cipher handles
@@ -1705,11 +1734,13 @@ 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. Any
-block cipher mode (@code{GCRY_CIPHER_MODE_ECB},
+(@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} or @code{GCRY_CIPHER_MODE_CTR}) will work
-with any block cipher algorithm.
+@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.
 
 The third argument @var{flags} can either be passed as @code{0} or as
 the bit-wise OR of the following constants.
@@ -1771,6 +1802,14 @@ Set the initialization vector used for encryption or decryption. The
 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.
+
 @end deftypefun
 
 @deftypefun gcry_error_t gcry_cipher_setctr (gcry_cipher_hd_t @var{h}, const void *@var{c}, size_t @var{l})
@@ -1790,6 +1829,37 @@ call to gcry_cipher_setkey and clear the initialization vector.
 Note that gcry_cipher_reset is implemented as a macro.
 @end deftypefun
 
+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:
+
+@deftypefun gcry_error_t gcry_cipher_authenticate (gcry_cipher_hd_t @var{h}, const void *@var{abuf}, size_t @var{abuflen})
+
+Process the buffer @var{abuf} of length @var{abuflen} as the additional
+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})
+
+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.
+
+@end deftypefun
+
+@deftypefun gcry_error_t gcry_cipher_checktag (gcry_cipher_hd_t @var{h}, const void *@var{tag}, 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
+and compared to internal authentication tag computed during
+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.
+
+@end deftypefun
+
 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.
@@ -1891,11 +1961,15 @@ Here is a list of supported codes for @var{what}:
 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
-@var{nbytes}; @var{buffer} must be zero.
+@var{nbytes}; @var{buffer} must be zero.  Note that it is usually
+better to use the convenience function
+@code{gcry_cipher_get_algo_keylen}.
 
 @item GCRYCTL_GET_BLKLEN:
 Return the block length of the algorithm.  The length is returned as a
-number of octets in @var{nbytes}; @var{buffer} must be zero.
+number of octets in @var{nbytes}; @var{buffer} must be zero.  Note
+that it is usually better to use the convenience function
+@code{gcry_cipher_get_algo_blklen}.
 
 @item GCRYCTL_TEST_ALGO:
 Returns @code{0} when the specified algorithm is available for use.
@@ -1907,6 +1981,31 @@ Returns @code{0} when the specified algorithm is available for use.
 @end deftypefun
 @c end gcry_cipher_algo_info
 
+@deftypefun size_t gcry_cipher_get_algo_keylen (@var{algo})
+
+This function returns length of the key for algorithm @var{algo}.  If
+the algorithm supports multiple key lengths, the maximum supported key
+length is returned.  On error @code{0} is returned.  The key length is
+returned as number of octets.
+
+This is a convenience functions which should be preferred over
+@code{gcry_cipher_algo_info} because it allows for proper type
+checking.
+@end deftypefun
+@c end gcry_cipher_get_algo_keylen
+
+@deftypefun size_t gcry_cipher_get_algo_blklen (int @var{algo})
+
+This functions returns the block-length of the algorithm @var{algo}
+counted in octets.  On error @code{0} is returned.
+
+This is a convenience functions which should be preferred over
+@code{gcry_cipher_algo_info} because it allows for proper type
+checking.
+@end deftypefun
+@c end gcry_cipher_get_algo_blklen
+
+
 @deftypefun {const char *} gcry_cipher_algo_name (int @var{algo})
 
 @code{gcry_cipher_algo_name} returns a string with the name of the
@@ -1947,11 +2046,8 @@ S-expressions.
 @menu
 * Available algorithms::        Algorithms supported by the library.
 * Used S-expressions::          Introduction into the used S-expression.
-* Public key modules::          How to work with public key modules.
 * Cryptographic Functions::     Functions for performing the cryptographic actions.
 * General public-key related Functions::  General functions, not implementing any cryptography.
-
-* AC Interface::                Alternative interface to public key functions.
 @end menu
 
 @node Available algorithms
@@ -1972,7 +2068,7 @@ with contexts as most of the other building blocks of Libgcrypt do.
 @noindent
 The following information are stored in S-expressions:
 
-@itemize @asis
+@itemize
 @item keys
 
 @item plain text data
@@ -2104,6 +2200,7 @@ and no @var{x-mpi}.
 @node ECC key parameters
 @subsection ECC key parameters
 
+@anchor{ecc_keyparam}
 @noindent
 An ECC private key is described by this S-expression:
 
@@ -2130,14 +2227,15 @@ Base point @math{g}.
 @item n-mpi
 Order of @math{g}
 @item q-point
-The point representing the public key @math{Q = dP}.
+The point representing the public key @math{Q = dG}.
 @item d-mpi
 The private key @math{d}
 @end table
 
-All point values are encoded in standard format; Libgcrypt does
-currently only support uncompressed points, thus the first byte needs to
-be @code{0x04}.
+All point values are encoded in standard format; Libgcrypt does in
+general only support uncompressed points, thus the first byte needs to
+be @code{0x04}.  However ``EdDSA'' describes its own compression
+scheme which is used by default.
 
 The public key is similar with "private-key" replaced by "public-key"
 and no @var{d-mpi}.
@@ -2153,7 +2251,8 @@ used.  For example
     (d @var{d-mpi})))
 @end example
 
-The @code{curve} parameter may be given in any case and is used to replace
+Note that @var{q-point} is optional for a private key.  The
+@code{curve} parameter may be given in any case and is used to replace
 missing parameters.
 
 @noindent
@@ -2188,166 +2287,95 @@ As usual the OIDs may optionally be prefixed with the string @code{OID.}
 or @code{oid.}.
 
 
-
-@node Public key modules
-@section Public key modules
-
-Libgcrypt makes it possible to load additional `public key
-modules'; these public key algorithms can be used just like the
-algorithms that are built into the library directly.  For an
-introduction into extension modules, see @xref{Modules}.
-
-@deftp {Data type} gcry_pk_spec_t
-This is the `module specification structure' needed for registering
-public key modules, which has to be filled in by the user before it
-can be used to register a module.  It contains the following members:
-
-@table @code
-@item const char *name
-The primary name of this algorithm.
-@item char **aliases
-A list of strings that are `aliases' for the algorithm.  The list
-must be terminated with a NULL element.
-@item const char *elements_pkey
-String containing the one-letter names of the MPI values contained in
-a public key.
-@item const char *element_skey
-String containing the one-letter names of the MPI values contained in
-a secret key.
-@item const char *elements_enc
-String containing the one-letter names of the MPI values that are the
-result of an encryption operation using this algorithm.
-@item const char *elements_sig
-String containing the one-letter names of the MPI values that are the
-result of a sign operation using this algorithm.
-@item const char *elements_grip
-String containing the one-letter names of the MPI values that are to
-be included in the `key grip'.
-@item int use
-The bitwise-OR of the following flags, depending on the abilities of
-the algorithm:
-@table @code
-@item GCRY_PK_USAGE_SIGN
-The algorithm supports signing and verifying of data.
-@item GCRY_PK_USAGE_ENCR
-The algorithm supports the encryption and decryption of data.
-@end table
-@item gcry_pk_generate_t generate
-The function responsible for generating a new key pair.  See below for
-a description of this type.
-@item gcry_pk_check_secret_key_t check_secret_key
-The function responsible for checking the sanity of a provided secret
-key.  See below for a description of this type.
-@item gcry_pk_encrypt_t encrypt
-The function responsible for encrypting data.  See below for a
-description of this type.
-@item gcry_pk_decrypt_t decrypt
-The function responsible for decrypting data.  See below for a
-description of this type.
-@item gcry_pk_sign_t sign
-The function responsible for signing data.  See below for a description
-of this type.
-@item gcry_pk_verify_t verify
-The function responsible for verifying that the provided signature
-matches the provided data.  See below for a description of this type.
-@item gcry_pk_get_nbits_t get_nbits
-The function responsible for returning the number of bits of a provided
-key.  See below for a description of this type.
-@end table
-@end deftp
-
-@deftp {Data type} gcry_pk_generate_t
-Type for the `generate' function, defined as: gcry_err_code_t
-(*gcry_pk_generate_t) (int algo, unsigned int nbits, unsigned long
-use_e, gcry_mpi_t *skey, gcry_mpi_t **retfactors)
-@end deftp
-
-@deftp {Data type} gcry_pk_check_secret_key_t
-Type for the `check_secret_key' function, defined as: gcry_err_code_t
-(*gcry_pk_check_secret_key_t) (int algo, gcry_mpi_t *skey)
-@end deftp
-
-@deftp {Data type} gcry_pk_encrypt_t
-Type for the `encrypt' function, defined as: gcry_err_code_t
-(*gcry_pk_encrypt_t) (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
-gcry_mpi_t *pkey, int flags)
-@end deftp
-
-@deftp {Data type} gcry_pk_decrypt_t
-Type for the `decrypt' function, defined as: gcry_err_code_t
-(*gcry_pk_decrypt_t) (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
-gcry_mpi_t *skey, int flags)
-@end deftp
-
-@deftp {Data type} gcry_pk_sign_t
-Type for the `sign' function, defined as: gcry_err_code_t
-(*gcry_pk_sign_t) (int algo, gcry_mpi_t *resarr, gcry_mpi_t data,
-gcry_mpi_t *skey)
-@end deftp
-
-@deftp {Data type} gcry_pk_verify_t
-Type for the `verify' function, defined as: gcry_err_code_t
-(*gcry_pk_verify_t) (int algo, gcry_mpi_t hash, gcry_mpi_t *data,
-gcry_mpi_t *pkey, int (*cmp) (void *, gcry_mpi_t), void *opaquev)
-@end deftp
-
-@deftp {Data type} gcry_pk_get_nbits_t
-Type for the `get_nbits' function, defined as: unsigned
-(*gcry_pk_get_nbits_t) (int algo, gcry_mpi_t *pkey)
-@end deftp
-
-@deftypefun gcry_error_t gcry_pk_register (gcry_pk_spec_t *@var{pubkey}, unsigned int *algorithm_id, gcry_module_t *@var{module})
-
-Register a new public key module whose specification can be found in
-@var{pubkey}.  On success, a new algorithm ID is stored in
-@var{algorithm_id} and a pointer representing this module is stored in
-@var{module}.  Deprecated; the module register interface will be
-removed in a future version.
-
-@end deftypefun
-
-@deftypefun void gcry_pk_unregister (gcry_module_t @var{module})
-Unregister the public key module identified by @var{module}, which
-must have been registered with gcry_pk_register.
-@end deftypefun
-
-@deftypefun gcry_error_t gcry_pk_list (int *@var{list}, int *@var{list_length})
-Get a list consisting of the IDs of the loaded pubkey modules.  If
-@var{list} is zero, write the number of loaded pubkey modules to
-@var{list_length} and return.  If @var{list} is non-zero, the first
-*@var{list_length} algorithm IDs are stored in @var{list}, which must
-be of according size.  In case there are less pubkey modules than
-*@var{list_length}, *@var{list_length} is updated to the correct
-number.
-@end deftypefun
-
 @node Cryptographic Functions
 @section Cryptographic Functions
 
 @noindent
-Note that we will in future allow to use keys without p,q and u
-specified and may also support other parameters for performance
-reasons.
+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:
 
-@noindent
+@table @code
 
-Some functions operating on S-expressions support `flags', that
-influence the operation.  These flags have to be listed in a
-sub-S-expression named `flags'; the following flags are known:
+@item comp
+@itemx nocomp
+@cindex comp
+@cindex nocomp
+If supported by the algorithm and curve the @code{comp} flag requests
+that points are returned in compact (compressed) representation.  The
+@code{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.
 
-@table @code
 @item pkcs1
+@cindex PKCS1
 Use PKCS#1 block type 2 padding for encryption, block type 1 padding
 for signing.
+
 @item oaep
+@cindex OAEP
 Use RSA-OAEP padding for encryption.
+
 @item pss
+@cindex PSS
 Use RSA-PSS padding for signing.
+
+@item eddsa
+@cindex EdDSA
+Use the EdDSA scheme signing instead of the default ECDSA algorithm.
+Note that the EdDSA uses a special form of the public key.
+
+@item rfc6979
+@cindex RFC6979
+For DSA and ECDSA use a deterministic scheme for the k parameter.
+
 @item no-blinding
+@cindex 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.
+
+@item param
+@cindex 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.
+
+@item transient-key
+@cindex 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.
+
+@item use-x931
+@cindex X9.31
+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 @code{derive-parms} is given or Libgcrypt is
+in FIPS mode.
+
+@item use-fips186
+@cindex FIPS 186
+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
+@code{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.
+
+@item use-fips186-2
+@cindex FIPS 186-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.
+
 @end table
 
 @noindent
@@ -2515,6 +2543,35 @@ format should be used:
 Here, the data to be signed is directly given as an @var{MPI}.
 
 @noindent
+For DSA the input data is expected in this format:
+
+@example
+(data
+  (flags raw)
+  (value @var{mpi}))
+@end example
+
+@noindent
+Here, the data to be signed is directly given as an @var{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.
+
+@example
+(data
+  (flags rfc6979)
+  (hash @var{hash-algo} @var{block}))
+@end example
+
+Note that the provided hash-algo is used for the internal HMAC; it
+should match the hash-algo used to create @var{block}.
+
+
+@noindent
 The signature is returned as a newly allocated S-expression in
 @var{r_sig} using this format for RSA:
 
@@ -2535,9 +2592,28 @@ S-expression returned is:
 @end example
 
 Where @var{r-mpi} and @var{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".
+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:
+
+@example
+(data
+  (flags eddsa)
+  (hash-algo sha512)
+  (value @var{message}))
+@end example
+
+Note that the @var{message} may be of any length; hashing is part of
+the algorithm.  Using a large data block for @var{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.
+
+
 @end deftypefun
 @c end gcry_pk_sign
 
@@ -2557,7 +2633,7 @@ the function in @var{sig}.
 
 @noindent
 The result is 0 for success (i.e. the data matches the signature), or an
-error code where the most relevant code is @code{GCRYERR_BAD_SIGNATURE}
+error code where the most relevant code is @code{GCRY_ERR_BAD_SIGNATURE}
 to indicate that the signature does not match the provided data.
 
 @end deftypefun
@@ -2684,8 +2760,10 @@ operations.  @var{cmd} controls what is to be done. The return value is
 @table @code
 @item GCRYCTL_DISABLE_ALGO
 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)}.
+@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
+threads are started.
 
 @end table
 @end deftypefun
@@ -2720,9 +2798,11 @@ supported parameters are:
 
 @table @code
 @item 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.
+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 @code{4:} in the
+above example.
 
 @item curve @var{name}
 For ECC a named curve may be used instead of giving the number of
@@ -2731,10 +2811,10 @@ default selection Libgcrypt would have taken if @code{nbits} has been
 given.  The available names are listed with the description of the ECC
 public key parameters.
 
-@item rsa-use-e
+@item rsa-use-e @var{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:
+@var{value} will be used as a base to test for a usable exponent. Some
+values are special:
 
 @table @samp
 @item 0
@@ -2752,10 +2832,10 @@ Use the given value.
 If this parameter is not used, Libgcrypt uses for historic reasons
 65537.
 
-@item qbits
+@item qbits @var{n}
 This is only meanigful for DSA keys.  If it is given the DSA key is
-generated with a Q parameyer of this size.  If it is not given or zero
-Q is deduced from NBITS in this way:
+generated with a Q parameyer of size @var{n} bits.  If it is not given
+or zero Q is deduced from NBITS in this way:
 @table @samp
 @item 512 <= N <= 1024
 Q = 160
@@ -2772,14 +2852,7 @@ 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.
 
-@item transient-key
-This is only meaningful for RSA, DSA, ECDSA, and ECDH keys.  This is a flag
-with no value.  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.
-
-@item domain
+@item domain @var{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
@@ -2797,7 +2870,7 @@ currently only implemented for DSA using this format:
 @code{nbits} and @code{qbits} may not be specified because they are
 derived from the domain parameters.
 
-@item derive-parms
+@item derive-parms @var{list}
 This is currently only implemented for RSA and DSA keys.  It is not
 allowed to use this together with a @code{domain} specification.  If
 given, it is used to derive the keys using the given parameters.
@@ -2835,28 +2908,25 @@ FIPS 186 algorithm is used even if libgcrypt is not in FIPS mode.
 @end example
 
 
-@item use-x931
-@cindex X9.31
-Force the use of the ANSI X9.31 key generation algorithm instead of
-the default algorithm. This flag is only meaningful for RSA and
-usually not required.  Note that this algorithm is implicitly used if
-either @code{derive-parms} is given or Libgcrypt is in FIPS mode.
-
-@item use-fips186
-@cindex FIPS 186
-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
-@code{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.
+@item flags @var{flaglist}
+This is preferred way to define flags.  @var{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.
+@example
+(genkey
+  (ecc
+    (flags transient-key)))
+@end example
 
-@item use-fips186-2
-Force the use of the FIPS 186-2 key generation algorithm instead of
-the default algorithm.  This algorithm is slighlty 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.
+@item transient-key
+@itemx use-x931
+@itemx use-fips186
+@itemx use-fips186-2
+These are deprecated ways to set a flag with that name; see above for
+a description of each flag.
 
 
 @end table
@@ -2868,7 +2938,8 @@ private and public keys are returned in one container and may be
 accompanied by some miscellaneous information.
 
 @noindent
-As an example, here is what the Elgamal key generation returns:
+Here are two examples; the first for Elgamal and the second for
+elliptic curve key generation:
 
 @example
 (key-data
@@ -2887,6 +2958,21 @@ As an example, here is what the Elgamal key generation returns:
     (pm1-factors @var{n1 n2 ... nn}))
 @end example
 
+@example
+(key-data
+  (public-key
+    (ecc
+      (curve Ed25519)
+      (flags eddsa)
+      (q @var{q-value})))
+  (private-key
+    (ecc
+      (curve Ed25519)
+      (flags eddsa)
+      (q @var{q-value})
+      (d @var{d-value}))))
+@end example
+
 @noindent
 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.
@@ -2898,561 +2984,67 @@ algorithm provides them.
 @end deftypefun
 @c end gcry_pk_genkey
 
-@node AC Interface
-@section Alternative Public Key Interface
-
-This section documents the alternative interface to asymmetric
-cryptography (ac) that is not based on S-expressions, but on native C
-data structures.  As opposed to the pk interface described in the
-former chapter, this one follows an open/use/close paradigm like other
-building blocks of the library.
-
-@strong{This interface has a few known problems; most noteworthy an
-inherent tendency to leak memory.  It might not be available in
-forthcoming versions of Libgcrypt.}
-
-
-@menu
-* Available asymmetric algorithms::  List of algorithms supported by the library.
-* Working with sets of data::   How to work with sets of data.
-* Working with IO objects::     How to work with IO objects.
-* Working with handles::        How to use handles.
-* Working with keys::           How to work with keys.
-* Using cryptographic functions::  How to perform cryptographic operations.
-* Handle-independent functions::  General functions independent of handles.
-@end menu
-
-@node Available asymmetric algorithms
-@subsection Available asymmetric 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.
 
-@deftp {Data type} gcry_ac_id_t
-
-The following constants are defined for this type:
+@noindent
+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:
+
+@deftypefun gcry_error_t gcry_pubkey_get_sexp (@w{gcry_sexp_t *@var{r_sexp}}, @
+ @w{int @var{mode}}, @w{gcry_ctx_t @var{ctx}})
+
+Return an S-expression representing the context @var{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 @var{r_sexp}; on error an error code is returned and NULL is stored
+at @var{r_sexp}.  @var{mode} must be one of:
 
 @table @code
-@item GCRY_AC_RSA
-Rivest-Shamir-Adleman
-@item GCRY_AC_DSA
-Digital Signature Algorithm
-@item GCRY_AC_ELG
-Elgamal
-@item GCRY_AC_ELG_E
-Elgamal, encryption only.
-@end table
-@end deftp
-
-@node Working with sets of data
-@subsection Working with sets of data
-
-In the context of this interface the term `data set' refers to a list
-of `named MPI values' that is used by functions performing
-cryptographic operations; a named MPI value is a an MPI value,
-associated with a label.
-
-Such data sets are used for representing keys, since keys simply
-consist of a variable amount of numbers.  Furthermore some functions
-return data sets to the caller that are to be provided to other
-functions.
-
-This section documents the data types, symbols and functions that are
-relevant for working with data sets.
-
-@deftp {Data type} gcry_ac_data_t
-A single data set.
-@end deftp
+@item 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.
 
-The following flags are supported:
+@item GCRY_PK_GET_PUBKEY
+Return the public key even if the context has the private key
+parameter.
 
-@table @code
-@item GCRY_AC_FLAG_DEALLOC
-Used for storing data in a data set.  If given, the data will be
-released by the library.  Note that whenever one of the ac functions
-is about to release objects because of this flag, the objects are
-expected to be stored in memory allocated through the Libgcrypt memory
-management.  In other words: gcry_free() is used instead of free().
-
-@item GCRY_AC_FLAG_COPY
-Used for storing/retrieving data in/from a data set.  If given, the
-library will create copies of the provided/contained data, which will
-then be given to the user/associated with the data set.
+@item GCRY_PK_GET_SECKEY
+Return the private key or the error @code{GPG_ERR_NO_SECKEY} if it is
+not possible.
 @end table
 
-@deftypefun gcry_error_t gcry_ac_data_new (gcry_ac_data_t *@var{data})
-Creates a new, empty data set and stores it in @var{data}.
-@end deftypefun
-
-@deftypefun void gcry_ac_data_destroy (gcry_ac_data_t @var{data})
-Destroys the data set @var{data}.
-@end deftypefun
+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.
 
-@deftypefun gcry_error_t gcry_ac_data_set (gcry_ac_data_t @var{data}, unsigned int @var{flags}, char *@var{name}, gcry_mpi_t @var{mpi})
-Add the value @var{mpi} to @var{data} with the label @var{name}.  If
-@var{flags} contains GCRY_AC_FLAG_COPY, the data set will contain
-copies of @var{name} and @var{mpi}.  If @var{flags} contains
-GCRY_AC_FLAG_DEALLOC or GCRY_AC_FLAG_COPY, the values
-contained in the data set will be deallocated when they are to be
-removed from the data set.
 @end deftypefun
+@c end gcry_pubkey_get_sexp
 
-@deftypefun gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *@var{data_cp}, gcry_ac_data_t @var{data})
-Create a copy of the data set @var{data} and store it in
-@var{data_cp}.  FIXME: exact semantics undefined.
-@end deftypefun
 
-@deftypefun {unsigned int} gcry_ac_data_length (gcry_ac_data_t @var{data})
-Returns the number of named MPI values inside of the data set
-@var{data}.
-@end deftypefun
 
-@deftypefun gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t @var{data}, unsigned int @var{flags}, char *@var{name}, gcry_mpi_t *@var{mpi})
-Store the value labelled with @var{name} found in @var{data} in
-@var{mpi}.  If @var{flags} contains GCRY_AC_FLAG_COPY, store a copy of
-the @var{mpi} value contained in the data set.  @var{mpi} may be NULL
-(this might be useful for checking the existence of an MPI with
-extracting it).
-@end deftypefun
 
-@deftypefun gcry_error_t gcry_ac_data_get_index (gcry_ac_data_t @var{data}, unsigned int flags, unsigned int @var{index}, const char **@var{name}, gcry_mpi_t *@var{mpi})
-Stores in @var{name} and @var{mpi} the named @var{mpi} value contained
-in the data set @var{data} with the index @var{idx}.  If @var{flags}
-contains GCRY_AC_FLAG_COPY, store copies of the values contained in
-the data set. @var{name} or @var{mpi} may be NULL.
-@end deftypefun
 
-@deftypefun void gcry_ac_data_clear (gcry_ac_data_t @var{data})
-Destroys any values contained in the data set @var{data}.
-@end deftypefun
+@c **********************************************************
+@c *******************  Hash Functions  *********************
+@c **********************************************************
+@node Hashing
+@chapter Hashing
 
-@deftypefun gcry_error_t gcry_ac_data_to_sexp (gcry_ac_data_t @var{data}, gcry_sexp_t *@var{sexp}, const char **@var{identifiers})
-This function converts the data set @var{data} into a newly created
-S-Expression, which is to be stored in @var{sexp}; @var{identifiers}
-is a NULL terminated list of C strings, which specifies the structure
-of the S-Expression.
+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.
 
-Example:
-
-If @var{identifiers} is a list of pointers to the strings ``foo'' and
-``bar'' and if @var{data} is a data set containing the values ``val1 =
-0x01'' and ``val2 = 0x02'', then the resulting S-Expression will look
-like this: (foo (bar ((val1 0x01) (val2 0x02))).
-@end deftypefun
-
-@deftypefun gcry_error gcry_ac_data_from_sexp (gcry_ac_data_t *@var{data}, gcry_sexp_t @var{sexp}, const char **@var{identifiers})
-This function converts the S-Expression @var{sexp} into a newly
-created data set, which is to be stored in @var{data};
-@var{identifiers} is a NULL terminated list of C strings, which
-specifies the structure of the S-Expression.  If the list of
-identifiers does not match the structure of the S-Expression, the
-function fails.
-@end deftypefun
-
-@node Working with IO objects
-@subsection Working with IO objects
-
-Note: IO objects are currently only used in the context of message
-encoding/decoding and encryption/signature schemes.
-
-@deftp {Data type} {gcry_ac_io_t}
-@code{gcry_ac_io_t} is the type to be used for IO objects.
-@end deftp
-
-IO objects provide an uniform IO layer on top of different underlying
-IO mechanisms; either they can be used for providing data to the
-library (mode is GCRY_AC_IO_READABLE) or they can be used for
-retrieving data from the library (mode is GCRY_AC_IO_WRITABLE).
-
-IO object need to be initialized by calling on of the following
-functions:
-
-@deftypefun void gcry_ac_io_init (gcry_ac_io_t *@var{ac_io}, gcry_ac_io_mode_t @var{mode}, gcry_ac_io_type_t @var{type}, ...);
-Initialize @var{ac_io} according to @var{mode}, @var{type} and the
-variable list of arguments.  The list of variable arguments to specify
-depends on the given @var{type}.
-@end deftypefun
-
-@deftypefun void gcry_ac_io_init_va (gcry_ac_io_t *@var{ac_io}, gcry_ac_io_mode_t @var{mode}, gcry_ac_io_type_t @var{type}, va_list @var{ap});
-Initialize @var{ac_io} according to @var{mode}, @var{type} and the
-variable list of arguments @var{ap}.  The list of variable arguments
-to specify depends on the given @var{type}.
-@end deftypefun
-
-The following types of IO objects exist:
-
-@table @code
-@item GCRY_AC_IO_STRING
-In case of GCRY_AC_IO_READABLE the IO object will provide data from a
-memory string.  Arguments to specify at initialization time:
-@table @code
-@item unsigned char *
-Pointer to the beginning of the memory string
-@item size_t
-Size of the memory string
-@end table
-In case of GCRY_AC_IO_WRITABLE the object will store retrieved data in
-a newly allocated memory string.  Arguments to specify at
-initialization time:
-@table @code
-@item unsigned char **
-Pointer to address, at which the pointer to the newly created memory
-string is to be stored
-@item size_t *
-Pointer to address, at which the size of the newly created memory
-string is to be stored
-@end table
-
-@item GCRY_AC_IO_CALLBACK
-In case of GCRY_AC_IO_READABLE the object will forward read requests
-to a provided callback function.  Arguments to specify at
-initialization time:
-@table @code
-@item gcry_ac_data_read_cb_t
-Callback function to use
-@item void *
-Opaque argument to provide to the callback function
-@end table
-In case of GCRY_AC_IO_WRITABLE the object will forward write requests
-to a provided callback function.  Arguments to specify at
-initialization time:
-@table @code
-@item gcry_ac_data_write_cb_t
-Callback function to use
-@item void *
-Opaque argument to provide to the callback function
-@end table
-@end table
-
-@node Working with handles
-@subsection Working with handles
-
-In order to use an algorithm, an according handle must be created.
-This is done using the following function:
-
-@deftypefun gcry_error_t gcry_ac_open (gcry_ac_handle_t *@var{handle}, int @var{algorithm}, int @var{flags})
-
-Creates a new handle for the algorithm @var{algorithm} and stores it
-in @var{handle}.  @var{flags} is not used currently.
-
-@var{algorithm} must be a valid algorithm ID, see @xref{Available
-asymmetric algorithms}, for a list of supported algorithms and the
-according constants.  Besides using the listed constants directly, the
-functions @code{gcry_pk_name_to_id} may be used to convert the textual
-name of an algorithm into the according numeric ID.
-@end deftypefun
-
-@deftypefun void gcry_ac_close (gcry_ac_handle_t @var{handle})
-Destroys the handle @var{handle}.
-@end deftypefun
-
-@node Working with keys
-@subsection Working with keys
-
-@deftp {Data type} gcry_ac_key_type_t
-Defined constants:
-
-@table @code
-@item GCRY_AC_KEY_SECRET
-Specifies a secret key.
-@item GCRY_AC_KEY_PUBLIC
-Specifies a public key.
-@end table
-@end deftp
-
-@deftp {Data type} gcry_ac_key_t
-This type represents a single `key', either a secret one or a public
-one.
-@end deftp
-
-@deftp {Data type} gcry_ac_key_pair_t
-This type represents a `key pair' containing a secret and a public key.
-@end deftp
-
-Key data structures can be created in two different ways; a new key
-pair can be generated, resulting in ready-to-use key.  Alternatively a
-key can be initialized from a given data set.
-
-@deftypefun gcry_error_t gcry_ac_key_init (gcry_ac_key_t *@var{key}, gcry_ac_handle_t @var{handle}, gcry_ac_key_type_t @var{type}, gcry_ac_data_t @var{data})
-Creates a new key of type @var{type}, consisting of the MPI values
-contained in the data set @var{data} and stores it in @var{key}.
-@end deftypefun
-
-@deftypefun gcry_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t @var{handle}, unsigned int @var{nbits}, void *@var{key_spec}, gcry_ac_key_pair_t *@var{key_pair}, gcry_mpi_t **@var{misc_data})
-
-Generates a new key pair via the handle @var{handle} of @var{NBITS}
-bits and stores it in @var{key_pair}.
-
-In case non-standard settings are wanted, a pointer to a structure of
-type @code{gcry_ac_key_spec_<algorithm>_t}, matching the selected
-algorithm, can be given as @var{key_spec}.  @var{misc_data} is not
-used yet.  Such a structure does only exist for RSA.  A description
-of the members of the supported structures follows.
-
-@table @code
-@item gcry_ac_key_spec_rsa_t
-@table @code
-@item gcry_mpi_t e
-Generate the key pair using a special @code{e}.  The value of @code{e}
-has the following meanings:
-@table @code
-@item = 0
-Let Libgcrypt decide what exponent should be used.
-@item = 1
-Request the use of a ``secure'' exponent; this is required by some
-specification to be 65537.
-@item > 2
-Try starting at this value until a working exponent is found.  Note
-that the current implementation leaks some information about the
-private key because the incrementation used is not randomized.  Thus,
-this function will be changed in the future to return a random
-exponent of the given size.
-@end table
-@end table
-@end table
-
-Example code:
-@example
-@{
-  gcry_ac_key_pair_t key_pair;
-  gcry_ac_key_spec_rsa_t rsa_spec;
-
-  rsa_spec.e = gcry_mpi_new (0);
-  gcry_mpi_set_ui (rsa_spec.e, 1);
-
-  err = gcry_ac_open  (&handle, GCRY_AC_RSA, 0);
-  assert (! err);
-
-  err = gcry_ac_key_pair_generate (handle, 1024, &rsa_spec,
-                                   &key_pair, NULL);
-  assert (! err);
-@}
-@end example
-@end deftypefun
-
-
-@deftypefun gcry_ac_key_t gcry_ac_key_pair_extract (gcry_ac_key_pair_t @var{key_pair}, gcry_ac_key_type_t @var{which})
-Returns the key of type @var{which} out of the key pair
-@var{key_pair}.
-@end deftypefun
-
-@deftypefun void gcry_ac_key_destroy (gcry_ac_key_t @var{key})
-Destroys the key @var{key}.
-@end deftypefun
-
-@deftypefun void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t @var{key_pair})
-Destroys the key pair @var{key_pair}.
-@end deftypefun
-
-@deftypefun gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t @var{key})
-Returns the data set contained in the key @var{key}.
-@end deftypefun
-
-@deftypefun gcry_error_t gcry_ac_key_test (gcry_ac_handle_t @var{handle}, gcry_ac_key_t @var{key})
-Verifies that the private key @var{key} is sane via @var{handle}.
-@end deftypefun
-
-@deftypefun gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t @var{handle}, gcry_ac_key_t @var{key}, unsigned int *@var{nbits})
-Stores the number of bits of the key @var{key} in @var{nbits} via @var{handle}.
-@end deftypefun
-
-@deftypefun gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t @var{handle}, gcry_ac_key_t @var{key}, unsigned char *@var{key_grip})
-Writes the 20 byte long key grip of the key @var{key} to
-@var{key_grip} via @var{handle}.
-@end deftypefun
-
-@node Using cryptographic functions
-@subsection Using cryptographic functions
-
-The following flags might be relevant:
-
-@table @code
-@item GCRY_AC_FLAG_NO_BLINDING
-Disable any blinding, which might be supported by the chosen
-algorithm; blinding is the default.
-@end table
-
-There exist two kinds of cryptographic functions available through the
-ac interface: primitives, and high-level functions.
-
-Primitives deal with MPIs (data sets) directly; what they provide is
-direct access to the cryptographic operations provided by an algorithm
-implementation.
-
-High-level functions deal with octet strings, according to a specified
-``scheme''.  Schemes make use of ``encoding methods'', which are
-responsible for converting the provided octet strings into MPIs, which
-are then forwared to the cryptographic primitives.  Since schemes are
-to be used for a special purpose in order to achieve a particular
-security goal, there exist ``encryption schemes'' and ``signature
-schemes''.  Encoding methods can be used seperately or implicitly
-through schemes.
-
-What follows is a description of the cryptographic primitives.
-
-@deftypefun gcry_error_t gcry_ac_data_encrypt (gcry_ac_handle_t @var{handle}, unsigned int @var{flags}, gcry_ac_key_t @var{key}, gcry_mpi_t @var{data_plain}, gcry_ac_data_t *@var{data_encrypted})
-Encrypts the plain text MPI value @var{data_plain} with the key public
-@var{key} under the control of the flags @var{flags} and stores the
-resulting data set into @var{data_encrypted}.
-@end deftypefun
-
-@deftypefun gcry_error_t gcry_ac_data_decrypt (gcry_ac_handle_t @var{handle}, unsigned int @var{flags}, gcry_ac_key_t @var{key}, gcry_mpi_t *@var{data_plain}, gcry_ac_data_t @var{data_encrypted})
-Decrypts the encrypted data contained in the data set
-@var{data_encrypted} with the secret key KEY under the control of the
-flags @var{flags} and stores the resulting plain text MPI value in
-@var{DATA_PLAIN}.
-@end deftypefun
-
-@deftypefun gcry_error_t gcry_ac_data_sign (gcry_ac_handle_t @var{handle}, gcry_ac_key_t @var{key}, gcry_mpi_t @var{data}, gcry_ac_data_t *@var{data_signature})
-Signs the data contained in @var{data} with the secret key @var{key}
-and stores the resulting signature in the data set
-@var{data_signature}.
-@end deftypefun
-
-@deftypefun gcry_error_t gcry_ac_data_verify (gcry_ac_handle_t @var{handle}, gcry_ac_key_t @var{key}, gcry_mpi_t @var{data}, gcry_ac_data_t @var{data_signature})
-Verifies that the signature contained in the data set
-@var{data_signature} is indeed the result of signing the data
-contained in @var{data} with the secret key belonging to the public
-key @var{key}.
-@end deftypefun
-
-What follows is a description of the high-level functions.
-
-The type ``gcry_ac_em_t'' is used for specifying encoding methods; the
-following methods are supported:
-
-@table @code
-@item GCRY_AC_EME_PKCS_V1_5
-PKCS-V1_5 Encoding Method for Encryption.  Options must be provided
-through a pointer to a correctly initialized object of type
-gcry_ac_eme_pkcs_v1_5_t.
-
-@item GCRY_AC_EMSA_PKCS_V1_5
-PKCS-V1_5 Encoding Method for Signatures with Appendix.  Options must
-be provided through a pointer to a correctly initialized object of
-type gcry_ac_emsa_pkcs_v1_5_t.
-@end table
-
-Option structure types:
-
-@table @code
-@item gcry_ac_eme_pkcs_v1_5_t
-@table @code
-@item gcry_ac_key_t key
-@item gcry_ac_handle_t handle
-@end table
-@item gcry_ac_emsa_pkcs_v1_5_t
-@table @code
-@item gcry_md_algo_t md
-@item size_t em_n
-@end table
-@end table
-
-Encoding methods can be used directly through the following functions:
-
-@deftypefun gcry_error_t gcry_ac_data_encode (gcry_ac_em_t @var{method}, unsigned int @var{flags}, void *@var{options}, unsigned char *@var{m}, size_t @var{m_n}, unsigned char **@var{em}, size_t *@var{em_n})
-Encodes the message contained in @var{m} of size @var{m_n} according
-to @var{method}, @var{flags} and @var{options}.  The newly created
-encoded message is stored in @var{em} and @var{em_n}.
-@end deftypefun
-
-@deftypefun gcry_error_t gcry_ac_data_decode (gcry_ac_em_t @var{method}, unsigned int @var{flags}, void *@var{options}, unsigned char *@var{em}, size_t @var{em_n}, unsigned char **@var{m}, size_t *@var{m_n})
-Decodes the message contained in @var{em} of size @var{em_n} according
-to @var{method}, @var{flags} and @var{options}.  The newly created
-decoded message is stored in @var{m} and @var{m_n}.
-@end deftypefun
-
-The type ``gcry_ac_scheme_t'' is used for specifying schemes; the
-following schemes are supported:
-
-@table @code
-@item GCRY_AC_ES_PKCS_V1_5
-PKCS-V1_5 Encryption Scheme.  No options can be provided.
-@item GCRY_AC_SSA_PKCS_V1_5
-PKCS-V1_5 Signature Scheme (with Appendix).  Options can be provided
-through a pointer to a correctly initialized object of type
-gcry_ac_ssa_pkcs_v1_5_t.
-@end table
-
-Option structure types:
-
-@table @code
-@item gcry_ac_ssa_pkcs_v1_5_t
-@table @code
-@item gcry_md_algo_t md
-@end table
-@end table
-
-The functions implementing schemes:
-
-@deftypefun gcry_error_t gcry_ac_data_encrypt_scheme (gcry_ac_handle_t @var{handle}, gcry_ac_scheme_t @var{scheme}, unsigned int @var{flags}, void *@var{opts}, gcry_ac_key_t @var{key}, gcry_ac_io_t *@var{io_message}, gcry_ac_io_t *@var{io_cipher})
-Encrypts the plain text readable from @var{io_message} through
-@var{handle} with the public key @var{key} according to @var{scheme},
-@var{flags} and @var{opts}.  If @var{opts} is not NULL, it has to be a
-pointer to a structure specific to the chosen scheme (gcry_ac_es_*_t).
-The encrypted message is written to @var{io_cipher}.
-@end deftypefun
-
-@deftypefun gcry_error_t gcry_ac_data_decrypt_scheme (gcry_ac_handle_t @var{handle}, gcry_ac_scheme_t @var{scheme}, unsigned int @var{flags}, void *@var{opts}, gcry_ac_key_t @var{key}, gcry_ac_io_t *@var{io_cipher}, gcry_ac_io_t *@var{io_message})
-Decrypts the cipher text readable from @var{io_cipher} through
-@var{handle} with the secret key @var{key} according to @var{scheme},
-@var{flags} and @var{opts}.  If @var{opts} is not NULL, it has to be a
-pointer to a structure specific to the chosen scheme (gcry_ac_es_*_t).
-The decrypted message is written to @var{io_message}.
-@end deftypefun
-
-@deftypefun gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t @var{handle}, gcry_ac_scheme_t @var{scheme}, unsigned int @var{flags}, void *@var{opts}, gcry_ac_key_t @var{key}, gcry_ac_io_t *@var{io_message}, gcry_ac_io_t *@var{io_signature})
-Signs the message readable from @var{io_message} through @var{handle}
-with the secret key @var{key} according to @var{scheme}, @var{flags}
-and @var{opts}.  If @var{opts} is not NULL, it has to be a pointer to
-a structure specific to the chosen scheme (gcry_ac_ssa_*_t).  The
-signature is written to @var{io_signature}.
-@end deftypefun
-
-@deftypefun gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t @var{handle}, gcry_ac_scheme_t @var{scheme}, unsigned int @var{flags}, void *@var{opts}, gcry_ac_key_t @var{key}, gcry_ac_io_t *@var{io_message}, gcry_ac_io_t *@var{io_signature})
-Verifies through @var{handle} that the signature readable from
-@var{io_signature} is indeed the result of signing the message
-readable from @var{io_message} with the secret key belonging to the
-public key @var{key} according to @var{scheme} and @var{opts}.  If
-@var{opts} is not NULL, it has to be an anonymous structure
-(gcry_ac_ssa_*_t) specific to the chosen scheme.
-@end deftypefun
-
-@node Handle-independent functions
-@subsection Handle-independent functions
-
-These two functions are deprecated; do not use them for new code.
-
-@deftypefun gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t @var{algorithm}, const char **@var{name})
-Stores the textual representation of the algorithm whose id is given
-in @var{algorithm} in @var{name}.  Deprecated; use @code{gcry_pk_algo_name}.
-@end deftypefun
-
-@deftypefun gcry_error_t gcry_ac_name_to_id (const char *@var{name}, gcry_ac_id_t *@var{algorithm})
-Stores the numeric ID of the algorithm whose textual representation is
-contained in @var{name} in @var{algorithm}. Deprecated; use
-@code{gcry_pk_map_name}.
-@end deftypefun
-
-@c **********************************************************
-@c *******************  Hash Functions  *********************
-@c **********************************************************
-@node Hashing
-@chapter 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 MAC 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.
+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.
-* Hash algorithm modules::      How to work with hash algorithm modules.
 * Working with hash algorithms::  List of functions related to hashing.
 @end menu
 
@@ -3494,7 +3086,7 @@ non-cryptographic application.
 
 @item GCRY_MD_MD4
 This is the MD4 algorithm, which yields a message digest of 16 bytes.
-This algorithms ha severe weaknesses and should not be used.
+This algorithm has severe weaknesses and should not be used.
 
 @item GCRY_MD_MD2
 This is an reserved identifier for MD-2; there is no implementation yet.
@@ -3553,109 +3145,20 @@ cryptographic sense.
 This is the Whirlpool algorithm which yields a message digest of 64
 bytes.
 
-@end table
-@c end table of hash algorithms
-
-@node Hash algorithm modules
-@section Hash algorithm modules
+@item GCRY_MD_GOSTR3411_94
+This is the hash algorithm described in GOST R 34.11-94 which yields a
+message digest of 32 bytes.
 
-Libgcrypt makes it possible to load additional `message
-digest modules'; these digests can be used just like the message digest
-algorithms that are built into the library directly.  For an
-introduction into extension modules, see @xref{Modules}.
-
-@deftp {Data type} gcry_md_spec_t
-This is the `module specification structure' needed for registering
-message digest modules, which has to be filled in by the user before
-it can be used to register a module.  It contains the following
-members:
-
-@table @code
-@item const char *name
-The primary name of this algorithm.
-@item unsigned char *asnoid
-Array of bytes that form the ASN OID.
-@item int asnlen
-Length of bytes in `asnoid'.
-@item gcry_md_oid_spec_t *oids
-A list of OIDs that are to be associated with the algorithm.  The
-list's last element must have it's `oid' member set to NULL.  See
-below for an explanation of this type.  See below for an explanation
-of this type.
-@item int mdlen
-Length of the message digest algorithm.  See below for an explanation
-of this type.
-@item gcry_md_init_t init
-The function responsible for initializing a handle.  See below for an
-explanation of this type.
-@item gcry_md_write_t write
-The function responsible for writing data into a message digest
-context.  See below for an explanation of this type.
-@item gcry_md_final_t final
-The function responsible for `finalizing' a message digest context.
-See below for an explanation of this type.
-@item gcry_md_read_t read
-The function responsible for reading out a message digest result.  See
-below for an explanation of this type.
-@item size_t contextsize
-The size of the algorithm-specific `context', that should be
-allocated for each handle.
-@end table
-@end deftp
+@item 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.
 
-@deftp {Data type} gcry_md_oid_spec_t
-This type is used for associating a user-provided algorithm
-implementation with certain OIDs.  It contains the following members:
+@item 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.
 
-@table @code
-@item const char *oidstring
-Textual representation of the OID.
 @end table
-@end deftp
-
-@deftp {Data type} gcry_md_init_t
-Type for the `init' function, defined as: void (*gcry_md_init_t) (void
-*c)
-@end deftp
-
-@deftp {Data type} gcry_md_write_t
-Type for the `write' function, defined as: void (*gcry_md_write_t)
-(void *c, unsigned char *buf, size_t nbytes)
-@end deftp
-
-@deftp {Data type} gcry_md_final_t
-Type for the `final' function, defined as: void (*gcry_md_final_t)
-(void *c)
-@end deftp
-
-@deftp {Data type} gcry_md_read_t
-Type for the `read' function, defined as: unsigned char
-*(*gcry_md_read_t) (void *c)
-@end deftp
-
-@deftypefun gcry_error_t gcry_md_register (gcry_md_spec_t *@var{digest}, unsigned int *algorithm_id, gcry_module_t *@var{module})
-
-Register a new digest module whose specification can be found in
-@var{digest}.  On success, a new algorithm ID is stored in
-@var{algorithm_id} and a pointer representing this module is stored
-in @var{module}.  Deprecated; the module register interface will be
-removed in a future version.
-@end deftypefun
-
-@deftypefun void gcry_md_unregister (gcry_module_t @var{module})
-Unregister the digest identified by @var{module}, which must have been
-registered with gcry_md_register.
-@end deftypefun
-
-@deftypefun gcry_error_t gcry_md_list (int *@var{list}, int *@var{list_length})
-Get a list consisting of the IDs of the loaded message digest modules.
-If @var{list} is zero, write the number of loaded message digest
-modules to @var{list_length} and return.  If @var{list} is non-zero,
-the first *@var{list_length} algorithm IDs are stored in @var{list},
-which must be of according size.  In case there are less message
-digests modules than *@var{list_length}, *@var{list_length} is updated
-to the correct number.
-@end deftypefun
+@c end table of hash algorithms
 
 @node Working with hash algorithms
 @section Working with hash algorithms
@@ -3691,6 +3194,22 @@ 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
+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.
+
+
 @end table
 @c begin table of hash flags
 
@@ -3810,8 +3329,36 @@ The function does return @code{NULL} if the requested algorithm has not
 been enabled.
 @end deftypefun
 
-Because it is often necessary to get the message digest of one block of
-memory, a fast convenience function is available for this task:
+Because it is often necessary to get the message digest of blocks of
+memory, two fast convenience function are available for this task:
+
+@deftypefun gpg_err_code_t gcry_md_hash_buffers ( @
+  @w{int @var{algo}}, @w{unsigned int @var{flags}}, @
+  @w{void *@var{digest}}, @
+  @w{const gcry_buffer_t *@var{iov}}, @w{int @var{iovcnt}} )
+
+@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
+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
+may be obtained by using the function @code{gcry_md_get_algo_dlen}.
+
+@var{iov} is an array of buffer descriptions with @var{iovcnt} items.
+The caller should zero out the structures in this array and for each
+array item set the fields @code{.data} to the address of the data to
+be hashed, @code{.len} to number of bytes to be hashed.  If @var{.off}
+is also set, the data is taken starting at @var{.off} bytes from the
+begin of the buffer.  The field @code{.size} is not used.
+
+The only supported flag value for @var{flags} is
+@var{GCRY_MD_FLAG_HMAC} which turns this function into a HMAC
+function; the first item in @var{iov} is then used as the key.
+
+On success the function returns 0 and stores the resulting hash or MAC
+at @var{digest}.
+@end deftypefun
 
 @deftypefun void gcry_md_hash_buffer (int @var{algo}, void *@var{digest}, const void *@var{buffer}, size_t @var{length});
 
@@ -3823,8 +3370,8 @@ enough to hold the message digest yielded by the the specified algorithm
 @var{algo}.  This required size may be obtained by using the function
 @code{gcry_md_get_algo_dlen}.
 
-Note that this function will abort the process if an unavailable
-algorithm is used.
+Note that in contrast to @code{gcry_md_hash_buffers} this function
+will abort the process if an unavailable algorithm is used.
 @end deftypefun
 
 @c ***********************************
@@ -3933,28 +3480,319 @@ because @code{gcry_md_close} implicitly stops debugging.
 @end deftypefun
 
 
-The following two deprecated macros are used for debugging by old code.
-They shopuld be replaced by @code{gcry_md_debug}.
 
-@deftypefun void gcry_md_start_debug (gcry_md_hd_t @var{h}, const char *@var{suffix})
+@c **********************************************************
+@c *******************  MAC Functions  **********************
+@c **********************************************************
+@node Message Authentication Codes
+@chapter 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.
 
-Enable debugging for the digest object with handle @var{h}.  This
-creates create 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
-@code{gcry_md_putc}.
+@menu
+* Available MAC algorithms::   List of MAC algorithms supported by the library.
+* Working with MAC algorithms::  List of functions related to MAC algorithms.
+@end menu
+
+@node Available MAC algorithms
+@section Available MAC algorithms
+
+@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-RIPE-MD-160
+@cindex HMAC-MD2, HMAC-MD4, HMAC-MD5
+@cindex HMAC-TIGER1
+@cindex HMAC-Whirlpool
+@cindex HMAC-Stribog-256, HMAC-Stribog-512
+@cindex HMAC-GOSTR-3411-94
+@table @code
+@item 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 @code{0}.
+
+@item GCRY_MAC_HMAC_SHA256
+This is keyed-hash message authentication code (HMAC) message authentication
+algorithm based on the SHA-256 hash algorithm.
+
+@item GCRY_MAC_HMAC_SHA224
+This is HMAC message authentication algorithm based on the SHA-224 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_SHA512
+This is HMAC message authentication algorithm based on the SHA-512 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_SHA384
+This is HMAC message authentication algorithm based on the SHA-384 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_SHA1
+This is HMAC message authentication algorithm based on the SHA-1 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_MD5
+This is HMAC message authentication algorithm based on the MD5 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_MD4
+This is HMAC message authentication algorithm based on the MD4 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_RMD160
+This is HMAC message authentication algorithm based on the RIPE-MD-160 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_WHIRLPOOL
+This is HMAC message authentication algorithm based on the WHIRLPOOL hash
+algorithm.
+
+@item GCRY_MAC_HMAC_GOSTR3411_94
+This is HMAC message authentication algorithm based on the GOST R 34.11-94 hash
+algorithm.
+
+@item GCRY_MAC_HMAC_STRIBOG256
+This is HMAC message authentication algorithm based on the 256-bit hash
+algorithm described in GOST R 34.11-2012.
+
+@item GCRY_MAC_HMAC_STRIBOG512
+This is HMAC message authentication algorithm based on the 512-bit hash
+algorithm described in GOST R 34.11-2012.
+
+@item GCRY_MAC_CMAC_AES
+This is CMAC (Cipher-based MAC) message authentication algorithm based on
+the AES block cipher algorithm.
+
+@item GCRY_MAC_CMAC_3DES
+This is CMAC message authentication algorithm based on the three-key EDE
+Triple-DES block cipher algorithm.
+
+@item GCRY_MAC_CMAC_CAMELLIA
+This is CMAC message authentication algorithm based on the Camellia block cipher
+algorithm.
+
+@item GCRY_MAC_CMAC_CAST5
+This is CMAC message authentication algorithm based on the CAST128-5
+block cipher algorithm.
+
+@item GCRY_MAC_CMAC_BLOWFISH
+This is CMAC message authentication algorithm based on the Blowfish
+block cipher algorithm.
+
+@item GCRY_MAC_CMAC_TWOFISH
+This is CMAC message authentication algorithm based on the Twofish
+block cipher algorithm.
+
+@item GCRY_MAC_CMAC_SERPENT
+This is CMAC message authentication algorithm based on the Serpent
+block cipher algorithm.
+
+@item GCRY_MAC_CMAC_SEED
+This is CMAC message authentication algorithm based on the SEED
+block cipher algorithm.
+
+@item GCRY_MAC_CMAC_RFC2268
+This is CMAC message authentication algorithm based on the Ron's Cipher 2
+block cipher algorithm.
+
+@item GCRY_MAC_CMAC_IDEA
+This is CMAC message authentication algorithm based on the IDEA
+block cipher algorithm.
+
+@item GCRY_MAC_CMAC_GOST28147
+This is CMAC message authentication algorithm based on the GOST 28147-89
+block cipher algorithm.
+
+@item GCRY_MAC_GMAC_AES
+This is GMAC (GCM mode based MAC) message authentication algorithm based on
+the AES block cipher algorithm.
+
+@item GCRY_MAC_GMAC_CAMELLIA
+This is GMAC message authentication algorithm based on the Camellia
+block cipher algorithm.
+
+@item GCRY_MAC_GMAC_TWOFISH
+This is GMAC message authentication algorithm based on the Twofish
+block cipher algorithm.
+
+@item GCRY_MAC_GMAC_SERPENT
+This is GMAC message authentication algorithm based on the Serpent
+block cipher algorithm.
+
+@item GCRY_MAC_GMAC_SEED
+This is GMAC message authentication algorithm based on the SEED
+block cipher algorithm.
+
+@end table
+@c end table of MAC algorithms
+
+@node Working with MAC algorithms
+@section Working with MAC algorithms
+
+To use most of these function it is necessary to create a context;
+this is done using:
+
+@deftypefun gcry_error_t gcry_mac_open (gcry_mac_hd_t *@var{hd}, int @var{algo}, unsigned int @var{flags}, gcry_ctx_t @var{ctx})
+
+Create a MAC object for algorithm @var{algo}. @var{flags} may be given as an
+bitwise OR of constants described below. @var{hd} is guaranteed to either
+receive a valid handle or NULL. @var{ctx} is context object to associate MAC
+object with. @var{ctx} maybe set to NULL.
+
+For a list of supported algorithms, see @xref{Available MAC algorithms}.
+
+The flags allowed for @var{mode} are:
+
+@c begin table of MAC flags
+@table @code
+@item GCRY_MAC_FLAG_SECURE
+Allocate all buffers and the resulting MAC in "secure memory".  Use this if the
+MAC data is highly confidential.
+
+@end table
+@c begin table of MAC flags
+
+@end deftypefun
+@c end function gcry_mac_open
+
+
+In order to use a handle for performing MAC algorithm operations, a
+`key' has to be set first:
+
+@deftypefun gcry_error_t gcry_mac_setkey (gcry_mac_hd_t @var{h}, const void *@var{key}, size_t @var{keylen})
+
+Set the MAC key to the value of @var{key} of length @var{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.
+@end deftypefun
+
+
+GMAC 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})
+
+Set the IV to the value of @var{iv} of length @var{ivlen} bytes.
+@end deftypefun
+
+
+After you are done with the MAC calculation, you should release the resources
+by using:
+
+@deftypefun void gcry_mac_close (gcry_mac_hd_t @var{h})
+
+Release all resources of MAC context @var{h}.  @var{h} should not be
+used after a call to this function.  A @code{NULL} passed as @var{h} is
+ignored.  The function also clears all sensitive information associated
+with this handle.
+@end deftypefun
+
+
+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:
+
+@deftypefun gcry_error_t gcry_mac_reset (gcry_mac_hd_t @var{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.
+@end deftypefun
+
+
+Now that we have prepared everything to calculate MAC, it is time to
+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.
+@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})
+
+@code{gcry_mac_read} returns the MAC after finalizing the calculation.
+Function copies the resulting MAC value to @var{buffer} of the length
+@var{length}. If @var{length} is larger than length of resulting MAC value,
+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})
+
+@code{gcry_mac_verify} finalizes MAC calculation and compares result with
+@var{length} bytes of data in @var{buffer}. Error code @code{GPG_ERR_CHECKSUM}
+is returned if the MAC value in the buffer @var{buffer} does not match
+the MAC calculated in object @var{h}.
+@end deftypefun
+
+
+@c ***********************************
+@c ***** MAC info functions **********
+@c ***********************************
+
+MAC algorithms are identified by internal algorithm numbers (see
+@code{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.
+
+@deftypefun {const char *} gcry_mac_algo_name (int @var{algo})
+
+Map the MAC algorithm id @var{algo} to a string representation of the
+algorithm name.  For unknown algorithms this function returns the
+string @code{"?"}.  This function should not be used to test for the
+availability of an algorithm.
+@end deftypefun
+
+@deftypefun int gcry_mac_map_name (const char *@var{name})
+
+Map the algorithm with @var{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.
+@end deftypefun
+
+
+To test whether an algorithm is actually available for use, the
+following macro should be used:
+
+@deftypefun gcry_error_t gcry_mac_test_algo (int @var{algo})
+
+The macro returns 0 if the MAC algorithm @var{algo} is available for use.
 @end deftypefun
 
 
-@deftypefun void gcry_md_stop_debug (gcry_md_hd_t @var{h}, int @var{reserved})
+If the length of a message digest is not known, it can be retrieved
+using the following function:
+
+@deftypefun {unsigned int} gcry_mac_get_algo_maclen (int @var{algo})
+
+Retrieve the length in bytes of the MAC yielded by algorithm @var{algo}.
+This is often used prior to @code{gcry_mac_read} to allocate sufficient memory
+for the MAC value. On error @code{0} is returned.
+@end deftypefun
+
 
-Stop debugging on handle @var{h}.  @var{reserved} should be specified as
-0.  This function is usually not required because @code{gcry_md_close}
-does implicitly stop debugging.
+@deftypefun {unsigned int} gcry_mac_get_algo_keylen (@var{algo})
+
+This function returns length of the key for MAC algorithm @var{algo}.  If
+the algorithm supports multiple key lengths, the default supported key
+length is returned.  On error @code{0} is returned.  The key length is
+returned as number of octets.
 @end deftypefun
 
 
+
 @c *******************************************************
 @c *******************  KDF  *****************************
 @c *******************************************************
@@ -4010,6 +3848,12 @@ iteration count.
 @item GCRY_KDF_PBKDF2
 The PKCS#5 Passphrase Based Key Derivation Function number 2.
 
+@item 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.
+
 @end table
 @end deftypefun
 
@@ -4293,8 +4137,9 @@ no such element, @code{NULL} is returned.
 @deftypefun gcry_sexp_t gcry_sexp_car (@w{const gcry_sexp_t @var{list}})
 
 Create and return a new S-expression from the first element in
-@var{list}; this called the "type" and should always exist and be a
-string. @code{NULL} is returned in case of a problem.
+@var{list}; this is called the "type" and should always exist per
+S-expression specification and in general be a string.  @code{NULL} is
+returned in case of a problem.
 @end deftypefun
 
 @deftypefun gcry_sexp_t gcry_sexp_cdr (@w{const gcry_sexp_t @var{list}})
@@ -4329,6 +4174,30 @@ printf ("my name is %.*s\n", (int)len, name);
 @end example
 @end deftypefun
 
+@deftypefun {void *} gcry_sexp_nth_buffer (@w{const gcry_sexp_t @var{list}}, @w{int @var{number}}, @w{size_t *@var{rlength}})
+
+This function is used to get data from a @var{list}.  A malloced
+buffer with the actual data at list index @var{number} is returned and
+the length of this buffer will be stored to @var{rlength}.  If there
+is no data at the given index or the index represents another list,
+@code{NULL} is returned.  The caller must release the result using
+@code{gcry_free}.
+
+@noindent
+Here is an example on how to extract and print the CRC value from the
+S-expression @samp{(hash crc32 #23ed00d7)}:
+
+@example
+size_t len;
+char *value;
+
+value = gcry_sexp_nth_buffer (list, 2, &len);
+if (value)
+  fwrite (value, len, 1, stdout);
+gcry_free (value);
+@end example
+@end deftypefun
+
 @deftypefun {char *} gcry_sexp_nth_string (@w{gcry_sexp_t @var{list}}, @w{int @var{number}})
 
 This function is used to get and convert data from a @var{list}. The
@@ -4350,6 +4219,70 @@ this function to parse results of a public key function, you most
 likely want to use @code{GCRYMPI_FMT_USG}.
 @end deftypefun
 
+@deftypefun gpg_error_t gcry_sexp_extract_param ( @
+  @w{gcry_sexp_t @var{sexp}}, @
+  @w{const char *@var{path}}, @
+  @w{const char *@var{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:
+
+@table @samp
+@item +
+Switch to unsigned integer format (GCRYMPI_FMT_USG).  This is the
+default mode.
+@item -
+Switch to standard signed format (GCRYMPI_FMT_STD).
+@item /
+Switch to opaque MPI format.  The resulting MPIs may not be used for
+computations; see @code{gcry_mpi_get_opaque} for details.
+@item &
+Switch to buffer descriptor mode.  See below for details.
+@item ?
+If immediately following a parameter letter (no white space allowed),
+that parameter is considered optional.
+@end table
+
+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
+@example
+  _gcry_sexp_extract_param (key, NULL, "n/x+e d-'foo'",
+                            &mpi_n, &mpi_x, &mpi_e, &mpi_foo, NULL)
+@end example
+
+stores the parameter 'n' from @var{key} as an unsigned MPI into
+@var{mpi_n}, the parameter 'x' as an opaque MPI into @var{mpi_x}, the
+parameter 'e' again as an unsigned MPI into @var{mpi_e}, and the
+parameter 'foo' as a signed MPI.
+
+@var{path} is an optional string used to locate a token.  The
+exclamation mark separated tokens are used via
+@code{gcry_sexp_find_token} to find a start point inside the
+S-expression.
+
+In buffer descriptor mode a pointer to a @code{gcry_buffer_t}
+descriptor is expected instead of a pointer to an MPI.  The caller may
+use two different operation modes here: If the @var{data} field of the
+provided descriptor is @code{NULL}, the function allocates a new
+buffer and stores it at @var{data}; the other fields are set
+accordingly with @var{off} set to 0.  If @var{data} is not
+@code{NULL}, the function assumes that the @var{data}, @var{size}, and
+@var{off} fields specify a buffer where to but the value of the
+respective parameter; on return the @var{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
+@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.
+@end deftypefun
+
 
 @c **********************************************************
 @c *******************  MPIs ******** ***********************
@@ -4364,6 +4297,7 @@ likely want to use @code{GCRYMPI_FMT_USG}.
 * 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.
 @end menu
 
@@ -4381,6 +4315,10 @@ numbers are called MPIs (multi-precision-integers).
 This type represents an object to hold an MPI.
 @end deftp
 
+@deftp {Data type} {gcry_mpi_point_t}
+This type represents an object to hold a point for elliptic curve math.
+@end deftp
+
 @node Basic functions
 @section Basic functions
 
@@ -4406,7 +4344,8 @@ confidential data like private key parameters.
 
 @deftypefun gcry_mpi_t gcry_mpi_copy (@w{const gcry_mpi_t @var{a}})
 
-Create a new MPI as the exact copy of @var{a}.
+Create a new MPI as the exact copy of @var{a} but with the constant
+and immutable flags cleared.
 @end deftypefun
 
 
@@ -4441,6 +4380,24 @@ small values (usually up to the word size of the CPU).
 Swap the values of @var{a} and @var{b}.
 @end deftypefun
 
+@deftypefun void gcry_mpi_snatch (@w{gcry_mpi_t @var{w}}, @
+                                  @w{const gcry_mpi_t @var{u}})
+
+Set @var{u} into @var{w} and release @var{u}.  If @var{w} is
+@code{NULL} only @var{u} will be released.
+@end deftypefun
+
+@deftypefun void gcry_mpi_neg (@w{gcry_mpi_t @var{w}}, @w{gcry_mpi_t @var{u}})
+
+Set the sign of @var{w} to the negative of @var{u}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_abs (@w{gcry_mpi_t @var{w}})
+
+Clear the sign of @var{w}.
+@end deftypefun
+
+
 @node MPI formats
 @section MPI formats
 
@@ -4461,7 +4418,8 @@ bytes actually scanned unless @var{nscanned} was given as
 
 @table @code
 @item GCRYMPI_FMT_STD
-2-complement stored without a length header.
+2-complement stored without a length header.  Note that
+@code{gcry_mpi_print} stores a @code{0} as a string of zero length.
 
 @item GCRYMPI_FMT_PGP
 As used by OpenPGP (only defined as unsigned). This is basically
@@ -4472,8 +4430,10 @@ As used in the Secure Shell protocol.  This is @code{GCRYMPI_FMT_STD}
 with a 4 byte big endian header.
 
 @item GCRYMPI_FMT_HEX
-Stored as a C style string with each byte of the MPI encoded as 2 hex
-digits.  When using this format, @var{buflen} must be zero.
+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, @var{buflen} must be zero.
 
 @item GCRYMPI_FMT_USG
 Simple unsigned integer.
@@ -4501,6 +4461,12 @@ Convert the MPI @var{a} into an external representation described by
 address will be stored in the variable @var{buffer} points to.  The
 number of bytes stored in this buffer will be stored in the variable
 @var{nbytes} points to, unless @var{nbytes} is @code{NULL}.
+
+Even if @var{nbytes} is zero, the function allocates at least one byte
+and store a zero there.  Thus with formats @code{GCRYMPI_FMT_STD} and
+@code{GCRYMPI_FMT_USG} the caller may safely set a returned length of
+0 to 1 to represent a zero as a 1 byte string.
+
 @end deftypefun
 
 @deftypefun void gcry_mpi_dump (@w{const gcry_mpi_t @var{a}})
@@ -4627,6 +4593,11 @@ integer @var{v} returning 0 for equality, a positive value for @var{u} >
 @var{v} and a negative for @var{u} < @var{v}.
 @end deftypefun
 
+@deftypefun int gcry_mpi_is_neg (@w{const gcry_mpi_t @var{a}})
+
+Return 1 if @var{a} is less than zero; return 0 if zero or positive.
+@end deftypefun
+
 
 @node Bit manipulations
 @section Bit manipulations
@@ -4677,22 +4648,230 @@ Shift the value of @var{a} by @var{n} bits to the left and store the
 result in @var{x}.
 @end deftypefun
 
+@node EC functions
+@section EC functions
+
+@noindent
+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.
+
+@deftypefun gcry_mpi_point_t gcry_mpi_point_new (@w{unsigned int @var{nbits}})
+
+Allocate a new point object, initialize it to 0, and allocate enough
+memory for a points of at least @var{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 @var{nbits} is usually the right thing to do.
+@end deftypefun
+
+@deftypefun void gcry_mpi_point_release (@w{gcry_mpi_point_t @var{point}})
+
+Release @var{point} and free all associated resources.  Passing
+@code{NULL} is allowed and ignored.
+@end deftypefun
+
+@deftypefun void gcry_mpi_point_get (@w{gcry_mpi_t @var{x}}, @
+ @w{gcry_mpi_t @var{y}}, @w{gcry_mpi_t @var{z}}, @
+ @w{gcry_mpi_point_t @var{point}})
+
+Store the projective coordinates from @var{point} into the MPIs
+@var{x}, @var{y}, and @var{z}.  If a coordinate is not required,
+@code{NULL} may be used for @var{x}, @var{y}, or @var{z}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_point_snatch_get (@w{gcry_mpi_t @var{x}}, @
+ @w{gcry_mpi_t @var{y}}, @w{gcry_mpi_t @var{z}}, @
+ @w{gcry_mpi_point_t @var{point}})
+
+Store the projective coordinates from @var{point} into the MPIs
+@var{x}, @var{y}, and @var{z}.  If a coordinate is not required,
+@code{NULL} may be used for @var{x}, @var{y}, or @var{z}.  The object
+@var{point} is then released.  Using this function instead of
+@code{gcry_mpi_point_get} and @code{gcry_mpi_point_release} has the
+advantage of avoiding some extra memory allocations and copies.
+@end deftypefun
+
+@deftypefun gcry_mpi_point_t gcry_mpi_point_set ( @
+ @w{gcry_mpi_point_t @var{point}}, @
+ @w{gcry_mpi_t @var{x}}, @w{gcry_mpi_t @var{y}}, @w{gcry_mpi_t @var{z}})
+
+Store the projective coordinates from @var{x}, @var{y}, and @var{z}
+into @var{point}.  If a coordinate is given as @code{NULL}, the value
+0 is used.  If @code{NULL} is used for @var{point} a new point object
+is allocated and returned.  Returns @var{point} or the newly allocated
+point object.
+@end deftypefun
+
+@deftypefun gcry_mpi_point_t gcry_mpi_point_snatch_set ( @
+ @w{gcry_mpi_point_t @var{point}}, @
+ @w{gcry_mpi_t @var{x}}, @w{gcry_mpi_t @var{y}}, @w{gcry_mpi_t @var{z}})
+
+Store the projective coordinates from @var{x}, @var{y}, and @var{z}
+into @var{point}.  If a coordinate is given as @code{NULL}, the value
+0 is used.  If @code{NULL} is used for @var{point} a new point object
+is allocated and returned.  The MPIs @var{x}, @var{y}, and @var{z} are
+released.  Using this function instead of @code{gcry_mpi_point_set}
+and 3 calls to @code{gcry_mpi_release} has the advantage of avoiding
+some extra memory allocations and copies.  Returns @var{point} or the
+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}}, @
+ @w{gcry_sexp_t @var{keyparam}}, @w{const char *@var{curvename}})
+
+Allocate a new context for elliptic curve operations.  If
+@var{keyparam} is given it specifies the parameters of the curve
+(@pxref{ecc_keyparam}).  If @var{curvename} is given in addition to
+@var{keyparam} and the key parameters do not include a named curve
+reference, the string @var{curvename} is used to fill in missing
+parameters.  If only @var{curvename} is given, the context is
+initialized for this named curve.
+
+If a parameter specifying a point (e.g. @code{g} or @code{q}) is not
+found, the parser looks for a non-encoded point by appending
+@code{.x}, @code{.y}, and @code{.z} to the parameter name and looking
+them all up to create a point.  A parameter with the suffix @code{.z}
+is optional and defaults to 1.
+
+On success the function returns 0 and stores the new context object at
+@var{r_ctx}; this object eventually needs to be released
+(@pxref{gcry_ctx_release}).  On error the function stores @code{NULL} at
+@var{r_ctx} and returns an error code.
+@end deftypefun
+
+@deftypefun gcry_mpi_t gcry_mpi_ec_get_mpi ( @
+ @w{const char *@var{name}}, @w{gcry_ctx_t @var{ctx}}, @w{int @var{copy}})
+
+Return the MPI with @var{name} from the context @var{ctx}.  If not
+found @code{NULL} is returned.  If the returned MPI may later be
+modified, it is suggested to pass @code{1} to @var{copy}, so that the
+function guarantees that a modifiable copy of the MPI is returned.  If
+@code{0} is used for @var{copy}, this function may return a constant
+flagged MPI.  In any case @code{gcry_mpi_release} needs to be called
+to release the result.  For valid names @ref{ecc_keyparam}.  If the
+public key @code{q} is requested but only the private key @code{d} is
+available, @code{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:
+@table @var
+@item q@@eddsa
+Return an EdDSA style compressed point.  This is only supported for
+Twisted Edwards curves.
+@end table
+@end deftypefun
+
+@deftypefun gcry_mpi_point_t gcry_mpi_ec_get_point ( @
+ @w{const char *@var{name}}, @w{gcry_ctx_t @var{ctx}}, @w{int @var{copy}})
+
+Return the point with @var{name} from the context @var{ctx}.  If not
+found @code{NULL} is returned.  If the returned MPI may later be
+modified, it is suggested to pass @code{1} to @var{copy}, so that the
+function guarantees that a modifiable copy of the MPI is returned.  If
+@code{0} is used for @var{copy}, this function may return a constant
+flagged point.  In any case @code{gcry_mpi_point_release} needs to be
+called to release the result.  If the public key @code{q} is requested
+but only the private key @code{d} is available, @code{q} will be
+recomputed on the fly.
+@end deftypefun
+
+@deftypefun gpg_error_t gcry_mpi_ec_set_mpi ( @
+ @w{const char *@var{name}}, @w{gcry_mpi_t @var{newvalue}}, @
+ @w{gcry_ctx_t @var{ctx}})
+
+Store the MPI @var{newvalue} at @var{name} into the context @var{ctx}.
+On success @code{0} is returned; on error an error code.  Valid names
+are the MPI parameters of an elliptic curve (@pxref{ecc_keyparam}).
+@end deftypefun
+
+@deftypefun gpg_error_t gcry_mpi_ec_set_point ( @
+ @w{const char *@var{name}}, @w{gcry_mpi_point_t @var{newvalue}}, @
+ @w{gcry_ctx_t @var{ctx}})
+
+Store the point @var{newvalue} at @var{name} into the context
+@var{ctx}.  On success @code{0} is returned; on error an error code.
+Valid names are the point parameters of an elliptic curve
+(@pxref{ecc_keyparam}).
+@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}})
+
+Compute the affine coordinates from the projective coordinates in
+@var{point} and store them into @var{x} and @var{y}.  If one
+coordinate is not required, @code{NULL} may be passed to @var{x} or
+@var{y}.  @var{ctx} is the context object which has been created using
+@code{gcry_mpi_ec_new}. Returns 0 on success or not 0 if @var{point}
+is at infinity.
+
+Note that you can use @code{gcry_mpi_ec_set_point} with the value
+@code{GCRYMPI_CONST_ONE} for @var{z} to convert affine coordinates
+back into projective coordinates.
+
+@end deftypefun
+
+@deftypefun void gcry_mpi_ec_dup ( @
+ @w{gcry_mpi_point_t @var{w}}, @w{gcry_mpi_point_t @var{u}}, @
+ @w{gcry_ctx_t @var{ctx}})
+
+Double the point @var{u} of the elliptic curve described by @var{ctx}
+and store the result into @var{w}.
+@end deftypefun
+
+@deftypefun void gcry_mpi_ec_add ( @
+ @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}})
+
+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_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}})
+
+Multiply the point @var{u} of the elliptic curve described by
+@var{ctx} by @var{n} and store the result into @var{w}.
+@end deftypefun
+
+@deftypefun int gcry_mpi_ec_curve_point ( @
+ @w{gcry_mpi_point_t @var{point}}, @w{gcry_ctx_t @var{ctx}})
+
+Return true if @var{point} is on the elliptic curve described by
+@var{ctx}.
+@end deftypefun
+
+
 @node Miscellaneous
 @section Miscellaneous
 
+An MPI data type is allowed to be ``misused'' to store an arbitrary
+value.  Two functions implement this kludge:
+
 @deftypefun gcry_mpi_t gcry_mpi_set_opaque (@w{gcry_mpi_t @var{a}}, @w{void *@var{p}}, @w{unsigned int @var{nbits}})
 
 Store @var{nbits} of the value @var{p} points to in @var{a} and mark
 @var{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
-@var{a}).
+@var{a}).  Ownership of @var{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 @var{p} has been allocated in a way
+that @code{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.
+@end deftypefun
 
+@deftypefun gcry_mpi_t gcry_mpi_set_opaque_copy (@w{gcry_mpi_t @var{a}}, @w{const void *@var{p}}, @w{unsigned int @var{nbits}})
+
+Same as @code{gcry_mpi_set_opaque} but ownership of @var{p} is not
+taken instead a copy of @var{p} is used.
 @end deftypefun
 
+
 @deftypefun {void *} gcry_mpi_get_opaque (@w{gcry_mpi_t @var{a}}, @w{unsigned int *@var{nbits}})
 
 Return a pointer to an opaque value stored in @var{a} and return its
@@ -4701,27 +4880,68 @@ size in @var{nbits}.  Note that the returned pointer is still owned by
 MPI.
 @end deftypefun
 
-@deftypefun void gcry_mpi_set_flag (@w{gcry_mpi_t @var{a}}, @w{enum gcry_mpi_flag @var{flag}})
+Each MPI has an associated set of flags for special purposes.  The
+currently defined flags are:
 
-Set the @var{flag} for the MPI @var{a}.  Currently only the flag
-@code{GCRYMPI_FLAG_SECURE} is allowed to convert @var{a} into an MPI
-stored in "secure memory".
-@end deftypefun
+@table @code
+@item GCRYMPI_FLAG_SECURE
+Setting this flag converts @var{a} into an MPI stored in "secure
+memory".  Clearing this flag is not allowed.
+@item 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.
+@item 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.
+@item 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 @code{GCRYMPI_CONST_ONE}, @code{GCRYMPI_CONST_TWO},
+@code{GCRYMPI_CONST_THREE}, @code{GCRYMPI_CONST_FOUR}, and
+@code{GCRYMPI_CONST_EIGHT}.
+@item GCRYMPI_FLAG_USER1
+@itemx GCRYMPI_FLAG_USER2
+@itemx GCRYMPI_FLAG_USER3
+@itemx GCRYMPI_FLAG_USER4
+These flags are reserved for use by the application.
+@end table
 
-@deftypefun void gcry_mpi_clear_flag (@w{gcry_mpi_t @var{a}}, @w{enum gcry_mpi_flag @var{flag}})
+@deftypefun void gcry_mpi_set_flag (@w{gcry_mpi_t @var{a}}, @
+ @w{enum gcry_mpi_flag @var{flag}})
 
-Clear @var{flag} for the multi-precision-integers @var{a}.  Note that
-this function is currently useless as no flags are allowed.
+Set the @var{flag} for the MPI @var{a}.  The only allowed flags are
+@code{GCRYMPI_FLAG_SECURE}, @code{GCRYMPI_FLAG_IMMUTABLE}, and
+@code{GCRYMPI_FLAG_CONST}.
 @end deftypefun
 
-@deftypefun int gcry_mpi_get_flag (@w{gcry_mpi_t @var{a}}, @w{enum gcry_mpi_flag @var{flag}})
+@deftypefun void gcry_mpi_clear_flag (@w{gcry_mpi_t @var{a}}, @
+ @w{enum gcry_mpi_flag @var{flag}})
 
-Return true when the @var{flag} is set for @var{a}.
+Clear @var{flag} for the multi-precision-integers @var{a}.  The only
+allowed flag is @code{GCRYMPI_FLAG_IMMUTABLE} but only if
+@code{GCRYMPI_FLAG_CONST} is not set.  If @code{GCRYMPI_FLAG_CONST} is
+set, clearing @code{GCRYMPI_FLAG_IMMUTABLE} will simply be ignored.
 @end deftypefun
+o
+@deftypefun int gcry_mpi_get_flag (@w{gcry_mpi_t @var{a}}, @
+ @w{enum gcry_mpi_flag @var{flag}})
+
+Return true if @var{flag} is set for @var{a}.
+@end deftypefun
+
+
+To put a random value into an MPI, the following convenience function
+may be used:
 
 @deftypefun void gcry_mpi_randomize (@w{gcry_mpi_t @var{w}}, @w{unsigned int @var{nbits}}, @w{enum gcry_random_level @var{level}})
 
-Set the multi-precision-integers @var{w} to a random value of
+Set the multi-precision-integers @var{w} to a random non-negative number of
 @var{nbits}, using random data quality of level @var{level}.  In case
 @var{nbits} is not a multiple of a byte, @var{nbits} is rounded up to
 the next byte boundary.  When using a @var{level} of
@@ -4771,7 +4991,7 @@ Convenience function to release the @var{factors} array.
 
 @deftypefun gcry_error_t gcry_prime_check (gcry_mpi_t @var{p}, unsigned int @var{flags})
 
-Check wether the number @var{p} is prime.  Returns zero in case @var{p}
+Check whether the number @var{p} is prime.  Returns zero in case @var{p}
 is indeed a prime, returns @code{GPG_ERR_NO_PRIME} in case @var{p} is
 not a prime and a different error code in case something went horribly
 wrong.
@@ -4784,9 +5004,12 @@ wrong.
 @chapter Utilities
 
 @menu
-* Memory allocation:: Functions related with memory allocation.
+* Memory allocation::   Functions related with memory allocation.
+* Context management::  Functions related with context management.
+* Buffer description::  A data type to describe buffers.
 @end menu
 
+
 @node Memory allocation
 @section Memory allocation
 
@@ -4826,6 +5049,119 @@ gcry_realloc tries to use secure memory as well.
 Release the memory area pointed to by @var{p}.
 @end deftypefun
 
+
+@node Context management
+@section 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.
+
+@deftp {Data type} {gcry_ctx_t}
+This type is used to refer to the general purpose context object.
+@end deftp
+
+@anchor{gcry_ctx_release}
+@deftypefun void gcry_ctx_release (gcry_ctx_t @var{ctx})
+Release the context object @var{ctx} and all associated resources.  A
+@code{NULL} passed as @var{ctx} is ignored.
+@end deftypefun
+
+@node Buffer description
+@section Buffer description
+
+To help hashing non-contiguous areas of memory a general purpose data
+type is defined:
+
+@deftp {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:
+
+@table @code
+  @item .size
+  This is either 0 for no information available or indicates the
+  allocated length of the buffer.
+  @item .off
+  This is the offset into the buffer.
+  @item .len
+  This is the valid length of the buffer starting at @code{.off}.
+  @item .data
+  This is the address of the buffer.
+  @end table
+@end deftp
+
+
+
+@c **********************************************************
+@c *********************  Tools  ****************************
+@c **********************************************************
+@node Tools
+@chapter Tools
+
+@menu
+* hmac256:: A standalone HMAC-SHA-256 implementation
+@end menu
+
+@manpage hmac256.1
+@node hmac256
+@section A HMAC-SHA-256 tool
+@ifset manverb
+.B hmac256
+\- Compute an HMAC-SHA-256 MAC
+@end ifset
+
+@mansect synopsis
+@ifset manverb
+.B  hmac256
+.RB [ \-\-binary ]
+.I key
+.I [FILENAME]
+@end ifset
+
+@mansect description
+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.
+
+@noindent
+@command{hmac256} is commonly invoked as
+
+@example
+hmac256 "This is my key" foo.txt
+@end example
+
+@noindent
+This compute the MAC on the file @file{foo.txt} using the key given on
+the command line.
+
+@mansect options
+@noindent
+@command{hmac256} understands these options:
+
+@table @gnupgtabopt
+
+@item --binary
+Print the MAC as a binary string.  The default is to print the MAC
+encoded has lower case hex digits.
+
+@item --version
+Print version of the program and exit.
+
+@end table
+
+@mansect see also
+@ifset isman
+@command{sha256sum}(1)
+@end ifset
+@manpause
+
 @c **********************************************************
 @c *****************  Architecure Overview  *****************
 @c **********************************************************
@@ -4890,12 +5226,6 @@ final close function releases all resources associated with the handle.
 @node Public-Key Subsystem Architecture
 @section Public-Key Architecture
 
-Libgcrypt implements two interfaces for public key cryptography: The
-standard interface is PK interface using functions in the
-@code{gcry_pk_} name space.  The AC interface in an alternative one
-which is now deprecated and will not be further described.  The AC
-interface is also disabled in FIPS mode.
-
 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
@@ -4931,18 +5261,13 @@ Create a new public/private key pair.
 
 @end table
 
-With the help of the module registration system all these functions
+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 (@file{cipher/pubkey.c}).  Thus the internal interface
 between the algorithm modules and the high level functions passes data
-in a custom format.  The interface to the modules is published
-(@file{gcrypt-modules.h}) so that it can used to register external
-implementations of algorithms with Libgcrypt.  However, for some
-algorithms this module interface is to limited and thus for the
-internal modules an extra interface is sometimes used to convey more
-information.
+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
@@ -5107,7 +5432,7 @@ 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.@footnote{Chae Hoon Lim
-and Pil Joong Lee. A key recovery attack on discrete log-based shemes
+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.}
@@ -5266,7 +5591,7 @@ output blocks.
 
 On Unix like systems the @code{GCRY_VERY_STRONG_RANDOM} and
 @code{GCRY_STRONG_RANDOM} generators are keyed and seeded using the
-rndlinux module with the @file{/dev/radnom} device. Thus these
+rndlinux module with the @file{/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.
 
@@ -5281,7 +5606,7 @@ 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 stucked generator.
+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
@@ -5307,7 +5632,7 @@ incremented on each use.
 @c them.  To use an S-expression with Libgcrypt it needs first be
 @c converted into the internal representation used by Libgcrypt (the type
 @c @code{gcry_sexp_t}).  The conversion functions support a large subset
-@c of the S-expression specification and further fature a printf like
+@c of the S-expression specification and further feature a printf like
 @c function to convert a list of big integers or other binary data into
 @c an S-expression.
 @c
@@ -5476,8 +5801,8 @@ The result is verified using the public key against the original data
 and against modified data.  (@code{cipher/@/rsa.c:@/selftest_sign_1024})
 @item
 A 1000 bit random value is encrypted and checked that it does not
-match the orginal random value.  The encrtypted result is then
-decrypted and checked that it macthes the original random value.
+match the original random value.  The encrypted result is then
+decrypted and checked that it matches the original random value.
 (@code{cipher/@/rsa.c:@/selftest_encr_1024})
 @end enumerate
 
@@ -5520,7 +5845,7 @@ keys.  The table itself is protected using a SHA-1 hash.
 @c --------------------------------
 @section Conditional Tests
 
-The conditional tests are performed if a certain contidion is met.
+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.
@@ -5555,12 +5880,7 @@ verification fails.  (@code{cipher/@/dsa.c:@/test_keys})
 
 @subsection Software Load Tests
 
-Loading of extra modules into libgcrypt is disabled in FIPS mode and
-thus no tests are
-implemented. (@code{cipher/@/cipher.c:@/_gcry_cipher_register},
-@code{cipher/@/md.c:@/_gcry_md_register},
-@code{cipher/@/pubkey.c:@/_gcry_pk_register})
-
+No code is loaded at runtime.
 
 @subsection Manual Key Entry Tests
 
@@ -5761,13 +6081,6 @@ large-pool-CSPRNG generator.
 The command @code{GCRYCTL_ENABLE_QUICK_RANDOM} is ignored.
 
 @item
-The Alternative Public Key Interface (@code{gcry_ac_xxx}) is not
-supported and all API calls return an error.
-
-@item
-Registration of external modules is not supported.
-
-@item
 Message digest debugging is disabled.
 
 @item
@@ -5827,7 +6140,7 @@ documentation only.
 
 @item Power-On
 Libgcrypt is loaded into memory and API calls may be made.  Compiler
-introducted constructor functions may be run.  Note that Libgcrypt does
+introduced constructor functions may be run.  Note that Libgcrypt does
 not implement any arbitrary constructor functions to be called by the
 operating system
 
@@ -5852,7 +6165,7 @@ will automatically transit into the  Shutdown state.
 
 @item Shutdown
 Libgcrypt is about to be terminated and removed from the memory. The
-application may at this point still runing cleanup handlers.
+application may at this point still running cleanup handlers.
 
 @end table
 @end float
@@ -5869,18 +6182,18 @@ a shared library and having it linked to an application.
 
 @item 2
 Power-On to Init is triggered by the application calling the
-Libgcrypt intialization function @code{gcry_check_version}.
+Libgcrypt initialization function @code{gcry_check_version}.
 
 @item 3
-Init to Self-Test is either triggred by a dedicated API call or implicit
-by invoking a libgrypt service conrolled by the FSM.
+Init to Self-Test is either triggered by a dedicated API call or implicit
+by invoking a libgrypt service controlled by the FSM.
 
 @item 4
 Self-Test to Operational is triggered after all self-tests passed
 successfully.
 
 @item 5
-Operational to Shutdown is an artifical state without any direct action
+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.
 
@@ -5901,7 +6214,7 @@ Error to Shutdown is similar to the Operational to Shutdown transition
 (5).
 
 @item 9
-Error to Fatal-Error is triggred if Libgrypt detects an fatal error
+Error to Fatal-Error is triggered if Libgrypt detects an fatal error
 while already being in Error state.
 
 @item 10
@@ -5909,26 +6222,26 @@ Fatal-Error to Shutdown is automatically entered by Libgcrypt
 after having reported the error.
 
 @item 11
-Power-On to Shutdown is an artifical state to document that Libgcrypt
-has not ye been initializaed but the process is about to terminate.
+Power-On to Shutdown is an artificial state to document that Libgcrypt
+has not ye been initialized but the process is about to terminate.
 
 @item 12
-Power-On to Fatal-Error will be triggerd if certain Libgcrypt functions
+Power-On to Fatal-Error will be triggered if certain Libgcrypt functions
 are used without having reached the Init state.
 
 @item 13
-Self-Test to Fatal-Error is triggred by severe errors in Libgcrypt while
+Self-Test to Fatal-Error is triggered by severe errors in Libgcrypt while
 running self-tests.
 
 @item 14
-Self-Test to Error is triggred by a failed self-test.
+Self-Test to Error is triggered by a failed self-test.
 
 @item 15
 Operational to Fatal-Error is triggered if Libcrypt encountered a
 non-recoverable error.
 
 @item 16
-Operational to Self-Test is triggred if the application requested to run
+Operational to Self-Test is triggered if the application requested to run
 the self-tests again.
 
 @item 17
@@ -5999,7 +6312,7 @@ memory and thus also the encryption contexts with these keys.
 
 GCRYCTL_SET_RANDOM_DAEMON_SOCKET
 GCRYCTL_USE_RANDOM_DAEMON
-The random damon is still a bit experimental, thus we do not document
+The random daemon is still a bit experimental, thus we do not document
 them.  Note that they should be used during initialization and that
 these functions are not really thread safe.
 
index 35b15f2..6eb301e 100644 (file)
@@ -287,12 +287,7 @@ 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.
 
-@iftex
-@heading NO WARRANTY
-@end iftex
-@ifinfo
 @center NO WARRANTY
-@end ifinfo
 
 @item
 BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
index a3f83cb..bbd18a0 100644 (file)
@@ -476,12 +476,7 @@ 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.
 
-@iftex
-@heading NO WARRANTY
-@end iftex
-@ifinfo
 @center NO WARRANTY
-@end ifinfo
 
 @item
 BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
index 2d06180..c058a72 100644 (file)
@@ -1,11 +1,11 @@
-%!PS-Adobe-2.0 EPSF-2.0
-%%Title: /home/wk/w/libgcrypt/doc/libgcrypt-modules.fig
-%%Creator: fig2dev Version 3.2 Patchlevel 4
-%%CreationDate: Mon Mar 28 14:04:57 2011
-%%For: wk@vigenere (Werner Koch,,,)
+%!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
 %%BoundingBox: 0 0 488 300
-%%Magnification: 1.0000
+%Magnification: 1.0000
 %%EndComments
+%%BeginProlog
 /$F2psDict 200 dict def
 $F2psDict begin
 $F2psDict /mtrx matrix put
@@ -42,125 +42,121 @@ $F2psDict /mtrx matrix put
 /col29 {1.000 0.750 0.750 srgb} bind def
 /col30 {1.000 0.880 0.880 srgb} bind def
 /col31 {1.000 0.840 0.000 srgb} bind def
-/col32 {0.555 0.555 0.555 srgb} bind def
-/col33 {0.254 0.270 0.254 srgb} bind def
-/col34 {0.750 0.750 0.750 srgb} bind def
-/col35 {0.500 0.500 0.500 srgb} bind def
-/col36 {0.387 0.387 0.387 srgb} bind def
-/col37 {0.801 0.801 0.801 srgb} bind def
-/col38 {0.422 0.422 0.422 srgb} bind def
-/col39 {0.773 0.715 0.590 srgb} bind def
-/col40 {0.934 0.969 0.996 srgb} bind def
-/col41 {0.859 0.793 0.648 srgb} bind def
-/col42 {0.250 0.250 0.250 srgb} bind def
-/col43 {0.875 0.875 0.875 srgb} bind def
-/col44 {0.555 0.559 0.555 srgb} bind def
-/col45 {0.664 0.664 0.664 srgb} bind def
-/col46 {0.332 0.332 0.332 srgb} bind def
-/col47 {0.840 0.840 0.840 srgb} bind def
-/col48 {0.680 0.680 0.680 srgb} bind def
-/col49 {0.742 0.742 0.742 srgb} bind def
-/col50 {0.316 0.316 0.316 srgb} bind def
-/col51 {0.902 0.887 0.902 srgb} bind def
-/col52 {0.000 0.000 0.285 srgb} bind def
-/col53 {0.473 0.473 0.473 srgb} bind def
-/col54 {0.188 0.203 0.188 srgb} bind def
-/col55 {0.254 0.254 0.254 srgb} bind def
-/col56 {0.777 0.711 0.586 srgb} bind def
-/col57 {0.863 0.613 0.574 srgb} bind def
-/col58 {0.941 0.922 0.875 srgb} bind def
-/col59 {0.762 0.762 0.762 srgb} bind def
-/col60 {0.883 0.781 0.656 srgb} bind def
-/col61 {0.879 0.879 0.879 srgb} bind def
-/col62 {0.820 0.820 0.820 srgb} bind def
-/col63 {0.926 0.926 0.926 srgb} bind def
-/col64 {0.852 0.477 0.102 srgb} bind def
-/col65 {0.941 0.891 0.102 srgb} bind def
-/col66 {0.531 0.488 0.758 srgb} bind def
-/col67 {0.836 0.836 0.836 srgb} bind def
-/col68 {0.547 0.547 0.645 srgb} bind def
-/col69 {0.289 0.289 0.289 srgb} bind def
-/col70 {0.547 0.418 0.418 srgb} bind def
-/col71 {0.352 0.352 0.352 srgb} bind def
-/col72 {0.715 0.605 0.449 srgb} bind def
-/col73 {0.254 0.574 0.996 srgb} bind def
-/col74 {0.746 0.438 0.230 srgb} bind def
-/col75 {0.855 0.465 0.000 srgb} bind def
-/col76 {0.852 0.719 0.000 srgb} bind def
-/col77 {0.000 0.391 0.000 srgb} bind def
-/col78 {0.352 0.418 0.230 srgb} bind def
-/col79 {0.824 0.824 0.824 srgb} bind def
-/col80 {0.555 0.555 0.641 srgb} bind def
-/col81 {0.949 0.723 0.363 srgb} bind def
-/col82 {0.535 0.598 0.418 srgb} bind def
-/col83 {0.391 0.391 0.391 srgb} bind def
-/col84 {0.715 0.898 0.996 srgb} bind def
-/col85 {0.523 0.750 0.922 srgb} bind def
-/col86 {0.738 0.738 0.738 srgb} bind def
-/col87 {0.824 0.582 0.320 srgb} bind def
-/col88 {0.594 0.820 0.992 srgb} bind def
-/col89 {0.547 0.609 0.418 srgb} bind def
-/col90 {0.965 0.418 0.000 srgb} bind def
-/col91 {0.352 0.418 0.223 srgb} bind def
-/col92 {0.547 0.609 0.418 srgb} bind def
-/col93 {0.547 0.609 0.480 srgb} bind def
-/col94 {0.094 0.289 0.094 srgb} bind def
-/col95 {0.676 0.676 0.676 srgb} bind def
-/col96 {0.965 0.738 0.352 srgb} bind def
-/col97 {0.387 0.418 0.609 srgb} bind def
-/col98 {0.965 0.965 0.965 srgb} bind def
-/col99 {0.867 0.000 0.000 srgb} bind def
-/col100 {0.676 0.676 0.676 srgb} bind def
-/col101 {0.965 0.738 0.352 srgb} bind def
-/col102 {0.676 0.676 0.676 srgb} bind def
-/col103 {0.965 0.738 0.352 srgb} bind def
-/col104 {0.387 0.418 0.609 srgb} bind def
-/col105 {0.320 0.418 0.160 srgb} bind def
-/col106 {0.578 0.578 0.578 srgb} bind def
-/col107 {0.000 0.387 0.000 srgb} bind def
-/col108 {0.000 0.387 0.289 srgb} bind def
-/col109 {0.480 0.516 0.289 srgb} bind def
-/col110 {0.902 0.738 0.480 srgb} bind def
-/col111 {0.645 0.707 0.773 srgb} bind def
-/col112 {0.418 0.418 0.578 srgb} bind def
-/col113 {0.516 0.418 0.418 srgb} bind def
-/col114 {0.320 0.609 0.289 srgb} bind def
-/col115 {0.836 0.902 0.902 srgb} bind def
-/col116 {0.320 0.387 0.387 srgb} bind def
-/col117 {0.094 0.418 0.289 srgb} bind def
-/col118 {0.609 0.645 0.707 srgb} bind def
-/col119 {0.996 0.578 0.000 srgb} bind def
-/col120 {0.996 0.578 0.000 srgb} bind def
-/col121 {0.000 0.387 0.289 srgb} bind def
-/col122 {0.480 0.516 0.289 srgb} bind def
-/col123 {0.387 0.449 0.480 srgb} bind def
-/col124 {0.902 0.738 0.480 srgb} bind def
-/col125 {0.867 0.867 0.867 srgb} bind def
-/col126 {0.949 0.930 0.824 srgb} bind def
-/col127 {0.957 0.680 0.363 srgb} bind def
-/col128 {0.582 0.805 0.598 srgb} bind def
-/col129 {0.707 0.082 0.488 srgb} bind def
-/col130 {0.930 0.930 0.930 srgb} bind def
-/col131 {0.516 0.516 0.516 srgb} bind def
-/col132 {0.480 0.480 0.480 srgb} bind def
-/col133 {0.000 0.352 0.000 srgb} bind def
-/col134 {0.902 0.449 0.449 srgb} bind def
-/col135 {0.996 0.793 0.191 srgb} bind def
-/col136 {0.160 0.473 0.289 srgb} bind def
-/col137 {0.867 0.156 0.129 srgb} bind def
-/col138 {0.129 0.348 0.773 srgb} bind def
-/col139 {0.969 0.969 0.969 srgb} bind def
-/col140 {0.898 0.898 0.898 srgb} bind def
-/col141 {0.129 0.516 0.352 srgb} bind def
-/col142 {0.785 0.785 0.785 srgb} bind def
-/col143 {0.871 0.844 0.871 srgb} bind def
-/col144 {0.965 0.949 0.965 srgb} bind def
+/col32 {0.557 0.557 0.557 srgb} bind def
+/col33 {0.255 0.271 0.255 srgb} bind def
+/col34 {0.753 0.753 0.753 srgb} bind def
+/col35 {0.502 0.502 0.502 srgb} bind def
+/col36 {0.388 0.388 0.388 srgb} bind def
+/col37 {0.804 0.804 0.804 srgb} bind def
+/col38 {0.424 0.424 0.424 srgb} bind def
+/col39 {0.776 0.718 0.592 srgb} bind def
+/col40 {0.937 0.973 1.000 srgb} bind def
+/col41 {0.863 0.796 0.651 srgb} bind def
+/col42 {0.251 0.251 0.251 srgb} bind def
+/col43 {0.878 0.878 0.878 srgb} bind def
+/col44 {0.557 0.561 0.557 srgb} bind def
+/col45 {0.667 0.667 0.667 srgb} bind def
+/col46 {0.333 0.333 0.333 srgb} bind def
+/col47 {0.843 0.843 0.843 srgb} bind def
+/col48 {0.682 0.682 0.682 srgb} bind def
+/col49 {0.745 0.745 0.745 srgb} bind def
+/col50 {0.318 0.318 0.318 srgb} bind def
+/col51 {0.906 0.890 0.906 srgb} bind def
+/col52 {0.000 0.000 0.286 srgb} bind def
+/col53 {0.475 0.475 0.475 srgb} bind def
+/col54 {0.188 0.204 0.188 srgb} bind def
+/col55 {0.255 0.255 0.255 srgb} bind def
+/col56 {0.780 0.714 0.588 srgb} bind def
+/col57 {0.867 0.616 0.576 srgb} bind def
+/col58 {0.945 0.925 0.878 srgb} bind def
+/col59 {0.765 0.765 0.765 srgb} bind def
+/col60 {0.886 0.784 0.659 srgb} bind def
+/col61 {0.882 0.882 0.882 srgb} bind def
+/col62 {0.824 0.824 0.824 srgb} bind def
+/col63 {0.929 0.929 0.929 srgb} bind def
+/col64 {0.855 0.478 0.102 srgb} bind def
+/col65 {0.945 0.894 0.102 srgb} bind def
+/col66 {0.533 0.490 0.761 srgb} bind def
+/col67 {0.839 0.839 0.839 srgb} bind def
+/col68 {0.549 0.549 0.647 srgb} bind def
+/col69 {0.290 0.290 0.290 srgb} bind def
+/col70 {0.549 0.420 0.420 srgb} bind def
+/col71 {0.353 0.353 0.353 srgb} bind def
+/col72 {0.718 0.608 0.451 srgb} bind def
+/col73 {0.255 0.576 1.000 srgb} bind def
+/col74 {0.749 0.439 0.231 srgb} bind def
+/col75 {0.859 0.467 0.000 srgb} bind def
+/col76 {0.855 0.722 0.000 srgb} bind def
+/col77 {0.000 0.392 0.000 srgb} bind def
+/col78 {0.353 0.420 0.231 srgb} bind def
+/col79 {0.827 0.827 0.827 srgb} bind def
+/col80 {0.557 0.557 0.643 srgb} bind def
+/col81 {0.953 0.725 0.365 srgb} bind def
+/col82 {0.537 0.600 0.420 srgb} bind def
+/col83 {0.392 0.392 0.392 srgb} bind def
+/col84 {0.718 0.902 1.000 srgb} bind def
+/col85 {0.525 0.753 0.925 srgb} bind def
+/col86 {0.741 0.741 0.741 srgb} bind def
+/col87 {0.827 0.584 0.322 srgb} bind def
+/col88 {0.596 0.824 0.996 srgb} bind def
+/col89 {0.549 0.612 0.420 srgb} bind def
+/col90 {0.969 0.420 0.000 srgb} bind def
+/col91 {0.353 0.420 0.224 srgb} bind def
+/col92 {0.549 0.612 0.420 srgb} bind def
+/col93 {0.549 0.612 0.482 srgb} bind def
+/col94 {0.094 0.290 0.094 srgb} bind def
+/col95 {0.678 0.678 0.678 srgb} bind def
+/col96 {0.969 0.741 0.353 srgb} bind def
+/col97 {0.388 0.420 0.612 srgb} bind def
+/col98 {0.969 0.969 0.969 srgb} bind def
+/col99 {0.871 0.000 0.000 srgb} bind def
+/col100 {0.678 0.678 0.678 srgb} bind def
+/col101 {0.969 0.741 0.353 srgb} bind def
+/col102 {0.678 0.678 0.678 srgb} bind def
+/col103 {0.969 0.741 0.353 srgb} bind def
+/col104 {0.388 0.420 0.612 srgb} bind def
+/col105 {0.322 0.420 0.161 srgb} bind def
+/col106 {0.580 0.580 0.580 srgb} bind def
+/col107 {0.000 0.388 0.000 srgb} bind def
+/col108 {0.000 0.388 0.290 srgb} bind def
+/col109 {0.482 0.518 0.290 srgb} bind def
+/col110 {0.906 0.741 0.482 srgb} bind def
+/col111 {0.647 0.710 0.776 srgb} bind def
+/col112 {0.420 0.420 0.580 srgb} bind def
+/col113 {0.518 0.420 0.420 srgb} bind def
+/col114 {0.322 0.612 0.290 srgb} bind def
+/col115 {0.839 0.906 0.906 srgb} bind def
+/col116 {0.322 0.388 0.388 srgb} bind def
+/col117 {0.094 0.420 0.290 srgb} bind def
+/col118 {0.612 0.647 0.710 srgb} bind def
+/col119 {1.000 0.580 0.000 srgb} bind def
+/col120 {1.000 0.580 0.000 srgb} bind def
+/col121 {0.000 0.388 0.290 srgb} bind def
+/col122 {0.482 0.518 0.290 srgb} bind def
+/col123 {0.388 0.451 0.482 srgb} bind def
+/col124 {0.906 0.741 0.482 srgb} bind def
+/col125 {0.871 0.871 0.871 srgb} bind def
+/col126 {0.953 0.933 0.827 srgb} bind def
+/col127 {0.961 0.682 0.365 srgb} bind def
+/col128 {0.584 0.808 0.600 srgb} bind def
+/col129 {0.710 0.082 0.490 srgb} bind def
+/col130 {0.933 0.933 0.933 srgb} bind def
+/col131 {0.518 0.518 0.518 srgb} bind def
+/col132 {0.482 0.482 0.482 srgb} bind def
+/col133 {0.000 0.353 0.000 srgb} bind def
+/col134 {0.906 0.451 0.451 srgb} bind def
+/col135 {1.000 0.796 0.192 srgb} bind def
+/col136 {0.161 0.475 0.290 srgb} bind def
+/col137 {0.871 0.157 0.129 srgb} bind def
+/col138 {0.129 0.349 0.776 srgb} bind def
+/col139 {0.973 0.973 0.973 srgb} bind def
+/col140 {0.902 0.902 0.902 srgb} bind def
+/col141 {0.129 0.518 0.353 srgb} bind def
+/col142 {0.788 0.788 0.788 srgb} bind def
+/col143 {0.875 0.847 0.875 srgb} bind def
+/col144 {0.969 0.953 0.969 srgb} bind def
 
 end
-save
-newpath 0 300 moveto 0 0 lineto 488 0 lineto 488 300 lineto closepath clip newpath
--32.6 348.9 translate
-1 -1 scale
 
 /cp {closepath} bind def
 /ef {eofill} bind def
@@ -234,82 +230,60 @@ newfontname newfont definefont pop end } def
 /$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def
 /$F2psEnd {$F2psEnteredState restore end} def
 
+/pageheader {
+save
+newpath 0 300 moveto 0 0 lineto 488 0 lineto 488 300 lineto closepath clip newpath
+-32.6 348.9 translate
+1 -1 scale
 $F2psBegin
 10 setmiterlimit
 0 slj 0 slc
  0.06299 0.06299 sc
+} bind def
+/pagefooter {
+$F2psEnd
+restore
+} bind def
+%%EndProlog
+pageheader
 %
 % Fig objects follow
 %
 % 
 % here starts figure with depth 50
-/Helvetica-iso ff 300.00 scf sf
-900 1440 m
-gs 1 -1 sc (Public-Key) col0 sh gr
-/Helvetica-iso ff 300.00 scf sf
-900 1815 m
-gs 1 -1 sc (Encryption) col0 sh gr
 % Polyline
+0 slj
+0 slc
 15.000 slw
 n 645 810 m 540 810 540 2055 105 arcto 4 {pop} repeat
   540 2160 2685 2160 105 arcto 4 {pop} repeat
   2790 2160 2790 915 105 arcto 4 {pop} repeat
   2790 810 645 810 105 arcto 4 {pop} repeat
  cp gs col0 s gr 
-/Helvetica-iso ff 300.00 scf sf
-630 3420 m
-gs 1 -1 sc (Multi-Precision-) col0 sh gr
-/Helvetica-iso ff 300.00 scf sf
-900 3795 m
-gs 1 -1 sc (Integers) col0 sh gr
 % Polyline
 n 645 2790 m 540 2790 540 4035 105 arcto 4 {pop} repeat
   540 4140 2685 4140 105 arcto 4 {pop} repeat
   2790 4140 2790 2895 105 arcto 4 {pop} repeat
   2790 2790 645 2790 105 arcto 4 {pop} repeat
  cp gs col0 s gr 
-/Helvetica-iso ff 300.00 scf sf
-3420 3420 m
-gs 1 -1 sc (Prime-Number) col0 sh gr
-/Helvetica-iso ff 300.00 scf sf
-3420 3795 m
-gs 1 -1 sc (Generator) col0 sh gr
 % Polyline
 n 3345 2790 m 3240 2790 3240 4035 105 arcto 4 {pop} repeat
   3240 4140 5385 4140 105 arcto 4 {pop} repeat
   5490 4140 5490 2895 105 arcto 4 {pop} repeat
   5490 2790 3345 2790 105 arcto 4 {pop} repeat
  cp gs col0 s gr 
-/Helvetica-iso ff 300.00 scf sf
-6420 3435 m
-gs 1 -1 sc (Random) col0 sh gr
-/Helvetica-iso ff 300.00 scf sf
-6420 3810 m
-gs 1 -1 sc (Numbers) col0 sh gr
 % Polyline
 n 6075 2805 m 5970 2805 5970 4050 105 arcto 4 {pop} repeat
   5970 4155 8115 4155 105 arcto 4 {pop} repeat
   8220 4155 8220 2910 105 arcto 4 {pop} repeat
   8220 2805 6075 2805 105 arcto 4 {pop} repeat
  cp gs col0 s gr 
-/Helvetica-iso ff 300.00 scf sf
-3600 1440 m
-gs 1 -1 sc (Symmetric) col0 sh gr
-/Helvetica-iso ff 300.00 scf sf
-3600 1815 m
-gs 1 -1 sc (Encryption) col0 sh gr
 % Polyline
 n 3345 810 m 3240 810 3240 2055 105 arcto 4 {pop} repeat
   3240 2160 5385 2160 105 arcto 4 {pop} repeat
   5490 2160 5490 915 105 arcto 4 {pop} repeat
   5490 810 3345 810 105 arcto 4 {pop} repeat
  cp gs col0 s gr 
-/Helvetica-iso ff 300.00 scf sf
-6435 1440 m
-gs 1 -1 sc (Hashing) col0 sh gr
-/Helvetica-iso ff 300.00 scf sf
-6435 1815 m
-gs 1 -1 sc (MACing) col0 sh gr
 % Polyline
 n 6090 810 m 5985 810 5985 2055 105 arcto 4 {pop} repeat
   5985 2160 8130 2160 105 arcto 4 {pop} repeat
@@ -322,28 +296,65 @@ n 3513 4563 m 3438 4563 3438 5438 75 arcto 4 {pop} repeat
   5022 5513 5022 4638 75 arcto 4 {pop} repeat
   5022 4563 3513 4563 75 arcto 4 {pop} repeat
  cp gs col0 s gr 
-/Helvetica-iso ff 210.00 scf sf
-3825 5130 m
-gs 1 -1 sc (Memory) col0 sh gr
 % Polyline
 n 5583 4563 m 5508 4563 5508 5438 75 arcto 4 {pop} repeat
   5508 5513 7017 5513 75 arcto 4 {pop} repeat
   7092 5513 7092 4638 75 arcto 4 {pop} repeat
   7092 4563 5583 4563 75 arcto 4 {pop} repeat
  cp gs col0 s gr 
-/Helvetica-iso ff 210.00 scf sf
-5635 5133 m
-gs 1 -1 sc (Miscelleanous) col0 sh gr
 % Polyline
 n 1443 4567 m 1368 4567 1368 5442 75 arcto 4 {pop} repeat
   1368 5517 2877 5517 75 arcto 4 {pop} repeat
   2952 5517 2952 4642 75 arcto 4 {pop} repeat
   2952 4567 1443 4567 75 arcto 4 {pop} repeat
  cp gs col0 s gr 
+/Helvetica-iso ff 300.00 scf sf
+900 1440 m
+gs 1 -1 sc (Public-Key) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+900 1815 m
+gs 1 -1 sc (Encryption) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+630 3420 m
+gs 1 -1 sc (Multi-Precision-) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+900 3795 m
+gs 1 -1 sc (Integers) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+3420 3420 m
+gs 1 -1 sc (Prime-Number) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+3420 3795 m
+gs 1 -1 sc (Generator) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+6420 3435 m
+gs 1 -1 sc (Random) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+6420 3810 m
+gs 1 -1 sc (Numbers) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+3600 1440 m
+gs 1 -1 sc (Symmetric) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+3600 1815 m
+gs 1 -1 sc (Encryption) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+6435 1440 m
+gs 1 -1 sc (Hashing) col0 sh gr
+/Helvetica-iso ff 300.00 scf sf
+6435 1815 m
+gs 1 -1 sc (MACing) col0 sh gr
+/Helvetica-iso ff 210.00 scf sf
+3825 5130 m
+gs 1 -1 sc (Memory) col0 sh gr
+/Helvetica-iso ff 210.00 scf sf
+5635 5133 m
+gs 1 -1 sc (Miscelleanous) col0 sh gr
 /Helvetica-iso ff 210.00 scf sf
 1495 5137 m
 gs 1 -1 sc (S-expressions) col0 sh gr
 % here ends figure;
-$F2psEnd
-rs
+pagefooter
 showpage
+%%Trailer
+%EOF
index 33e3ae7..117e246 100644 (file)
Binary files a/doc/libgcrypt-modules.pdf and b/doc/libgcrypt-modules.pdf differ
index 90fa4eb..2f45552 100644 (file)
Binary files a/doc/libgcrypt-modules.png and b/doc/libgcrypt-modules.png differ
index 38b85a6..6de9ee8 100644 (file)
@@ -1,4 +1,4 @@
-@set UPDATED 29 June 2011
-@set UPDATED-MONTH June 2011
-@set EDITION 1.5.0
-@set VERSION 1.5.0
+@set UPDATED 29 January 2014
+@set UPDATED-MONTH January 2014
+@set EDITION 1.6.1
+@set VERSION 1.6.1
index 38b85a6..6de9ee8 100644 (file)
@@ -1,4 +1,4 @@
-@set UPDATED 29 June 2011
-@set UPDATED-MONTH June 2011
-@set EDITION 1.5.0
-@set VERSION 1.5.0
+@set UPDATED 29 January 2014
+@set UPDATED-MONTH January 2014
+@set EDITION 1.6.1
+@set VERSION 1.6.1
diff --git a/doc/yat2m.c b/doc/yat2m.c
new file mode 100644 (file)
index 0000000..2ac4390
--- /dev/null
@@ -0,0 +1,1486 @@
+/* yat2m.c - Yet Another Texi 2 Man converter
+ *     Copyright (C) 2005, 2013 g10 Code GmbH
+ *      Copyright (C) 2006, 2008, 2011 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
+ * the Free Software Foundation; either version 3 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, see <http://www.gnu.org/licenses/>.
+ */
+
+/*
+    This is a simple texinfo to man page converter.  It needs some
+    special markup in th e texinfo and tries best to get a create man
+    page.  It has been designed for the GnuPG man pages and thus only
+    a few texinfo commands are supported.
+
+    To use this you need to add the following macros into your texinfo
+    source:
+
+      @macro manpage {a}
+      @end macro
+      @macro mansect {a}
+      @end macro
+      @macro manpause
+      @end macro
+      @macro mancont
+      @end macro
+
+    They are used by yat2m to select parts of the Texinfo which should
+    go into the man page. These macros need to be used without leading
+    left space. Processing starts after a "manpage" macro has been
+    seen.  "mansect" identifies the section and yat2m make sure to
+    emit the sections in the proper order.  Note that @mansect skips
+    the next input line if that line begins with @section, @subsection or
+    @chapheading.
+
+    To insert verbatim troff markup, the following texinfo code may be
+    used:
+
+      @ifset manverb
+      .B whateever you want
+      @end ifset
+
+    alternativly a special comment may be used:
+
+      @c man:.B whatever you want
+
+    This is useful in case you need just one line. If you want to
+    include parts only in the man page but keep the texinfo
+    translation you may use:
+
+      @ifset isman
+      stuff to be rendered only on man pages
+      @end ifset
+
+    or to exclude stuff from man pages:
+
+      @ifclear isman
+      stuff not to be rendered on man pages
+      @end ifclear
+
+    the keyword @section is ignored, however @subsection gets rendered
+    as ".SS".  @menu is completely skipped. Several man pages may be
+    extracted from one file, either using the --store or the --select
+    option.
+
+    If you want to indent tables in the source use this style:
+
+      @table foo
+        @item
+        @item
+        @table
+          @item
+        @end
+      @end
+
+    Don't change the indentation within a table and keep the same
+    number of white space at the start of the line.  yat2m simply
+    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.
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+#include <time.h>
+
+
+#define PGM "yat2m"
+#define VERSION "1.0"
+
+/* The maximum length of a line including the linefeed and one extra
+   character. */
+#define LINESIZE 1024
+
+/* Number of allowed condition nestings.  */
+#define MAX_CONDITION_NESTING  10
+
+/* Option flags. */
+static int verbose;
+static int quiet;
+static int debug;
+static const char *opt_source;
+static const char *opt_release;
+static const char *opt_select;
+static const char *opt_include;
+static int opt_store;
+
+/* Flag to keep track whether any error occurred.  */
+static int any_error;
+
+
+/* Object to keep macro definitions.  */
+struct macro_s
+{
+  struct macro_s *next;
+  char *value;    /* Malloced value. */
+  char name[1];
+};
+typedef struct macro_s *macro_t;
+
+/* List of all defined macros. */
+static macro_t macrolist;
+
+/* List of global macro names.  The value part is not used.  */
+static macro_t predefinedmacrolist;
+
+/* Object to keep track of @isset and @ifclear.  */
+struct condition_s
+{
+  int manverb;   /* "manverb" needs special treatment.  */
+  int isset;     /* This is an @isset condition.  */
+  char name[1];  /* Name of the condition macro.  */
+};
+typedef struct condition_s *condition_t;
+
+/* The stack used to evaluate conditions.  And the current states. */
+static condition_t condition_stack[MAX_CONDITION_NESTING];
+static int condition_stack_idx;
+static int cond_is_active;     /* State of ifset/ifclear */
+static int cond_in_verbatim;   /* State of "manverb".  */
+
+
+/* Object to store one line of content.  */
+struct line_buffer_s
+{
+  struct line_buffer_s *next;
+  int verbatim;  /* True if LINE contains verbatim data.  The default
+                    is Texinfo source.  */
+  char *line;
+};
+typedef struct line_buffer_s *line_buffer_t;
+
+
+/* Object to collect the data of a section.  */
+struct section_buffer_s
+{
+  char *name;           /* Malloced name of the section. This may be
+                           NULL to indicate this slot is not used.  */
+  line_buffer_t lines;  /* Linked list with the lines of the section.  */
+  line_buffer_t *lines_tail; /* Helper for faster appending to the
+                                linked list.  */
+  line_buffer_t last_line;   /* Points to the last line appended.  */
+};
+typedef struct section_buffer_s *section_buffer_t;
+
+/* Variable to keep info about the current page together.  */
+static struct
+{
+  /* Filename of the current page or NULL if no page is active.  Malloced. */
+  char *name;
+
+  /* Number of allocated elements in SECTIONS below.  */
+  size_t n_sections;
+  /* Array with the data of the sections.  */
+  section_buffer_t sections;
+
+} thepage;
+
+
+/* The list of standard section names.  COMMANDS and ASSUAN are GnuPG
+   specific. */
+static const char * const standard_sections[] =
+  { "NAME",  "SYNOPSIS",  "DESCRIPTION",
+    "RETURN VALUE", "EXIT STATUS", "ERROR HANDLING", "ERRORS",
+    "COMMANDS", "OPTIONS", "USAGE", "EXAMPLES", "FILES",
+    "ENVIRONMENT", "DIAGNOSTICS", "SECURITY", "CONFORMING TO",
+    "ASSUAN", "NOTES", "BUGS", "AUTHOR", "SEE ALSO", NULL };
+
+
+/*-- Local prototypes.  --*/
+static void proc_texi_buffer (FILE *fp, const char *line, size_t len,
+                              int *table_level, int *eol_action);
+
+
+
+/* Print diagnostic message and exit with failure. */
+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);
+  putc ('\n', stderr);
+
+  exit (1);
+}
+
+
+/* Print diagnostic message. */
+static void
+err (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  fflush (stdout);
+  if (strncmp (format, "%s:%d:", 6))
+    fprintf (stderr, "%s: ", PGM);
+
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+  putc ('\n', stderr);
+  any_error = 1;
+}
+
+/* Print diagnostic message. */
+static void
+inf (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);
+  putc ('\n', stderr);
+}
+
+
+static void *
+xmalloc (size_t n)
+{
+  void *p = malloc (n);
+  if (!p)
+    die ("out of core: %s", strerror (errno));
+  return p;
+}
+
+static void *
+xcalloc (size_t n, size_t m)
+{
+  void *p = calloc (n, m);
+  if (!p)
+    die ("out of core: %s", strerror (errno));
+  return p;
+}
+
+static void *
+xrealloc (void *old, size_t n)
+{
+  void *p = realloc (old, n);
+  if (!p)
+    die ("out of core: %s", strerror (errno));
+  return p;
+}
+
+static char *
+xstrdup (const char *string)
+{
+  void *p = malloc (strlen (string)+1);
+  if (!p)
+    die ("out of core: %s", strerror (errno));
+  strcpy (p, string);
+  return p;
+}
+
+
+/* Uppercase the ascii characters in STRING.  */
+static char *
+ascii_strupr (char *string)
+{
+  char *p;
+
+  for (p = string; *p; p++)
+    if (!(*p & 0x80))
+      *p = toupper (*p);
+  return string;
+}
+
+
+/* Return the current date as an ISO string.  */
+const char *
+isodatestring (void)
+{
+  static char buffer[11+5];
+  struct tm *tp;
+  time_t atime = time (NULL);
+
+  if (atime < 0)
+    strcpy (buffer, "????" "-??" "-??");
+  else
+    {
+      tp = gmtime (&atime);
+      sprintf (buffer,"%04d-%02d-%02d",
+               1900+tp->tm_year, tp->tm_mon+1, tp->tm_mday );
+    }
+  return buffer;
+}
+
+
+/* Add NAME to the list of predefined macros which are global for all
+   files.  */
+static void
+add_predefined_macro (const char *name)
+{
+  macro_t m;
+
+  for (m=predefinedmacrolist; m; m = m->next)
+    if (!strcmp (m->name, name))
+      break;
+  if (!m)
+    {
+      m = xcalloc (1, sizeof *m + strlen (name));
+      strcpy (m->name, name);
+      m->next = predefinedmacrolist;
+      predefinedmacrolist = m;
+    }
+}
+
+
+/* Create or update a macro with name MACRONAME and set its values TO
+   MACROVALUE.  Note that ownership of the macro value is transferred
+   to this function.  */
+static void
+set_macro (const char *macroname, char *macrovalue)
+{
+  macro_t m;
+
+  for (m=macrolist; m; m = m->next)
+    if (!strcmp (m->name, macroname))
+      break;
+  if (m)
+    free (m->value);
+  else
+    {
+      m = xcalloc (1, sizeof *m + strlen (macroname));
+      strcpy (m->name, macroname);
+      m->next = macrolist;
+      macrolist = m;
+    }
+  m->value = macrovalue;
+  macrovalue = NULL;
+}
+
+
+/* Return true if the macro NAME is set, i.e. not the empty string and
+   not evaluating to 0.  */
+static int
+macro_set_p (const char *name)
+{
+  macro_t m;
+
+  for (m = macrolist; 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))
+    return 1; /* Not a digit but some other string.  */
+  return !!atoi (m->value);
+}
+
+
+/* Evaluate the current conditions.  */
+static void
+evaluate_conditions (const char *fname, int lnr)
+{
+  int i;
+
+  /* for (i=0; i < condition_stack_idx; i++) */
+  /*   inf ("%s:%d:   stack[%d] %s %s %c", */
+  /*        fname, lnr, i, condition_stack[i]->isset? "set":"clr", */
+  /*        condition_stack[i]->name, */
+  /*        (macro_set_p (condition_stack[i]->name) */
+  /*         ^ !condition_stack[i]->isset)? 't':'f'); */
+
+  cond_is_active = 1;
+  cond_in_verbatim = 0;
+  if (condition_stack_idx)
+    {
+      for (i=0; i < condition_stack_idx; i++)
+        {
+          if (condition_stack[i]->manverb)
+            cond_in_verbatim = (macro_set_p (condition_stack[i]->name)
+                                ^ !condition_stack[i]->isset);
+          else if (!(macro_set_p (condition_stack[i]->name)
+                     ^ !condition_stack[i]->isset))
+            {
+              cond_is_active = 0;
+              break;
+            }
+        }
+    }
+
+  /* inf ("%s:%d:   active=%d verbatim=%d", */
+  /*      fname, lnr, cond_is_active, cond_in_verbatim); */
+}
+
+
+/* Push a condition with condition macro NAME onto the stack.  If
+   ISSET is true, a @isset condition is pushed.  */
+static void
+push_condition (const char *name, int isset, const char *fname, int lnr)
+{
+  condition_t cond;
+  int manverb = 0;
+
+  if (condition_stack_idx >= MAX_CONDITION_NESTING)
+    {
+      err ("%s:%d: condition nested too deep", fname, lnr);
+      return;
+    }
+
+  if (!strcmp (name, "manverb"))
+    {
+      if (!isset)
+        {
+          err ("%s:%d: using \"@ifclear manverb\" is not allowed", fname, lnr);
+          return;
+        }
+      manverb = 1;
+    }
+
+  cond = xcalloc (1, sizeof *cond + strlen (name));
+  cond->manverb = manverb;
+  cond->isset = isset;
+  strcpy (cond->name, name);
+
+  condition_stack[condition_stack_idx++] = cond;
+  evaluate_conditions (fname, lnr);
+}
+
+
+/* Remove the last condition from the stack.  ISSET is used for error
+   reporting.  */
+static void
+pop_condition (int isset, const char *fname, int lnr)
+{
+  if (!condition_stack_idx)
+    {
+      err ("%s:%d: unbalanced \"@end %s\"",
+           fname, lnr, isset?"isset":"isclear");
+      return;
+    }
+  condition_stack_idx--;
+  free (condition_stack[condition_stack_idx]);
+  condition_stack[condition_stack_idx] = NULL;
+  evaluate_conditions (fname, lnr);
+}
+
+
+\f
+/* Return a section buffer for the section NAME.  Allocate a new buffer
+   if this is a new section.  Keep track of the sections in THEPAGE.
+   This function may reallocate the section array in THEPAGE.  */
+static section_buffer_t
+get_section_buffer (const char *name)
+{
+  int i;
+  section_buffer_t sect;
+
+  /* If there is no section we put everything into the required NAME
+     section.  Given that this is the first one listed it is likely
+     that error are easily visible.  */
+  if (!name)
+    name = "NAME";
+
+  for (i=0; i < thepage.n_sections; i++)
+    {
+      sect = thepage.sections + i;
+      if (sect->name && !strcmp (name, sect->name))
+        return sect;
+    }
+  for (i=0; i < thepage.n_sections; i++)
+    if (!thepage.sections[i].name)
+      break;
+  if (i < thepage.n_sections)
+    sect = thepage.sections + i;
+  else
+    {
+      /* We need to allocate or reallocate the section array.  */
+      size_t old_n = thepage.n_sections;
+      size_t new_n = 20;
+
+      if (!old_n)
+        thepage.sections = xcalloc (new_n, sizeof *thepage.sections);
+      else
+        {
+          thepage.sections = xrealloc (thepage.sections,
+                                       ((old_n + new_n)
+                                        * sizeof *thepage.sections));
+          memset (thepage.sections + old_n, 0,
+                  new_n * sizeof *thepage.sections);
+        }
+      thepage.n_sections += new_n;
+
+      /* Setup the tail pointers.  */
+      for (i=old_n; i < thepage.n_sections; i++)
+        {
+          sect = thepage.sections + i;
+          sect->lines_tail = &sect->lines;
+        }
+      sect = thepage.sections + old_n;
+    }
+
+  /* Store the name.  */
+  assert (!sect->name);
+  sect->name = xstrdup (name);
+  return sect;
+}
+
+
+
+/* Add the content of LINE to the section named SECTNAME.  */
+static void
+add_content (const char *sectname, char *line, int verbatim)
+{
+  section_buffer_t sect;
+  line_buffer_t lb;
+
+  sect = get_section_buffer (sectname);
+  if (sect->last_line && !sect->last_line->verbatim == !verbatim)
+    {
+      /* Lets append that line to the last one.  We do this to keep
+         all lines of the same kind (i.e.verbatim or not) together in
+         one large buffer.  */
+      size_t n1, n;
+
+      lb = sect->last_line;
+      n1 = strlen (lb->line);
+      n = n1 + 1 + strlen (line) + 1;
+      lb->line = xrealloc (lb->line, n);
+      strcpy (lb->line+n1, "\n");
+      strcpy (lb->line+n1+1, line);
+    }
+  else
+    {
+      lb = xcalloc (1, sizeof *lb);
+      lb->verbatim = verbatim;
+      lb->line = xstrdup (line);
+      sect->last_line = lb;
+      *sect->lines_tail = lb;
+      sect->lines_tail = &lb->next;
+    }
+}
+
+
+/* Prepare for a new man page using the filename NAME. */
+static void
+start_page (char *name)
+{
+  if (verbose)
+    inf ("starting page '%s'", name);
+  assert (!thepage.name);
+  thepage.name = xstrdup (name);
+  thepage.n_sections = 0;
+}
+
+
+/* Write the .TH entry of the current page.  Return -1 if there is a
+   problem with the page. */
+static int
+write_th (FILE *fp)
+{
+  char *name, *p;
+
+  fputs (".\\\" Created from Texinfo source by yat2m " VERSION "\n", fp);
+
+  name = ascii_strupr (xstrdup (thepage.name));
+  p = strrchr (name, '.');
+  if (!p || !p[1])
+    {
+      err ("no section name in man page '%s'", thepage.name);
+      free (name);
+      return -1;
+    }
+  *p++ = 0;
+  fprintf (fp, ".TH %s %s %s \"%s\" \"%s\"\n",
+           name, p, isodatestring (), opt_release, opt_source);
+  return 0;
+}
+
+
+/* Process the texinfo command COMMAND (without the leading @) and
+   write output if needed to FP. REST is the remainer of the line
+   which should either point to an opening brace or to a white space.
+   The function returns the number of characters already processed
+   from REST.  LEN is the usable length of REST.  TABLE_LEVEL is used to
+   control the indentation of tables.  */
+static size_t
+proc_texi_cmd (FILE *fp, const char *command, const char *rest, size_t len,
+               int *table_level, int *eol_action)
+{
+  static struct {
+    const char *name;    /* Name of the command.  */
+    int what;            /* What to do with this command. */
+    const char *lead_in; /* String to print with a opening brace.  */
+    const char *lead_out;/* String to print with the closing brace. */
+  } cmdtbl[] = {
+    { "command", 0, "\\fB", "\\fR" },
+    { "code",    0, "\\fB", "\\fR" },
+    { "sc",      0, "\\fB", "\\fR" },
+    { "var",     0, "\\fI", "\\fR" },
+    { "samp",    0, "\\(aq", "\\(aq"  },
+    { "file",    0, "\\(oq\\fI","\\fR\\(cq" },
+    { "env",     0, "\\(oq\\fI","\\fR\\(cq" },
+    { "acronym", 0 },
+    { "dfn",     0 },
+    { "option",  0, "\\fB", "\\fR"   },
+    { "example", 1, ".RS 2\n.nf\n" },
+    { "smallexample", 1, ".RS 2\n.nf\n" },
+    { "asis",    7 },
+    { "anchor",  7 },
+    { "cartouche", 1 },
+    { "xref",    0, "see: [", "]" },
+    { "pxref",   0, "see: [", "]" },
+    { "uref",    0, "(\\fB", "\\fR)" },
+    { "footnote",0, " ([", "])" },
+    { "emph",    0, "\\fI", "\\fR" },
+    { "w",       1 },
+    { "c",       5 },
+    { "opindex", 1 },
+    { "cpindex", 1 },
+    { "cindex",  1 },
+    { "noindent", 0 },
+    { "section", 1 },
+    { "chapter", 1 },
+    { "subsection", 6, "\n.SS " },
+    { "chapheading", 0},
+    { "item",    2, ".TP\n.B " },
+    { "itemx",   2, ".TP\n.B " },
+    { "table",   3 },
+    { "itemize",   3 },
+    { "bullet",  0, "* " },
+    { "end",     4 },
+    { "quotation",1, ".RS\n\\fB" },
+    { NULL }
+  };
+  size_t n;
+  int i;
+  const char *s;
+  const char *lead_out = NULL;
+  int ignore_args = 0;
+
+  for (i=0; cmdtbl[i].name && strcmp (cmdtbl[i].name, command); i++)
+    ;
+  if (cmdtbl[i].name)
+    {
+      s = cmdtbl[i].lead_in;
+      if (s)
+        fputs (s, fp);
+      lead_out = cmdtbl[i].lead_out;
+      switch (cmdtbl[i].what)
+        {
+        case 1: /* Throw away the entire line.  */
+          s = memchr (rest, '\n', len);
+          return s? (s-rest)+1 : len;
+        case 2: /* Handle @item.  */
+          break;
+        case 3: /* Handle table.  */
+          if (++(*table_level) > 1)
+            fputs (".RS\n", fp);
+          /* Now throw away the entire line. */
+          s = memchr (rest, '\n', len);
+          return s? (s-rest)+1 : len;
+          break;
+        case 4: /* Handle end.  */
+          for (s=rest, n=len; n && (*s == ' ' || *s == '\t'); s++, n--)
+            ;
+          if (n >= 5 && !memcmp (s, "table", 5)
+              && (!n || s[5] == ' ' || s[5] == '\t' || s[5] == '\n'))
+            {
+              if ((*table_level)-- > 1)
+                fputs (".RE\n", fp);
+            }
+          else if (n >= 7 && !memcmp (s, "example", 7)
+              && (!n || s[7] == ' ' || s[7] == '\t' || s[7] == '\n'))
+            {
+              fputs (".fi\n.RE\n", fp);
+            }
+          else if (n >= 12 && !memcmp (s, "smallexample", 12)
+              && (!n || s[12] == ' ' || s[12] == '\t' || s[12] == '\n'))
+            {
+              fputs (".fi\n.RE\n", fp);
+            }
+          else if (n >= 9 && !memcmp (s, "quotation", 9)
+              && (!n || s[9] == ' ' || s[9] == '\t' || s[9] == '\n'))
+            {
+              fputs ("\\fR\n.RE\n", fp);
+            }
+          /* Now throw away the entire line. */
+          s = memchr (rest, '\n', len);
+          return s? (s-rest)+1 : len;
+        case 5: /* Handle special comments. */
+          for (s=rest, n=len; n && (*s == ' ' || *s == '\t'); s++, n--)
+            ;
+          if (n >= 4 && !memcmp (s, "man:", 4))
+            {
+              for (s+=4, n-=4; n && *s != '\n'; n--, s++)
+                putc (*s, fp);
+              putc ('\n', fp);
+            }
+          /* Now throw away the entire line. */
+          s = memchr (rest, '\n', len);
+          return s? (s-rest)+1 : len;
+        case 6:
+          *eol_action = 1;
+          break;
+        case 7:
+          ignore_args = 1;
+          break;
+        default:
+          break;
+        }
+    }
+  else
+    {
+      macro_t m;
+
+      for (m = macrolist; m ; m = m->next)
+        if (!strcmp (m->name, command))
+            break;
+      if (m)
+        {
+          proc_texi_buffer (fp, m->value, strlen (m->value),
+                            table_level, eol_action);
+          ignore_args = 1; /* Parameterized macros are not yet supported. */
+        }
+      else
+        inf ("texinfo command '%s' not supported (%.*s)", command,
+             ((s = memchr (rest, '\n', len)), (s? (s-rest) : len)), rest);
+    }
+
+  if (*rest == '{')
+    {
+      /* Find matching closing brace.  */
+      for (s=rest+1, n=1, i=1; i && *s && n < len; s++, n++)
+        if (*s == '{')
+          i++;
+        else if (*s == '}')
+          i--;
+      if (i)
+        {
+          err ("closing brace for command '%s' not found", command);
+          return len;
+        }
+      if (n > 2 && !ignore_args)
+        proc_texi_buffer (fp, rest+1, n-2, table_level, eol_action);
+    }
+  else
+    n = 0;
+
+  if (lead_out)
+    fputs (lead_out, fp);
+
+  return n;
+}
+
+
+
+/* Process the string LINE with LEN bytes of Texinfo content. */
+static void
+proc_texi_buffer (FILE *fp, const char *line, size_t len,
+                  int *table_level, int *eol_action)
+{
+  const char *s;
+  char cmdbuf[256];
+  int cmdidx = 0;
+  int in_cmd = 0;
+  size_t n;
+
+  for (s=line; *s && len; s++, len--)
+    {
+      if (in_cmd)
+        {
+          if (in_cmd == 1)
+            {
+              switch (*s)
+                {
+                case '@': case '{': case '}':
+                  putc (*s, fp); in_cmd = 0;
+                  break;
+                case ':': /* Not ending a sentence flag.  */
+                  in_cmd = 0;
+                  break;
+                case '.': case '!': case '?': /* Ending a sentence. */
+                  putc (*s, fp); in_cmd = 0;
+                  break;
+                case ' ': case '\t': case '\n': /* Non collapsing spaces.  */
+                  putc (*s, fp); in_cmd = 0;
+                  break;
+                default:
+                  cmdidx = 0;
+                  cmdbuf[cmdidx++] = *s;
+                  in_cmd++;
+                  break;
+                }
+            }
+          else if (*s == '{' || *s == ' ' || *s == '\t' || *s == '\n')
+            {
+              cmdbuf[cmdidx] = 0;
+              n = proc_texi_cmd (fp, cmdbuf, s, len, table_level, eol_action);
+              assert (n <= len);
+              s += n; len -= n;
+              s--; len++;
+              in_cmd = 0;
+            }
+          else if (cmdidx < sizeof cmdbuf -1)
+            cmdbuf[cmdidx++] = *s;
+          else
+            {
+              err ("texinfo command too long - ignored");
+              in_cmd = 0;
+            }
+        }
+      else if (*s == '@')
+        in_cmd = 1;
+      else if (*s == '\n')
+        {
+          switch (*eol_action)
+            {
+            case 1: /* Create a dummy paragraph. */
+              fputs ("\n\\ \n", fp);
+              break;
+            default:
+              putc (*s, fp);
+            }
+          *eol_action = 0;
+        }
+      else if (*s == '\\')
+        fputs ("\\\\", fp);
+      else
+        putc (*s, fp);
+    }
+
+  if (in_cmd > 1)
+    {
+      cmdbuf[cmdidx] = 0;
+      n = proc_texi_cmd (fp, cmdbuf, s, len, table_level, eol_action);
+      assert (n <= len);
+      s += n; len -= n;
+      s--; len++;
+      in_cmd = 0;
+    }
+}
+
+
+/* Do something with the Texinfo line LINE.  */
+static void
+parse_texi_line (FILE *fp, const char *line, int *table_level)
+{
+  int eol_action = 0;
+
+  /* A quick test whether there are any texinfo commands.  */
+  if (!strchr (line, '@'))
+    {
+      fputs (line, fp);
+      putc ('\n', fp);
+      return;
+    }
+  proc_texi_buffer (fp, line, strlen (line), table_level, &eol_action);
+  putc ('\n', fp);
+}
+
+
+/* Write all the lines LINES to FP.  */
+static void
+write_content (FILE *fp, line_buffer_t lines)
+{
+  line_buffer_t line;
+  int table_level = 0;
+
+  for (line = lines; line; line = line->next)
+    {
+      if (line->verbatim)
+        {
+          fputs (line->line, fp);
+          putc ('\n', fp);
+        }
+      else
+        {
+/*           fputs ("TEXI---", fp); */
+/*           fputs (line->line, fp); */
+/*           fputs ("---\n", fp); */
+          parse_texi_line (fp, line->line, &table_level);
+        }
+    }
+}
+
+
+
+static int
+is_standard_section (const char *name)
+{
+  int i;
+  const char *s;
+
+  for (i=0; (s=standard_sections[i]); i++)
+    if (!strcmp (s, name))
+      return 1;
+  return 0;
+}
+
+
+/* Finish a page; that is sort the data and write it out to the file.  */
+static void
+finish_page (void)
+{
+  FILE *fp;
+  section_buffer_t sect = NULL;
+  int idx;
+  const char *s;
+  int i;
+
+  if (!thepage.name)
+    return; /* No page active.  */
+
+  if (verbose)
+    inf ("finishing page '%s'", thepage.name);
+
+  if (opt_select)
+    {
+      if (!strcmp (opt_select, thepage.name))
+        {
+          inf ("selected '%s'", thepage.name );
+          fp = stdout;
+        }
+      else
+        {
+          fp = fopen ( "/dev/null", "w" );
+          if (!fp)
+            die ("failed to open /dev/null: %s\n", strerror (errno));
+        }
+    }
+  else if (opt_store)
+    {
+      inf ("writing '%s'", thepage.name );
+      fp = fopen ( thepage.name, "w" );
+      if (!fp)
+        die ("failed to create '%s': %s\n", thepage.name, strerror (errno));
+    }
+  else
+    fp = stdout;
+
+  if (write_th (fp))
+    goto leave;
+
+  for (idx=0; (s=standard_sections[idx]); idx++)
+    {
+      for (i=0; i < thepage.n_sections; i++)
+        {
+          sect = thepage.sections + i;
+          if (sect->name && !strcmp (s, sect->name))
+            break;
+        }
+      if (i == thepage.n_sections)
+        sect = NULL;
+
+      if (sect)
+        {
+          fprintf (fp, ".SH %s\n", sect->name);
+          write_content (fp, sect->lines);
+          /* Now continue with all non standard sections directly
+             following this one. */
+          for (i++; i < thepage.n_sections; i++)
+            {
+              sect = thepage.sections + i;
+              if (sect->name && is_standard_section (sect->name))
+                break;
+              if (sect->name)
+                {
+                  fprintf (fp, ".SH %s\n", sect->name);
+                  write_content (fp, sect->lines);
+                }
+            }
+
+        }
+    }
+
+
+ leave:
+  if (fp != stdout)
+    fclose (fp);
+  free (thepage.name);
+  thepage.name = NULL;
+  /* FIXME: Cleanup the content.  */
+}
+
+
+
+
+/* Parse one Texinfo file and create manpages according to the
+   embedded instructions.  */
+static void
+parse_file (const char *fname, FILE *fp, char **section_name, int in_pause)
+{
+  char *line;
+  int lnr = 0;
+  /* Fixme: The following state variables don't carry over to include
+     files. */
+  int skip_to_end = 0;        /* Used to skip over menu entries. */
+  int skip_sect_line = 0;     /* Skip after @mansect.  */
+  int item_indent = 0;        /* How far is the current @item indented.  */
+
+  /* Helper to define a macro. */
+  char *macroname = NULL;
+  char *macrovalue = NULL;
+  size_t macrovaluesize = 0;
+  size_t macrovalueused = 0;
+
+  line = xmalloc (LINESIZE);
+  while (fgets (line, LINESIZE, fp))
+    {
+      size_t n = strlen (line);
+      int got_line = 0;
+      char *p, *pend;
+
+      lnr++;
+      if (!n || line[n-1] != '\n')
+        {
+          err ("%s:%d: trailing linefeed missing, line too long or "
+               "embedded Nul character", fname, lnr);
+          break;
+        }
+      line[--n] = 0;
+
+      /* Kludge to allow indentation of tables.  */
+      for (p=line; *p == ' ' || *p == '\t'; p++)
+        ;
+      if (*p)
+        {
+          if (*p == '@' && !strncmp (p+1, "item", 4))
+            item_indent = p - line;  /* Set a new indent level.  */
+          else if (p - line < item_indent)
+            item_indent = 0;         /* Switch off indention.  */
+
+          if (item_indent)
+            {
+              memmove (line, line+item_indent, n - item_indent + 1);
+              n -= item_indent;
+            }
+        }
+
+
+      if (*line == '@')
+        {
+          for (p=line+1, n=1; *p && *p != ' ' && *p != '\t'; p++)
+            n++;
+          while (*p == ' ' || *p == '\t')
+            p++;
+        }
+      else
+        p = line;
+
+      /* Take action on macro.  */
+      if (macroname)
+        {
+          if (n == 4 && !memcmp (line, "@end", 4)
+              && (line[4]==' '||line[4]=='\t'||!line[4])
+              && !strncmp (p, "macro", 5)
+              && (p[5]==' '||p[5]=='\t'||!p[5]))
+            {
+              if (macrovalueused)
+                macrovalue[--macrovalueused] = 0; /* Kill the last LF. */
+              macrovalue[macrovalueused] = 0;     /* Terminate macro. */
+              macrovalue = xrealloc (macrovalue, macrovalueused+1);
+
+              set_macro (macroname, macrovalue);
+              macrovalue = NULL;
+              free (macroname);
+              macroname = NULL;
+            }
+          else
+            {
+              if (macrovalueused + strlen (line) + 2 >= macrovaluesize)
+                {
+                  macrovaluesize += strlen (line) + 256;
+                  macrovalue = xrealloc (macrovalue,  macrovaluesize);
+                }
+              strcpy (macrovalue+macrovalueused, line);
+              macrovalueused += strlen (line);
+              macrovalue[macrovalueused++] = '\n';
+            }
+          continue;
+        }
+
+
+      if (n >= 5 && !memcmp (line, "@node", 5)
+          && (line[5]==' '||line[5]=='\t'||!line[5]))
+        {
+          /* Completey ignore @node lines.  */
+          continue;
+        }
+
+
+      if (skip_sect_line)
+        {
+          skip_sect_line = 0;
+          if (!strncmp (line, "@section", 8)
+              || !strncmp (line, "@subsection", 11)
+              || !strncmp (line, "@chapheading", 12))
+            continue;
+        }
+
+      /* We only parse lines we need and ignore the rest.  There are a
+         few macros used to control this as well as one @ifset
+         command.  Parts we know about are saved away into containers
+         separate for each section. */
+
+      /* First process ifset/ifclear commands. */
+      if (*line == '@')
+        {
+          if (n == 6 && !memcmp (line, "@ifset", 6)
+                   && (line[6]==' '||line[6]=='\t'))
+            {
+              for (p=line+7; *p == ' ' || *p == '\t'; p++)
+                ;
+              if (!*p)
+                {
+                  err ("%s:%d: name missing after \"@ifset\"", fname, lnr);
+                  continue;
+                }
+              for (pend=p; *pend && *pend != ' ' && *pend != '\t'; pend++)
+                ;
+              *pend = 0;  /* Ignore rest of the line.  */
+              push_condition (p, 1, fname, lnr);
+              continue;
+            }
+          else if (n == 8 && !memcmp (line, "@ifclear", 8)
+                   && (line[8]==' '||line[8]=='\t'))
+            {
+              for (p=line+9; *p == ' ' || *p == '\t'; p++)
+                ;
+              if (!*p)
+                {
+                  err ("%s:%d: name missing after \"@ifsclear\"", fname, lnr);
+                  continue;
+                }
+              for (pend=p; *pend && *pend != ' ' && *pend != '\t'; pend++)
+                ;
+              *pend = 0;  /* Ignore rest of the line.  */
+              push_condition (p, 0, fname, lnr);
+              continue;
+            }
+          else if (n == 4 && !memcmp (line, "@end", 4)
+                   && (line[4]==' '||line[4]=='\t')
+                   && !strncmp (p, "ifset", 5)
+                   && (p[5]==' '||p[5]=='\t'||!p[5]))
+            {
+              pop_condition (1, fname, lnr);
+              continue;
+            }
+          else if (n == 4 && !memcmp (line, "@end", 4)
+                   && (line[4]==' '||line[4]=='\t')
+                   && !strncmp (p, "ifclear", 7)
+                   && (p[7]==' '||p[7]=='\t'||!p[7]))
+            {
+              pop_condition (0, fname, lnr);
+              continue;
+            }
+        }
+
+      /* Take action on ifset/ifclear.  */
+      if (!cond_is_active)
+        continue;
+
+      /* Process commands. */
+      if (*line == '@')
+        {
+          if (skip_to_end
+              && n == 4 && !memcmp (line, "@end", 4)
+              && (line[4]==' '||line[4]=='\t'||!line[4]))
+            {
+              skip_to_end = 0;
+            }
+          else if (cond_in_verbatim)
+            {
+                got_line = 1;
+            }
+          else if (n == 6 && !memcmp (line, "@macro", 6))
+            {
+              macroname = xstrdup (p);
+              macrovalue = xmalloc ((macrovaluesize = 1024));
+              macrovalueused = 0;
+            }
+          else if (n == 8 && !memcmp (line, "@manpage", 8))
+            {
+              free (*section_name);
+              *section_name = NULL;
+              finish_page ();
+              start_page (p);
+              in_pause = 0;
+            }
+          else if (n == 8 && !memcmp (line, "@mansect", 8))
+            {
+              if (!thepage.name)
+                err ("%s:%d: section outside of a man page", fname, lnr);
+              else
+                {
+                  free (*section_name);
+                  *section_name = ascii_strupr (xstrdup (p));
+                  in_pause = 0;
+                  skip_sect_line = 1;
+                }
+            }
+          else if (n == 9 && !memcmp (line, "@manpause", 9))
+            {
+              if (!*section_name)
+                err ("%s:%d: pausing outside of a man section", fname, lnr);
+              else if (in_pause)
+                err ("%s:%d: already pausing", fname, lnr);
+              else
+                in_pause = 1;
+            }
+          else if (n == 8 && !memcmp (line, "@mancont", 8))
+            {
+              if (!*section_name)
+                err ("%s:%d: continue outside of a man section", fname, lnr);
+              else if (!in_pause)
+                err ("%s:%d: continue while not pausing", fname, lnr);
+              else
+                in_pause = 0;
+            }
+          else if (n == 5 && !memcmp (line, "@menu", 5)
+                   && (line[5]==' '||line[5]=='\t'||!line[5]))
+            {
+              skip_to_end = 1;
+            }
+          else if (n == 8 && !memcmp (line, "@include", 8)
+                   && (line[8]==' '||line[8]=='\t'||!line[8]))
+            {
+              char *incname = xstrdup (p);
+              FILE *incfp = fopen (incname, "r");
+
+              if (!incfp && opt_include && *opt_include && *p != '/')
+                {
+                  free (incname);
+                  incname = xmalloc (strlen (opt_include) + 1
+                                     + strlen (p) + 1);
+                  strcpy (incname, opt_include);
+                  if ( incname[strlen (incname)-1] != '/' )
+                    strcat (incname, "/");
+                  strcat (incname, p);
+                  incfp = fopen (incname, "r");
+                }
+
+              if (!incfp)
+                err ("can't open include file '%s':%s",
+                     incname, strerror (errno));
+              else
+                {
+                  parse_file (incname, incfp, section_name, in_pause);
+                  fclose (incfp);
+                }
+              free (incname);
+            }
+          else if (n == 4 && !memcmp (line, "@bye", 4)
+                   && (line[4]==' '||line[4]=='\t'||!line[4]))
+            {
+              break;
+            }
+          else if (!skip_to_end)
+            got_line = 1;
+        }
+      else if (!skip_to_end)
+        got_line = 1;
+
+      if (got_line && cond_in_verbatim)
+        add_content (*section_name, line, 1);
+      else if (got_line && thepage.name && *section_name && !in_pause)
+        add_content (*section_name, line, 0);
+
+    }
+  if (ferror (fp))
+    err ("%s:%d: read error: %s", fname, lnr, strerror (errno));
+  free (macroname);
+  free (macrovalue);
+  free (line);
+}
+
+
+static void
+top_parse_file (const char *fname, FILE *fp)
+{
+  char *section_name = NULL;  /* Name of the current section or NULL
+                                 if not in a section.  */
+  macro_t m;
+
+  while (macrolist)
+    {
+      macro_t next = macrolist->next;
+      free (macrolist->value);
+      free (macrolist);
+      macrolist = next;
+    }
+  for (m=predefinedmacrolist; m; m = m->next)
+    set_macro (m->name, xstrdup ("1"));
+  cond_is_active = 1;
+  cond_in_verbatim = 0;
+
+  parse_file (fname, fp, &section_name, 0);
+  free (section_name);
+  finish_page ();
+}
+
+
+int
+main (int argc, char **argv)
+{
+  int last_argc = -1;
+
+  opt_source = "GNU";
+  opt_release = "";
+
+  /* Define default macros.  The trick is that these macros are not
+     defined when using the actual texinfo renderer. */
+  add_predefined_macro ("isman");
+  add_predefined_macro ("manverb");
+
+  /* Option parsing.  */
+  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: " PGM " [OPTION] [FILE]\n"
+                "Extract man pages from a Texinfo source.\n\n"
+                "  --source NAME    use NAME as source field\n"
+                "  --release STRING use STRING as the release field\n"
+                "  --store          write output using @manpage name\n"
+                "  --select NAME    only output pages with @manpage NAME\n"
+                "  --verbose        enable extra informational output\n"
+                "  --debug          enable additional debug output\n"
+                "  --help           display this help and exit\n"
+                "  -I DIR           also search in include DIR\n"
+                "  -D gpgone        the only useable define\n\n"
+                "With no FILE, or when FILE is -, read standard input.\n\n"
+                "Report bugs to <bugs@g10code.com>.");
+          exit (0);
+        }
+      else if (!strcmp (*argv, "--version"))
+        {
+          puts (PGM " " VERSION "\n"
+               "Copyright (C) 2005 g10 Code GmbH\n"
+               "This program comes with ABSOLUTELY NO WARRANTY.\n"
+               "This is free software, and you are welcome to redistribute it\n"
+                "under certain conditions. See the file COPYING for details.");
+          exit (0);
+        }
+      else if (!strcmp (*argv, "--verbose"))
+        {
+          verbose = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--quiet"))
+        {
+          quiet = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--debug"))
+        {
+          verbose = debug = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--source"))
+        {
+          argc--; argv++;
+          if (argc)
+            {
+              opt_source = *argv;
+              argc--; argv++;
+            }
+        }
+      else if (!strcmp (*argv, "--release"))
+        {
+          argc--; argv++;
+          if (argc)
+            {
+              opt_release = *argv;
+              argc--; argv++;
+            }
+        }
+      else if (!strcmp (*argv, "--store"))
+        {
+          opt_store = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--select"))
+        {
+          argc--; argv++;
+          if (argc)
+            {
+              opt_select = strrchr (*argv, '/');
+              if (opt_select)
+                opt_select++;
+              else
+                opt_select = *argv;
+              argc--; argv++;
+            }
+        }
+      else if (!strcmp (*argv, "-I"))
+        {
+          argc--; argv++;
+          if (argc)
+            {
+              opt_include = *argv;
+              argc--; argv++;
+            }
+        }
+      else if (!strcmp (*argv, "-D"))
+        {
+          argc--; argv++;
+          if (argc)
+            {
+              add_predefined_macro (*argv);
+              argc--; argv++;
+            }
+        }
+    }
+
+  if (argc > 1)
+    die ("usage: " PGM " [OPTION] [FILE] (try --help for more information)\n");
+
+  /* Start processing. */
+  if (argc && strcmp (*argv, "-"))
+    {
+      FILE *fp = fopen (*argv, "rb");
+      if (!fp)
+        die ("%s:0: can't open file: %s", *argv, strerror (errno));
+      top_parse_file (*argv, fp);
+      fclose (fp);
+    }
+  else
+    top_parse_file ("-", stdin);
+
+  return !!any_error;
+}
+
+
+/*
+Local Variables:
+compile-command: "gcc -Wall -g -Wall -o yat2m yat2m.c"
+End:
+*/
similarity index 73%
rename from m4/ChangeLog
rename to m4/ChangeLog-2011
index 1537fca..2b5100a 100644 (file)
@@ -1,3 +1,10 @@
+2011-12-01  Werner Koch  <wk@g10code.com>
+
+       NB: ChangeLog files are no longer manually maintained.  Starting
+       on December 1st, 2011 we put change information only in the GIT
+       commit log, and generate a top-level ChangeLog file from logs at
+       "make dist".  See doc/HACKING for details.
+
 2011-02-23  Werner Koch  <wk@g10code.com>
 
        * gpg-error.m4: New.  Take from current gpg-error master.
@@ -37,3 +44,7 @@
 2003-12-08  Werner Koch  <wk@gnupg.org>
 
        * libtool.m4: New.
+
+Local Variables:
+buffer-read-only: t
+End:
index 0c90875..0ee9ba7 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
+EXTRA_DIST += gpg-error.m4 lock.m4 threadlib.m4
index 2fbb056..fea19c7 100644 (file)
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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; \
+    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;; \
+    esac; \
+    test $$am__dry = yes; \
+  }
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -34,26 +51,39 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = m4
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ChangeLog
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.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/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/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
        $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
-       $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+       $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/acinclude.m4 \
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
+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_at = $(am__v_at_@AM_V@)
+am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
+am__v_at_0 = @
 SOURCES =
 DIST_SOURCES =
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AR = @AR@
 AS = @AS@
 AUTOCONF = @AUTOCONF@
@@ -68,6 +98,7 @@ CCAS = @CCAS@
 CCASDEPMODE = @CCASDEPMODE@
 CCASFLAGS = @CCASFLAGS@
 CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
@@ -87,6 +118,8 @@ FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
 FGREP = @FGREP@
 GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
 GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_HWF_MODULES = @GCRYPT_HWF_MODULES@
+GCRYPT_KDFS = @GCRYPT_KDFS@
 GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
 GCRYPT_RANDOM = @GCRYPT_RANDOM@
 GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
@@ -112,14 +145,19 @@ 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@
 MKDIR_P = @MKDIR_P@
 MPI_SFLAGS = @MPI_SFLAGS@
 NM = @NM@
@@ -142,16 +180,19 @@ PTH_CONFIG = @PTH_CONFIG@
 PTH_LIBS = @PTH_LIBS@
 RANLIB = @RANLIB@
 RC = @RC@
+RUN_LARGE_DATA_TESTS = @RUN_LARGE_DATA_TESTS@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
 SYS_SOCKET_H = @SYS_SOCKET_H@
 VERSION = @VERSION@
+VERSION_NUMBER = @VERSION_NUMBER@
 abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
@@ -187,7 +228,6 @@ libdir = @libdir@
 libexecdir = @libexecdir@
 localedir = @localedir@
 localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 oldincludedir = @oldincludedir@
@@ -204,7 +244,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
+       noexecstack.m4 gpg-error.m4 lock.m4 threadlib.m4
 all: all-am
 
 .SUFFIXES:
@@ -295,10 +335,15 @@ install-am: all-am
 
 installcheck: installcheck-am
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-         `test -z '$(STRIP)' || \
-           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+       if test -z '$(STRIP)'; then \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+             install; \
+       else \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+           "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+       fi
 mostlyclean-generic:
 
 clean-generic:
index 8d82925..eb5d7c4 100644 (file)
@@ -14,10 +14,21 @@ dnl                   [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND ]]])
 dnl Test for libgpg-error and define GPG_ERROR_CFLAGS and GPG_ERROR_LIBS
 dnl
 AC_DEFUN([AM_PATH_GPG_ERROR],
-[ AC_ARG_WITH(gpg-error-prefix,
-            AC_HELP_STRING([--with-gpg-error-prefix=PFX],
+[
+  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="")
+
+  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="")
+
   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
index 1e7ea47..1d62b05 100644 (file)
@@ -1,7 +1,8 @@
 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
 #
 #   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
-#                 2006, 2007, 2008 Free Software Foundation, Inc.
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
 #   Written by Gordon Matzigkeit, 1996
 #
 # This file is free software; the Free Software Foundation gives
@@ -10,7 +11,8 @@
 
 m4_define([_LT_COPYING], [dnl
 #   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
-#                 2006, 2007, 2008 Free Software Foundation, Inc.
+#                 2006, 2007, 2008, 2009, 2010, 2011 Free Software
+#                 Foundation, Inc.
 #   Written by Gordon Matzigkeit, 1996
 #
 #   This file is part of GNU Libtool.
@@ -37,7 +39,7 @@ m4_define([_LT_COPYING], [dnl
 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 ])
 
-# serial 56 LT_INIT
+# serial 57 LT_INIT
 
 
 # LT_PREREQ(VERSION)
@@ -66,6 +68,7 @@ esac
 # ------------------
 AC_DEFUN([LT_INIT],
 [AC_PREREQ([2.58])dnl We use AC_INCLUDES_DEFAULT
+AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl
 AC_BEFORE([$0], [LT_LANG])dnl
 AC_BEFORE([$0], [LT_OUTPUT])dnl
 AC_BEFORE([$0], [LTDL_INIT])dnl
@@ -82,6 +85,8 @@ AC_REQUIRE([LTVERSION_VERSION])dnl
 AC_REQUIRE([LTOBSOLETE_VERSION])dnl
 m4_require([_LT_PROG_LTMAIN])dnl
 
+_LT_SHELL_INIT([SHELL=${CONFIG_SHELL-/bin/sh}])
+
 dnl Parse OPTIONS
 _LT_SET_OPTIONS([$0], [$1])
 
@@ -118,7 +123,7 @@ m4_defun([_LT_CC_BASENAME],
     *) break;;
   esac
 done
-cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"`
+cc_basename=`$ECHO "$cc_temp" | $SED "s%.*/%%; s%^$host_alias-%%"`
 ])
 
 
@@ -138,6 +143,11 @@ m4_defun([_LT_FILEUTILS_DEFAULTS],
 m4_defun([_LT_SETUP],
 [AC_REQUIRE([AC_CANONICAL_HOST])dnl
 AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([_LT_PREPARE_SED_QUOTE_VARS])dnl
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])dnl
+
+_LT_DECL([], [PATH_SEPARATOR], [1], [The PATH separator for the build system])dnl
+dnl
 _LT_DECL([], [host_alias], [0], [The host system])dnl
 _LT_DECL([], [host], [0])dnl
 _LT_DECL([], [host_os], [0])dnl
@@ -160,10 +170,13 @@ _LT_DECL([], [exeext], [0], [Executable file suffix (normally "")])dnl
 dnl
 m4_require([_LT_FILEUTILS_DEFAULTS])dnl
 m4_require([_LT_CHECK_SHELL_FEATURES])dnl
+m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl
 m4_require([_LT_CMD_RELOAD])dnl
 m4_require([_LT_CHECK_MAGIC_METHOD])dnl
+m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl
 m4_require([_LT_CMD_OLD_ARCHIVE])dnl
 m4_require([_LT_CMD_GLOBAL_SYMBOLS])dnl
+m4_require([_LT_WITH_SYSROOT])dnl
 
 _LT_CONFIG_LIBTOOL_INIT([
 # See if we are running on zsh, and set the options which allow our
@@ -179,7 +192,6 @@ fi
 _LT_CHECK_OBJDIR
 
 m4_require([_LT_TAG_COMPILER])dnl
-_LT_PROG_ECHO_BACKSLASH
 
 case $host_os in
 aix3*)
@@ -193,23 +205,6 @@ aix3*)
   ;;
 esac
 
-# Sed substitution that helps us do robust quoting.  It backslashifies
-# metacharacters that are still active within double-quoted strings.
-sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
-
-# Same as above, but do not quote variable references.
-double_quote_subst='s/\([["`\\]]\)/\\\1/g'
-
-# Sed substitution to delay expansion of an escaped shell variable in a
-# double_quote_subst'ed string.
-delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
-
-# Sed substitution to delay expansion of an escaped single quote.
-delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
-
-# Sed substitution to avoid accidental globbing in evaled expressions
-no_glob_subst='s/\*/\\\*/g'
-
 # Global variables:
 ofile=libtool
 can_build_shared=yes
@@ -250,6 +245,28 @@ _LT_CONFIG_COMMANDS
 ])# _LT_SETUP
 
 
+# _LT_PREPARE_SED_QUOTE_VARS
+# --------------------------
+# Define a few sed substitution that help us do robust quoting.
+m4_defun([_LT_PREPARE_SED_QUOTE_VARS],
+[# Backslashify metacharacters that are still active within
+# double-quoted strings.
+sed_quote_subst='s/\([["`$\\]]\)/\\\1/g'
+
+# Same as above, but do not quote variable references.
+double_quote_subst='s/\([["`\\]]\)/\\\1/g'
+
+# Sed substitution to delay expansion of an escaped shell variable in a
+# double_quote_subst'ed string.
+delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g'
+
+# Sed substitution to delay expansion of an escaped single quote.
+delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g'
+
+# Sed substitution to avoid accidental globbing in evaled expressions
+no_glob_subst='s/\*/\\\*/g'
+])
+
 # _LT_PROG_LTMAIN
 # ---------------
 # Note that this code is called both from `configure', and `config.status'
@@ -408,7 +425,7 @@ m4_define([_lt_decl_all_varnames],
 # declaration there will have the same value as in `configure'.  VARNAME
 # must have a single quote delimited value for this to work.
 m4_define([_LT_CONFIG_STATUS_DECLARE],
-[$1='`$ECHO "X$][$1" | $Xsed -e "$delay_single_quote_subst"`'])
+[$1='`$ECHO "$][$1" | $SED "$delay_single_quote_subst"`'])
 
 
 # _LT_CONFIG_STATUS_DECLARATIONS
@@ -418,7 +435,7 @@ m4_define([_LT_CONFIG_STATUS_DECLARE],
 # embedded single quotes properly.  In configure, this macro expands
 # each variable declared with _LT_DECL (and _LT_TAGDECL) into:
 #
-#    <var>='`$ECHO "X$<var>" | $Xsed -e "$delay_single_quote_subst"`'
+#    <var>='`$ECHO "$<var>" | $SED "$delay_single_quote_subst"`'
 m4_defun([_LT_CONFIG_STATUS_DECLARATIONS],
 [m4_foreach([_lt_var], m4_quote(lt_decl_all_varnames),
     [m4_n([_LT_CONFIG_STATUS_DECLARE(_lt_var)])])])
@@ -517,12 +534,20 @@ LTCC='$LTCC'
 LTCFLAGS='$LTCFLAGS'
 compiler='$compiler_DEFAULT'
 
+# A function that is used when there is no print builtin or printf.
+func_fallback_echo ()
+{
+  eval 'cat <<_LTECHO_EOF
+\$[]1
+_LTECHO_EOF'
+}
+
 # Quote evaled strings.
 for var in lt_decl_all_varnames([[ \
 ]], lt_decl_quote_varnames); do
-    case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
     *[[\\\\\\\`\\"\\\$]]*)
-      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED \\"\\\$sed_quote_subst\\"\\\`\\\\\\""
       ;;
     *)
       eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -533,9 +558,9 @@ done
 # Double-quote double-evaled strings.
 for var in lt_decl_all_varnames([[ \
 ]], lt_decl_dquote_varnames); do
-    case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in
+    case \`eval \\\\\$ECHO \\\\""\\\\\$\$var"\\\\"\` in
     *[[\\\\\\\`\\"\\\$]]*)
-      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
+      eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"\\\$\$var\\" | \\\$SED -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\""
       ;;
     *)
       eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\""
@@ -543,16 +568,38 @@ for var in lt_decl_all_varnames([[ \
     esac
 done
 
-# Fix-up fallback echo if it was mangled by the above quoting rules.
-case \$lt_ECHO in
-*'\\\[$]0 --fallback-echo"')dnl "
-  lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\[$]0 --fallback-echo"\[$]/\[$]0 --fallback-echo"/'\`
-  ;;
-esac
-
 _LT_OUTPUT_LIBTOOL_INIT
 ])
 
+# _LT_GENERATED_FILE_INIT(FILE, [COMMENT])
+# ------------------------------------
+# Generate a child script FILE with all initialization necessary to
+# reuse the environment learned by the parent script, and make the
+# file executable.  If COMMENT is supplied, it is inserted after the
+# `#!' sequence but before initialization text begins.  After this
+# macro, additional text can be appended to FILE to form the body of
+# the child script.  The macro ends with non-zero status if the
+# file could not be fully written (such as if the disk is full).
+m4_ifdef([AS_INIT_GENERATED],
+[m4_defun([_LT_GENERATED_FILE_INIT],[AS_INIT_GENERATED($@)])],
+[m4_defun([_LT_GENERATED_FILE_INIT],
+[m4_require([AS_PREPARE])]dnl
+[m4_pushdef([AS_MESSAGE_LOG_FD])]dnl
+[lt_write_fail=0
+cat >$1 <<_ASEOF || lt_write_fail=1
+#! $SHELL
+# Generated by $as_me.
+$2
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$1 <<\_ASEOF || lt_write_fail=1
+AS_SHELL_SANITIZE
+_AS_PREPARE
+exec AS_MESSAGE_FD>&1
+_ASEOF
+test $lt_write_fail = 0 && chmod +x $1[]dnl
+m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_GENERATED_FILE_INIT
 
 # LT_OUTPUT
 # ---------
@@ -562,20 +609,11 @@ _LT_OUTPUT_LIBTOOL_INIT
 AC_DEFUN([LT_OUTPUT],
 [: ${CONFIG_LT=./config.lt}
 AC_MSG_NOTICE([creating $CONFIG_LT])
-cat >"$CONFIG_LT" <<_LTEOF
-#! $SHELL
-# Generated by $as_me.
-# Run this file to recreate a libtool stub with the current configuration.
-
-lt_cl_silent=false
-SHELL=\${CONFIG_SHELL-$SHELL}
-_LTEOF
+_LT_GENERATED_FILE_INIT(["$CONFIG_LT"],
+[# Run this file to recreate a libtool stub with the current configuration.])
 
 cat >>"$CONFIG_LT" <<\_LTEOF
-AS_SHELL_SANITIZE
-_AS_PREPARE
-
-exec AS_MESSAGE_FD>&1
+lt_cl_silent=false
 exec AS_MESSAGE_LOG_FD>>config.log
 {
   echo
@@ -601,7 +639,7 @@ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_NAME ])config.lt[]dnl
 m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION])
 configured by $[0], generated by m4_PACKAGE_STRING.
 
-Copyright (C) 2008 Free Software Foundation, Inc.
+Copyright (C) 2011 Free Software Foundation, Inc.
 This config.lt script is free software; the Free Software Foundation
 gives unlimited permision to copy, distribute and modify it."
 
@@ -646,15 +684,13 @@ chmod +x "$CONFIG_LT"
 # appending to config.log, which fails on DOS, as config.log is still kept
 # open by configure.  Here we exec the FD to /dev/null, effectively closing
 # config.log, so it can be properly (re)opened and appended to by config.lt.
-if test "$no_create" != yes; then
-  lt_cl_success=:
-  test "$silent" = yes &&
-    lt_config_lt_args="$lt_config_lt_args --quiet"
-  exec AS_MESSAGE_LOG_FD>/dev/null
-  $SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
-  exec AS_MESSAGE_LOG_FD>>config.log
-  $lt_cl_success || AS_EXIT(1)
-fi
+lt_cl_success=:
+test "$silent" = yes &&
+  lt_config_lt_args="$lt_config_lt_args --quiet"
+exec AS_MESSAGE_LOG_FD>/dev/null
+$SHELL "$CONFIG_LT" $lt_config_lt_args || lt_cl_success=false
+exec AS_MESSAGE_LOG_FD>>config.log
+$lt_cl_success || AS_EXIT(1)
 ])# LT_OUTPUT
 
 
@@ -717,15 +753,12 @@ _LT_EOF
   # if finds mixed CR/LF and LF-only lines.  Since sed operates in
   # text mode, it properly converts lines to CR/LF.  This bash problem
   # is reportedly fixed, but why not run on old versions too?
-  sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \
-    || (rm -f "$cfgfile"; exit 1)
-
-  _LT_PROG_XSI_SHELLFNS
+  sed '$q' "$ltmain" >> "$cfgfile" \
+     || (rm -f "$cfgfile"; exit 1)
 
-  sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \
-    || (rm -f "$cfgfile"; exit 1)
+  _LT_PROG_REPLACE_SHELLFNS
 
-  mv -f "$cfgfile" "$ofile" ||
+   mv -f "$cfgfile" "$ofile" ||
     (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile")
   chmod +x "$ofile"
 ],
@@ -770,6 +803,7 @@ AC_DEFUN([LT_LANG],
 m4_case([$1],
   [C],                 [_LT_LANG(C)],
   [C++],               [_LT_LANG(CXX)],
+  [Go],                        [_LT_LANG(GO)],
   [Java],              [_LT_LANG(GCJ)],
   [Fortran 77],                [_LT_LANG(F77)],
   [Fortran],           [_LT_LANG(FC)],
@@ -791,6 +825,31 @@ m4_defun([_LT_LANG],
 ])# _LT_LANG
 
 
+m4_ifndef([AC_PROG_GO], [
+############################################################
+# NOTE: This macro has been submitted for inclusion into   #
+#  GNU Autoconf as AC_PROG_GO.  When it is available in    #
+#  a released version of Autoconf we should remove this    #
+#  macro and use it instead.                               #
+############################################################
+m4_defun([AC_PROG_GO],
+[AC_LANG_PUSH(Go)dnl
+AC_ARG_VAR([GOC],     [Go compiler command])dnl
+AC_ARG_VAR([GOFLAGS], [Go compiler flags])dnl
+_AC_ARG_VAR_LDFLAGS()dnl
+AC_CHECK_TOOL(GOC, gccgo)
+if test -z "$GOC"; then
+  if test -n "$ac_tool_prefix"; then
+    AC_CHECK_PROG(GOC, [${ac_tool_prefix}gccgo], [${ac_tool_prefix}gccgo])
+  fi
+fi
+if test -z "$GOC"; then
+  AC_CHECK_PROG(GOC, gccgo, gccgo, false)
+fi
+])#m4_defun
+])#m4_ifndef
+
+
 # _LT_LANG_DEFAULT_CONFIG
 # -----------------------
 m4_defun([_LT_LANG_DEFAULT_CONFIG],
@@ -821,6 +880,10 @@ AC_PROVIDE_IFELSE([AC_PROG_GCJ],
        m4_ifdef([LT_PROG_GCJ],
        [m4_define([LT_PROG_GCJ], defn([LT_PROG_GCJ])[LT_LANG(GCJ)])])])])])
 
+AC_PROVIDE_IFELSE([AC_PROG_GO],
+  [LT_LANG(GO)],
+  [m4_define([AC_PROG_GO], defn([AC_PROG_GO])[LT_LANG(GO)])])
+
 AC_PROVIDE_IFELSE([LT_PROG_RC],
   [LT_LANG(RC)],
   [m4_define([LT_PROG_RC], defn([LT_PROG_RC])[LT_LANG(RC)])])
@@ -831,11 +894,13 @@ AU_DEFUN([AC_LIBTOOL_CXX], [LT_LANG(C++)])
 AU_DEFUN([AC_LIBTOOL_F77], [LT_LANG(Fortran 77)])
 AU_DEFUN([AC_LIBTOOL_FC], [LT_LANG(Fortran)])
 AU_DEFUN([AC_LIBTOOL_GCJ], [LT_LANG(Java)])
+AU_DEFUN([AC_LIBTOOL_RC], [LT_LANG(Windows Resource)])
 dnl aclocal-1.4 backwards compatibility:
 dnl AC_DEFUN([AC_LIBTOOL_CXX], [])
 dnl AC_DEFUN([AC_LIBTOOL_F77], [])
 dnl AC_DEFUN([AC_LIBTOOL_FC], [])
 dnl AC_DEFUN([AC_LIBTOOL_GCJ], [])
+dnl AC_DEFUN([AC_LIBTOOL_RC], [])
 
 
 # _LT_TAG_COMPILER
@@ -921,7 +986,13 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
        $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \
          -dynamiclib -Wl,-single_module conftest.c 2>conftest.err
         _lt_result=$?
-       if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then
+       # If there is a non-empty error log, and "single_module"
+       # appears in it, assume the flag caused a linker warning
+        if test -s conftest.err && $GREP single_module conftest.err; then
+         cat conftest.err >&AS_MESSAGE_LOG_FD
+       # Otherwise, if the output was created with a 0 exit code from
+       # the compiler, it worked.
+       elif test -f libconftest.dylib && test $_lt_result -eq 0; then
          lt_cv_apple_cc_single_mod=yes
        else
          cat conftest.err >&AS_MESSAGE_LOG_FD
@@ -929,6 +1000,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
        rm -rf libconftest.dylib*
        rm -f conftest.*
       fi])
+
     AC_CACHE_CHECK([for -exported_symbols_list linker flag],
       [lt_cv_ld_exported_symbols_list],
       [lt_cv_ld_exported_symbols_list=no
@@ -940,6 +1012,34 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
        [lt_cv_ld_exported_symbols_list=no])
        LDFLAGS="$save_LDFLAGS"
     ])
+
+    AC_CACHE_CHECK([for -force_load linker flag],[lt_cv_ld_force_load],
+      [lt_cv_ld_force_load=no
+      cat > conftest.c << _LT_EOF
+int forced_loaded() { return 2;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD
+      $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD
+      echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD
+      $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD
+      echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD
+      $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD
+      cat > conftest.c << _LT_EOF
+int main() { return 0;}
+_LT_EOF
+      echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD
+      $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err
+      _lt_result=$?
+      if test -s conftest.err && $GREP force_load conftest.err; then
+       cat conftest.err >&AS_MESSAGE_LOG_FD
+      elif test -f conftest && test $_lt_result -eq 0 && $GREP forced_load conftest >/dev/null 2>&1 ; then
+       lt_cv_ld_force_load=yes
+      else
+       cat conftest.err >&AS_MESSAGE_LOG_FD
+      fi
+        rm -f conftest.err libconftest.a conftest conftest.c
+        rm -rf conftest.dSYM
+    ])
     case $host_os in
     rhapsody* | darwin1.[[012]])
       _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;;
@@ -967,7 +1067,7 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
     else
       _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}'
     fi
-    if test "$DSYMUTIL" != ":"; then
+    if test "$DSYMUTIL" != ":" && test "$lt_cv_ld_force_load" = "no"; then
       _lt_dsymutil='~$DSYMUTIL $lib || :'
     else
       _lt_dsymutil=
@@ -977,8 +1077,8 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[
 ])
 
 
-# _LT_DARWIN_LINKER_FEATURES
-# --------------------------
+# _LT_DARWIN_LINKER_FEATURES([TAG])
+# ---------------------------------
 # Checks for linker and compiler features on darwin
 m4_defun([_LT_DARWIN_LINKER_FEATURES],
 [
@@ -987,7 +1087,13 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
   _LT_TAGVAR(hardcode_direct, $1)=no
   _LT_TAGVAR(hardcode_automatic, $1)=yes
   _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
-  _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+  if test "$lt_cv_ld_force_load" = "yes"; then
+    _LT_TAGVAR(whole_archive_flag_spec, $1)='`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience ${wl}-force_load,$conv\"; done; func_echo_all \"$new_convenience\"`'
+    m4_case([$1], [F77], [_LT_TAGVAR(compiler_needs_object, $1)=yes],
+                  [FC],  [_LT_TAGVAR(compiler_needs_object, $1)=yes])
+  else
+    _LT_TAGVAR(whole_archive_flag_spec, $1)=''
+  fi
   _LT_TAGVAR(link_all_deplibs, $1)=yes
   _LT_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined"
   case $cc_basename in
@@ -995,7 +1101,7 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
      *) _lt_dar_can_shared=$GCC ;;
   esac
   if test "$_lt_dar_can_shared" = "yes"; then
-    output_verbose_link_cmd=echo
+    output_verbose_link_cmd=func_echo_all
     _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}"
     _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}"
     _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}"
@@ -1011,203 +1117,142 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES],
   fi
 ])
 
-# _LT_SYS_MODULE_PATH_AIX
-# -----------------------
+# _LT_SYS_MODULE_PATH_AIX([TAGNAME])
+# ----------------------------------
 # Links a minimal program and checks the executable
 # for the system default hardcoded library path. In most cases,
 # this is /usr/lib:/lib, but when the MPI compilers are used
 # the location of the communication and MPI libs are included too.
 # If we don't find anything, use the default library path according
 # to the aix ld manual.
+# Store the results from the different compilers for each TAGNAME.
+# Allow to override them for all tags through lt_cv_aix_libpath.
 m4_defun([_LT_SYS_MODULE_PATH_AIX],
 [m4_require([_LT_DECL_SED])dnl
-AC_LINK_IFELSE(AC_LANG_PROGRAM,[
-lt_aix_libpath_sed='
-    /Import File Strings/,/^$/ {
-       /^0/ {
-           s/^0  *\(.*\)$/\1/
-           p
-       }
-    }'
-aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-# Check for a 64-bit object if we didn't find anything.
-if test -z "$aix_libpath"; then
-  aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
-fi],[])
-if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi
+if test "${lt_cv_aix_libpath+set}" = set; then
+  aix_libpath=$lt_cv_aix_libpath
+else
+  AC_CACHE_VAL([_LT_TAGVAR([lt_cv_aix_libpath_], [$1])],
+  [AC_LINK_IFELSE([AC_LANG_PROGRAM],[
+  lt_aix_libpath_sed='[
+      /Import File Strings/,/^$/ {
+         /^0/ {
+             s/^0  *\([^ ]*\) *$/\1/
+             p
+         }
+      }]'
+  _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  # Check for a 64-bit object if we didn't find anything.
+  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"`
+  fi],[])
+  if test -z "$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])"; then
+    _LT_TAGVAR([lt_cv_aix_libpath_], [$1])="/usr/lib:/lib"
+  fi
+  ])
+  aix_libpath=$_LT_TAGVAR([lt_cv_aix_libpath_], [$1])
+fi
 ])# _LT_SYS_MODULE_PATH_AIX
 
 
 # _LT_SHELL_INIT(ARG)
 # -------------------
 m4_define([_LT_SHELL_INIT],
-[ifdef([AC_DIVERSION_NOTICE],
-            [AC_DIVERT_PUSH(AC_DIVERSION_NOTICE)],
-        [AC_DIVERT_PUSH(NOTICE)])
-$1
-AC_DIVERT_POP
-])# _LT_SHELL_INIT
+[m4_divert_text([M4SH-INIT], [$1
+])])# _LT_SHELL_INIT
+
 
 
 # _LT_PROG_ECHO_BACKSLASH
 # -----------------------
-# Add some code to the start of the generated configure script which
-# will find an echo command which doesn't interpret backslashes.
+# Find how we can fake an echo command that does not interpret backslash.
+# In particular, with Autoconf 2.60 or later we add some code to the start
+# of the generated configure script which will find a shell with a builtin
+# printf (which we can use as an echo command).
 m4_defun([_LT_PROG_ECHO_BACKSLASH],
-[_LT_SHELL_INIT([
-# Check that we are running under the correct shell.
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-case X$lt_ECHO in
-X*--fallback-echo)
-  # Remove one level of quotation (which was required for Make).
-  ECHO=`echo "$lt_ECHO" | sed 's,\\\\\[$]\\[$]0,'[$]0','`
-  ;;
-esac
-
-ECHO=${lt_ECHO-echo}
-if test "X[$]1" = X--no-reexec; then
-  # Discard the --no-reexec flag, and continue.
-  shift
-elif test "X[$]1" = X--fallback-echo; then
-  # Avoid inline document here, it may be left over
-  :
-elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then
-  # Yippee, $ECHO works!
-  :
+[ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+
+AC_MSG_CHECKING([how to print strings])
+# Test print first, because it will be a builtin if present.
+if test "X`( print -r -- -n ) 2>/dev/null`" = X-n && \
+   test "X`print -r -- $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='print -r --'
+elif test "X`printf %s $ECHO 2>/dev/null`" = "X$ECHO"; then
+  ECHO='printf %s\n'
 else
-  # Restart under the correct shell.
-  exec $SHELL "[$]0" --no-reexec ${1+"[$]@"}
-fi
-
-if test "X[$]1" = X--fallback-echo; then
-  # used as fallback echo
-  shift
-  cat <<_LT_EOF
-[$]*
-_LT_EOF
-  exit 0
+  # Use this function as a fallback that always works.
+  func_fallback_echo ()
+  {
+    eval 'cat <<_LTECHO_EOF
+$[]1
+_LTECHO_EOF'
+  }
+  ECHO='func_fallback_echo'
 fi
 
-# The HP-UX ksh and POSIX shell print the target directory to stdout
-# if CDPATH is set.
-(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
-
-if test -z "$lt_ECHO"; then
-  if test "X${echo_test_string+set}" != Xset; then
-    # find a string as large as possible, as long as the shell can cope with it
-    for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do
-      # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ...
-      if { echo_test_string=`eval $cmd`; } 2>/dev/null &&
-        { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null
-      then
-        break
-      fi
-    done
-  fi
-
-  if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
-     echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
-     test "X$echo_testing_string" = "X$echo_test_string"; then
-    :
-  else
-    # The Solaris, AIX, and Digital Unix default echo programs unquote
-    # backslashes.  This makes it impossible to quote backslashes using
-    #   echo "$something" | sed 's/\\/\\\\/g'
-    #
-    # So, first we look for a working echo in the user's PATH.
-
-    lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR
-    for dir in $PATH /usr/ucb; do
-      IFS="$lt_save_ifs"
-      if (test -f $dir/echo || test -f $dir/echo$ac_exeext) &&
-         test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' &&
-         echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` &&
-         test "X$echo_testing_string" = "X$echo_test_string"; then
-        ECHO="$dir/echo"
-        break
-      fi
-    done
-    IFS="$lt_save_ifs"
-
-    if test "X$ECHO" = Xecho; then
-      # We didn't find a better echo, so look for alternatives.
-      if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' &&
-         echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` &&
-         test "X$echo_testing_string" = "X$echo_test_string"; then
-        # This shell has a builtin print -r that does the trick.
-        ECHO='print -r'
-      elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } &&
-          test "X$CONFIG_SHELL" != X/bin/ksh; then
-        # If we have ksh, try running configure again with it.
-        ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh}
-        export ORIGINAL_CONFIG_SHELL
-        CONFIG_SHELL=/bin/ksh
-        export CONFIG_SHELL
-        exec $CONFIG_SHELL "[$]0" --no-reexec ${1+"[$]@"}
-      else
-        # Try using printf.
-        ECHO='printf %s\n'
-        if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' &&
-          echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` &&
-          test "X$echo_testing_string" = "X$echo_test_string"; then
-         # Cool, printf works
-         :
-        elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
-            test "X$echo_testing_string" = 'X\t' &&
-            echo_testing_string=`($ORIGINAL_CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
-            test "X$echo_testing_string" = "X$echo_test_string"; then
-         CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL
-         export CONFIG_SHELL
-         SHELL="$CONFIG_SHELL"
-         export SHELL
-         ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
-        elif echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo '\t') 2>/dev/null` &&
-            test "X$echo_testing_string" = 'X\t' &&
-            echo_testing_string=`($CONFIG_SHELL "[$]0" --fallback-echo "$echo_test_string") 2>/dev/null` &&
-            test "X$echo_testing_string" = "X$echo_test_string"; then
-         ECHO="$CONFIG_SHELL [$]0 --fallback-echo"
-        else
-         # maybe with a smaller string...
-         prev=:
-
-         for cmd in 'echo test' 'sed 2q "[$]0"' 'sed 10q "[$]0"' 'sed 20q "[$]0"' 'sed 50q "[$]0"'; do
-           if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null
-           then
-             break
-           fi
-           prev="$cmd"
-         done
+# func_echo_all arg...
+# Invoke $ECHO with all args, space-separated.
+func_echo_all ()
+{
+    $ECHO "$*"
+}
 
-         if test "$prev" != 'sed 50q "[$]0"'; then
-           echo_test_string=`eval $prev`
-           export echo_test_string
-           exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "[$]0" ${1+"[$]@"}
-         else
-           # Oops.  We lost completely, so just stick with echo.
-           ECHO=echo
-         fi
-        fi
-      fi
-    fi
-  fi
-fi
+case "$ECHO" in
+  printf*) AC_MSG_RESULT([printf]) ;;
+  print*) AC_MSG_RESULT([print -r]) ;;
+  *) AC_MSG_RESULT([cat]) ;;
+esac
 
-# Copy echo and quote the copy suitably for passing to libtool from
-# the Makefile, instead of quoting the original, which is used later.
-lt_ECHO=$ECHO
-if test "X$lt_ECHO" = "X$CONFIG_SHELL [$]0 --fallback-echo"; then
-   lt_ECHO="$CONFIG_SHELL \\\$\[$]0 --fallback-echo"
-fi
+m4_ifdef([_AS_DETECT_SUGGESTED],
+[_AS_DETECT_SUGGESTED([
+  test -n "${ZSH_VERSION+set}${BASH_VERSION+set}" || (
+    ECHO='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO
+    ECHO=$ECHO$ECHO$ECHO$ECHO$ECHO$ECHO
+    PATH=/empty FPATH=/empty; export PATH FPATH
+    test "X`printf %s $ECHO`" = "X$ECHO" \
+      || test "X`print -r -- $ECHO`" = "X$ECHO" )])])
 
-AC_SUBST(lt_ECHO)
-])
 _LT_DECL([], [SHELL], [1], [Shell to use when invoking shell scripts])
-_LT_DECL([], [ECHO], [1],
-    [An echo program that does not interpret backslashes])
+_LT_DECL([], [ECHO], [1], [An echo program that protects backslashes])
 ])# _LT_PROG_ECHO_BACKSLASH
 
 
+# _LT_WITH_SYSROOT
+# ----------------
+AC_DEFUN([_LT_WITH_SYSROOT],
+[AC_MSG_CHECKING([for sysroot])
+AC_ARG_WITH([sysroot],
+[  --with-sysroot[=DIR] Search for dependent libraries within DIR
+                        (or the compiler's sysroot if not specified).],
+[], [with_sysroot=no])
+
+dnl lt_sysroot will always be passed unquoted.  We quote it here
+dnl in case the user passed a directory name.
+lt_sysroot=
+case ${with_sysroot} in #(
+ yes)
+   if test "$GCC" = yes; then
+     lt_sysroot=`$CC --print-sysroot 2>/dev/null`
+   fi
+   ;; #(
+ /*)
+   lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"`
+   ;; #(
+ no|'')
+   ;; #(
+ *)
+   AC_MSG_RESULT([${with_sysroot}])
+   AC_MSG_ERROR([The sysroot must be an absolute path.])
+   ;;
+esac
+
+ AC_MSG_RESULT([${lt_sysroot:-no}])
+_LT_DECL([], [lt_sysroot], [0], [The root where to search for ]dnl
+[dependent libraries, and in which our libraries should be installed.])])
+
 # _LT_ENABLE_LOCK
 # ---------------
 m4_defun([_LT_ENABLE_LOCK],
@@ -1236,7 +1281,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+  echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
     if test "$lt_cv_prog_gnu_ld" = yes; then
       case `/usr/bin/file conftest.$ac_objext` in
@@ -1281,7 +1326,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
          x86_64-*linux*)
            LD="${LD-ld} -m elf_i386"
            ;;
-         ppc64-*linux*|powerpc64-*linux*)
+         powerpc64le-*)
+           LD="${LD-ld} -m elf32lppclinux"
+           ;;
+         powerpc64-*)
            LD="${LD-ld} -m elf32ppclinux"
            ;;
          s390x-*linux*)
@@ -1300,7 +1348,10 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
          x86_64-*linux*)
            LD="${LD-ld} -m elf_x86_64"
            ;;
-         ppc*-*linux*|powerpc*-*linux*)
+         powerpcle-*)
+           LD="${LD-ld} -m elf64lppc"
+           ;;
+         powerpc-*)
            LD="${LD-ld} -m elf64ppc"
            ;;
          s390*-*linux*|s390*-*tpf*)
@@ -1329,14 +1380,27 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux*)
     CFLAGS="$SAVE_CFLAGS"
   fi
   ;;
-sparc*-*solaris*)
+*-*solaris*)
   # Find out which ABI we are using.
   echo 'int i;' > conftest.$ac_ext
   if AC_TRY_EVAL(ac_compile); then
     case `/usr/bin/file conftest.o` in
     *64-bit*)
       case $lt_cv_prog_gnu_ld in
-      yes*) LD="${LD-ld} -m elf64_sparc" ;;
+      yes*)
+        case $host in
+        i?86-*-solaris*)
+          LD="${LD-ld} -m elf_x86_64"
+          ;;
+        sparc*-*-solaris*)
+          LD="${LD-ld} -m elf64_sparc"
+          ;;
+        esac
+        # GNU ld 2.21 introduced _sol2 emulations.  Use them if available.
+        if ${LD-ld} -V | grep _sol2 >/dev/null 2>&1; then
+          LD="${LD-ld}_sol2"
+        fi
+        ;;
       *)
        if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then
          LD="${LD-ld} -64"
@@ -1354,14 +1418,47 @@ need_locks="$enable_libtool_lock"
 ])# _LT_ENABLE_LOCK
 
 
+# _LT_PROG_AR
+# -----------
+m4_defun([_LT_PROG_AR],
+[AC_CHECK_TOOLS(AR, [ar], false)
+: ${AR=ar}
+: ${AR_FLAGS=cru}
+_LT_DECL([], [AR], [1], [The archiver])
+_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive])
+
+AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file],
+  [lt_cv_ar_at_file=no
+   AC_COMPILE_IFELSE([AC_LANG_PROGRAM],
+     [echo conftest.$ac_objext > conftest.lst
+      lt_ar_try='$AR $AR_FLAGS libconftest.a @conftest.lst >&AS_MESSAGE_LOG_FD'
+      AC_TRY_EVAL([lt_ar_try])
+      if test "$ac_status" -eq 0; then
+       # Ensure the archiver fails upon bogus file names.
+       rm -f conftest.$ac_objext libconftest.a
+       AC_TRY_EVAL([lt_ar_try])
+       if test "$ac_status" -ne 0; then
+          lt_cv_ar_at_file=@
+        fi
+      fi
+      rm -f conftest.* libconftest.a
+     ])
+  ])
+
+if test "x$lt_cv_ar_at_file" = xno; then
+  archiver_list_spec=
+else
+  archiver_list_spec=$lt_cv_ar_at_file
+fi
+_LT_DECL([], [archiver_list_spec], [1],
+  [How to feed a file listing to the archiver])
+])# _LT_PROG_AR
+
+
 # _LT_CMD_OLD_ARCHIVE
 # -------------------
 m4_defun([_LT_CMD_OLD_ARCHIVE],
-[AC_CHECK_TOOL(AR, ar, false)
-test -z "$AR" && AR=ar
-test -z "$AR_FLAGS" && AR_FLAGS=cru
-_LT_DECL([], [AR], [1], [The archiver])
-_LT_DECL([], [AR_FLAGS], [1])
+[_LT_PROG_AR
 
 AC_CHECK_TOOL(STRIP, strip, :)
 test -z "$STRIP" && STRIP=:
@@ -1380,18 +1477,27 @@ old_postuninstall_cmds=
 if test -n "$RANLIB"; then
   case $host_os in
   openbsd*)
-    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib"
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib"
     ;;
   *)
-    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib"
+    old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib"
     ;;
   esac
-  old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib"
+  old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib"
 fi
+
+case $host_os in
+  darwin*)
+    lock_old_archive_extraction=yes ;;
+  *)
+    lock_old_archive_extraction=no ;;
+esac
 _LT_DECL([], [old_postinstall_cmds], [2])
 _LT_DECL([], [old_postuninstall_cmds], [2])
 _LT_TAGDECL([], [old_archive_cmds], [2],
     [Commands used to build an old-style archive])
+_LT_DECL([], [lock_old_archive_extraction], [0],
+    [Whether to use a lock for old archive extraction])
 ])# _LT_CMD_OLD_ARCHIVE
 
 
@@ -1416,15 +1522,15 @@ AC_CACHE_CHECK([$1], [$2],
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&AS_MESSAGE_LOG_FD
-   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
-     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
      $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
      if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
        $2=yes
@@ -1464,7 +1570,7 @@ AC_CACHE_CHECK([$1], [$2],
      if test -s conftest.err; then
        # Append any errors to the config.log.
        cat conftest.err 1>&AS_MESSAGE_LOG_FD
-       $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp
+       $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp
        $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
        if diff conftest.exp conftest.er2 >/dev/null; then
          $2=yes
@@ -1527,6 +1633,11 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
     lt_cv_sys_max_cmd_len=8192;
     ;;
 
+  mint*)
+    # On MiNT this can take a long time and run out of memory.
+    lt_cv_sys_max_cmd_len=8192;
+    ;;
+
   amigaos*)
     # On AmigaOS with pdksh, this test takes hours, literally.
     # So we just punt and use a minimum line length of 8192.
@@ -1552,6 +1663,11 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
     lt_cv_sys_max_cmd_len=196608
     ;;
 
+  os2*)
+    # The test takes a long time on OS/2.
+    lt_cv_sys_max_cmd_len=8192
+    ;;
+
   osf*)
     # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure
     # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not
@@ -1591,8 +1707,8 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl
       # If test is not a shell built-in, we'll probably end up computing a
       # maximum length that is only half of the actual maximum length, but
       # we can't tell.
-      while { test "X"`$SHELL [$]0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \
-                = "XX$teststring$teststring"; } >/dev/null 2>&1 &&
+      while { test "X"`env echo "$teststring$teststring" 2>/dev/null` \
+                = "X$teststring$teststring"; } >/dev/null 2>&1 &&
              test $i != 17 # 1/2 MB should be enough
       do
         i=`expr $i + 1`
@@ -1643,7 +1759,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-[#line __oline__ "configure"
+[#line $LINENO "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -1684,7 +1800,13 @@ else
 #  endif
 #endif
 
-void fnord() { int i=42;}
+/* When -fvisbility=hidden is used, assume the code has been annotated
+   correspondingly for the symbols needed.  */
+#if defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3))
+int fnord () __attribute__((visibility("default")));
+#endif
+
+int fnord () { return 42; }
 int main ()
 {
   void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW);
@@ -1693,7 +1815,11 @@ int main ()
   if (self)
     {
       if (dlsym (self,"fnord"))       status = $lt_dlno_uscore;
-      else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore;
+      else
+        {
+         if (dlsym( self,"_fnord"))  status = $lt_dlneed_uscore;
+          else puts (dlerror ());
+       }
       /* dlclose (self); */
     }
   else
@@ -1869,16 +1995,16 @@ AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext],
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
+   (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&AS_MESSAGE_LOG_FD)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&AS_MESSAGE_LOG_FD
-   echo "$as_me:__oline__: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
+   echo "$as_me:$LINENO: \$? = $ac_status" >&AS_MESSAGE_LOG_FD
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings
-     $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp
+     $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' > out/conftest.exp
      $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2
      if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then
        _LT_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes
@@ -2037,6 +2163,7 @@ m4_require([_LT_DECL_EGREP])dnl
 m4_require([_LT_FILEUTILS_DEFAULTS])dnl
 m4_require([_LT_DECL_OBJDUMP])dnl
 m4_require([_LT_DECL_SED])dnl
+m4_require([_LT_CHECK_SHELL_FEATURES])dnl
 AC_MSG_CHECKING([dynamic linker characteristics])
 m4_if([$1],
        [], [
@@ -2045,16 +2172,23 @@ if test "$GCC" = yes; then
     darwin*) lt_awk_arg="/^libraries:/,/LR/" ;;
     *) lt_awk_arg="/^libraries:/" ;;
   esac
-  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"`
-  if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then
+  case $host_os in
+    mingw* | cegcc*) lt_sed_strip_eq="s,=\([[A-Za-z]]:\),\1,g" ;;
+    *) lt_sed_strip_eq="s,=/,/,g" ;;
+  esac
+  lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq`
+  case $lt_search_path_spec in
+  *\;*)
     # if the path contains ";" then we assume it to be the separator
     # otherwise default to the standard path separator (i.e. ":") - it is
     # assumed that no part of a normal pathname contains ";" but that should
     # okay in the real world where ";" in dirpaths is itself problematic.
-    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'`
-  else
-    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
-  fi
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED 's/;/ /g'`
+    ;;
+  *)
+    lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED "s/$PATH_SEPARATOR/ /g"`
+    ;;
+  esac
   # Ok, now we have the path, separated by spaces, we can step through it
   # and add multilib dir if necessary.
   lt_tmp_lt_search_path_spec=
@@ -2067,7 +2201,7 @@ if test "$GCC" = yes; then
        lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path"
     fi
   done
-  lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk '
+  lt_search_path_spec=`$ECHO "$lt_tmp_lt_search_path_spec" | awk '
 BEGIN {RS=" "; FS="/|\n";} {
   lt_foo="";
   lt_count=0;
@@ -2087,7 +2221,13 @@ BEGIN {RS=" "; FS="/|\n";} {
   if (lt_foo != "") { lt_freq[[lt_foo]]++; }
   if (lt_freq[[lt_foo]] == 1) { print lt_foo; }
 }'`
-  sys_lib_search_path_spec=`$ECHO $lt_search_path_spec`
+  # AWK program above erroneously prepends '/' to C:/dos/paths
+  # for these hosts.
+  case $host_os in
+    mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\
+      $SED 's,/\([[A-Za-z]]:\),\1,g'` ;;
+  esac
+  sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP`
 else
   sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
 fi])
@@ -2113,7 +2253,7 @@ need_version=unknown
 
 case $host_os in
 aix3*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a'
   shlibpath_var=LIBPATH
 
@@ -2122,7 +2262,7 @@ aix3*)
   ;;
 
 aix[[4-9]]*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   hardcode_into_libs=yes
@@ -2175,7 +2315,7 @@ amigaos*)
   m68k)
     library_names_spec='$libname.ixlibrary $libname.a'
     # Create ${libname}_ixlibrary.a entries in /sys/libs.
-    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
+    finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`func_echo_all "$lib" | $SED '\''s%^.*/\([[^/]]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done'
     ;;
   esac
   ;;
@@ -2187,7 +2327,7 @@ beos*)
   ;;
 
 bsdi[[45]]*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
@@ -2206,8 +2346,9 @@ cygwin* | mingw* | pw32* | cegcc*)
   need_version=no
   need_lib_prefix=no
 
-  case $GCC,$host_os in
-  yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*)
+  case $GCC,$cc_basename in
+  yes,*)
+    # gcc
     library_names_spec='$libname.dll.a'
     # DLL is installed to $(libdir)/../bin by postinstall_cmds
     postinstall_cmds='base_file=`basename \${file}`~
@@ -2228,36 +2369,83 @@ cygwin* | mingw* | pw32* | cegcc*)
     cygwin*)
       # Cygwin DLLs use 'cyg' prefix rather than 'lib'
       soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
-      sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib"
+m4_if([$1], [],[
+      sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"])
       ;;
     mingw* | cegcc*)
       # MinGW DLLs use traditional 'lib' prefix
       soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
-      sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"`
-      if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
-        # It is most probably a Windows format PATH printed by
-        # mingw gcc, but we are running on Cygwin. Gcc prints its search
-        # path with ; separators, and with drive letters. We can handle the
-        # drive letters (cygwin fileutils understands them), so leave them,
-        # especially as we might pass files found there to a mingw objdump,
-        # which wouldn't understand a cygwinified path. Ahh.
-        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
-      else
-        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED  -e "s/$PATH_SEPARATOR/ /g"`
-      fi
       ;;
     pw32*)
       # pw32 DLLs use 'pw' prefix rather than 'lib'
       library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
       ;;
     esac
+    dynamic_linker='Win32 ld.exe'
+    ;;
+
+  *,cl*)
+    # Native MSVC
+    libname_spec='$name'
+    soname_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext}'
+    library_names_spec='${libname}.dll.lib'
+
+    case $build_os in
+    mingw*)
+      sys_lib_search_path_spec=
+      lt_save_ifs=$IFS
+      IFS=';'
+      for lt_path in $LIB
+      do
+        IFS=$lt_save_ifs
+        # Let DOS variable expansion print the short 8.3 style file name.
+        lt_path=`cd "$lt_path" 2>/dev/null && cmd //C "for %i in (".") do @echo %~si"`
+        sys_lib_search_path_spec="$sys_lib_search_path_spec $lt_path"
+      done
+      IFS=$lt_save_ifs
+      # Convert to MSYS style.
+      sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'`
+      ;;
+    cygwin*)
+      # Convert to unix form, then to dos form, then back to unix form
+      # but this time dos style (no spaces!) so that the unix form looks
+      # like /cygdrive/c/PROGRA~1:/cygdr...
+      sys_lib_search_path_spec=`cygpath --path --unix "$LIB"`
+      sys_lib_search_path_spec=`cygpath --path --dos "$sys_lib_search_path_spec" 2>/dev/null`
+      sys_lib_search_path_spec=`cygpath --path --unix "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      ;;
+    *)
+      sys_lib_search_path_spec="$LIB"
+      if $ECHO "$sys_lib_search_path_spec" | [$GREP ';[c-zC-Z]:/' >/dev/null]; then
+        # It is most probably a Windows format PATH.
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'`
+      else
+        sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"`
+      fi
+      # FIXME: find the short name or the path components, as spaces are
+      # common. (e.g. "Program Files" -> "PROGRA~1")
+      ;;
+    esac
+
+    # DLL is installed to $(libdir)/../bin by postinstall_cmds
+    postinstall_cmds='base_file=`basename \${file}`~
+      dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~
+      dldir=$destdir/`dirname \$dlpath`~
+      test -d \$dldir || mkdir -p \$dldir~
+      $install_prog $dir/$dlname \$dldir/$dlname'
+    postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~
+      dlpath=$dir/\$dldll~
+       $RM \$dlpath'
+    shlibpath_overrides_runpath=yes
+    dynamic_linker='Win32 link.exe'
     ;;
 
   *)
+    # Assume MSVC wrapper
     library_names_spec='${libname}`echo ${release} | $SED -e 's/[[.]]/-/g'`${versuffix}${shared_ext} $libname.lib'
+    dynamic_linker='Win32 ld.exe'
     ;;
   esac
-  dynamic_linker='Win32 ld.exe'
   # FIXME: first we should search . and the directory the executable is in
   shlibpath_var=PATH
   ;;
@@ -2278,7 +2466,7 @@ m4_if([$1], [],[
   ;;
 
 dgux*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext'
@@ -2286,10 +2474,6 @@ dgux*)
   shlibpath_var=LD_LIBRARY_PATH
   ;;
 
-freebsd1*)
-  dynamic_linker=no
-  ;;
-
 freebsd* | dragonfly*)
   # DragonFly does not have aout.  When/if they implement a new
   # versioning mechanism, adjust this.
@@ -2297,7 +2481,7 @@ freebsd* | dragonfly*)
     objformat=`/usr/bin/objformat`
   else
     case $host_os in
-    freebsd[[123]]*) objformat=aout ;;
+    freebsd[[23]].*) objformat=aout ;;
     *) objformat=elf ;;
     esac
   fi
@@ -2315,7 +2499,7 @@ freebsd* | dragonfly*)
   esac
   shlibpath_var=LD_LIBRARY_PATH
   case $host_os in
-  freebsd2*)
+  freebsd2.*)
     shlibpath_overrides_runpath=yes
     ;;
   freebsd3.[[01]]* | freebsdelf3.[[01]]*)
@@ -2335,12 +2519,26 @@ freebsd* | dragonfly*)
   ;;
 
 gnu*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=no
+  hardcode_into_libs=yes
+  ;;
+
+haiku*)
+  version_type=linux # correct to gnu/linux during the next big refactor
+  need_lib_prefix=no
+  need_version=no
+  dynamic_linker="$host_os runtime_loader"
+  library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}'
+  soname_spec='${libname}${release}${shared_ext}$major'
+  shlibpath_var=LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+  sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib'
   hardcode_into_libs=yes
   ;;
 
@@ -2386,12 +2584,14 @@ hpux9* | hpux10* | hpux11*)
     soname_spec='${libname}${release}${shared_ext}$major'
     ;;
   esac
-  # HP-UX runs *really* slowly unless shared libraries are mode 555.
+  # HP-UX runs *really* slowly unless shared libraries are mode 555, ...
   postinstall_cmds='chmod 555 $lib'
+  # or fails outright, so override atomically:
+  install_override_mode=555
   ;;
 
 interix[[3-9]]*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}'
@@ -2407,7 +2607,7 @@ irix5* | irix6* | nonstopux*)
     nonstopux*) version_type=nonstopux ;;
     *)
        if test "$lt_cv_prog_gnu_ld" = yes; then
-               version_type=linux
+               version_type=linux # correct to gnu/linux during the next big refactor
        else
                version_type=irix
        fi ;;
@@ -2444,9 +2644,29 @@ linux*oldld* | linux*aout* | linux*coff*)
   dynamic_linker=no
   ;;
 
-# This must be Linux ELF.
-linux* | k*bsd*-gnu)
-  version_type=linux
+linux*android*)
+  version_type=none # Android doesn't support versioned libraries.
+  need_lib_prefix=no
+  need_version=no
+  library_names_spec='$libname$release$shared_ext'
+  soname_spec='$libname$release$shared_ext'
+  finish_cmds=
+  shlibpath_var=LD_LIBRARY_PATH
+  shlibpath_overrides_runpath=yes
+
+  # This implies no fast_install, which is unacceptable.
+  # Some rework will be needed to allow for fast_install
+  # before this can be enabled.
+  hardcode_into_libs=yes
+
+  dynamic_linker='Android linker'
+  # Don't embed -rpath directories since the linker doesn't support them.
+  _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+  ;;
+
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -2454,16 +2674,21 @@ linux* | k*bsd*-gnu)
   finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=no
+
   # Some binutils ld are patched to set DT_RUNPATH
-  save_LDFLAGS=$LDFLAGS
-  save_libdir=$libdir
-  eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
-       LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
-  AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
-    [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
-       [shlibpath_overrides_runpath=yes])])
-  LDFLAGS=$save_LDFLAGS
-  libdir=$save_libdir
+  AC_CACHE_VAL([lt_cv_shlibpath_overrides_runpath],
+    [lt_cv_shlibpath_overrides_runpath=no
+    save_LDFLAGS=$LDFLAGS
+    save_libdir=$libdir
+    eval "libdir=/foo; wl=\"$_LT_TAGVAR(lt_prog_compiler_wl, $1)\"; \
+        LDFLAGS=\"\$LDFLAGS $_LT_TAGVAR(hardcode_libdir_flag_spec, $1)\""
+    AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])],
+      [AS_IF([ ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null],
+        [lt_cv_shlibpath_overrides_runpath=yes])])
+    LDFLAGS=$save_LDFLAGS
+    libdir=$save_libdir
+    ])
+  shlibpath_overrides_runpath=$lt_cv_shlibpath_overrides_runpath
 
   # This implies no fast_install, which is unacceptable.
   # Some rework will be needed to allow for fast_install
@@ -2472,7 +2697,7 @@ linux* | k*bsd*-gnu)
 
   # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
-    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[  ]*hwcap[        ]/d;s/[:,      ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[  ]*hwcap[        ]/d;s/[:,      ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;s/"//g;/^$/d' | tr '\n' ' '`
     sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
   fi
 
@@ -2516,7 +2741,7 @@ netbsd*)
   ;;
 
 newsos6)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   shlibpath_var=LD_LIBRARY_PATH
   shlibpath_overrides_runpath=yes
@@ -2585,7 +2810,7 @@ rdos*)
   ;;
 
 solaris*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -2610,7 +2835,7 @@ sunos4*)
   ;;
 
 sysv4 | sysv4.3*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
@@ -2634,7 +2859,7 @@ sysv4 | sysv4.3*)
 
 sysv4*MP*)
   if test -d /usr/nec ;then
-    version_type=linux
+    version_type=linux # correct to gnu/linux during the next big refactor
     library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}'
     soname_spec='$libname${shared_ext}.$major'
     shlibpath_var=LD_LIBRARY_PATH
@@ -2665,7 +2890,7 @@ sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
 
 tpf*)
   # TPF is a cross-target only.  Preferred cross-host = GNU/Linux.
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   need_lib_prefix=no
   need_version=no
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
@@ -2675,7 +2900,7 @@ tpf*)
   ;;
 
 uts4*)
-  version_type=linux
+  version_type=linux # correct to gnu/linux during the next big refactor
   library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}'
   soname_spec='${libname}${release}${shared_ext}$major'
   shlibpath_var=LD_LIBRARY_PATH
@@ -2717,6 +2942,8 @@ _LT_DECL([], [library_names_spec], [1],
     The last name is the one that the linker finds with -lNAME]])
 _LT_DECL([], [soname_spec], [1],
     [[The coded name of the library, if different from the real name]])
+_LT_DECL([], [install_override_mode], [1],
+    [Permission mode override for installation of shared libraries])
 _LT_DECL([], [postinstall_cmds], [2],
     [Command to use after installation of a shared archive])
 _LT_DECL([], [postuninstall_cmds], [2],
@@ -2829,6 +3056,7 @@ AC_REQUIRE([AC_CANONICAL_HOST])dnl
 AC_REQUIRE([AC_CANONICAL_BUILD])dnl
 m4_require([_LT_DECL_SED])dnl
 m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PROG_ECHO_BACKSLASH])dnl
 
 AC_ARG_WITH([gnu-ld],
     [AS_HELP_STRING([--with-gnu-ld],
@@ -2950,6 +3178,11 @@ case $reload_flag in
 esac
 reload_cmds='$LD$reload_flag -o $output$reload_objs'
 case $host_os in
+  cygwin* | mingw* | pw32* | cegcc*)
+    if test "$GCC" != yes; then
+      reload_cmds=false
+    fi
+    ;;
   darwin*)
     if test "$GCC" = yes; then
       reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs'
@@ -2958,8 +3191,8 @@ case $host_os in
     fi
     ;;
 esac
-_LT_DECL([], [reload_flag], [1], [How to create reloadable object files])dnl
-_LT_DECL([], [reload_cmds], [2])dnl
+_LT_TAGDECL([], [reload_flag], [1], [How to create reloadable object files])dnl
+_LT_TAGDECL([], [reload_cmds], [2])dnl
 ])# _LT_CMD_RELOAD
 
 
@@ -3011,16 +3244,18 @@ mingw* | pw32*)
   # Base MSYS/MinGW do not provide the 'file' command needed by
   # func_win32_libid shell function, so use a weaker test based on 'objdump',
   # unless we find 'file', for example because we are cross-compiling.
-  if ( file / ) >/dev/null 2>&1; then
+  # func_win32_libid assumes BSD nm, so disallow it if using MS dumpbin.
+  if ( test "$lt_cv_nm_interface" = "BSD nm" && file / ) >/dev/null 2>&1; then
     lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL'
     lt_cv_file_magic_cmd='func_win32_libid'
   else
-    lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?'
+    # Keep this pattern in sync with the one in func_win32_libid.
+    lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)'
     lt_cv_file_magic_cmd='$OBJDUMP -f'
   fi
   ;;
 
-cegcc)
+cegcc*)
   # use the weaker test based on 'objdump'. See mingw*.
   lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?'
   lt_cv_file_magic_cmd='$OBJDUMP -f'
@@ -3050,6 +3285,10 @@ gnu*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
+haiku*)
+  lt_cv_deplibs_check_method=pass_all
+  ;;
+
 hpux10.20* | hpux11*)
   lt_cv_file_magic_cmd=/usr/bin/file
   case $host_cpu in
@@ -3058,11 +3297,11 @@ hpux10.20* | hpux11*)
     lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so
     ;;
   hppa*64*)
-    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]']
+    [lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF[ -][0-9][0-9])(-bit)?( [LM]SB)? shared object( file)?[, -]* PA-RISC [0-9]\.[0-9]']
     lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl
     ;;
   *)
-    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]].[[0-9]]) shared library'
+    lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|PA-RISC[[0-9]]\.[[0-9]]) shared library'
     lt_cv_file_magic_test_file=/usr/lib/libc.sl
     ;;
   esac
@@ -3083,8 +3322,8 @@ irix5* | irix6* | nonstopux*)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
-# This must be Linux ELF.
-linux* | k*bsd*-gnu)
+# This must be glibc/ELF.
+linux* | k*bsd*-gnu | kopensolaris*-gnu)
   lt_cv_deplibs_check_method=pass_all
   ;;
 
@@ -3162,6 +3401,21 @@ tpf*)
   ;;
 esac
 ])
+
+file_magic_glob=
+want_nocaseglob=no
+if test "$build" = "$host"; then
+  case $host_os in
+  mingw* | pw32*)
+    if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then
+      want_nocaseglob=yes
+    else
+      file_magic_glob=`echo aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ | $SED -e "s/\(..\)/s\/[[\1]]\/[[\1]]\/g;/g"`
+    fi
+    ;;
+  esac
+fi
+
 file_magic_cmd=$lt_cv_file_magic_cmd
 deplibs_check_method=$lt_cv_deplibs_check_method
 test -z "$deplibs_check_method" && deplibs_check_method=unknown
@@ -3169,7 +3423,11 @@ test -z "$deplibs_check_method" && deplibs_check_method=unknown
 _LT_DECL([], [deplibs_check_method], [1],
     [Method to check whether dependent libraries are shared objects])
 _LT_DECL([], [file_magic_cmd], [1],
-    [Command to use when deplibs_check_method == "file_magic"])
+    [Command to use when deplibs_check_method = "file_magic"])
+_LT_DECL([], [file_magic_glob], [1],
+    [How to find potential files when deplibs_check_method = "file_magic"])
+_LT_DECL([], [want_nocaseglob], [1],
+    [Find potential files using nocaseglob when deplibs_check_method = "file_magic"])
 ])# _LT_CHECK_MAGIC_METHOD
 
 
@@ -3226,7 +3484,19 @@ if test "$lt_cv_path_NM" != "no"; then
   NM="$lt_cv_path_NM"
 else
   # Didn't find any BSD compatible name lister, look for dumpbin.
-  AC_CHECK_TOOLS(DUMPBIN, ["dumpbin -symbols" "link -dump -symbols"], :)
+  if test -n "$DUMPBIN"; then :
+    # Let the user override the test.
+  else
+    AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :)
+    case `$DUMPBIN -symbols /dev/null 2>&1 | sed '1q'` in
+    *COFF*)
+      DUMPBIN="$DUMPBIN -symbols"
+      ;;
+    *)
+      DUMPBIN=:
+      ;;
+    esac
+  fi
   AC_SUBST([DUMPBIN])
   if test "$DUMPBIN" != ":"; then
     NM="$DUMPBIN"
@@ -3239,13 +3509,13 @@ _LT_DECL([], [NM], [1], [A BSD- or MS-compatible name lister])dnl
 AC_CACHE_CHECK([the name lister ($NM) interface], [lt_cv_nm_interface],
   [lt_cv_nm_interface="BSD nm"
   echo "int some_variable = 0;" > conftest.$ac_ext
-  (eval echo "\"\$as_me:__oline__: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
+  (eval echo "\"\$as_me:$LINENO: $ac_compile\"" >&AS_MESSAGE_LOG_FD)
   (eval "$ac_compile" 2>conftest.err)
   cat conftest.err >&AS_MESSAGE_LOG_FD
-  (eval echo "\"\$as_me:__oline__: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
+  (eval echo "\"\$as_me:$LINENO: $NM \\\"conftest.$ac_objext\\\"\"" >&AS_MESSAGE_LOG_FD)
   (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
   cat conftest.err >&AS_MESSAGE_LOG_FD
-  (eval echo "\"\$as_me:__oline__: output\"" >&AS_MESSAGE_LOG_FD)
+  (eval echo "\"\$as_me:$LINENO: output\"" >&AS_MESSAGE_LOG_FD)
   cat conftest.out >&AS_MESSAGE_LOG_FD
   if $GREP 'External.*some_variable' conftest.out > /dev/null; then
     lt_cv_nm_interface="MS dumpbin"
@@ -3260,6 +3530,67 @@ dnl aclocal-1.4 backwards compatibility:
 dnl AC_DEFUN([AM_PROG_NM], [])
 dnl AC_DEFUN([AC_PROG_NM], [])
 
+# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+# --------------------------------
+# how to determine the name of the shared library
+# associated with a specific link library.
+#  -- PORTME fill in with the dynamic library characteristics
+m4_defun([_LT_CHECK_SHAREDLIB_FROM_LINKLIB],
+[m4_require([_LT_DECL_EGREP])
+m4_require([_LT_DECL_OBJDUMP])
+m4_require([_LT_DECL_DLLTOOL])
+AC_CACHE_CHECK([how to associate runtime and link libraries],
+lt_cv_sharedlib_from_linklib_cmd,
+[lt_cv_sharedlib_from_linklib_cmd='unknown'
+
+case $host_os in
+cygwin* | mingw* | pw32* | cegcc*)
+  # two different shell functions defined in ltmain.sh
+  # decide which to use based on capabilities of $DLLTOOL
+  case `$DLLTOOL --help 2>&1` in
+  *--identify-strict*)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib
+    ;;
+  *)
+    lt_cv_sharedlib_from_linklib_cmd=func_cygming_dll_for_implib_fallback
+    ;;
+  esac
+  ;;
+*)
+  # fallback: assume linklib IS sharedlib
+  lt_cv_sharedlib_from_linklib_cmd="$ECHO"
+  ;;
+esac
+])
+sharedlib_from_linklib_cmd=$lt_cv_sharedlib_from_linklib_cmd
+test -z "$sharedlib_from_linklib_cmd" && sharedlib_from_linklib_cmd=$ECHO
+
+_LT_DECL([], [sharedlib_from_linklib_cmd], [1],
+    [Command to associate shared and link libraries])
+])# _LT_CHECK_SHAREDLIB_FROM_LINKLIB
+
+
+# _LT_PATH_MANIFEST_TOOL
+# ----------------------
+# locate the manifest tool
+m4_defun([_LT_PATH_MANIFEST_TOOL],
+[AC_CHECK_TOOL(MANIFEST_TOOL, mt, :)
+test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt
+AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool],
+  [lt_cv_path_mainfest_tool=no
+  echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD
+  $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out
+  cat conftest.err >&AS_MESSAGE_LOG_FD
+  if $GREP 'Manifest Tool' conftest.out > /dev/null; then
+    lt_cv_path_mainfest_tool=yes
+  fi
+  rm -f conftest*])
+if test "x$lt_cv_path_mainfest_tool" != xyes; then
+  MANIFEST_TOOL=:
+fi
+_LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl
+])# _LT_PATH_MANIFEST_TOOL
+
 
 # LT_LIB_M
 # --------
@@ -3268,7 +3599,7 @@ AC_DEFUN([LT_LIB_M],
 [AC_REQUIRE([AC_CANONICAL_HOST])dnl
 LIBM=
 case $host in
-*-*-beos* | *-*-cygwin* | *-*-pw32* | *-*-darwin*)
+*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*)
   # These system don't have libm, or don't need it
   ;;
 *-ncr-sysv4.3*)
@@ -3296,7 +3627,12 @@ m4_defun([_LT_COMPILER_NO_RTTI],
 _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=
 
 if test "$GCC" = yes; then
-  _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin'
+  case $cc_basename in
+  nvcc*)
+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -Xcompiler -fno-builtin' ;;
+  *)
+    _LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)=' -fno-builtin' ;;
+  esac
 
   _LT_COMPILER_OPTION([if $compiler supports -fno-rtti -fno-exceptions],
     lt_cv_prog_compiler_rtti_exceptions,
@@ -3313,6 +3649,7 @@ _LT_TAGDECL([no_builtin_flag], [lt_prog_compiler_no_builtin_flag], [1],
 m4_defun([_LT_CMD_GLOBAL_SYMBOLS],
 [AC_REQUIRE([AC_CANONICAL_HOST])dnl
 AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_AWK])dnl
 AC_REQUIRE([LT_PATH_NM])dnl
 AC_REQUIRE([LT_PATH_LD])dnl
 m4_require([_LT_DECL_SED])dnl
@@ -3380,8 +3717,8 @@ esac
 lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'"
 
 # Transform an extracted symbol line into symbol name and symbol address
-lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p'"
-lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\) $/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p'"
+lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([[^ ]]*\)[[ ]]*$/  {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \(lib[[^ ]]*\)$/  {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/  {\"lib\2\", (void *) \&\2},/p'"
 
 # Handle CRLF in mingw tool chain
 opt_cr=
@@ -3405,6 +3742,7 @@ for ac_symprfx in "" "_"; do
     # which start with @ or ?.
     lt_cv_sys_global_symbol_pipe="$AWK ['"\
 "     {last_section=section; section=\$ 3};"\
+"     /^COFF SYMBOL TABLE/{for(i in hide) delete hide[i]};"\
 "     /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\
 "     \$ 0!~/External *\|/{next};"\
 "     / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\
@@ -3417,6 +3755,7 @@ for ac_symprfx in "" "_"; do
   else
     lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[    ]]\($symcode$symcode*\)[[       ]][[    ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'"
   fi
+  lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'"
 
   # Check to see that the pipe works correctly.
   pipe_works=no
@@ -3438,7 +3777,7 @@ _LT_EOF
   if AC_TRY_EVAL(ac_compile); then
     # Now try to grab the symbols.
     nlist=conftest.nm
-    if AC_TRY_EVAL(NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) && test -s "$nlist"; then
+    if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then
       # Try sorting and uniquifying the output.
       if sort "$nlist" | uniq > "$nlist"T; then
        mv -f "$nlist"T "$nlist"
@@ -3450,6 +3789,18 @@ _LT_EOF
       if $GREP ' nm_test_var$' "$nlist" >/dev/null; then
        if $GREP ' nm_test_func$' "$nlist" >/dev/null; then
          cat <<_LT_EOF > conftest.$ac_ext
+/* Keep this code in sync between libtool.m4, ltmain, lt_system.h, and tests.  */
+#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN32_WCE)
+/* DATA imports from DLLs on WIN32 con't be const, because runtime
+   relocations are performed -- see ld's documentation on pseudo-relocs.  */
+# define LT@&t@_DLSYM_CONST
+#elif defined(__osf__)
+/* This system does not cope well with relocations in const data.  */
+# define LT@&t@_DLSYM_CONST
+#else
+# define LT@&t@_DLSYM_CONST const
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -3461,7 +3812,7 @@ _LT_EOF
          cat <<_LT_EOF >> conftest.$ac_ext
 
 /* The mapping between symbol names and symbols.  */
-const struct {
+LT@&t@_DLSYM_CONST struct {
   const char *name;
   void       *address;
 }
@@ -3487,15 +3838,15 @@ static const void *lt_preloaded_setup() {
 _LT_EOF
          # Now try linking the two files.
          mv conftest.$ac_objext conftstm.$ac_objext
-         lt_save_LIBS="$LIBS"
-         lt_save_CFLAGS="$CFLAGS"
+         lt_globsym_save_LIBS=$LIBS
+         lt_globsym_save_CFLAGS=$CFLAGS
          LIBS="conftstm.$ac_objext"
          CFLAGS="$CFLAGS$_LT_TAGVAR(lt_prog_compiler_no_builtin_flag, $1)"
          if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext}; then
            pipe_works=yes
          fi
-         LIBS="$lt_save_LIBS"
-         CFLAGS="$lt_save_CFLAGS"
+         LIBS=$lt_globsym_save_LIBS
+         CFLAGS=$lt_globsym_save_CFLAGS
        else
          echo "cannot find nm_test_func in $nlist" >&AS_MESSAGE_LOG_FD
        fi
@@ -3528,6 +3879,13 @@ else
   AC_MSG_RESULT(ok)
 fi
 
+# Response file support.
+if test "$lt_cv_nm_interface" = "MS dumpbin"; then
+  nm_file_list_spec='@'
+elif $NM --help 2>/dev/null | grep '[[@]]FILE' >/dev/null; then
+  nm_file_list_spec='@'
+fi
+
 _LT_DECL([global_symbol_pipe], [lt_cv_sys_global_symbol_pipe], [1],
     [Take the output of nm and produce a listing of raw symbols and C names])
 _LT_DECL([global_symbol_to_cdecl], [lt_cv_sys_global_symbol_to_cdecl], [1],
@@ -3538,6 +3896,8 @@ _LT_DECL([global_symbol_to_c_name_address],
 _LT_DECL([global_symbol_to_c_name_address_lib_prefix],
     [lt_cv_sys_global_symbol_to_c_name_address_lib_prefix], [1],
     [Transform the output of nm in a C name address pair when lib prefix is needed])
+_LT_DECL([], [nm_file_list_spec], [1],
+    [Specify filename containing input files for $NM])
 ]) # _LT_CMD_GLOBAL_SYMBOLS
 
 
@@ -3549,7 +3909,6 @@ _LT_TAGVAR(lt_prog_compiler_wl, $1)=
 _LT_TAGVAR(lt_prog_compiler_pic, $1)=
 _LT_TAGVAR(lt_prog_compiler_static, $1)=
 
-AC_MSG_CHECKING([for $compiler option to produce PIC])
 m4_if([$1], [CXX], [
   # C++ specific cases for pic, static, wl, etc.
   if test "$GXX" = yes; then
@@ -3600,6 +3959,11 @@ m4_if([$1], [CXX], [
       # DJGPP does not support shared libraries at all
       _LT_TAGVAR(lt_prog_compiler_pic, $1)=
       ;;
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)=
+      ;;
     interix[[3-9]]*)
       # Interix 3.x gcc -fpic/-fPIC options generate broken code.
       # Instead, we relocate shared libraries at runtime.
@@ -3649,6 +4013,12 @@ m4_if([$1], [CXX], [
          ;;
        esac
        ;;
+      mingw* | cygwin* | os2* | pw32* | cegcc*)
+       # This hack is so that the source file can tell whether it is being
+       # built for inclusion in a dll (and should export symbols for example).
+       m4_if([$1], [GCJ], [],
+         [_LT_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT'])
+       ;;
       dgux*)
        case $cc_basename in
          ec++*)
@@ -3705,7 +4075,7 @@ m4_if([$1], [CXX], [
            ;;
        esac
        ;;
-      linux* | k*bsd*-gnu)
+      linux* | k*bsd*-gnu | kopensolaris*-gnu)
        case $cc_basename in
          KCC*)
            # KAI C++ Compiler
@@ -3738,8 +4108,8 @@ m4_if([$1], [CXX], [
            _LT_TAGVAR(lt_prog_compiler_pic, $1)=
            _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
            ;;
-         xlc* | xlC*)
-           # IBM XL 8.0 on PPC
+         xlc* | xlC* | bgxl[[cC]]* | mpixl[[cC]]*)
+           # IBM XL 8.0, 9.0 on PPC and BlueGene
            _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
            _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
@@ -3801,7 +4171,7 @@ m4_if([$1], [CXX], [
        ;;
       solaris*)
        case $cc_basename in
-         CC*)
+         CC* | sunCC*)
            # Sun C++ 4.2, 5.x and Centerline C++
            _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
            _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
@@ -3905,6 +4275,12 @@ m4_if([$1], [CXX], [
       _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common'
       ;;
 
+    haiku*)
+      # PIC is the default for Haiku.
+      # The "-static" flag exists, but is broken.
+      _LT_TAGVAR(lt_prog_compiler_static, $1)=
+      ;;
+
     hpux*)
       # PIC is the default for 64-bit PA HP-UX, but not for 32-bit
       # PA HP-UX.  On IA64 HP-UX, PIC is the default but the pic flag
@@ -3947,6 +4323,15 @@ m4_if([$1], [CXX], [
       _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
       ;;
     esac
+
+    case $cc_basename in
+    nvcc*) # Cuda Compiler Driver 2.2
+      _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Xlinker '
+      if test -n "$_LT_TAGVAR(lt_prog_compiler_pic, $1)"; then
+        _LT_TAGVAR(lt_prog_compiler_pic, $1)="-Xcompiler $_LT_TAGVAR(lt_prog_compiler_pic, $1)"
+      fi
+      ;;
+    esac
   else
     # PORTME Check for flag to pass linker flags through the system compiler.
     case $host_os in
@@ -3989,7 +4374,7 @@ m4_if([$1], [CXX], [
       _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
       ;;
 
-    linux* | k*bsd*-gnu)
+    linux* | k*bsd*-gnu | kopensolaris*-gnu)
       case $cc_basename in
       # old Intel for x86_64 which still supported -KPIC.
       ecc*)
@@ -4010,7 +4395,13 @@ m4_if([$1], [CXX], [
        _LT_TAGVAR(lt_prog_compiler_pic, $1)='--shared'
        _LT_TAGVAR(lt_prog_compiler_static, $1)='--static'
        ;;
-      pgcc* | pgf77* | pgf90* | pgf95*)
+      nagfor*)
+       # NAG Fortran compiler
+       _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,-Wl,,'
+       _LT_TAGVAR(lt_prog_compiler_pic, $1)='-PIC'
+       _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+       ;;
+      pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*)
         # Portland Group compilers (*not* the Pentium gcc compiler,
        # which looks to be a dead project)
        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
@@ -4022,25 +4413,40 @@ m4_if([$1], [CXX], [
         # All Alpha code is PIC.
         _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared'
         ;;
-      xl*)
-       # IBM XL C 8.0/Fortran 10.1 on PPC
+      xl* | bgxl* | bgf* | mpixl*)
+       # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene
        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
        _LT_TAGVAR(lt_prog_compiler_pic, $1)='-qpic'
        _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink'
        ;;
       *)
        case `$CC -V 2>&1 | sed 5q` in
+       *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*)
+         # Sun Fortran 8.3 passes all unrecognized flags to the linker
+         _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+         _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+         _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
+         ;;
+       *Sun\ F* | *Sun*Fortran*)
+         _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+         _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
+         _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld '
+         ;;
        *Sun\ C*)
          # Sun C 5.9
          _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
          _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
          _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
          ;;
-       *Sun\ F*)
-         # Sun Fortran 8.3 passes all unrecognized flags to the linker
-         _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
+        *Intel*\ [[CF]]*Compiler*)
+         _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+         _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC'
+         _LT_TAGVAR(lt_prog_compiler_static, $1)='-static'
+         ;;
+       *Portland\ Group*)
+         _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,'
+         _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fpic'
          _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
-         _LT_TAGVAR(lt_prog_compiler_wl, $1)=''
          ;;
        esac
        ;;
@@ -4072,7 +4478,7 @@ m4_if([$1], [CXX], [
       _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC'
       _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic'
       case $cc_basename in
-      f77* | f90* | f95*)
+      f77* | f90* | f95* | sunf77* | sunf90* | sunf95*)
        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ';;
       *)
        _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,';;
@@ -4129,9 +4535,11 @@ case $host_os in
     _LT_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_TAGVAR(lt_prog_compiler_pic, $1)@&t@m4_if([$1],[],[ -DPIC],[m4_if([$1],[CXX],[ -DPIC],[])])"
     ;;
 esac
-AC_MSG_RESULT([$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
-_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
-       [How to pass a linker flag through the compiler])
+
+AC_CACHE_CHECK([for $compiler option to produce PIC],
+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)],
+  [_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_prog_compiler_pic, $1)])
+_LT_TAGVAR(lt_prog_compiler_pic, $1)=$_LT_TAGVAR(lt_cv_prog_compiler_pic, $1)
 
 #
 # Check to make sure the PIC flag actually works.
@@ -4150,6 +4558,8 @@ fi
 _LT_TAGDECL([pic_flag], [lt_prog_compiler_pic], [1],
        [Additional compiler flags for building library objects])
 
+_LT_TAGDECL([wl], [lt_prog_compiler_wl], [1],
+       [How to pass a linker flag through the compiler])
 #
 # Check to make sure the static flag actually works.
 #
@@ -4170,6 +4580,7 @@ _LT_TAGDECL([link_static_flag], [lt_prog_compiler_static], [1],
 m4_defun([_LT_LINKER_SHLIBS],
 [AC_REQUIRE([LT_PATH_LD])dnl
 AC_REQUIRE([LT_PATH_NM])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
 m4_require([_LT_FILEUTILS_DEFAULTS])dnl
 m4_require([_LT_DECL_EGREP])dnl
 m4_require([_LT_DECL_SED])dnl
@@ -4178,30 +4589,40 @@ m4_require([_LT_TAG_COMPILER])dnl
 AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries])
 m4_if([$1], [CXX], [
   _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
+  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
   case $host_os in
   aix[[4-9]]*)
     # If we're using GNU nm, then we don't want the "-C" option.
     # -C means demangle to AIX nm, but means don't demangle with GNU nm
+    # Also, AIX nm treats weak defined symbols like other global defined
+    # symbols, whereas GNU nm marks them as "W".
     if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
     else
       _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
     fi
     ;;
   pw32*)
     _LT_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds"
-  ;;
+    ;;
   cygwin* | mingw* | cegcc*)
-    _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
-  ;;
-  linux* | k*bsd*-gnu)
+    case $cc_basename in
+    cl*)
+      _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+      ;;
+    *)
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
+      ;;
+    esac
+    ;;
+  linux* | k*bsd*-gnu | gnu*)
     _LT_TAGVAR(link_all_deplibs, $1)=no
-  ;;
+    ;;
   *)
     _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols'
-  ;;
+    ;;
   esac
-  _LT_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*']
 ], [
   runpath_var=
   _LT_TAGVAR(allow_undefined_flag, $1)=
@@ -4216,7 +4637,6 @@ m4_if([$1], [CXX], [
   _LT_TAGVAR(hardcode_direct, $1)=no
   _LT_TAGVAR(hardcode_direct_absolute, $1)=no
   _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
-  _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
   _LT_TAGVAR(hardcode_libdir_separator, $1)=
   _LT_TAGVAR(hardcode_minus_L, $1)=no
   _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
@@ -4261,13 +4681,39 @@ dnl Note also adjust exclude_expsyms for C++ above.
   openbsd*)
     with_gnu_ld=no
     ;;
-  linux* | k*bsd*-gnu)
+  linux* | k*bsd*-gnu | gnu*)
     _LT_TAGVAR(link_all_deplibs, $1)=no
     ;;
   esac
 
   _LT_TAGVAR(ld_shlibs, $1)=yes
+
+  # On some targets, GNU ld is compatible enough with the native linker
+  # that we're better off using the native interface for both.
+  lt_use_gnu_ld_interface=no
   if test "$with_gnu_ld" = yes; then
+    case $host_os in
+      aix*)
+       # The AIX port of GNU ld has always aspired to compatibility
+       # with the native linker.  However, as the warning in the GNU ld
+       # block says, versions before 2.19.5* couldn't really create working
+       # shared libraries, regardless of the interface used.
+       case `$LD -v 2>&1` in
+         *\ \(GNU\ Binutils\)\ 2.19.5*) ;;
+         *\ \(GNU\ Binutils\)\ 2.[[2-9]]*) ;;
+         *\ \(GNU\ Binutils\)\ [[3-9]]*) ;;
+         *)
+           lt_use_gnu_ld_interface=yes
+           ;;
+       esac
+       ;;
+      *)
+       lt_use_gnu_ld_interface=yes
+       ;;
+    esac
+  fi
+
+  if test "$lt_use_gnu_ld_interface" = yes; then
     # If archive_cmds runs LD, not CC, wlarc should be empty
     wlarc='${wl}'
 
@@ -4285,6 +4731,7 @@ dnl Note also adjust exclude_expsyms for C++ above.
     fi
     supports_anon_versioning=no
     case `$LD -v 2>&1` in
+      *GNU\ gold*) supports_anon_versioning=yes ;;
       *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11
       *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ...
       *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ...
@@ -4300,11 +4747,12 @@ dnl Note also adjust exclude_expsyms for C++ above.
        _LT_TAGVAR(ld_shlibs, $1)=no
        cat <<_LT_EOF 1>&2
 
-*** Warning: the GNU linker, at least up to release 2.9.1, is reported
+*** Warning: the GNU linker, at least up to release 2.19, is reported
 *** to be unable to reliably create shared libraries on AIX.
 *** Therefore, libtool is disabling shared libraries support.  If you
-*** really care for shared libraries, you may want to modify your PATH
-*** so that a non-GNU linker is found, and then restart.
+*** really care for shared libraries, you may want to install binutils
+*** 2.20 or above, or modify your PATH so that a non-GNU linker is found.
+*** You will then need to restart the configuration process.
 
 _LT_EOF
       fi
@@ -4340,16 +4788,18 @@ _LT_EOF
       # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
       # as there is no search path for DLLs.
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+      _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
       _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
       _LT_TAGVAR(always_export_symbols, $1)=no
       _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols'
+      _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname']
 
       if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
         _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
        # If the export-symbols file already is a .def file (1st line
        # is EXPORTS), use it as is; otherwise, prepend...
-       _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
+       _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED \"$sed_uncomment_deffile\" $export_symbols | $SED 1q`" = xEXPORTS; then
          cp $export_symbols $output_objdir/$soname.def;
        else
          echo EXPORTS > $output_objdir/$soname.def;
@@ -4361,6 +4811,11 @@ _LT_EOF
       fi
       ;;
 
+    haiku*)
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+      _LT_TAGVAR(link_all_deplibs, $1)=yes
+      ;;
+
     interix[[3-9]]*)
       _LT_TAGVAR(hardcode_direct, $1)=no
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
@@ -4376,7 +4831,7 @@ _LT_EOF
       _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib'
       ;;
 
-    gnu* | linux* | tpf* | k*bsd*-gnu)
+    gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu)
       tmp_diet=no
       if test "$host_os" = linux-dietlibc; then
        case $cc_basename in
@@ -4386,15 +4841,16 @@ _LT_EOF
       if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \
         && test "$tmp_diet" = no
       then
-       tmp_addflag=
+       tmp_addflag=' $pic_flag'
        tmp_sharedflag='-shared'
        case $cc_basename,$host_cpu in
         pgcc*)                         # Portland Group C compiler
-         _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+         _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
          tmp_addflag=' $pic_flag'
          ;;
-       pgf77* | pgf90* | pgf95*)       # Portland Group f77 and f90 compilers
-         _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+       pgf77* | pgf90* | pgf95* | pgfortran*)
+                                       # Portland Group f77 and f90 compilers
+         _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
          tmp_addflag=' $pic_flag -Mnomain' ;;
        ecc*,ia64* | icc*,ia64*)        # Intel C compiler on ia64
          tmp_addflag=' -i_dynamic' ;;
@@ -4405,13 +4861,17 @@ _LT_EOF
        lf95*)                          # Lahey Fortran 8.1
          _LT_TAGVAR(whole_archive_flag_spec, $1)=
          tmp_sharedflag='--shared' ;;
-       xl[[cC]]*)                      # IBM XL C 8.0 on PPC (deal with xlf below)
+       xl[[cC]]* | bgxl[[cC]]* | mpixl[[cC]]*) # IBM XL C 8.0 on PPC (deal with xlf below)
          tmp_sharedflag='-qmkshrobj'
          tmp_addflag= ;;
+       nvcc*)  # Cuda Compiler Driver 2.2
+         _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
+         _LT_TAGVAR(compiler_needs_object, $1)=yes
+         ;;
        esac
        case `$CC -V 2>&1 | sed 5q` in
        *Sun\ C*)                       # Sun C 5.9
-         _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+         _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
          _LT_TAGVAR(compiler_needs_object, $1)=yes
          tmp_sharedflag='-G' ;;
        *Sun\ F*)                       # Sun Fortran 8.3
@@ -4427,17 +4887,16 @@ _LT_EOF
         fi
 
        case $cc_basename in
-       xlf*)
+       xlf* | bgf* | bgxlf* | mpixlf*)
          # IBM XL Fortran 10.1 on PPC cannot create shared libs itself
          _LT_TAGVAR(whole_archive_flag_spec, $1)='--whole-archive$convenience --no-whole-archive'
-         _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
-         _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='-rpath $libdir'
-         _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib'
+         _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
+         _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib'
          if test "x$supports_anon_versioning" = xyes; then
            _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~
              cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~
              echo "local: *; };" >> $output_objdir/$libname.ver~
-             $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
+             $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib'
          fi
          ;;
        esac
@@ -4451,8 +4910,8 @@ _LT_EOF
        _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib'
        wlarc=
       else
-       _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-       _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       fi
       ;;
 
@@ -4470,8 +4929,8 @@ _LT_EOF
 
 _LT_EOF
       elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-       _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-       _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
        _LT_TAGVAR(ld_shlibs, $1)=no
       fi
@@ -4517,8 +4976,8 @@ _LT_EOF
 
     *)
       if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then
-       _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
-       _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+       _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+       _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
       else
        _LT_TAGVAR(ld_shlibs, $1)=no
       fi
@@ -4558,8 +5017,10 @@ _LT_EOF
       else
        # If we're using GNU nm, then we don't want the "-C" option.
        # -C means demangle to AIX nm, but means don't demangle with GNU nm
+       # Also, AIX nm treats weak defined symbols like other global
+       # defined symbols, whereas GNU nm marks them as "W".
        if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then
-         _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
+         _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
        else
          _LT_TAGVAR(export_symbols_cmds, $1)='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && ([substr](\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols'
        fi
@@ -4647,9 +5108,9 @@ _LT_EOF
        _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
         # Determine the default libpath from the value encoded in an
         # empty executable.
-        _LT_SYS_MODULE_PATH_AIX
+        _LT_SYS_MODULE_PATH_AIX([$1])
         _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
-        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
       else
        if test "$host_cpu" = ia64; then
          _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
@@ -4658,14 +5119,19 @@ _LT_EOF
        else
         # Determine the default libpath from the value encoded in an
         # empty executable.
-        _LT_SYS_MODULE_PATH_AIX
+        _LT_SYS_MODULE_PATH_AIX([$1])
         _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
          # Warning - without using the other run time loading flags,
          # -berok will link without error, but may produce a broken library.
          _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
          _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
-         # Exported symbols can be pulled into shared objects from archives
-         _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+         if test "$with_gnu_ld" = yes; then
+           # We only use this code for GNU lds that support --whole-archive.
+           _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+         else
+           # Exported symbols can be pulled into shared objects from archives
+           _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+         fi
          _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
          # This is similar to how AIX traditionally builds its shared libraries.
          _LT_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname'
@@ -4697,20 +5163,64 @@ _LT_EOF
       # Microsoft Visual C++.
       # hardcode_libdir_flag_spec is actually meaningless, as there is
       # no search path for DLLs.
-      _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
-      _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
-      # Tell ltmain to make .lib files, not .a files.
-      libext=lib
-      # Tell ltmain to make .dll files, not .so files.
-      shrext_cmds=".dll"
-      # FIXME: Setting linknames here is a bad hack.
-      _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames='
-      # The linker will automatically build a .lib file if we build a DLL.
-      _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
-      # FIXME: Should let the user specify the lib program.
-      _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
-      _LT_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`'
-      _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+      case $cc_basename in
+      cl*)
+       # Native MSVC
+       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+       _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+       _LT_TAGVAR(always_export_symbols, $1)=yes
+       _LT_TAGVAR(file_list_spec, $1)='@'
+       # Tell ltmain to make .lib files, not .a files.
+       libext=lib
+       # Tell ltmain to make .dll files, not .so files.
+       shrext_cmds=".dll"
+       # FIXME: Setting linknames here is a bad hack.
+       _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+       _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED \"$sed_uncomment_deffile\" $export_symbols | $SED 1q`" = xEXPORTS; then
+           sed -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+         else
+           sed -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+         fi~
+         $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+         linknames='
+       # The linker will not automatically build a static lib if we build a DLL.
+       # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+       _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+       _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*'
+       _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1,DATA/'\'' | $SED -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols'
+       # Don't use ranlib
+       _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+       _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+         lt_tool_outputfile="@TOOL_OUTPUT@"~
+         case $lt_outputfile in
+           *.exe|*.EXE) ;;
+           *)
+             lt_outputfile="$lt_outputfile.exe"
+             lt_tool_outputfile="$lt_tool_outputfile.exe"
+             ;;
+         esac~
+         if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+           $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+           $RM "$lt_outputfile.manifest";
+         fi'
+       ;;
+      *)
+       # Assume MSVC wrapper
+       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+       _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+       # Tell ltmain to make .lib files, not .a files.
+       libext=lib
+       # Tell ltmain to make .dll files, not .so files.
+       shrext_cmds=".dll"
+       # FIXME: Setting linknames here is a bad hack.
+       _LT_TAGVAR(archive_cmds, $1)='$CC -o $lib $libobjs $compiler_flags `func_echo_all "$deplibs" | $SED '\''s/ -lc$//'\''` -link -dll~linknames='
+       # The linker will automatically build a .lib file if we build a DLL.
+       _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+       # FIXME: Should let the user specify the lib program.
+       _LT_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs'
+       _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+       ;;
+      esac
       ;;
 
     darwin* | rhapsody*)
@@ -4723,10 +5233,6 @@ _LT_EOF
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
       ;;
 
-    freebsd1*)
-      _LT_TAGVAR(ld_shlibs, $1)=no
-      ;;
-
     # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor
     # support.  Future versions do this automatically, but an explicit c++rt0.o
     # does not break anything, and helps significantly (at the cost of a little
@@ -4739,7 +5245,7 @@ _LT_EOF
       ;;
 
     # Unfortunately, older versions of FreeBSD 2 do not have this feature.
-    freebsd2*)
+    freebsd2.*)
       _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags'
       _LT_TAGVAR(hardcode_direct, $1)=yes
       _LT_TAGVAR(hardcode_minus_L, $1)=yes
@@ -4748,7 +5254,7 @@ _LT_EOF
 
     # FreeBSD 3 and greater uses gcc -shared to do shared libraries.
     freebsd* | dragonfly*)
-      _LT_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags'
+      _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags'
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
       _LT_TAGVAR(hardcode_direct, $1)=yes
       _LT_TAGVAR(hardcode_shlibpath_var, $1)=no
@@ -4756,7 +5262,7 @@ _LT_EOF
 
     hpux9*)
       if test "$GCC" = yes; then
-       _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+       _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
       else
        _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
       fi
@@ -4771,14 +5277,13 @@ _LT_EOF
       ;;
 
     hpux10*)
-      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
-       _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
+       _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
       else
        _LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'
       fi
       if test "$with_gnu_ld" = no; then
        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
-       _LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir'
        _LT_TAGVAR(hardcode_libdir_separator, $1)=:
        _LT_TAGVAR(hardcode_direct, $1)=yes
        _LT_TAGVAR(hardcode_direct_absolute, $1)=yes
@@ -4790,16 +5295,16 @@ _LT_EOF
       ;;
 
     hpux11*)
-      if test "$GCC" = yes -a "$with_gnu_ld" = no; then
+      if test "$GCC" = yes && test "$with_gnu_ld" = no; then
        case $host_cpu in
        hppa*64*)
          _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
          ;;
        ia64*)
-         _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
+         _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
          ;;
        *)
-         _LT_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+         _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
          ;;
        esac
       else
@@ -4811,7 +5316,14 @@ _LT_EOF
          _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags'
          ;;
        *)
-         _LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'
+       m4_if($1, [], [
+         # Older versions of the 11.00 compiler do not understand -b yet
+         # (HP92453-01 A.11.01.20 doesn't, HP92453-01 B.11.X.35175-35176.GP does)
+         _LT_LINKER_OPTION([if $CC understands -b],
+           _LT_TAGVAR(lt_cv_prog_compiler__b, $1), [-b],
+           [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'],
+           [_LT_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags'])],
+         [_LT_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags'])
          ;;
        esac
       fi
@@ -4839,19 +5351,34 @@ _LT_EOF
 
     irix5* | irix6* | nonstopux*)
       if test "$GCC" = yes; then
-       _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+       _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
        # Try to use the -exported_symbol ld option, if it does not
        # work, assume that -exports_file does not work either and
        # implicitly export all symbols.
-        save_LDFLAGS="$LDFLAGS"
-        LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
-        AC_LINK_IFELSE(int foo(void) {},
-          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
-        )
-        LDFLAGS="$save_LDFLAGS"
+       # This should be the same for all languages, so no per-tag cache variable.
+       AC_CACHE_CHECK([whether the $host_os linker accepts -exported_symbol],
+         [lt_cv_irix_exported_symbol],
+         [save_LDFLAGS="$LDFLAGS"
+          LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null"
+          AC_LINK_IFELSE(
+            [AC_LANG_SOURCE(
+               [AC_LANG_CASE([C], [[int foo (void) { return 0; }]],
+                             [C++], [[int foo (void) { return 0; }]],
+                             [Fortran 77], [[
+      subroutine foo
+      end]],
+                             [Fortran], [[
+      subroutine foo
+      end]])])],
+             [lt_cv_irix_exported_symbol=yes],
+             [lt_cv_irix_exported_symbol=no])
+           LDFLAGS="$save_LDFLAGS"])
+       if test "$lt_cv_irix_exported_symbol" = yes; then
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib'
+       fi
       else
-       _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
-       _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
+       _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
+       _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib'
       fi
       _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
@@ -4913,17 +5440,17 @@ _LT_EOF
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
       _LT_TAGVAR(hardcode_minus_L, $1)=yes
       _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
-      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
+      _LT_TAGVAR(archive_cmds, $1)='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~echo DATA >> $output_objdir/$libname.def~echo " SINGLE NONSHARED" >> $output_objdir/$libname.def~echo EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def'
       _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def'
       ;;
 
     osf3*)
       if test "$GCC" = yes; then
        _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
-       _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+       _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
       else
        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
-       _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+       _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
       fi
       _LT_TAGVAR(archive_cmds_need_lc, $1)='no'
       _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
@@ -4933,13 +5460,13 @@ _LT_EOF
     osf4* | osf5*)     # as osf3* with the addition of -msym flag
       if test "$GCC" = yes; then
        _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
-       _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+       _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $pic_flag $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
       else
        _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
-       _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+       _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
        _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~
-       $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
+       $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp'
 
        # Both c and cxx compiler support -rpath directly
        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
@@ -4952,9 +5479,9 @@ _LT_EOF
       _LT_TAGVAR(no_undefined_flag, $1)=' -z defs'
       if test "$GCC" = yes; then
        wlarc='${wl}'
-       _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
+       _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags'
        _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-         $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
+         $CC -shared $pic_flag ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp'
       else
        case `$CC -V 2>&1` in
        *"Compilers 5.0"*)
@@ -5130,36 +5657,38 @@ x|xyes)
       # Test whether the compiler implicitly links with -lc since on some
       # systems, -lgcc has to come before -lc. If gcc already passes -lc
       # to ld, don't add -lc before -lgcc.
-      AC_MSG_CHECKING([whether -lc should be explicitly linked in])
-      $RM conftest*
-      echo "$lt_simple_compile_test_code" > conftest.$ac_ext
-
-      if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
-        soname=conftest
-        lib=conftest
-        libobjs=conftest.$ac_objext
-        deplibs=
-        wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
-       pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
-        compiler_flags=-v
-        linker_flags=-v
-        verstring=
-        output_objdir=.
-        libname=conftest
-        lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
-        _LT_TAGVAR(allow_undefined_flag, $1)=
-        if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
-        then
-         _LT_TAGVAR(archive_cmds_need_lc, $1)=no
-        else
-         _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
-        fi
-        _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
-      else
-        cat conftest.err 1>&5
-      fi
-      $RM conftest*
-      AC_MSG_RESULT([$_LT_TAGVAR(archive_cmds_need_lc, $1)])
+      AC_CACHE_CHECK([whether -lc should be explicitly linked in],
+       [lt_cv_]_LT_TAGVAR(archive_cmds_need_lc, $1),
+       [$RM conftest*
+       echo "$lt_simple_compile_test_code" > conftest.$ac_ext
+
+       if AC_TRY_EVAL(ac_compile) 2>conftest.err; then
+         soname=conftest
+         lib=conftest
+         libobjs=conftest.$ac_objext
+         deplibs=
+         wl=$_LT_TAGVAR(lt_prog_compiler_wl, $1)
+         pic_flag=$_LT_TAGVAR(lt_prog_compiler_pic, $1)
+         compiler_flags=-v
+         linker_flags=-v
+         verstring=
+         output_objdir=.
+         libname=conftest
+         lt_save_allow_undefined_flag=$_LT_TAGVAR(allow_undefined_flag, $1)
+         _LT_TAGVAR(allow_undefined_flag, $1)=
+         if AC_TRY_EVAL(_LT_TAGVAR(archive_cmds, $1) 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1)
+         then
+           lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+         else
+           lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)=yes
+         fi
+         _LT_TAGVAR(allow_undefined_flag, $1)=$lt_save_allow_undefined_flag
+       else
+         cat conftest.err 1>&5
+       fi
+       $RM conftest*
+       ])
+      _LT_TAGVAR(archive_cmds_need_lc, $1)=$lt_cv_[]_LT_TAGVAR(archive_cmds_need_lc, $1)
       ;;
     esac
   fi
@@ -5196,9 +5725,6 @@ _LT_TAGDECL([], [no_undefined_flag], [1],
 _LT_TAGDECL([], [hardcode_libdir_flag_spec], [1],
     [Flag to hardcode $libdir into a binary during linking.
     This must work even if $libdir does not exist])
-_LT_TAGDECL([], [hardcode_libdir_flag_spec_ld], [1],
-    [[If ld is used when linking, flag to hardcode $libdir into a binary
-    during linking.  This must work even if $libdir does not exist]])
 _LT_TAGDECL([], [hardcode_libdir_separator], [1],
     [Whether we need a single "-rpath" flag with a separated argument])
 _LT_TAGDECL([], [hardcode_direct], [0],
@@ -5224,8 +5750,6 @@ _LT_TAGDECL([], [inherit_rpath], [0],
     to runtime path list])
 _LT_TAGDECL([], [link_all_deplibs], [0],
     [Whether libtool must link a program against all its dependency libraries])
-_LT_TAGDECL([], [fix_srcfile_path], [1],
-    [Fix the shell variable $srcfile for the compiler])
 _LT_TAGDECL([], [always_export_symbols], [0],
     [Set to "yes" if exported symbols are required])
 _LT_TAGDECL([], [export_symbols_cmds], [2],
@@ -5236,6 +5760,8 @@ _LT_TAGDECL([], [include_expsyms], [1],
     [Symbols that must always be exported])
 _LT_TAGDECL([], [prelink_cmds], [2],
     [Commands necessary for linking programs (against libraries) with templates])
+_LT_TAGDECL([], [postlink_cmds], [2],
+    [Commands necessary for finishing linking programs])
 _LT_TAGDECL([], [file_list_spec], [1],
     [Specify filename containing input files])
 dnl FIXME: Not yet implemented
@@ -5329,37 +5855,22 @@ CC="$lt_save_CC"
 ])# _LT_LANG_C_CONFIG
 
 
-# _LT_PROG_CXX
-# ------------
-# Since AC_PROG_CXX is broken, in that it returns g++ if there is no c++
-# compiler, we have our own version here.
-m4_defun([_LT_PROG_CXX],
-[
-pushdef([AC_MSG_ERROR], [_lt_caught_CXX_error=yes])
-AC_PROG_CXX
-if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
-    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
-    (test "X$CXX" != "Xg++"))) ; then
-  AC_PROG_CXXCPP
-else
-  _lt_caught_CXX_error=yes
-fi
-popdef([AC_MSG_ERROR])
-])# _LT_PROG_CXX
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([_LT_PROG_CXX], [])
-
-
 # _LT_LANG_CXX_CONFIG([TAG])
 # --------------------------
 # Ensure that the configuration variables for a C++ compiler are suitably
 # defined.  These variables are subsequently used by _LT_CONFIG to write
 # the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_CXX_CONFIG],
-[AC_REQUIRE([_LT_PROG_CXX])dnl
-m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+[m4_require([_LT_FILEUTILS_DEFAULTS])dnl
 m4_require([_LT_DECL_EGREP])dnl
+m4_require([_LT_PATH_MANIFEST_TOOL])dnl
+if test -n "$CXX" && ( test "X$CXX" != "Xno" &&
+    ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) ||
+    (test "X$CXX" != "Xg++"))) ; then
+  AC_PROG_CXXCPP
+else
+  _lt_caught_CXX_error=yes
+fi
 
 AC_LANG_PUSH(C++)
 _LT_TAGVAR(archive_cmds_need_lc, $1)=no
@@ -5371,7 +5882,6 @@ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
 _LT_TAGVAR(hardcode_direct, $1)=no
 _LT_TAGVAR(hardcode_direct_absolute, $1)=no
 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
-_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
 _LT_TAGVAR(hardcode_libdir_separator, $1)=
 _LT_TAGVAR(hardcode_minus_L, $1)=no
 _LT_TAGVAR(hardcode_shlibpath_var, $1)=unsupported
@@ -5381,6 +5891,8 @@ _LT_TAGVAR(module_cmds, $1)=
 _LT_TAGVAR(module_expsym_cmds, $1)=
 _LT_TAGVAR(link_all_deplibs, $1)=unknown
 _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
 _LT_TAGVAR(no_undefined_flag, $1)=
 _LT_TAGVAR(whole_archive_flag_spec, $1)=
 _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
@@ -5412,6 +5924,7 @@ if test "$_lt_caught_CXX_error" != yes; then
 
   # Allow CC to be a program name with arguments.
   lt_save_CC=$CC
+  lt_save_CFLAGS=$CFLAGS
   lt_save_LD=$LD
   lt_save_GCC=$GCC
   GCC=$GXX
@@ -5429,6 +5942,7 @@ if test "$_lt_caught_CXX_error" != yes; then
   fi
   test -z "${LDCXX+set}" || LD=$LDCXX
   CC=${CXX-"c++"}
+  CFLAGS=$CXXFLAGS
   compiler=$CC
   _LT_TAGVAR(compiler, $1)=$CC
   _LT_CC_BASENAME([$compiler])
@@ -5450,8 +5964,8 @@ if test "$_lt_caught_CXX_error" != yes; then
       # Check if GNU C++ uses GNU ld as the underlying linker, since the
       # archiving commands below assume that GNU ld is being used.
       if test "$with_gnu_ld" = yes; then
-        _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
-        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
+        _LT_TAGVAR(archive_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(archive_expsym_cmds, $1)='$CC $pic_flag -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib'
 
         _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
         _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
@@ -5483,7 +5997,7 @@ if test "$_lt_caught_CXX_error" != yes; then
       # Commands to make compiler produce verbose output that lists
       # what "hidden" libraries, object files and flags are used when
       # linking a shared library.
-      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+      output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 
     else
       GXX=no
@@ -5592,10 +6106,10 @@ if test "$_lt_caught_CXX_error" != yes; then
           _LT_TAGVAR(allow_undefined_flag, $1)='-berok'
           # Determine the default libpath from the value encoded in an empty
           # executable.
-          _LT_SYS_MODULE_PATH_AIX
+          _LT_SYS_MODULE_PATH_AIX([$1])
           _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
 
-          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
+          _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then func_echo_all "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag"
         else
           if test "$host_cpu" = ia64; then
            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib'
@@ -5604,14 +6118,19 @@ if test "$_lt_caught_CXX_error" != yes; then
           else
            # Determine the default libpath from the value encoded in an
            # empty executable.
-           _LT_SYS_MODULE_PATH_AIX
+           _LT_SYS_MODULE_PATH_AIX([$1])
            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath"
            # Warning - without using the other run time loading flags,
            # -berok will link without error, but may produce a broken library.
            _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok'
            _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok'
-           # Exported symbols can be pulled into shared objects from archives
-           _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+           if test "$with_gnu_ld" = yes; then
+             # We only use this code for GNU lds that support --whole-archive.
+             _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive'
+           else
+             # Exported symbols can be pulled into shared objects from archives
+             _LT_TAGVAR(whole_archive_flag_spec, $1)='$convenience'
+           fi
            _LT_TAGVAR(archive_cmds_need_lc, $1)=yes
            # This is similar to how AIX traditionally builds its shared
            # libraries.
@@ -5641,28 +6160,75 @@ if test "$_lt_caught_CXX_error" != yes; then
         ;;
 
       cygwin* | mingw* | pw32* | cegcc*)
-        # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
-        # as there is no search path for DLLs.
-        _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
-        _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
-        _LT_TAGVAR(always_export_symbols, $1)=no
-        _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
-
-        if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
-          _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-          # If the export-symbols file already is a .def file (1st line
-          # is EXPORTS), use it as is; otherwise, prepend...
-          _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then
-           cp $export_symbols $output_objdir/$soname.def;
-          else
-           echo EXPORTS > $output_objdir/$soname.def;
-           cat $export_symbols >> $output_objdir/$soname.def;
-          fi~
-          $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
-        else
-          _LT_TAGVAR(ld_shlibs, $1)=no
-        fi
-        ;;
+       case $GXX,$cc_basename in
+       ,cl* | no,cl*)
+         # Native MSVC
+         # hardcode_libdir_flag_spec is actually meaningless, as there is
+         # no search path for DLLs.
+         _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' '
+         _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+         _LT_TAGVAR(always_export_symbols, $1)=yes
+         _LT_TAGVAR(file_list_spec, $1)='@'
+         # Tell ltmain to make .lib files, not .a files.
+         libext=lib
+         # Tell ltmain to make .dll files, not .so files.
+         shrext_cmds=".dll"
+         # FIXME: Setting linknames here is a bad hack.
+         _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-dll~linknames='
+         _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED \"$sed_uncomment_deffile\" $export_symbols | $SED 1q`" = xEXPORTS; then
+             $SED -n -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' -e '1\\\!p' < $export_symbols > $output_objdir/$soname.exp;
+           else
+             $SED -e 's/\\\\\\\(.*\\\\\\\)/-link\\\ -EXPORT:\\\\\\\1/' < $export_symbols > $output_objdir/$soname.exp;
+           fi~
+           $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~
+           linknames='
+         # The linker will not automatically build a static lib if we build a DLL.
+         # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true'
+         _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+         # Don't use ranlib
+         _LT_TAGVAR(old_postinstall_cmds, $1)='chmod 644 $oldlib'
+         _LT_TAGVAR(postlink_cmds, $1)='lt_outputfile="@OUTPUT@"~
+           lt_tool_outputfile="@TOOL_OUTPUT@"~
+           case $lt_outputfile in
+             *.exe|*.EXE) ;;
+             *)
+               lt_outputfile="$lt_outputfile.exe"
+               lt_tool_outputfile="$lt_tool_outputfile.exe"
+               ;;
+           esac~
+           func_to_tool_file "$lt_outputfile"~
+           if test "$MANIFEST_TOOL" != ":" && test -f "$lt_outputfile.manifest"; then
+             $MANIFEST_TOOL -manifest "$lt_tool_outputfile.manifest" -outputresource:"$lt_tool_outputfile" || exit 1;
+             $RM "$lt_outputfile.manifest";
+           fi'
+         ;;
+       *)
+         # g++
+         # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless,
+         # as there is no search path for DLLs.
+         _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir'
+         _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-all-symbols'
+         _LT_TAGVAR(allow_undefined_flag, $1)=unsupported
+         _LT_TAGVAR(always_export_symbols, $1)=no
+         _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes
+
+         if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then
+           _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+           # If the export-symbols file already is a .def file (1st line
+           # is EXPORTS), use it as is; otherwise, prepend...
+           _LT_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED \"$sed_uncomment_deffile\" $export_symbols | $SED 1q`" = xEXPORTS; then
+             cp $export_symbols $output_objdir/$soname.def;
+           else
+             echo EXPORTS > $output_objdir/$soname.def;
+             cat $export_symbols >> $output_objdir/$soname.def;
+           fi~
+           $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib'
+         else
+           _LT_TAGVAR(ld_shlibs, $1)=no
+         fi
+         ;;
+       esac
+       ;;
       darwin* | rhapsody*)
         _LT_DARWIN_LINKER_FEATURES($1)
        ;;
@@ -5685,7 +6251,7 @@ if test "$_lt_caught_CXX_error" != yes; then
         esac
         ;;
 
-      freebsd[[12]]*)
+      freebsd2.*)
         # C++ shared libraries reported to be fairly broken before
        # switch to ELF
         _LT_TAGVAR(ld_shlibs, $1)=no
@@ -5704,6 +6270,11 @@ if test "$_lt_caught_CXX_error" != yes; then
       gnu*)
         ;;
 
+      haiku*)
+        _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib'
+        _LT_TAGVAR(link_all_deplibs, $1)=yes
+        ;;
+
       hpux9*)
         _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir'
         _LT_TAGVAR(hardcode_libdir_separator, $1)=:
@@ -5728,11 +6299,11 @@ if test "$_lt_caught_CXX_error" != yes; then
             # explicitly linking system object files so we need to strip them
             # from the output so that they don't get included in the library
             # dependencies.
-            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+            output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
             ;;
           *)
             if test "$GXX" = yes; then
-              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
+              _LT_TAGVAR(archive_cmds, $1)='$RM $output_objdir/$soname~$CC -shared -nostdlib $pic_flag ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib'
             else
               # FIXME: insert proper C++ library support
               _LT_TAGVAR(ld_shlibs, $1)=no
@@ -5793,7 +6364,7 @@ if test "$_lt_caught_CXX_error" != yes; then
            # explicitly linking system object files so we need to strip them
            # from the output so that they don't get included in the library
            # dependencies.
-           output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+           output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
            ;;
           *)
            if test "$GXX" = yes; then
@@ -5803,10 +6374,10 @@ if test "$_lt_caught_CXX_error" != yes; then
                    _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
                    ;;
                  ia64*)
-                   _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+                   _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
                    ;;
                  *)
-                   _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
+                   _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $pic_flag ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
                    ;;
                esac
              fi
@@ -5836,7 +6407,7 @@ if test "$_lt_caught_CXX_error" != yes; then
         case $cc_basename in
           CC*)
            # SGI C++
-           _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+           _LT_TAGVAR(archive_cmds, $1)='$CC -shared -all -multigot $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
 
            # Archives containing C++ object files must be created using
            # "CC -ar", where "CC" is the IRIX C++ compiler.  This is
@@ -5847,9 +6418,9 @@ if test "$_lt_caught_CXX_error" != yes; then
           *)
            if test "$GXX" = yes; then
              if test "$with_gnu_ld" = no; then
-               _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+               _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
              else
-               _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` -o $lib'
+               _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` -o $lib'
              fi
            fi
            _LT_TAGVAR(link_all_deplibs, $1)=yes
@@ -5860,7 +6431,7 @@ if test "$_lt_caught_CXX_error" != yes; then
         _LT_TAGVAR(inherit_rpath, $1)=yes
         ;;
 
-      linux* | k*bsd*-gnu)
+      linux* | k*bsd*-gnu | kopensolaris*-gnu)
         case $cc_basename in
           KCC*)
            # Kuck and Associates, Inc. (KAI) C++ Compiler
@@ -5878,7 +6449,7 @@ if test "$_lt_caught_CXX_error" != yes; then
            # explicitly linking system object files so we need to strip them
            # from the output so that they don't get included in the library
            # dependencies.
-           output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+           output_verbose_link_cmd='templist=`$CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 | $GREP "ld"`; rm -f libconftest$shared_ext; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
 
            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir'
            _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
@@ -5915,26 +6486,26 @@ if test "$_lt_caught_CXX_error" != yes; then
           pgCC* | pgcpp*)
             # Portland Group C++ compiler
            case `$CC -V` in
-           *pgCC\ [[1-5]]* | *pgcpp\ [[1-5]]*)
+           *pgCC\ [[1-5]].* | *pgcpp\ [[1-5]].*)
              _LT_TAGVAR(prelink_cmds, $1)='tpldir=Template.dir~
                rm -rf $tpldir~
                $CC --prelink_objects --instantiation_dir $tpldir $objs $libobjs $compile_deplibs~
-               compile_command="$compile_command `find $tpldir -name \*.o | $NL2SP`"'
+               compile_command="$compile_command `find $tpldir -name \*.o | sort | $NL2SP`"'
              _LT_TAGVAR(old_archive_cmds, $1)='tpldir=Template.dir~
                rm -rf $tpldir~
                $CC --prelink_objects --instantiation_dir $tpldir $oldobjs$old_deplibs~
-               $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | $NL2SP`~
+               $AR $AR_FLAGS $oldlib$oldobjs$old_deplibs `find $tpldir -name \*.o | sort | $NL2SP`~
                $RANLIB $oldlib'
              _LT_TAGVAR(archive_cmds, $1)='tpldir=Template.dir~
                rm -rf $tpldir~
                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
-               $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
+               $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
              _LT_TAGVAR(archive_expsym_cmds, $1)='tpldir=Template.dir~
                rm -rf $tpldir~
                $CC --prelink_objects --instantiation_dir $tpldir $predep_objects $libobjs $deplibs $convenience $postdep_objects~
-               $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
+               $CC -shared $pic_flag $predep_objects $libobjs $deplibs `find $tpldir -name \*.o | sort | $NL2SP` $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
              ;;
-           *) # Version 6 will use weak symbols
+           *) # Version 6 and above use weak symbols
              _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib'
              _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib'
              ;;
@@ -5942,7 +6513,7 @@ if test "$_lt_caught_CXX_error" != yes; then
 
            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir'
            _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
-           _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+           _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test  -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
             ;;
          cxx*)
            # Compaq C++
@@ -5961,9 +6532,9 @@ if test "$_lt_caught_CXX_error" != yes; then
            # explicitly linking system object files so we need to strip them
            # from the output so that they don't get included in the library
            # dependencies.
-           output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+           output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "X$list" | $Xsed'
            ;;
-         xl*)
+         xl* | mpixl* | bgxl*)
            # IBM XL 8.0 on PPC, with GNU ld
            _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
            _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic'
@@ -5983,13 +6554,13 @@ if test "$_lt_caught_CXX_error" != yes; then
              _LT_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags'
              _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols'
              _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir'
-             _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive'
+             _LT_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` ${wl}--no-whole-archive'
              _LT_TAGVAR(compiler_needs_object, $1)=yes
 
              # Not sure whether something based on
              # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1
              # would be better.
-             output_verbose_link_cmd='echo'
+             output_verbose_link_cmd='func_echo_all'
 
              # Archives containing C++ object files must be created using
              # "CC -xar", where "CC" is the Sun C++ compiler.  This is
@@ -6058,7 +6629,7 @@ if test "$_lt_caught_CXX_error" != yes; then
            _LT_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E'
            _LT_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive'
          fi
-         output_verbose_link_cmd=echo
+         output_verbose_link_cmd=func_echo_all
        else
          _LT_TAGVAR(ld_shlibs, $1)=no
        fi
@@ -6093,15 +6664,15 @@ if test "$_lt_caught_CXX_error" != yes; then
            case $host in
              osf3*)
                _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
-               _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && $ECHO "X${wl}-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+               _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname $soname `test -n "$verstring" && func_echo_all "${wl}-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
                _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir'
                ;;
              *)
                _LT_TAGVAR(allow_undefined_flag, $1)=' -expect_unresolved \*'
-               _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib'
+               _LT_TAGVAR(archive_cmds, $1)='$CC -shared${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname `test -n "$verstring" && func_echo_all "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib'
                _LT_TAGVAR(archive_expsym_cmds, $1)='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done~
                  echo "-hidden">> $lib.exp~
-                 $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~
+                 $CC -shared$allow_undefined_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -msym -soname $soname ${wl}-input ${wl}$lib.exp  `test -n "$verstring" && $ECHO "-set_version $verstring"` -update_registry ${output_objdir}/so_locations -o $lib~
                  $RM $lib.exp'
                _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-rpath $libdir'
                ;;
@@ -6117,17 +6688,17 @@ if test "$_lt_caught_CXX_error" != yes; then
            # explicitly linking system object files so we need to strip them
            # from the output so that they don't get included in the library
            # dependencies.
-           output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`$ECHO "X$templist" | $Xsed -e "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; $ECHO "X$list" | $Xsed'
+           output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "ld" | $GREP -v "ld:"`; templist=`func_echo_all "$templist" | $SED "s/\(^.*ld.*\)\( .*ld.*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"'
            ;;
          *)
            if test "$GXX" = yes && test "$with_gnu_ld" = no; then
              _LT_TAGVAR(allow_undefined_flag, $1)=' ${wl}-expect_unresolved ${wl}\*'
              case $host in
                osf3*)
-                 _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+                 _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
                  ;;
                *)
-                 _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
+                 _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib ${allow_undefined_flag} $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && func_echo_all "${wl}-set_version ${wl}$verstring"` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib'
                  ;;
              esac
 
@@ -6137,7 +6708,7 @@ if test "$_lt_caught_CXX_error" != yes; then
              # Commands to make compiler produce verbose output that lists
              # what "hidden" libraries, object files and flags are used when
              # linking a shared library.
-             output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+             output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
 
            else
              # FIXME: insert proper C++ library support
@@ -6173,7 +6744,7 @@ if test "$_lt_caught_CXX_error" != yes; then
 
       solaris*)
         case $cc_basename in
-          CC*)
+          CC* | sunCC*)
            # Sun C++ 4.2, 5.x and Centerline C++
             _LT_TAGVAR(archive_cmds_need_lc,$1)=yes
            _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs'
@@ -6194,7 +6765,7 @@ if test "$_lt_caught_CXX_error" != yes; then
            esac
            _LT_TAGVAR(link_all_deplibs, $1)=yes
 
-           output_verbose_link_cmd='echo'
+           output_verbose_link_cmd='func_echo_all'
 
            # Archives containing C++ object files must be created using
            # "CC -xar", where "CC" is the Sun C++ compiler.  This is
@@ -6214,14 +6785,14 @@ if test "$_lt_caught_CXX_error" != yes; then
            if test "$GXX" = yes && test "$with_gnu_ld" = no; then
              _LT_TAGVAR(no_undefined_flag, $1)=' ${wl}-z ${wl}defs'
              if $CC --version | $GREP -v '^2\.7' > /dev/null; then
-               _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
+               _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -nostdlib $LDFLAGS $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-h $wl$soname -o $lib'
                _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~
-                 $CC -shared -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
+                 $CC -shared $pic_flag -nostdlib ${wl}-M $wl$lib.exp -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$RM $lib.exp'
 
                # Commands to make compiler produce verbose output that lists
                # what "hidden" libraries, object files and flags are used when
                # linking a shared library.
-               output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+               output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
              else
                # g++ 2.7 appears to require `-G' NOT `-shared' on this
                # platform.
@@ -6232,7 +6803,7 @@ if test "$_lt_caught_CXX_error" != yes; then
                # Commands to make compiler produce verbose output that lists
                # what "hidden" libraries, object files and flags are used when
                # linking a shared library.
-               output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP "\-L"'
+               output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"'
              fi
 
              _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir'
@@ -6286,6 +6857,10 @@ if test "$_lt_caught_CXX_error" != yes; then
           CC*)
            _LT_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
            _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
+           _LT_TAGVAR(old_archive_cmds, $1)='$CC -Tprelink_objects $oldobjs~
+             '"$_LT_TAGVAR(old_archive_cmds, $1)"
+           _LT_TAGVAR(reload_cmds, $1)='$CC -Tprelink_objects $reload_objs~
+             '"$_LT_TAGVAR(reload_cmds, $1)"
            ;;
          *)
            _LT_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags'
@@ -6341,6 +6916,7 @@ if test "$_lt_caught_CXX_error" != yes; then
   fi # test -n "$compiler"
 
   CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
   LDCXX=$LD
   LD=$lt_save_LD
   GCC=$lt_save_GCC
@@ -6355,6 +6931,29 @@ AC_LANG_POP
 ])# _LT_LANG_CXX_CONFIG
 
 
+# _LT_FUNC_STRIPNAME_CNF
+# ----------------------
+# func_stripname_cnf prefix suffix name
+# strip PREFIX and SUFFIX off of NAME.
+# PREFIX and SUFFIX must not contain globbing or regex special
+# characters, hashes, percent signs, but SUFFIX may contain a leading
+# dot (in which case that matches only a dot).
+#
+# This function is identical to the (non-XSI) version of func_stripname,
+# except this one can be used by m4 code that may be executed by configure,
+# rather than the libtool script.
+m4_defun([_LT_FUNC_STRIPNAME_CNF],[dnl
+AC_REQUIRE([_LT_DECL_SED])
+AC_REQUIRE([_LT_PROG_ECHO_BACKSLASH])
+func_stripname_cnf ()
+{
+  case ${2} in
+  .*) func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%\\\\${2}\$%%"`;;
+  *)  func_stripname_result=`$ECHO "${3}" | $SED "s%^${1}%%; s%${2}\$%%"`;;
+  esac
+} # func_stripname_cnf
+])# _LT_FUNC_STRIPNAME_CNF
+
 # _LT_SYS_HIDDEN_LIBDEPS([TAGNAME])
 # ---------------------------------
 # Figure out "hidden" library dependencies from verbose
@@ -6363,6 +6962,7 @@ AC_LANG_POP
 # objects, libraries and library flags.
 m4_defun([_LT_SYS_HIDDEN_LIBDEPS],
 [m4_require([_LT_FILEUTILS_DEFAULTS])dnl
+AC_REQUIRE([_LT_FUNC_STRIPNAME_CNF])dnl
 # Dependencies to place before and after the object being linked:
 _LT_TAGVAR(predep_objects, $1)=
 _LT_TAGVAR(postdep_objects, $1)=
@@ -6412,7 +7012,20 @@ public class foo {
   }
 };
 _LT_EOF
+], [$1], [GO], [cat > conftest.$ac_ext <<_LT_EOF
+package foo
+func foo() {
+}
+_LT_EOF
 ])
+
+_lt_libdeps_save_CFLAGS=$CFLAGS
+case "$CC $CFLAGS " in #(
+*\ -flto*\ *) CFLAGS="$CFLAGS -fno-lto" ;;
+*\ -fwhopr*\ *) CFLAGS="$CFLAGS -fno-whopr" ;;
+*\ -fuse-linker-plugin*\ *) CFLAGS="$CFLAGS -fno-use-linker-plugin" ;;
+esac
+
 dnl Parse the compiler output and extract the necessary
 dnl objects, libraries and library flags.
 if AC_TRY_EVAL(ac_compile); then
@@ -6424,7 +7037,7 @@ if AC_TRY_EVAL(ac_compile); then
   pre_test_object_deps_done=no
 
   for p in `eval "$output_verbose_link_cmd"`; do
-    case $p in
+    case ${prev}${p} in
 
     -L* | -R* | -l*)
        # Some compilers place space between "-{L,R}" and the path.
@@ -6433,13 +7046,22 @@ if AC_TRY_EVAL(ac_compile); then
           test $p = "-R"; then
         prev=$p
         continue
-       else
-        prev=
        fi
 
+       # Expand the sysroot to ease extracting the directories later.
+       if test -z "$prev"; then
+         case $p in
+         -L*) func_stripname_cnf '-L' '' "$p"; prev=-L; p=$func_stripname_result ;;
+         -R*) func_stripname_cnf '-R' '' "$p"; prev=-R; p=$func_stripname_result ;;
+         -l*) func_stripname_cnf '-l' '' "$p"; prev=-l; p=$func_stripname_result ;;
+         esac
+       fi
+       case $p in
+       =*) func_stripname_cnf '=' '' "$p"; p=$lt_sysroot$func_stripname_result ;;
+       esac
        if test "$pre_test_object_deps_done" = no; then
-        case $p in
-        -L* | -R*)
+        case ${prev} in
+        -L | -R)
           # Internal compiler library paths should come after those
           # provided the user.  The postdeps already come after the
           # user supplied libs so there is no need to process them.
@@ -6459,8 +7081,10 @@ if AC_TRY_EVAL(ac_compile); then
           _LT_TAGVAR(postdeps, $1)="${_LT_TAGVAR(postdeps, $1)} ${prev}${p}"
         fi
        fi
+       prev=
        ;;
 
+    *.lto.$objext) ;; # Ignore GCC LTO objects
     *.$objext)
        # This assumes that the test object file only shows up
        # once in the compiler output.
@@ -6496,6 +7120,7 @@ else
 fi
 
 $RM -f confest.$objext
+CFLAGS=$_lt_libdeps_save_CFLAGS
 
 # PORTME: override above test on systems where it is broken
 m4_if([$1], [CXX],
@@ -6532,7 +7157,7 @@ linux*)
 
 solaris*)
   case $cc_basename in
-  CC*)
+  CC* | sunCC*)
     # The more standards-conforming stlport4 library is
     # incompatible with the Cstd library. Avoid specifying
     # it if it's in CXXFLAGS. Ignore libCrun as
@@ -6576,32 +7201,16 @@ _LT_TAGDECL([], [compiler_lib_search_path], [1],
 ])# _LT_SYS_HIDDEN_LIBDEPS
 
 
-# _LT_PROG_F77
-# ------------
-# Since AC_PROG_F77 is broken, in that it returns the empty string
-# if there is no fortran compiler, we have our own version here.
-m4_defun([_LT_PROG_F77],
-[
-pushdef([AC_MSG_ERROR], [_lt_disable_F77=yes])
-AC_PROG_F77
-if test -z "$F77" || test "X$F77" = "Xno"; then
-  _lt_disable_F77=yes
-fi
-popdef([AC_MSG_ERROR])
-])# _LT_PROG_F77
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([_LT_PROG_F77], [])
-
-
 # _LT_LANG_F77_CONFIG([TAG])
 # --------------------------
 # Ensure that the configuration variables for a Fortran 77 compiler are
 # suitably defined.  These variables are subsequently used by _LT_CONFIG
 # to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_F77_CONFIG],
-[AC_REQUIRE([_LT_PROG_F77])dnl
-AC_LANG_PUSH(Fortran 77)
+[AC_LANG_PUSH(Fortran 77)
+if test -z "$F77" || test "X$F77" = "Xno"; then
+  _lt_disable_F77=yes
+fi
 
 _LT_TAGVAR(archive_cmds_need_lc, $1)=no
 _LT_TAGVAR(allow_undefined_flag, $1)=
@@ -6611,7 +7220,6 @@ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
 _LT_TAGVAR(hardcode_direct, $1)=no
 _LT_TAGVAR(hardcode_direct_absolute, $1)=no
 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
-_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
 _LT_TAGVAR(hardcode_libdir_separator, $1)=
 _LT_TAGVAR(hardcode_minus_L, $1)=no
 _LT_TAGVAR(hardcode_automatic, $1)=no
@@ -6620,6 +7228,8 @@ _LT_TAGVAR(module_cmds, $1)=
 _LT_TAGVAR(module_expsym_cmds, $1)=
 _LT_TAGVAR(link_all_deplibs, $1)=unknown
 _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
 _LT_TAGVAR(no_undefined_flag, $1)=
 _LT_TAGVAR(whole_archive_flag_spec, $1)=
 _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
@@ -6659,7 +7269,9 @@ if test "$_lt_disable_F77" != yes; then
   # Allow CC to be a program name with arguments.
   lt_save_CC="$CC"
   lt_save_GCC=$GCC
+  lt_save_CFLAGS=$CFLAGS
   CC=${F77-"f77"}
+  CFLAGS=$FFLAGS
   compiler=$CC
   _LT_TAGVAR(compiler, $1)=$CC
   _LT_CC_BASENAME([$compiler])
@@ -6713,38 +7325,24 @@ if test "$_lt_disable_F77" != yes; then
 
   GCC=$lt_save_GCC
   CC="$lt_save_CC"
+  CFLAGS="$lt_save_CFLAGS"
 fi # test "$_lt_disable_F77" != yes
 
 AC_LANG_POP
 ])# _LT_LANG_F77_CONFIG
 
 
-# _LT_PROG_FC
-# -----------
-# Since AC_PROG_FC is broken, in that it returns the empty string
-# if there is no fortran compiler, we have our own version here.
-m4_defun([_LT_PROG_FC],
-[
-pushdef([AC_MSG_ERROR], [_lt_disable_FC=yes])
-AC_PROG_FC
-if test -z "$FC" || test "X$FC" = "Xno"; then
-  _lt_disable_FC=yes
-fi
-popdef([AC_MSG_ERROR])
-])# _LT_PROG_FC
-
-dnl aclocal-1.4 backwards compatibility:
-dnl AC_DEFUN([_LT_PROG_FC], [])
-
-
 # _LT_LANG_FC_CONFIG([TAG])
 # -------------------------
 # Ensure that the configuration variables for a Fortran compiler are
 # suitably defined.  These variables are subsequently used by _LT_CONFIG
 # to write the compiler configuration to `libtool'.
 m4_defun([_LT_LANG_FC_CONFIG],
-[AC_REQUIRE([_LT_PROG_FC])dnl
-AC_LANG_PUSH(Fortran)
+[AC_LANG_PUSH(Fortran)
+
+if test -z "$FC" || test "X$FC" = "Xno"; then
+  _lt_disable_FC=yes
+fi
 
 _LT_TAGVAR(archive_cmds_need_lc, $1)=no
 _LT_TAGVAR(allow_undefined_flag, $1)=
@@ -6754,7 +7352,6 @@ _LT_TAGVAR(export_dynamic_flag_spec, $1)=
 _LT_TAGVAR(hardcode_direct, $1)=no
 _LT_TAGVAR(hardcode_direct_absolute, $1)=no
 _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=
-_LT_TAGVAR(hardcode_libdir_flag_spec_ld, $1)=
 _LT_TAGVAR(hardcode_libdir_separator, $1)=
 _LT_TAGVAR(hardcode_minus_L, $1)=no
 _LT_TAGVAR(hardcode_automatic, $1)=no
@@ -6763,6 +7360,8 @@ _LT_TAGVAR(module_cmds, $1)=
 _LT_TAGVAR(module_expsym_cmds, $1)=
 _LT_TAGVAR(link_all_deplibs, $1)=unknown
 _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
 _LT_TAGVAR(no_undefined_flag, $1)=
 _LT_TAGVAR(whole_archive_flag_spec, $1)=
 _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=no
@@ -6802,7 +7401,9 @@ if test "$_lt_disable_FC" != yes; then
   # Allow CC to be a program name with arguments.
   lt_save_CC="$CC"
   lt_save_GCC=$GCC
+  lt_save_CFLAGS=$CFLAGS
   CC=${FC-"f95"}
+  CFLAGS=$FCFLAGS
   compiler=$CC
   GCC=$ac_cv_fc_compiler_gnu
 
@@ -6858,7 +7459,8 @@ if test "$_lt_disable_FC" != yes; then
   fi # test -n "$compiler"
 
   GCC=$lt_save_GCC
-  CC="$lt_save_CC"
+  CC=$lt_save_CC
+  CFLAGS=$lt_save_CFLAGS
 fi # test "$_lt_disable_FC" != yes
 
 AC_LANG_POP
@@ -6895,10 +7497,12 @@ _LT_COMPILER_BOILERPLATE
 _LT_LINKER_BOILERPLATE
 
 # Allow CC to be a program name with arguments.
-lt_save_CC="$CC"
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
 lt_save_GCC=$GCC
 GCC=yes
 CC=${GCJ-"gcj"}
+CFLAGS=$GCJFLAGS
 compiler=$CC
 _LT_TAGVAR(compiler, $1)=$CC
 _LT_TAGVAR(LD, $1)="$LD"
@@ -6908,6 +7512,8 @@ _LT_CC_BASENAME([$compiler])
 _LT_TAGVAR(archive_cmds_need_lc, $1)=no
 
 _LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
 
 ## CAVEAT EMPTOR:
 ## There is no encapsulation within the following macros, do not change
@@ -6927,10 +7533,82 @@ fi
 AC_LANG_RESTORE
 
 GCC=$lt_save_GCC
-CC="$lt_save_CC"
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
 ])# _LT_LANG_GCJ_CONFIG
 
 
+# _LT_LANG_GO_CONFIG([TAG])
+# --------------------------
+# Ensure that the configuration variables for the GNU Go compiler
+# are suitably defined.  These variables are subsequently used by _LT_CONFIG
+# to write the compiler configuration to `libtool'.
+m4_defun([_LT_LANG_GO_CONFIG],
+[AC_REQUIRE([LT_PROG_GO])dnl
+AC_LANG_SAVE
+
+# Source file extension for Go test sources.
+ac_ext=go
+
+# Object file extension for compiled Go test sources.
+objext=o
+_LT_TAGVAR(objext, $1)=$objext
+
+# Code to be used in simple compile tests
+lt_simple_compile_test_code="package main; func main() { }"
+
+# Code to be used in simple link tests
+lt_simple_link_test_code='package main; func main() { }'
+
+# ltmain only uses $CC for tagged configurations so make sure $CC is set.
+_LT_TAG_COMPILER
+
+# save warnings/boilerplate of simple test code
+_LT_COMPILER_BOILERPLATE
+_LT_LINKER_BOILERPLATE
+
+# Allow CC to be a program name with arguments.
+lt_save_CC=$CC
+lt_save_CFLAGS=$CFLAGS
+lt_save_GCC=$GCC
+GCC=yes
+CC=${GOC-"gccgo"}
+CFLAGS=$GOFLAGS
+compiler=$CC
+_LT_TAGVAR(compiler, $1)=$CC
+_LT_TAGVAR(LD, $1)="$LD"
+_LT_CC_BASENAME([$compiler])
+
+# Go did not exist at the time GCC didn't implicitly link libc in.
+_LT_TAGVAR(archive_cmds_need_lc, $1)=no
+
+_LT_TAGVAR(old_archive_cmds, $1)=$old_archive_cmds
+_LT_TAGVAR(reload_flag, $1)=$reload_flag
+_LT_TAGVAR(reload_cmds, $1)=$reload_cmds
+
+## CAVEAT EMPTOR:
+## There is no encapsulation within the following macros, do not change
+## the running order or otherwise move them around unless you know exactly
+## what you are doing...
+if test -n "$compiler"; then
+  _LT_COMPILER_NO_RTTI($1)
+  _LT_COMPILER_PIC($1)
+  _LT_COMPILER_C_O($1)
+  _LT_COMPILER_FILE_LOCKS($1)
+  _LT_LINKER_SHLIBS($1)
+  _LT_LINKER_HARDCODE_LIBPATH($1)
+
+  _LT_CONFIG($1)
+fi
+
+AC_LANG_RESTORE
+
+GCC=$lt_save_GCC
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
+])# _LT_LANG_GO_CONFIG
+
+
 # _LT_LANG_RC_CONFIG([TAG])
 # -------------------------
 # Ensure that the configuration variables for the Windows resource compiler
@@ -6962,9 +7640,11 @@ _LT_LINKER_BOILERPLATE
 
 # Allow CC to be a program name with arguments.
 lt_save_CC="$CC"
+lt_save_CFLAGS=$CFLAGS
 lt_save_GCC=$GCC
 GCC=
 CC=${RC-"windres"}
+CFLAGS=
 compiler=$CC
 _LT_TAGVAR(compiler, $1)=$CC
 _LT_CC_BASENAME([$compiler])
@@ -6977,7 +7657,8 @@ fi
 
 GCC=$lt_save_GCC
 AC_LANG_RESTORE
-CC="$lt_save_CC"
+CC=$lt_save_CC
+CFLAGS=$lt_save_CFLAGS
 ])# _LT_LANG_RC_CONFIG
 
 
@@ -6997,6 +7678,13 @@ dnl aclocal-1.4 backwards compatibility:
 dnl AC_DEFUN([LT_AC_PROG_GCJ], [])
 
 
+# LT_PROG_GO
+# ----------
+AC_DEFUN([LT_PROG_GO],
+[AC_CHECK_TOOL(GOC, gccgo,)
+])
+
+
 # LT_PROG_RC
 # ----------
 AC_DEFUN([LT_PROG_RC],
@@ -7036,6 +7724,15 @@ _LT_DECL([], [OBJDUMP], [1], [An object symbol dumper])
 AC_SUBST([OBJDUMP])
 ])
 
+# _LT_DECL_DLLTOOL
+# ----------------
+# Ensure DLLTOOL variable is set.
+m4_defun([_LT_DECL_DLLTOOL],
+[AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+test -z "$DLLTOOL" && DLLTOOL=dlltool
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])
+AC_SUBST([DLLTOOL])
+])
 
 # _LT_DECL_SED
 # ------------
@@ -7129,8 +7826,8 @@ m4_defun([_LT_CHECK_SHELL_FEATURES],
 # Try some XSI features
 xsi_shell=no
 ( _lt_dummy="a/b/c"
-  test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \
-      = c,a/b,, \
+  test "${_lt_dummy##*/},${_lt_dummy%/*},${_lt_dummy#??}"${_lt_dummy%"$_lt_dummy"}, \
+      = c,a/b,b/c, \
     && eval 'test $(( 1 + 1 )) -eq 2 \
     && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \
   && xsi_shell=yes
@@ -7169,208 +7866,162 @@ _LT_DECL([NL2SP], [lt_NL2SP], [1], [turn newlines into spaces])dnl
 ])# _LT_CHECK_SHELL_FEATURES
 
 
-# _LT_PROG_XSI_SHELLFNS
-# ---------------------
-# Bourne and XSI compatible variants of some useful shell functions.
-m4_defun([_LT_PROG_XSI_SHELLFNS],
-[case $xsi_shell in
-  yes)
-    cat << \_LT_EOF >> "$cfgfile"
-
-# func_dirname file append nondir_replacement
-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-func_dirname ()
-{
-  case ${1} in
-    */*) func_dirname_result="${1%/*}${2}" ;;
-    *  ) func_dirname_result="${3}" ;;
-  esac
-}
-
-# func_basename file
-func_basename ()
-{
-  func_basename_result="${1##*/}"
-}
-
-# func_dirname_and_basename file append nondir_replacement
-# perform func_basename and func_dirname in a single function
-# call:
-#   dirname:  Compute the dirname of FILE.  If nonempty,
-#             add APPEND to the result, otherwise set result
-#             to NONDIR_REPLACEMENT.
-#             value returned in "$func_dirname_result"
-#   basename: Compute filename of FILE.
-#             value retuned in "$func_basename_result"
-# Implementation must be kept synchronized with func_dirname
-# and func_basename. For efficiency, we do not delegate to
-# those functions but instead duplicate the functionality here.
-func_dirname_and_basename ()
-{
-  case ${1} in
-    */*) func_dirname_result="${1%/*}${2}" ;;
-    *  ) func_dirname_result="${3}" ;;
-  esac
-  func_basename_result="${1##*/}"
-}
-
-# func_stripname prefix suffix name
-# strip PREFIX and SUFFIX off of NAME.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-func_stripname ()
-{
-  # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
-  # positional parameters, so assign one to ordinary parameter first.
-  func_stripname_result=${3}
-  func_stripname_result=${func_stripname_result#"${1}"}
-  func_stripname_result=${func_stripname_result%"${2}"}
-}
-
-# func_opt_split
-func_opt_split ()
-{
-  func_opt_split_opt=${1%%=*}
-  func_opt_split_arg=${1#*=}
-}
-
-# func_lo2o object
-func_lo2o ()
-{
-  case ${1} in
-    *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
-    *)    func_lo2o_result=${1} ;;
-  esac
-}
+# _LT_PROG_FUNCTION_REPLACE (FUNCNAME, REPLACEMENT-BODY)
+# ------------------------------------------------------
+# In `$cfgfile', look for function FUNCNAME delimited by `^FUNCNAME ()$' and
+# '^} FUNCNAME ', and replace its body with REPLACEMENT-BODY.
+m4_defun([_LT_PROG_FUNCTION_REPLACE],
+[dnl {
+sed -e '/^$1 ()$/,/^} # $1 /c\
+$1 ()\
+{\
+m4_bpatsubsts([$2], [$], [\\], [^\([    ]\)], [\\\1])
+} # Extended-shell $1 implementation' "$cfgfile" > $cfgfile.tmp \
+  && mv -f "$cfgfile.tmp" "$cfgfile" \
+    || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+test 0 -eq $? || _lt_function_replace_fail=:
+])
 
-# func_xform libobj-or-source
-func_xform ()
-{
-  func_xform_result=${1%.*}.lo
-}
 
-# func_arith arithmetic-term...
-func_arith ()
-{
-  func_arith_result=$(( $[*] ))
-}
+# _LT_PROG_REPLACE_SHELLFNS
+# -------------------------
+# Replace existing portable implementations of several shell functions with
+# equivalent extended shell implementations where those features are available..
+m4_defun([_LT_PROG_REPLACE_SHELLFNS],
+[if test x"$xsi_shell" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_dirname], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac])
+
+  _LT_PROG_FUNCTION_REPLACE([func_basename], [dnl
+    func_basename_result="${1##*/}"])
+
+  _LT_PROG_FUNCTION_REPLACE([func_dirname_and_basename], [dnl
+    case ${1} in
+      */*) func_dirname_result="${1%/*}${2}" ;;
+      *  ) func_dirname_result="${3}" ;;
+    esac
+    func_basename_result="${1##*/}"])
 
-# func_len string
-# STRING may not start with a hyphen.
-func_len ()
-{
-  func_len_result=${#1}
-}
+  _LT_PROG_FUNCTION_REPLACE([func_stripname], [dnl
+    # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are
+    # positional parameters, so assign one to ordinary parameter first.
+    func_stripname_result=${3}
+    func_stripname_result=${func_stripname_result#"${1}"}
+    func_stripname_result=${func_stripname_result%"${2}"}])
 
-_LT_EOF
-    ;;
-  *) # Bourne compatible functions.
-    cat << \_LT_EOF >> "$cfgfile"
+  _LT_PROG_FUNCTION_REPLACE([func_split_long_opt], [dnl
+    func_split_long_opt_name=${1%%=*}
+    func_split_long_opt_arg=${1#*=}])
 
-# func_dirname file append nondir_replacement
-# Compute the dirname of FILE.  If nonempty, add APPEND to the result,
-# otherwise set result to NONDIR_REPLACEMENT.
-func_dirname ()
-{
-  # Extract subdirectory from the argument.
-  func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"`
-  if test "X$func_dirname_result" = "X${1}"; then
-    func_dirname_result="${3}"
-  else
-    func_dirname_result="$func_dirname_result${2}"
-  fi
-}
+  _LT_PROG_FUNCTION_REPLACE([func_split_short_opt], [dnl
+    func_split_short_opt_arg=${1#??}
+    func_split_short_opt_name=${1%"$func_split_short_opt_arg"}])
 
-# func_basename file
-func_basename ()
-{
-  func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"`
-}
+  _LT_PROG_FUNCTION_REPLACE([func_lo2o], [dnl
+    case ${1} in
+      *.lo) func_lo2o_result=${1%.lo}.${objext} ;;
+      *)    func_lo2o_result=${1} ;;
+    esac])
 
-dnl func_dirname_and_basename
-dnl A portable version of this function is already defined in general.m4sh
-dnl so there is no need for it here.
+  _LT_PROG_FUNCTION_REPLACE([func_xform], [    func_xform_result=${1%.*}.lo])
 
-# func_stripname prefix suffix name
-# strip PREFIX and SUFFIX off of NAME.
-# PREFIX and SUFFIX must not contain globbing or regex special
-# characters, hashes, percent signs, but SUFFIX may contain a leading
-# dot (in which case that matches only a dot).
-# func_strip_suffix prefix name
-func_stripname ()
-{
-  case ${2} in
-    .*) func_stripname_result=`$ECHO "X${3}" \
-           | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;;
-    *)  func_stripname_result=`$ECHO "X${3}" \
-           | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;;
-  esac
-}
+  _LT_PROG_FUNCTION_REPLACE([func_arith], [    func_arith_result=$(( $[*] ))])
 
-# sed scripts:
-my_sed_long_opt='1s/^\(-[[^=]]*\)=.*/\1/;q'
-my_sed_long_arg='1s/^-[[^=]]*=//'
+  _LT_PROG_FUNCTION_REPLACE([func_len], [    func_len_result=${#1}])
+fi
 
-# func_opt_split
-func_opt_split ()
-{
-  func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"`
-  func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"`
-}
+if test x"$lt_shell_append" = xyes; then
+  _LT_PROG_FUNCTION_REPLACE([func_append], [    eval "${1}+=\\${2}"])
 
-# func_lo2o object
-func_lo2o ()
-{
-  func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"`
-}
+  _LT_PROG_FUNCTION_REPLACE([func_append_quoted], [dnl
+    func_quote_for_eval "${2}"
+dnl m4 expansion turns \\\\ into \\, and then the shell eval turns that into \
+    eval "${1}+=\\\\ \\$func_quote_for_eval_result"])
 
-# func_xform libobj-or-source
-func_xform ()
-{
-  func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[[^.]]*$/.lo/'`
-}
-
-# func_arith arithmetic-term...
-func_arith ()
-{
-  func_arith_result=`expr "$[@]"`
-}
-
-# func_len string
-# STRING may not start with a hyphen.
-func_len ()
-{
-  func_len_result=`expr "$[1]" : ".*" 2>/dev/null || echo $max_cmd_len`
-}
-
-_LT_EOF
-esac
+  # Save a `func_append' function call where possible by direct use of '+='
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1+="%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+else
+  # Save a `func_append' function call even when '+=' is not available
+  sed -e 's%func_append \([[a-zA-Z_]]\{1,\}\) "%\1="$\1%g' $cfgfile > $cfgfile.tmp \
+    && mv -f "$cfgfile.tmp" "$cfgfile" \
+      || (rm -f "$cfgfile" && cp "$cfgfile.tmp" "$cfgfile" && rm -f "$cfgfile.tmp")
+  test 0 -eq $? || _lt_function_replace_fail=:
+fi
 
-case $lt_shell_append in
-  yes)
-    cat << \_LT_EOF >> "$cfgfile"
+if test x"$_lt_function_replace_fail" = x":"; then
+  AC_MSG_WARN([Unable to substitute extended shell functions in $ofile])
+fi
+])
 
-# func_append var value
-# Append VALUE to the end of shell variable VAR.
-func_append ()
-{
-  eval "$[1]+=\$[2]"
-}
-_LT_EOF
+# _LT_PATH_CONVERSION_FUNCTIONS
+# -----------------------------
+# Determine which file name conversion functions should be used by
+# func_to_host_file (and, implicitly, by func_to_host_path).  These are needed
+# for certain cross-compile configurations and native mingw.
+m4_defun([_LT_PATH_CONVERSION_FUNCTIONS],
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_MSG_CHECKING([how to convert $build file names to $host format])
+AC_CACHE_VAL(lt_cv_to_host_file_cmd,
+[case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_cygwin_to_w32
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_w32
+        ;;
+    esac
     ;;
-  *)
-    cat << \_LT_EOF >> "$cfgfile"
-
-# func_append var value
-# Append VALUE to the end of shell variable VAR.
-func_append ()
-{
-  eval "$[1]=\$$[1]\$[2]"
-}
-
-_LT_EOF
+  *-*-cygwin* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin
+        ;;
+      *-*-cygwin* )
+        lt_cv_to_host_file_cmd=func_convert_file_noop
+        ;;
+      * ) # otherwise, assume *nix
+        lt_cv_to_host_file_cmd=func_convert_file_nix_to_cygwin
+        ;;
+    esac
     ;;
-  esac
+  * ) # unhandled hosts (and "normal" native builds)
+    lt_cv_to_host_file_cmd=func_convert_file_noop
+    ;;
+esac
+])
+to_host_file_cmd=$lt_cv_to_host_file_cmd
+AC_MSG_RESULT([$lt_cv_to_host_file_cmd])
+_LT_DECL([to_host_file_cmd], [lt_cv_to_host_file_cmd],
+         [0], [convert $build file names to $host format])dnl
+
+AC_MSG_CHECKING([how to convert $build file names to toolchain format])
+AC_CACHE_VAL(lt_cv_to_tool_file_cmd,
+[#assume ordinary cross tools, or native build.
+lt_cv_to_tool_file_cmd=func_convert_file_noop
+case $host in
+  *-*-mingw* )
+    case $build in
+      *-*-mingw* ) # actually msys
+        lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32
+        ;;
+    esac
+    ;;
+esac
 ])
+to_tool_file_cmd=$lt_cv_to_tool_file_cmd
+AC_MSG_RESULT([$lt_cv_to_tool_file_cmd])
+_LT_DECL([to_tool_file_cmd], [lt_cv_to_tool_file_cmd],
+         [0], [convert $build files to toolchain format])dnl
+])# _LT_PATH_CONVERSION_FUNCTIONS
diff --git a/m4/lock.m4 b/m4/lock.m4
new file mode 100644 (file)
index 0000000..73a3c54
--- /dev/null
@@ -0,0 +1,42 @@
+# 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], [:])
index 34151a3..5d9acd8 100644 (file)
@@ -1,13 +1,14 @@
 # Helper functions for option handling.                    -*- Autoconf -*-
 #
-#   Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
+#   Copyright (C) 2004, 2005, 2007, 2008, 2009 Free Software Foundation,
+#   Inc.
 #   Written by Gary V. Vaughan, 2004
 #
 # 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 ltoptions.m4
+# serial 7 ltoptions.m4
 
 # This is to help aclocal find these macros, as it can't see m4_define.
 AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
@@ -125,7 +126,7 @@ LT_OPTION_DEFINE([LT_INIT], [win32-dll],
 [enable_win32_dll=yes
 
 case $host in
-*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*)
+*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*)
   AC_CHECK_TOOL(AS, as, false)
   AC_CHECK_TOOL(DLLTOOL, dlltool, false)
   AC_CHECK_TOOL(OBJDUMP, objdump, false)
@@ -133,13 +134,13 @@ case $host in
 esac
 
 test -z "$AS" && AS=as
-_LT_DECL([], [AS],      [0], [Assembler program])dnl
+_LT_DECL([], [AS],      [1], [Assembler program])dnl
 
 test -z "$DLLTOOL" && DLLTOOL=dlltool
-_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl
+_LT_DECL([], [DLLTOOL], [1], [DLL creation program])dnl
 
 test -z "$OBJDUMP" && OBJDUMP=objdump
-_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl
+_LT_DECL([], [OBJDUMP], [1], [Object dumper program])dnl
 ])# win32-dll
 
 AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
@@ -325,9 +326,24 @@ dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
 # MODE is either `yes' or `no'.  If omitted, it defaults to `both'.
 m4_define([_LT_WITH_PIC],
 [AC_ARG_WITH([pic],
-    [AS_HELP_STRING([--with-pic],
+    [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@],
        [try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
-    [pic_mode="$withval"],
+    [lt_p=${PACKAGE-default}
+    case $withval in
+    yes|no) pic_mode=$withval ;;
+    *)
+      pic_mode=default
+      # Look at the argument we got.  We use all the common list separators.
+      lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
+      for lt_pkg in $withval; do
+       IFS="$lt_save_ifs"
+       if test "X$lt_pkg" = "X$lt_p"; then
+         pic_mode=yes
+       fi
+      done
+      IFS="$lt_save_ifs"
+      ;;
+    esac],
     [pic_mode=default])
 
 test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
index f3c5309..07a8602 100644 (file)
@@ -7,17 +7,17 @@
 # unlimited permission to copy and/or distribute it, with or without
 # modifications, as long as this notice is preserved.
 
-# Generated from ltversion.in.
+# @configure_input@
 
-# serial 3017 ltversion.m4
+# serial 3337 ltversion.m4
 # This file is part of GNU Libtool
 
-m4_define([LT_PACKAGE_VERSION], [2.2.6b])
-m4_define([LT_PACKAGE_REVISION], [1.3017])
+m4_define([LT_PACKAGE_VERSION], [2.4.2])
+m4_define([LT_PACKAGE_REVISION], [1.3337])
 
 AC_DEFUN([LTVERSION_VERSION],
-[macro_version='2.2.6b'
-macro_revision='1.3017'
+[macro_version='2.4.2'
+macro_revision='1.3337'
 _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
 _LT_DECL(, macro_revision, 0)
 ])
index 637bb20..c573da9 100644 (file)
@@ -1,13 +1,13 @@
 # lt~obsolete.m4 -- aclocal satisfying obsolete definitions.    -*-Autoconf-*-
 #
-#   Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
+#   Copyright (C) 2004, 2005, 2007, 2009 Free Software Foundation, Inc.
 #   Written by Scott James Remnant, 2004.
 #
 # 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 lt~obsolete.m4
+# serial 5 lt~obsolete.m4
 
 # These exist entirely to fool aclocal when bootstrapping libtool.
 #
@@ -77,7 +77,6 @@ m4_ifndef([AC_DISABLE_FAST_INSTALL],  [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
 m4_ifndef([_LT_AC_LANG_CXX],           [AC_DEFUN([_LT_AC_LANG_CXX])])
 m4_ifndef([_LT_AC_LANG_F77],           [AC_DEFUN([_LT_AC_LANG_F77])])
 m4_ifndef([_LT_AC_LANG_GCJ],           [AC_DEFUN([_LT_AC_LANG_GCJ])])
-m4_ifndef([AC_LIBTOOL_RC],             [AC_DEFUN([AC_LIBTOOL_RC])])
 m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG],  [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
 m4_ifndef([_LT_AC_LANG_C_CONFIG],      [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
 m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG],        [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
@@ -90,3 +89,10 @@ m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG],       [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
 m4_ifndef([_LT_AC_LANG_RC_CONFIG],     [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
 m4_ifndef([AC_LIBTOOL_CONFIG],         [AC_DEFUN([AC_LIBTOOL_CONFIG])])
 m4_ifndef([_LT_AC_FILE_LTDLL_C],       [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])
+m4_ifndef([_LT_REQUIRED_DARWIN_CHECKS],        [AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS])])
+m4_ifndef([_LT_AC_PROG_CXXCPP],                [AC_DEFUN([_LT_AC_PROG_CXXCPP])])
+m4_ifndef([_LT_PREPARE_SED_QUOTE_VARS],        [AC_DEFUN([_LT_PREPARE_SED_QUOTE_VARS])])
+m4_ifndef([_LT_PROG_ECHO_BACKSLASH],   [AC_DEFUN([_LT_PROG_ECHO_BACKSLASH])])
+m4_ifndef([_LT_PROG_F77],              [AC_DEFUN([_LT_PROG_F77])])
+m4_ifndef([_LT_PROG_FC],               [AC_DEFUN([_LT_PROG_FC])])
+m4_ifndef([_LT_PROG_CXX],              [AC_DEFUN([_LT_PROG_CXX])])
diff --git a/m4/threadlib.m4 b/m4/threadlib.m4
new file mode 100644 (file)
index 0000000..b015365
--- /dev/null
@@ -0,0 +1,349 @@
+# 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.
similarity index 97%
rename from mpi/ChangeLog
rename to mpi/ChangeLog-2011
index 7d32f5a..1e07872 100644 (file)
@@ -1,3 +1,15 @@
+2011-12-01  Werner Koch  <wk@g10code.com>
+
+       NB: ChangeLog files are no longer manually maintained.  Starting
+       on December 1st, 2011 we put change information only in the GIT
+       commit log, and generate a top-level ChangeLog file from logs at
+       "make dist".  See doc/HACKING for details.
+
+2011-07-04  Werner Koch  <wk@g10code.com>
+
+       * longlong.h (add_ssaaaa) [__arm__]: Do no use asm if thumb code
+       generation is enabled.  This is bug#1202.  Reported for gpg 1.4.
+
 2011-03-28  Werner Koch  <wk@g10code.com>
 
        * mpi-pow.c (gcry_mpi_powm): Remove unused var RSEC.
 
        * mpi-internal.h: Put limb_t definition in an ifdef.
 
-       Major change:
+       Major change:
        Removed all GnuPG stuff and renamed this piece of software
        to gcrypt.
 
@@ -813,3 +825,7 @@ Mon Feb 16 13:00:27 1998  Werner Koch  (wk@isil.d.shuttle.de)
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
index e900539..c41b1ea 100644 (file)
@@ -174,4 +174,4 @@ libmpi_la_SOURCES = longlong.h         \
              mpih-div.c     \
              mpih-mul.c     \
              mpiutil.c      \
-              ec.c
+              ec.c ec-internal.h ec-ed25519.c
index d9039d2..dc0798d 100644 (file)
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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; \
+    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;; \
+    esac; \
+    test $$am__dry = yes; \
+  }
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -57,18 +74,19 @@ POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
 subdir = mpi
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ChangeLog
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.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/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/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
        $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
-       $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+       $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/acinclude.m4 \
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 CONFIG_CLEAN_VPATH_FILES =
@@ -77,7 +95,7 @@ libmpi_la_LIBADD =
 am_libmpi_la_OBJECTS = mpi-add.lo mpi-bit.lo mpi-cmp.lo mpi-div.lo \
        mpi-gcd.lo mpi-inline.lo mpi-inv.lo mpi-mul.lo mpi-mod.lo \
        mpi-pow.lo mpi-mpow.lo mpi-scan.lo mpicoder.lo mpih-div.lo \
-       mpih-mul.lo mpiutil.lo ec.lo
+       mpih-mul.lo mpiutil.lo ec.lo ec-ed25519.lo
 @MPI_MOD_ASM_MPIH_ADD1_FALSE@@MPI_MOD_C_MPIH_ADD1_TRUE@am__objects_1 = mpih-add1.lo
 @MPI_MOD_ASM_MPIH_ADD1_TRUE@am__objects_1 = mpih-add1-asm.lo
 @MPI_MOD_ASM_MPIH_SUB1_FALSE@@MPI_MOD_C_MPIH_SUB1_TRUE@am__objects_2 = mpih-sub1.lo
@@ -102,34 +120,60 @@ nodist_libmpi_la_OBJECTS = $(am__objects_1) $(am__objects_2) \
        $(am__objects_9)
 libmpi_la_OBJECTS = $(am_libmpi_la_OBJECTS) \
        $(nodist_libmpi_la_OBJECTS)
-libmpi_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+libmpi_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
        $(libmpi_la_LDFLAGS) $(LDFLAGS) -o $@
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
 am__depfiles_maybe = depfiles
 am__mv = mv -f
 CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
        $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)
-LTCPPASCOMPILE = $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-       --mode=compile $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
-       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS)
+LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \
+       $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(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 = @
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
-       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+       $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(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    " $@;
 CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
-       $(LDFLAGS) -o $@
+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   " $@;
 SOURCES = $(libmpi_la_SOURCES) $(nodist_libmpi_la_SOURCES)
 DIST_SOURCES = $(libmpi_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AR = @AR@
 AS = @AS@
 AUTOCONF = @AUTOCONF@
@@ -144,6 +188,7 @@ CCAS = @CCAS@
 CCASDEPMODE = @CCASDEPMODE@
 CCASFLAGS = @CCASFLAGS@
 CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
@@ -163,6 +208,8 @@ FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
 FGREP = @FGREP@
 GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
 GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_HWF_MODULES = @GCRYPT_HWF_MODULES@
+GCRYPT_KDFS = @GCRYPT_KDFS@
 GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
 GCRYPT_RANDOM = @GCRYPT_RANDOM@
 GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
@@ -188,14 +235,19 @@ 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@
 MKDIR_P = @MKDIR_P@
 MPI_SFLAGS = @MPI_SFLAGS@
 NM = @NM@
@@ -218,16 +270,19 @@ PTH_CONFIG = @PTH_CONFIG@
 PTH_LIBS = @PTH_LIBS@
 RANLIB = @RANLIB@
 RC = @RC@
+RUN_LARGE_DATA_TESTS = @RUN_LARGE_DATA_TESTS@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
 SYS_SOCKET_H = @SYS_SOCKET_H@
 VERSION = @VERSION@
+VERSION_NUMBER = @VERSION_NUMBER@
 abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
@@ -263,7 +318,6 @@ libdir = @libdir@
 libexecdir = @libexecdir@
 localedir = @localedir@
 localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 oldincludedir = @oldincludedir@
@@ -369,7 +423,7 @@ libmpi_la_SOURCES = longlong.h         \
              mpih-div.c     \
              mpih-mul.c     \
              mpiutil.c      \
-              ec.c
+              ec.c ec-internal.h ec-ed25519.c
 
 all: all-am
 
@@ -414,8 +468,8 @@ clean-noinstLTLIBRARIES:
          echo "rm -f \"$${dir}/so_locations\""; \
          rm -f "$${dir}/so_locations"; \
        done
-libmpi.la: $(libmpi_la_OBJECTS) $(libmpi_la_DEPENDENCIES) 
-       $(libmpi_la_LINK)  $(libmpi_la_OBJECTS) $(libmpi_la_LIBADD) $(LIBS)
+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)
 
 mostlyclean-compile:
        -rm -f *.$(OBJEXT)
@@ -423,6 +477,7 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec-ed25519.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ec.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-add.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpi-bit.Plo@am__quote@
@@ -460,46 +515,46 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/udiv.Plo@am__quote@
 
 .S.o:
-@am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCCAS_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCCAS_FALSE@    source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@    $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCCAS_FALSE@    DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCCAS_FALSE@        $(CPPASCOMPILE) -c -o $@ $<
+@am__fastdepCCAS_FALSE@        $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ $<
 
 .S.obj:
-@am__fastdepCCAS_TRUE@ $(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCCAS_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCCAS_FALSE@    source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@    $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCCAS_FALSE@    DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCCAS_FALSE@        $(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCCAS_FALSE@        $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
 
 .S.lo:
-@am__fastdepCCAS_TRUE@ $(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCCAS_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCCAS_FALSE@    source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCCAS_FALSE@    $(AM_V_CPPAS)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCCAS_FALSE@    DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCCAS_FALSE@        $(LTCPPASCOMPILE) -c -o $@ $<
+@am__fastdepCCAS_FALSE@        $(AM_V_CPPAS@am__nodep@)$(LTCPPASCOMPILE) -c -o $@ $<
 
 .c.o:
-@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@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@  $(COMPILE) -c $<
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
 
 .c.obj:
-@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@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@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
 
 .c.lo:
-@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
 mostlyclean-libtool:
        -rm -f *.lo
@@ -603,10 +658,15 @@ install-am: all-am
 
 installcheck: installcheck-am
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-         `test -z '$(STRIP)' || \
-           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+       if test -z '$(STRIP)'; then \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+             install; \
+       else \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+           "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+       fi
 mostlyclean-generic:
 
 clean-generic:
index 1180f76..a332a1d 100644 (file)
 #include "sysdep.h"
 #include "asm-syntax.h"
 
-
-/*******************
- * mpi_limb_t
- * _gcry_mpih_addmul_2( mpi_ptr_t res_ptr,      (sp + 4)
- *                  mpi_ptr_t s1_ptr,       (sp + 8)
- *                  mpi_size_t s1_size,     (sp + 12)
- *                  mpi_limb_t s2_limb)     (sp + 16)
- */
-
-       /* i80386 addmul_1 -- Multiply a limb vector with a limb and add
- *                   the result to a second limb vector.
- *
- *      Copyright (C) 1992, 1994, 1998,
- *                    2001, 2002 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
- *
- * Note: This code is heavily based on the GNU MP Library.
- *      Actually it's the same code with only minor changes in the
- *      way the data is stored; this is to support the abstraction
- *      of an optional secure memory allocation which may be used
- *      to avoid revealing of sensitive data due to paging etc.
- */
-
-
-#include "sysdep.h"
-#include "asm-syntax.h"
-
-
 /*******************
  * mpi_limb_t
  * _gcry_mpih_addmul_1( mpi_ptr_t res_ptr,   (rdi)
index 7e910ee..0217d35 100644 (file)
@@ -1,5 +1,6 @@
 # config.links - helper for ../configure             -*- mode: sh -*-
 # Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
+# Copyright (C) 2012  g10 Code GmbH
 #
 # This file is part of Libgcrypt.
 #
 # sourced by ../configure to get the list of files to link
 # this should set $mpi_ln_list.
 # Note: this is called from the above directory.
+#
+# Reguired variables:
+#  $ac_cv_sys_symbol_underscore
+#  $gcry_cv_gcc_arm_platform_as_ok
 
 mpi_sflags=
 mpi_extra_modules=
+mpi_cpu_arch=
 
 test -d ./mpi || mkdir ./mpi
 
@@ -37,13 +43,13 @@ mpi_optional_modules=`$AWK '/^#BEGIN_ASM_LIST/,/^#END_ASM_LIST/ {
 echo '/* created by config.links - do not edit */' >./mpi/asm-syntax.h
 echo "/* Host: ${host} */" >>./mpi/asm-syntax.h
 
-if test "$try_asm_modules" = "yes" ; then
 case "${host}" in
     powerpc-apple-darwin*          | \
     i[34567]86*-*-openbsd[12]*     | \
     i[34567]86*-*-openbsd3.[0123]*)
        echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
        path=""
+       mpi_cpu_arch="x86"
        ;;
     i[3467]86*-*-openbsd*      | \
     i[3467]86*-*-freebsd*-elf  | \
@@ -54,6 +60,7 @@ case "${host}" in
        echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/i386/syntax.h     >>./mpi/asm-syntax.h
        path="i386"
+       mpi_cpu_arch="x86"
        ;;
     i586*-*-openbsd*         | \
     i586*-*-freebsd*-elf     | \
@@ -66,11 +73,13 @@ case "${host}" in
        echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/i386/syntax.h     >>./mpi/asm-syntax.h
        path="i586 i386"
+       mpi_cpu_arch="x86"
        ;;
     i[34]86*-*-bsdi4*)
        echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/i386/syntax.h   >>./mpi/asm-syntax.h
        path="i386"
+       mpi_cpu_arch="x86"
        ;;
     i[3467]86*-*-linuxaout*  | \
     i[3467]86*-*-linuxoldld* | \
@@ -79,6 +88,7 @@ case "${host}" in
        echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/i386/syntax.h      >>./mpi/asm-syntax.h
        path="i386"
+        mpi_cpu_arch="x86"
        ;;
     i586*-*-linuxaout*  | \
     i586*-*-linuxoldld* | \
@@ -87,23 +97,27 @@ case "${host}" in
        echo '#define X86_BROKEN_ALIGN' >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/i386/syntax.h      >>./mpi/asm-syntax.h
        path="i586 i386"
+        mpi_cpu_arch="x86"
        ;;
     i[3467]86*-msdosdjgpp* | \
     i[34]86*-apple-darwin*)
        echo '#define BSD_SYNTAX'        >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/i386/syntax.h   >>./mpi/asm-syntax.h
        path="i386"
+        mpi_cpu_arch="x86"
        ;;
     i586*-msdosdjgpp* | \
     i[567]86*-apple-darwin*)
        echo '#define BSD_SYNTAX'        >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/i386/syntax.h   >>./mpi/asm-syntax.h
        path="i586 i386"
+        mpi_cpu_arch="x86"
        ;;
     i[3467]86*-*-*)
        echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/i386/syntax.h      >>./mpi/asm-syntax.h
        path="i386"
+        mpi_cpu_arch="x86"
        ;;
     i586*-*-*  | \
     pentium-*-*   | \
@@ -111,78 +125,109 @@ case "${host}" in
        echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/i386/syntax.h      >>./mpi/asm-syntax.h
        path="i586 i386"
+        mpi_cpu_arch="x86"
        ;;
     x86_64-*-*)
        echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/i386/syntax.h      >>./mpi/asm-syntax.h
        path="amd64"
+        mpi_cpu_arch="x86"
        ;;
     alpha*-*-*)
        echo '/* configured for alpha */' >>./mpi/asm-syntax.h
        path="alpha"
        mpi_extra_modules="udiv-qrnnd"
+        mpi_cpu_arch="alpha"
+       ;;
+    aarch64-*-*)
+       echo '/* configured for aarch64 */' >>./mpi/asm-syntax.h
+       path="aarch64"
+       mpi_cpu_arch="aarch64"
+       ;;
+    arm*-*-*)
+       mpi_cpu_arch="arm"
+       if test "$gcry_cv_gcc_arm_platform_as_ok" = "yes" ; then
+         echo '/* configured for arm */' >>./mpi/asm-syntax.h
+         path="arm"
+       else
+         echo '/* No assembler modules configured */' >>./mpi/asm-syntax.h
+         path=""
+       fi
        ;;
     hppa7000*-*-*)
        echo '/* configured for HPPA (pa7000) */' >>./mpi/asm-syntax.h
        path="hppa1.1 hppa"
        mpi_extra_modules="udiv-qrnnd"
+       mpi_cpu_arch="hppa"
        ;;
     hppa1.0*-*-*)
        echo '/* configured for HPPA 1.0 */' >>./mpi/asm-syntax.h
        path="hppa"
        mpi_extra_modules="udiv-qrnnd"
+       mpi_cpu_arch="hppa"
        ;;
     hppa*-*-*) # assume pa7100
        echo '/* configured for HPPA (pa7100) */' >>./mpi/asm-syntax.h
        path="pa7100 hppa1.1 hppa"
        mpi_extra_modules="udiv-qrnnd"
+       mpi_cpu_arch="hppa"
        ;;
     sparc64-*-linux-gnu)
         echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
        path=""
+        mpi_cpu_arch="sparc"
        ;;
     sparc64-sun-solaris2*)
         echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
        path=""
+        mpi_cpu_arch="sparc"
         ;;
     sparc64-*-netbsd* | sparc64-*-freebsd* | sparc64-*-openbsd*)
        # There are no sparc64 assembler modules that work on the
        # *BSDs, so use the generic C functions.
        echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
        path=""
+       mpi_cpu_arch="sparc"
        ;;
     sparc64*-*-*)
        echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h
        path=""
+       mpi_cpu_arch="sparc"
        ;;
     sparc9*-*-*     | \
     ultrasparc*-*-* )
        echo '/* configured for sparc9 or higher */' >>./mpi/asm-syntax.h
        path="sparc32v8 sparc32"
+        mpi_cpu_arch="sparc"
        ;;
     sparc8*-*-*     | \
     microsparc*-*-*)
        echo '/* configured for sparc8 */' >>./mpi/asm-syntax.h
        path="sparc32v8 sparc32"
+        mpi_cpu_arch="sparc"
        ;;
     supersparc*-*-*)
        echo '/* configured for supersparc */' >>./mpi/asm-syntax.h
        path="supersparc sparc32v8 sparc32"
        mpi_extra_modules="udiv"
+        mpi_cpu_arch="sparc"
        ;;
     sparc*-*-*)
        echo '/* configured for sparc */' >>./mpi/asm-syntax.h
        path="sparc32"
        mpi_extra_modules="udiv"
+        mpi_cpu_arch="sparc"
        ;;
     mips[34]*-*-* | \
     mips*-*-irix6*)
        echo '/* configured for MIPS3 */' >>./mpi/asm-syntax.h
        path="mips3"
+       mpi_cpu_arch="mips"
        ;;
     mips*-*-*)
        echo '/* configured for MIPS2 */' >>./mpi/asm-syntax.h
        path="mips2"
+       mpi_cpu_arch="mips"
        ;;
 
     # Motorola 68k configurations.  Let m68k mean 68020-68040.
@@ -192,38 +237,45 @@ case "${host}" in
        echo '#define MIT_SYNTAX'           >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/m68k/syntax.h      >>./mpi/asm-syntax.h
        path="m68k/mc68020 m68k"
+        mpi_cpu_arch="m68k"
        ;;
     m68060*-*-linuxaout*)
        echo '#define MIT_SYNTAX'           >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/m68k/syntax.h      >>./mpi/asm-syntax.h
        path="m68k"
+        mpi_cpu_arch="m68k"
        ;;
     m680[234]0*-*-linux* | \
     m68k*-*-linux*)
        echo '#define ELF_SYNTAX'           >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/m68k/syntax.h      >>./mpi/asm-syntax.h
+        mpi_cpu_arch="m68k"
        ;;
     m68060*-*-linux*)
        echo '#define ELF_SYNTAX'           >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/m68k/syntax.h      >>./mpi/asm-syntax.h
        path="m68k"
+        mpi_cpu_arch="m68k"
        ;;
     m68k-atari-mint)
        echo '#define MIT_SYNTAX'           >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/m68k/syntax.h      >>./mpi/asm-syntax.h
-       path="m68k/mc68020 m68k"
+       path="m68k"
+        mpi_cpu_arch="m68k"
        ;;
     m68000*-*-* | \
     m68060*-*-*)
        echo '#define MIT_SYNTAX'           >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/m68k/syntax.h      >>./mpi/asm-syntax.h
        path="m68k/mc68000"
+        mpi_cpu_arch="m68k"
        ;;
     m680[234]0*-*-* | \
     m68k*-*-*)
        echo '#define MIT_SYNTAX'           >>./mpi/asm-syntax.h
        cat  $srcdir/mpi/m68k/syntax.h      >>./mpi/asm-syntax.h
        path="m68k/mc68020 m68k"
+        mpi_cpu_arch="m68k"
        ;;
 
     powerpc*-*-netbsd* | powerpc*-*-openbsd*)
@@ -232,18 +284,21 @@ case "${host}" in
        cat   $srcdir/mpi/powerpc32/syntax.h     >>./mpi/asm-syntax.h
        mpi_sflags="-Wa,-mppc"
        path="powerpc32"
+       mpi_cpu_arch="ppc"
        ;;
 
     ppc620-*-*     | \
     powerpc64*-*-*)
        mpi_sflags="-Wa,-mppc"
        path="powerpc64"
+        mpi_cpu_arch="ppc"
        ;;
     powerpc*-*-linux*)
        echo '/* configured for powerpc/ELF */' >>./mpi/asm-syntax.h
        echo '#define ELF_SYNTAX'               >>./mpi/asm-syntax.h
        cat   $srcdir/mpi/powerpc32/syntax.h    >>./mpi/asm-syntax.h
        path="powerpc32"
+       mpi_cpu_arch="ppc"
        ;;
 
     rs6000-*-aix[456789]*    | \
@@ -251,6 +306,7 @@ case "${host}" in
        mpi_sflags="-Wa,-mpwr"
        path="power"
        mpi_extra_modules="udiv-w-sdiv"
+       mpi_cpu_arch="ppc"
        ;;
     rs6000-*-* | \
     power-*-*  | \
@@ -258,6 +314,7 @@ case "${host}" in
        mpi_sflags="-Wa,-mppc"
        path="power"
        mpi_extra_modules="udiv-w-sdiv"
+        mpi_cpu_arch="ppc"
        ;;
     powerpc-ibm-aix4.2.* )
        # I am not sure about this one but a machine identified by
@@ -265,27 +322,41 @@ case "${host}" in
        mpi_sflags="-Wa,-mpwr"
        path="power"
        mpi_extra_modules="udiv-w-sdiv"
+        mpi_cpu_arch="ppc"
        ;;
     ppc601-*-*)
        mpi_sflags="-Wa,-mppc"
        path="power powerpc32"
+        mpi_cpu_arch="ppc"
        ;;
     ppc60[234]*-*-*)
        mpi_sflags="-Wa,-mppc"
        path="powerpc32"
+        mpi_cpu_arch="ppc"
        ;;
     powerpc*-*-*)
        mpi_sflags="-Wa,-mppc"
        path="powerpc32"
+        mpi_cpu_arch="ppc"
        ;;
     *)
-       echo '/* No assembler modules configured */' >>./mpi/asm-syntax.h
+       echo '/* Platform not known */' >>./mpi/asm-syntax.h
        path=""
        ;;
 esac
-else
-    echo '/* Assembler modules disabled on request */' >>./mpi/asm-syntax.h
+
+# If asm modules are disabled reset the found variables but keep
+# mpi_cpu_arch.
+if test "$try_asm_modules" != "yes" ; then
+    echo '/* Assembler modules disabled on request */' >./mpi/asm-syntax.h
     path=""
+    mpi_sflags=""
+    mpi_extra_modules=""
+fi
+
+# Make sure that mpi_cpu_arch is not the empty string.
+if test x"$mpi_cpu_arch" = x ; then
+    mpi_cpu_arch="unknown"
 fi
 
 
diff --git a/mpi/ec-ed25519.c b/mpi/ec-ed25519.c
new file mode 100644 (file)
index 0000000..acfe2a6
--- /dev/null
@@ -0,0 +1,37 @@
+/* ec-ed25519.c -  Ed25519 optimized elliptic curve functions
+ * Copyright (C) 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/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "mpi-internal.h"
+#include "longlong.h"
+#include "g10lib.h"
+#include "context.h"
+#include "ec-context.h"
+
+
+void
+_gcry_mpi_ec_ed25519_mod (gcry_mpi_t a)
+{
+  (void)a;
+
+}
diff --git a/mpi/ec-internal.h b/mpi/ec-internal.h
new file mode 100644 (file)
index 0000000..759335a
--- /dev/null
@@ -0,0 +1,25 @@
+/* ec-internal.h - Internal declarations of ec*.c
+ * Copyright (C) 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/>.
+ */
+
+#ifndef GCRY_EC_INTERNAL_H
+#define GCRY_EC_INTERNAL_H
+
+void _gcry_mpi_ec_ed25519_mod (gcry_mpi_t a);
+
+#endif /*GCRY_EC_INTERNAL_H*/
index e325358..168076f 100644 (file)
--- a/mpi/ec.c
+++ b/mpi/ec.c
 /* ec.c -  Elliptic Curve functions
-   Copyright (C) 2007 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
-   USA.  */
-
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ * Copyright (C) 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/>.
+ */
 
 #include <config.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <errno.h>
 
 #include "mpi-internal.h"
 #include "longlong.h"
 #include "g10lib.h"
+#include "context.h"
+#include "ec-context.h"
+#include "ec-internal.h"
 
 
-#define point_init(a)  _gcry_mpi_ec_point_init ((a))
-#define point_free(a)  _gcry_mpi_ec_point_free ((a))
+#define point_init(a)  _gcry_mpi_point_init ((a))
+#define point_free(a)  _gcry_mpi_point_free_parts ((a))
 
 
-/* Object to represent a point in projective coordinates. */
-/* Currently defined in mpi.h */
-
-/* This context is used with all our EC functions. */
-struct mpi_ec_ctx_s
+/* Print a point using the log fucntions.  If CTX is not NULL affine
+   coordinates will be printed.  */
+void
+_gcry_mpi_point_log (const char *name, mpi_point_t point, mpi_ec_t ctx)
 {
-  /* Domain parameters.  */
-  gcry_mpi_t p;   /* Prime specifying the field GF(p).  */
-  gcry_mpi_t a;   /* First coefficient of the Weierstrass equation.  */
+  gcry_mpi_t x, y;
+  char buf[100];
 
-  int a_is_pminus3;  /* True if A = P - 3. */
+  if (!point)
+    {
+      snprintf (buf, sizeof buf - 1, "%s.*", name);
+      log_mpidump (buf, NULL);
+      return;
+    }
+  snprintf (buf, sizeof buf - 1, "%s.X", name);
 
-  /* Some often used constants.  */
-  gcry_mpi_t one;
-  gcry_mpi_t two;
-  gcry_mpi_t three;
-  gcry_mpi_t four;
-  gcry_mpi_t eight;
-  gcry_mpi_t two_inv_p;
+  if (ctx)
+    {
+      x = mpi_new (0);
+      y = mpi_new (0);
+    }
+  if (!ctx || _gcry_mpi_ec_get_affine (x, y, point, ctx))
+    {
+      log_mpidump (buf, point->x);
+      buf[strlen(buf)-1] = 'Y';
+      log_mpidump (buf, point->y);
+      buf[strlen(buf)-1] = 'Z';
+      log_mpidump (buf, point->z);
+    }
+  else
+    {
+      buf[strlen(buf)-1] = 'x';
+      log_mpidump (buf, x);
+      buf[strlen(buf)-1] = 'y';
+      log_mpidump (buf, y);
 
-  /* Scratch variables.  */
-  gcry_mpi_t scratch[11];
+    }
+  if (ctx)
+    {
+      _gcry_mpi_release (x);
+      _gcry_mpi_release (y);
+    }
+}
 
-  /* Helper for fast reduction.  */
-/*   int nist_nbits; /\* If this is a NIST curve, the number of bits.  *\/ */
-/*   gcry_mpi_t s[10]; */
-/*   gcry_mpi_t c; */
 
-};
+/* Create a new point option.  NBITS gives the size in bits of one
+   coordinate; it is only used to pre-allocate some resources and
+   might also be passed as 0 to use a default value.  */
+mpi_point_t
+_gcry_mpi_point_new (unsigned int nbits)
+{
+  mpi_point_t p;
 
+  (void)nbits;  /* Currently not used.  */
 
+  p = xmalloc (sizeof *p);
+  _gcry_mpi_point_init (p);
+  return p;
+}
 
-/* Initialized a point object.  gcry_mpi_ec_point_free shall be used
-   to release this object.  */
+
+/* Release the point object P.  P may be NULL. */
 void
-_gcry_mpi_ec_point_init (mpi_point_t *p)
+_gcry_mpi_point_release (mpi_point_t p)
+{
+  if (p)
+    {
+      _gcry_mpi_point_free_parts (p);
+      xfree (p);
+    }
+}
+
+
+/* Initialize the fields of a point object.  gcry_mpi_point_free_parts
+   may be used to release the fields.  */
+void
+_gcry_mpi_point_init (mpi_point_t p)
 {
   p->x = mpi_new (0);
   p->y = mpi_new (0);
@@ -75,18 +119,19 @@ _gcry_mpi_ec_point_init (mpi_point_t *p)
 }
 
 
-/* Release a point object. */
+/* Release the parts of a point object. */
 void
-_gcry_mpi_ec_point_free (mpi_point_t *p)
+_gcry_mpi_point_free_parts (mpi_point_t p)
 {
   mpi_free (p->x); p->x = NULL;
   mpi_free (p->y); p->y = NULL;
   mpi_free (p->z); p->z = NULL;
 }
 
+
 /* Set the value from S into D.  */
 static void
-point_set (mpi_point_t *d, mpi_point_t *s)
+point_set (mpi_point_t d, mpi_point_t s)
 {
   mpi_set (d->x, s->x);
   mpi_set (d->y, s->y);
@@ -94,132 +139,132 @@ point_set (mpi_point_t *d, mpi_point_t *s)
 }
 
 
+/* 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
+_gcry_mpi_point_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+                     mpi_point_t point)
+{
+  if (x)
+    mpi_set (x, point->x);
+  if (y)
+    mpi_set (y, point->y);
+  if (z)
+    mpi_set (z, point->z);
+}
+
+
+/* Set the projective coordinates from POINT into X, Y, and Z and
+   release POINT.  If a coordinate is not required, X, Y, or Z may be
+   passed as NULL.  */
+void
+_gcry_mpi_point_snatch_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+                            mpi_point_t point)
+{
+  mpi_snatch (x, point->x);
+  mpi_snatch (y, point->y);
+  mpi_snatch (z, point->z);
+  xfree (point);
+}
+
+
+/* Set the projective coordinates from X, Y, and Z into POINT.  If a
+   coordinate is given as NULL, the value 0 is stored into point.  If
+   POINT is given as NULL a new point object is allocated.  Returns
+   POINT or the newly allocated point object. */
+mpi_point_t
+_gcry_mpi_point_set (mpi_point_t point,
+                     gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z)
+{
+  if (!point)
+    point = mpi_point_new (0);
+
+  if (x)
+    mpi_set (point->x, x);
+  else
+    mpi_clear (point->x);
+  if (y)
+    mpi_set (point->y, y);
+  else
+    mpi_clear (point->y);
+  if (z)
+    mpi_set (point->z, z);
+  else
+    mpi_clear (point->z);
+
+  return point;
+}
+
+
+/* Set the projective coordinates from X, Y, and Z into POINT.  If a
+   coordinate is given as NULL, the value 0 is stored into point.  If
+   POINT is given as NULL a new point object is allocated.  The
+   coordinates X, Y, and Z are released.  Returns POINT or the newly
+   allocated point object. */
+mpi_point_t
+_gcry_mpi_point_snatch_set (mpi_point_t point,
+                            gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z)
+{
+  if (!point)
+    point = mpi_point_new (0);
+
+  if (x)
+    mpi_snatch (point->x, x);
+  else
+    mpi_clear (point->x);
+  if (y)
+    mpi_snatch (point->y, y);
+  else
+    mpi_clear (point->y);
+  if (z)
+    mpi_snatch (point->z, z);
+  else
+    mpi_clear (point->z);
+
+  return point;
+}
+
+
+/* W = W mod P.  */
+static void
+ec_mod (gcry_mpi_t w, mpi_ec_t ec)
+{
+  if (0 && ec->dialect == ECC_DIALECT_ED25519)
+    _gcry_mpi_ec_ed25519_mod (w);
+  else if (ec->t.p_barrett)
+    _gcry_mpi_mod_barrett (w, w, ec->t.p_barrett);
+  else
+    _gcry_mpi_mod (w, w, ec->p);
+}
 
 static void
 ec_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
 {
-  mpi_addm (w, u, v, ctx->p);
+  mpi_add (w, u, v);
+  ec_mod (w, ctx);
 }
 
 static void
-ec_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
+ec_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ec)
 {
-  mpi_subm (w, u, v, ctx->p);
+  (void)ec;
+  mpi_sub (w, u, v);
+  /*ec_mod (w, ec);*/
 }
 
 static void
 ec_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, mpi_ec_t ctx)
 {
-#if 0
-  /* NOTE: This code works only for limb sizes of 32 bit.  */
-  mpi_limb_t *wp, *sp;
+  mpi_mul (w, u, v);
+  ec_mod (w, ctx);
+}
 
-  if (ctx->nist_nbits == 192)
-    {
-      mpi_mul (w, u, v);
-      mpi_resize (w, 12);
-      wp = w->d;
-
-      sp = ctx->s[0]->d;
-      sp[0*2+0] = wp[0*2+0];
-      sp[0*2+1] = wp[0*2+1];
-      sp[1*2+0] = wp[1*2+0];
-      sp[1*2+1] = wp[1*2+1];
-      sp[2*2+0] = wp[2*2+0];
-      sp[2*2+1] = wp[2*2+1];
-
-      sp = ctx->s[1]->d;
-      sp[0*2+0] = wp[3*2+0];
-      sp[0*2+1] = wp[3*2+1];
-      sp[1*2+0] = wp[3*2+0];
-      sp[1*2+1] = wp[3*2+1];
-      sp[2*2+0] = 0;
-      sp[2*2+1] = 0;
-
-      sp = ctx->s[2]->d;
-      sp[0*2+0] = 0;
-      sp[0*2+1] = 0;
-      sp[1*2+0] = wp[4*2+0];
-      sp[1*2+1] = wp[4*2+1];
-      sp[2*2+0] = wp[4*2+0];
-      sp[2*2+1] = wp[4*2+1];
-
-      sp = ctx->s[3]->d;
-      sp[0*2+0] = wp[5*2+0];
-      sp[0*2+1] = wp[5*2+1];
-      sp[1*2+0] = wp[5*2+0];
-      sp[1*2+1] = wp[5*2+1];
-      sp[2*2+0] = wp[5*2+0];
-      sp[2*2+1] = wp[5*2+1];
-
-      ctx->s[0]->nlimbs = 6;
-      ctx->s[1]->nlimbs = 6;
-      ctx->s[2]->nlimbs = 6;
-      ctx->s[3]->nlimbs = 6;
-
-      mpi_add (ctx->c, ctx->s[0], ctx->s[1]);
-      mpi_add (ctx->c, ctx->c, ctx->s[2]);
-      mpi_add (ctx->c, ctx->c, ctx->s[3]);
-
-      while ( mpi_cmp (ctx->c, ctx->p ) >= 0 )
-        mpi_sub ( ctx->c, ctx->c, ctx->p );
-      mpi_set (w, ctx->c);
-    }
-  else if (ctx->nist_nbits == 384)
-    {
-      int i;
-      mpi_mul (w, u, v);
-      mpi_resize (w, 24);
-      wp = w->d;
-
-#define NEXT(a) do { ctx->s[(a)]->nlimbs = 12; \
-                     sp = ctx->s[(a)]->d; \
-                     i = 0; } while (0)
-#define X(a) do { sp[i++] = wp[(a)];} while (0)
-#define X0(a) do { sp[i++] = 0; } while (0)
-      NEXT(0);
-      X(0);X(1);X(2);X(3);X(4);X(5);X(6);X(7);X(8);X(9);X(10);X(11);
-      NEXT(1);
-      X0();X0();X0();X0();X(21);X(22);X(23);X0();X0();X0();X0();X0();
-      NEXT(2);
-      X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);X(21);X(22);X(23);
-      NEXT(3);
-      X(21);X(22);X(23);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);
-      NEXT(4);
-      X0();X(23);X0();X(20);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);
-      NEXT(5);
-      X0();X0();X0();X0();X(20);X(21);X(22);X(23);X0();X0();X0();X0();
-      NEXT(6);
-      X(20);X0();X0();X(21);X(22);X(23);X0();X0();X0();X0();X0();X0();
-      NEXT(7);
-      X(23);X(12);X(13);X(14);X(15);X(16);X(17);X(18);X(19);X(20);X(21);X(22);
-      NEXT(8);
-      X0();X(20);X(21);X(22);X(23);X0();X0();X0();X0();X0();X0();X0();
-      NEXT(9);
-      X0();X0();X0();X(23);X(23);X0();X0();X0();X0();X0();X0();X0();
-#undef X0
-#undef X
-#undef NEXT
-      mpi_add (ctx->c, ctx->s[0], ctx->s[1]);
-      mpi_add (ctx->c, ctx->c, ctx->s[1]);
-      mpi_add (ctx->c, ctx->c, ctx->s[2]);
-      mpi_add (ctx->c, ctx->c, ctx->s[3]);
-      mpi_add (ctx->c, ctx->c, ctx->s[4]);
-      mpi_add (ctx->c, ctx->c, ctx->s[5]);
-      mpi_add (ctx->c, ctx->c, ctx->s[6]);
-      mpi_sub (ctx->c, ctx->c, ctx->s[7]);
-      mpi_sub (ctx->c, ctx->c, ctx->s[8]);
-      mpi_sub (ctx->c, ctx->c, ctx->s[9]);
-
-      while ( mpi_cmp (ctx->c, ctx->p ) >= 0 )
-        mpi_sub ( ctx->c, ctx->c, ctx->p );
-      while ( ctx->c->sign )
-        mpi_add ( ctx->c, ctx->c, ctx->p );
-      mpi_set (w, ctx->c);
-    }
-  else
-#endif /*0*/
-    mpi_mulm (w, u, v, ctx->p);
+/* W = 2 * U mod P.  */
+static void
+ec_mul2 (gcry_mpi_t w, gcry_mpi_t u, mpi_ec_t ctx)
+{
+  mpi_lshift (w, u, 1);
+  ec_mod (w, ctx);
 }
 
 static void
@@ -227,58 +272,128 @@ ec_powm (gcry_mpi_t w, const gcry_mpi_t b, const gcry_mpi_t e,
          mpi_ec_t ctx)
 {
   mpi_powm (w, b, e, ctx->p);
+  /* _gcry_mpi_abs (w); */
+}
+
+
+/* Shortcut for
+     ec_powm (B, B, mpi_const (MPI_C_TWO), ctx);
+   for easier optimization.  */
+static void
+ec_pow2 (gcry_mpi_t w, const gcry_mpi_t b, mpi_ec_t ctx)
+{
+  /* Using mpi_mul is slightly faster (at least on amd64).  */
+  /* mpi_powm (w, b, mpi_const (MPI_C_TWO), ctx->p); */
+  ec_mulm (w, b, b, ctx);
+}
+
+
+/* Shortcut for
+     ec_powm (B, B, mpi_const (MPI_C_THREE), ctx);
+   for easier optimization.  */
+static void
+ec_pow3 (gcry_mpi_t w, const gcry_mpi_t b, mpi_ec_t ctx)
+{
+  mpi_powm (w, b, mpi_const (MPI_C_THREE), ctx->p);
 }
 
+
 static void
 ec_invm (gcry_mpi_t x, gcry_mpi_t a, mpi_ec_t ctx)
 {
-  mpi_invm (x, a, ctx->p);
+  if (!mpi_invm (x, a, ctx->p))
+    {
+      log_error ("ec_invm: inverse does not exist:\n");
+      log_mpidump ("  a", a);
+      log_mpidump ("  p", ctx->p);
+    }
 }
 
 
+/* Force recomputation of all helper variables.  */
+void
+_gcry_mpi_ec_get_reset (mpi_ec_t ec)
+{
+  ec->t.valid.a_is_pminus3 = 0;
+  ec->t.valid.two_inv_p = 0;
+}
 
-/* This function returns a new context for elliptic curve based on the
-   field GF(p).  P is the prime specifying thuis field, A is the first
-   coefficient.
 
-   This context needs to be released using _gcry_mpi_ec_free.  */
-mpi_ec_t
-_gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a)
+/* Accessor for helper variable.  */
+static int
+ec_get_a_is_pminus3 (mpi_ec_t ec)
 {
-  int i;
-  mpi_ec_t ctx;
   gcry_mpi_t tmp;
 
-  mpi_normalize (p);
-  mpi_normalize (a);
+  if (!ec->t.valid.a_is_pminus3)
+    {
+      ec->t.valid.a_is_pminus3 = 1;
+      tmp = mpi_alloc_like (ec->p);
+      mpi_sub_ui (tmp, ec->p, 3);
+      ec->t.a_is_pminus3 = !mpi_cmp (ec->a, tmp);
+      mpi_free (tmp);
+    }
+
+  return ec->t.a_is_pminus3;
+}
+
+
+/* Accessor for helper variable.  */
+static gcry_mpi_t
+ec_get_two_inv_p (mpi_ec_t ec)
+{
+  if (!ec->t.valid.two_inv_p)
+    {
+      ec->t.valid.two_inv_p = 1;
+      if (!ec->t.two_inv_p)
+        ec->t.two_inv_p = mpi_alloc (0);
+      ec_invm (ec->t.two_inv_p, mpi_const (MPI_C_TWO), ec);
+    }
+  return ec->t.two_inv_p;
+}
 
-  /* Fixme: Do we want to check some constraints? e.g.
-     a < p
-  */
 
-  ctx = gcry_xcalloc (1, sizeof *ctx);
 
+/* This function initialized a context for elliptic curve based on the
+   field GF(p).  P is the prime specifying this field, A is the first
+   coefficient.  CTX is expected to be zeroized.  */
+static void
+ec_p_init (mpi_ec_t ctx, enum gcry_mpi_ec_models model,
+           enum ecc_dialects dialect,
+           int flags,
+           gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b)
+{
+  int i;
+  static int use_barrett;
+
+  if (!use_barrett)
+    {
+      if (getenv ("GCRYPT_BARRETT"))
+        use_barrett = 1;
+      else
+        use_barrett = -1;
+    }
+
+  /* Fixme: Do we want to check some constraints? e.g.  a < p  */
+
+  ctx->model = model;
+  ctx->dialect = dialect;
+  ctx->flags = flags;
+  if (dialect == ECC_DIALECT_ED25519)
+    ctx->nbits = 256;
+  else
+    ctx->nbits = mpi_get_nbits (p);
   ctx->p = mpi_copy (p);
   ctx->a = mpi_copy (a);
+  ctx->b = mpi_copy (b);
 
-  tmp = mpi_alloc_like (ctx->p);
-  mpi_sub_ui (tmp, ctx->p, 3);
-  ctx->a_is_pminus3 = !mpi_cmp (ctx->a, tmp);
-  mpi_free (tmp);
-
+  ctx->t.p_barrett = use_barrett > 0? _gcry_mpi_barrett_init (ctx->p, 0):NULL;
 
-  /* Allocate constants.  */
-  ctx->one   = mpi_alloc_set_ui (1);
-  ctx->two   = mpi_alloc_set_ui (2);
-  ctx->three = mpi_alloc_set_ui (3);
-  ctx->four  = mpi_alloc_set_ui (4);
-  ctx->eight = mpi_alloc_set_ui (8);
-  ctx->two_inv_p = mpi_alloc (0);
-  ec_invm (ctx->two_inv_p, ctx->two, ctx);
+  _gcry_mpi_ec_get_reset (ctx);
 
   /* Allocate scratch variables.  */
-  for (i=0; i< DIM(ctx->scratch); i++)
-    ctx->scratch[i] = mpi_alloc_like (ctx->p);
+  for (i=0; i< DIM(ctx->t.scratch); i++)
+    ctx->t.scratch[i] = mpi_alloc_like (ctx->p);
 
   /* Prepare for fast reduction.  */
   /* FIXME: need a test for NIST values.  However it does not gain us
@@ -297,31 +412,33 @@ _gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a)
 /*         ctx->s[i] = mpi_new (384); */
 /*       ctx->c    = mpi_new (384*2); */
 /*     } */
-
-  return ctx;
 }
 
-void
-_gcry_mpi_ec_free (mpi_ec_t ctx)
+
+static void
+ec_deinit (void *opaque)
 {
+  mpi_ec_t ctx = opaque;
   int i;
 
-  if (!ctx)
-    return;
+  _gcry_mpi_barrett_free (ctx->t.p_barrett);
 
+  /* Domain parameter.  */
   mpi_free (ctx->p);
   mpi_free (ctx->a);
+  mpi_free (ctx->b);
+  _gcry_mpi_point_release (ctx->G);
+  mpi_free (ctx->n);
 
-  mpi_free (ctx->one);
-  mpi_free (ctx->two);
-  mpi_free (ctx->three);
-  mpi_free (ctx->four);
-  mpi_free (ctx->eight);
+  /* The key.  */
+  _gcry_mpi_point_release (ctx->Q);
+  mpi_free (ctx->d);
 
-  mpi_free (ctx->two_inv_p);
+  /* Private data of ec.c.  */
+  mpi_free (ctx->t.two_inv_p);
 
-  for (i=0; i< DIM(ctx->scratch); i++)
-    mpi_free (ctx->scratch[i]);
+  for (i=0; i< DIM(ctx->t.scratch); i++)
+    mpi_free (ctx->t.scratch[i]);
 
 /*   if (ctx->nist_nbits == 192) */
 /*     { */
@@ -335,61 +452,195 @@ _gcry_mpi_ec_free (mpi_ec_t ctx)
 /*         mpi_free (ctx->s[i]); */
 /*       mpi_free (ctx->c); */
 /*     } */
+}
+
+
+/* This function returns a new context for elliptic curve based on the
+   field GF(p).  P is the prime specifying this field, A is the first
+   coefficient, B is the second coefficient, and MODEL is the model
+   for the curve.  This function is only used within Libgcrypt and not
+   part of the public API.
 
-  gcry_free (ctx);
+   This context needs to be released using _gcry_mpi_ec_free.  */
+mpi_ec_t
+_gcry_mpi_ec_p_internal_new (enum gcry_mpi_ec_models model,
+                             enum ecc_dialects dialect,
+                             int flags,
+                             gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b)
+{
+  mpi_ec_t ctx;
+
+  ctx = xcalloc (1, sizeof *ctx);
+  ec_p_init (ctx, model, dialect, flags, p, a, b);
+
+  return ctx;
 }
 
+
+/* This is a variant of _gcry_mpi_ec_p_internal_new which returns an
+   public context and does some error checking on the supplied
+   arguments.  On success the new context is stored at R_CTX and 0 is
+   returned; on error NULL is stored at R_CTX and an error code is
+   returned.
+
+   The context needs to be released using gcry_ctx_release.  */
+gpg_err_code_t
+_gcry_mpi_ec_p_new (gcry_ctx_t *r_ctx,
+                    enum gcry_mpi_ec_models model,
+                    enum ecc_dialects dialect,
+                    int flags,
+                    gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b)
+{
+  gcry_ctx_t ctx;
+  mpi_ec_t ec;
+
+  *r_ctx = NULL;
+  if (!p || !a || !mpi_cmp_ui (a, 0))
+    return GPG_ERR_EINVAL;
+
+  ctx = _gcry_ctx_alloc (CONTEXT_TYPE_EC, sizeof *ec, ec_deinit);
+  if (!ctx)
+    return gpg_err_code_from_syserror ();
+  ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
+  ec_p_init (ec, model, dialect, flags, p, a, b);
+
+  *r_ctx = ctx;
+  return 0;
+}
+
+
+void
+_gcry_mpi_ec_free (mpi_ec_t ctx)
+{
+  if (ctx)
+    {
+      ec_deinit (ctx);
+      xfree (ctx);
+    }
+}
+
+
+gcry_mpi_t
+_gcry_mpi_ec_get_mpi (const char *name, gcry_ctx_t ctx, int copy)
+{
+  mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
+
+  return _gcry_ecc_get_mpi (name, ec, copy);
+}
+
+
+gcry_mpi_point_t
+_gcry_mpi_ec_get_point (const char *name, gcry_ctx_t ctx, int copy)
+{
+  mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
+
+  (void)copy;  /* Not used.  */
+
+  return _gcry_ecc_get_point (name, ec);
+}
+
+
+gpg_err_code_t
+_gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue,
+                      gcry_ctx_t ctx)
+{
+  mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
+
+  return _gcry_ecc_set_mpi (name, newvalue, ec);
+}
+
+
+gpg_err_code_t
+_gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue,
+                        gcry_ctx_t ctx)
+{
+  mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC);
+
+  return _gcry_ecc_set_point (name, newvalue, ec);
+}
+
+
 /* 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
    on success or !0 if POINT is at infinity.  */
 int
-_gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t *point,
+_gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t point,
                          mpi_ec_t ctx)
 {
-  gcry_mpi_t z1, z2, z3;
-
   if (!mpi_cmp_ui (point->z, 0))
     return -1;
 
-  z1 = mpi_new (0);
-  z2 = mpi_new (0);
-  ec_invm (z1, point->z, ctx);  /* z1 = z^(-1) mod p  */
-  ec_mulm (z2, z1, z1, ctx);    /* z2 = z^(-2) mod p  */
-
-  if (x)
-    ec_mulm (x, point->x, z2, ctx);
-
-  if (y)
+  switch (ctx->model)
     {
-      z3 = mpi_new (0);
-      ec_mulm (z3, z2, z1, ctx);      /* z3 = z^(-3) mod p  */
-      ec_mulm (y, point->y, z3, ctx);
-      mpi_free (z3);
+    case MPI_EC_WEIERSTRASS: /* Using Jacobian coordinates.  */
+      {
+        gcry_mpi_t z1, z2, z3;
+
+        z1 = mpi_new (0);
+        z2 = mpi_new (0);
+        ec_invm (z1, point->z, ctx);  /* z1 = z^(-1) mod p  */
+        ec_mulm (z2, z1, z1, ctx);    /* z2 = z^(-2) mod p  */
+
+        if (x)
+          ec_mulm (x, point->x, z2, ctx);
+
+        if (y)
+          {
+            z3 = mpi_new (0);
+            ec_mulm (z3, z2, z1, ctx);      /* z3 = z^(-3) mod p  */
+            ec_mulm (y, point->y, z3, ctx);
+            mpi_free (z3);
+          }
+
+        mpi_free (z2);
+        mpi_free (z1);
+      }
+      return 0;
+
+    case MPI_EC_MONTGOMERY:
+      {
+        log_fatal ("%s: %s not yet supported\n",
+                   "_gcry_mpi_ec_get_affine", "Montgomery");
+      }
+      return -1;
+
+    case MPI_EC_TWISTEDEDWARDS:
+      {
+        gcry_mpi_t z;
+
+        z = mpi_new (0);
+        ec_invm (z, point->z, ctx);
+
+        if (x)
+          ec_mulm (x, point->x, z, ctx);
+        if (y)
+          ec_mulm (y, point->y, z, ctx);
+
+        _gcry_mpi_release (z);
+      }
+      return 0;
+
+    default:
+      return -1;
     }
-
-  mpi_free (z2);
-  mpi_free (z1);
-  return 0;
 }
 
 
-
-
 \f
-/*  RESULT = 2 * POINT  */
-void
-_gcry_mpi_ec_dup_point (mpi_point_t *result, mpi_point_t *point, mpi_ec_t ctx)
+/*  RESULT = 2 * POINT  (Weierstrass version). */
+static void
+dup_point_weierstrass (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
 {
 #define x3 (result->x)
 #define y3 (result->y)
 #define z3 (result->z)
-#define t1 (ctx->scratch[0])
-#define t2 (ctx->scratch[1])
-#define t3 (ctx->scratch[2])
-#define l1 (ctx->scratch[3])
-#define l2 (ctx->scratch[4])
-#define l3 (ctx->scratch[5])
+#define t1 (ctx->t.scratch[0])
+#define t2 (ctx->t.scratch[1])
+#define t3 (ctx->t.scratch[2])
+#define l1 (ctx->t.scratch[3])
+#define l2 (ctx->t.scratch[4])
+#define l3 (ctx->t.scratch[5])
 
   if (!mpi_cmp_ui (point->y, 0) || !mpi_cmp_ui (point->z, 0))
     {
@@ -400,14 +651,14 @@ _gcry_mpi_ec_dup_point (mpi_point_t *result, mpi_point_t *point, mpi_ec_t ctx)
     }
   else
     {
-      if (ctx->a_is_pminus3)  /* Use the faster case.  */
+      if (ec_get_a_is_pminus3 (ctx))  /* Use the faster case.  */
         {
           /* L1 = 3(X - Z^2)(X + Z^2) */
           /*                          T1: used for Z^2. */
           /*                          T2: used for the right term.  */
-          ec_powm (t1, point->z, ctx->two, ctx);
+          ec_pow2 (t1, point->z, ctx);
           ec_subm (l1, point->x, t1, ctx);
-          ec_mulm (l1, l1, ctx->three, ctx);
+          ec_mulm (l1, l1, mpi_const (MPI_C_THREE), ctx);
           ec_addm (t2, point->x, t1, ctx);
           ec_mulm (l1, l1, t2, ctx);
         }
@@ -415,32 +666,32 @@ _gcry_mpi_ec_dup_point (mpi_point_t *result, mpi_point_t *point, mpi_ec_t ctx)
         {
           /* L1 = 3X^2 + aZ^4 */
           /*                          T1: used for aZ^4. */
-          ec_powm (l1, point->x, ctx->two, ctx);
-          ec_mulm (l1, l1, ctx->three, ctx);
-          ec_powm (t1, point->z, ctx->four, ctx);
+          ec_pow2 (l1, point->x, ctx);
+          ec_mulm (l1, l1, mpi_const (MPI_C_THREE), ctx);
+          ec_powm (t1, point->z, mpi_const (MPI_C_FOUR), ctx);
           ec_mulm (t1, t1, ctx->a, ctx);
           ec_addm (l1, l1, t1, ctx);
         }
       /* Z3 = 2YZ */
       ec_mulm (z3, point->y, point->z, ctx);
-      ec_mulm (z3, z3, ctx->two, ctx);
+      ec_mul2 (z3, z3, ctx);
 
       /* L2 = 4XY^2 */
       /*                              T2: used for Y2; required later. */
-      ec_powm (t2, point->y, ctx->two, ctx);
+      ec_pow2 (t2, point->y, ctx);
       ec_mulm (l2, t2, point->x, ctx);
-      ec_mulm (l2, l2, ctx->four, ctx);
+      ec_mulm (l2, l2, mpi_const (MPI_C_FOUR), ctx);
 
       /* X3 = L1^2 - 2L2 */
       /*                              T1: used for L2^2. */
-      ec_powm (x3, l1, ctx->two, ctx);
-      ec_mulm (t1, l2, ctx->two, ctx);
+      ec_pow2 (x3, l1, ctx);
+      ec_mul2 (t1, l2, ctx);
       ec_subm (x3, x3, t1, ctx);
 
       /* L3 = 8Y^4 */
       /*                              T2: taken from above. */
-      ec_powm (t2, t2, ctx->two, ctx);
-      ec_mulm (l3, t2, ctx->eight, ctx);
+      ec_pow2 (t2, t2, ctx);
+      ec_mulm (l3, t2, mpi_const (MPI_C_EIGHT), ctx);
 
       /* Y3 = L1(L2 - X3) - L3 */
       ec_subm (y3, l2, x3, ctx);
@@ -460,12 +711,118 @@ _gcry_mpi_ec_dup_point (mpi_point_t *result, mpi_point_t *point, mpi_ec_t ctx)
 }
 
 
+/*  RESULT = 2 * POINT  (Montgomery version). */
+static void
+dup_point_montgomery (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
+{
+  (void)result;
+  (void)point;
+  (void)ctx;
+  log_fatal ("%s: %s not yet supported\n",
+             "_gcry_mpi_ec_dup_point", "Montgomery");
+}
 
-/* RESULT = P1 + P2 */
+
+/*  RESULT = 2 * POINT  (Twisted Edwards version). */
+static void
+dup_point_twistededwards (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
+{
+#define X1 (point->x)
+#define Y1 (point->y)
+#define Z1 (point->z)
+#define X3 (result->x)
+#define Y3 (result->y)
+#define Z3 (result->z)
+#define B (ctx->t.scratch[0])
+#define C (ctx->t.scratch[1])
+#define D (ctx->t.scratch[2])
+#define E (ctx->t.scratch[3])
+#define F (ctx->t.scratch[4])
+#define H (ctx->t.scratch[5])
+#define J (ctx->t.scratch[6])
+
+  /* Compute: (X_3 : Y_3 : Z_3) = 2( X_1 : Y_1 : Z_1 ) */
+
+  /* B = (X_1 + Y_1)^2  */
+  ec_addm (B, X1, Y1, ctx);
+  ec_pow2 (B, B, ctx);
+
+  /* C = X_1^2 */
+  /* D = Y_1^2 */
+  ec_pow2 (C, X1, ctx);
+  ec_pow2 (D, Y1, ctx);
+
+  /* E = aC */
+  if (ctx->dialect == ECC_DIALECT_ED25519)
+    {
+      mpi_set (E, C);
+      _gcry_mpi_neg (E, E);
+    }
+  else
+    ec_mulm (E, ctx->a, C, ctx);
+
+  /* F = E + D */
+  ec_addm (F, E, D, ctx);
+
+  /* H = Z_1^2 */
+  ec_pow2 (H, Z1, ctx);
+
+  /* J = F - 2H */
+  ec_mul2 (J, H, ctx);
+  ec_subm (J, F, J, ctx);
+
+  /* X_3 = (B - C - D) · J */
+  ec_subm (X3, B, C, ctx);
+  ec_subm (X3, X3, D, ctx);
+  ec_mulm (X3, X3, J, ctx);
+
+  /* Y_3 = F · (E - D) */
+  ec_subm (Y3, E, D, ctx);
+  ec_mulm (Y3, Y3, F, ctx);
+
+  /* Z_3 = F · J */
+  ec_mulm (Z3, F, J, ctx);
+
+#undef X1
+#undef Y1
+#undef Z1
+#undef X3
+#undef Y3
+#undef Z3
+#undef B
+#undef C
+#undef D
+#undef E
+#undef F
+#undef H
+#undef J
+}
+
+
+/*  RESULT = 2 * POINT  */
 void
-_gcry_mpi_ec_add_points (mpi_point_t *result,
-                         mpi_point_t *p1, mpi_point_t *p2,
-                         mpi_ec_t ctx)
+_gcry_mpi_ec_dup_point (mpi_point_t result, mpi_point_t point, mpi_ec_t ctx)
+{
+  switch (ctx->model)
+    {
+    case MPI_EC_WEIERSTRASS:
+      dup_point_weierstrass (result, point, ctx);
+      break;
+    case MPI_EC_MONTGOMERY:
+      dup_point_montgomery (result, point, ctx);
+      break;
+    case MPI_EC_TWISTEDEDWARDS:
+      dup_point_twistededwards (result, point, ctx);
+      break;
+    }
+}
+
+
+/* RESULT = P1 + P2  (Weierstrass version).*/
+static void
+add_points_weierstrass (mpi_point_t result,
+                        mpi_point_t p1, mpi_point_t p2,
+                        mpi_ec_t ctx)
 {
 #define x1 (p1->x    )
 #define y1 (p1->y    )
@@ -476,17 +833,17 @@ _gcry_mpi_ec_add_points (mpi_point_t *result,
 #define x3 (result->x)
 #define y3 (result->y)
 #define z3 (result->z)
-#define l1 (ctx->scratch[0])
-#define l2 (ctx->scratch[1])
-#define l3 (ctx->scratch[2])
-#define l4 (ctx->scratch[3])
-#define l5 (ctx->scratch[4])
-#define l6 (ctx->scratch[5])
-#define l7 (ctx->scratch[6])
-#define l8 (ctx->scratch[7])
-#define l9 (ctx->scratch[8])
-#define t1 (ctx->scratch[9])
-#define t2 (ctx->scratch[10])
+#define l1 (ctx->t.scratch[0])
+#define l2 (ctx->t.scratch[1])
+#define l3 (ctx->t.scratch[2])
+#define l4 (ctx->t.scratch[3])
+#define l5 (ctx->t.scratch[4])
+#define l6 (ctx->t.scratch[5])
+#define l7 (ctx->t.scratch[6])
+#define l8 (ctx->t.scratch[7])
+#define l9 (ctx->t.scratch[8])
+#define t1 (ctx->t.scratch[9])
+#define t2 (ctx->t.scratch[10])
 
   if ( (!mpi_cmp (x1, x2)) && (!mpi_cmp (y1, y2)) && (!mpi_cmp (z1, z2)) )
     {
@@ -518,23 +875,23 @@ _gcry_mpi_ec_add_points (mpi_point_t *result,
         mpi_set (l1, x1);
       else
         {
-          ec_powm (l1, z2, ctx->two, ctx);
+          ec_pow2 (l1, z2, ctx);
           ec_mulm (l1, l1, x1, ctx);
         }
       if (z1_is_one)
-        mpi_set (l2, x1);
+        mpi_set (l2, x2);
       else
         {
-          ec_powm (l2, z1, ctx->two, ctx);
+          ec_pow2 (l2, z1, ctx);
           ec_mulm (l2, l2, x2, ctx);
         }
       /* l3 = l1 - l2 */
       ec_subm (l3, l1, l2, ctx);
       /* l4 = y1 z2^3  */
-      ec_powm (l4, z2, ctx->three, ctx);
+      ec_powm (l4, z2, mpi_const (MPI_C_THREE), ctx);
       ec_mulm (l4, l4, y1, ctx);
       /* l5 = y2 z1^3  */
-      ec_powm (l5, z1, ctx->three, ctx);
+      ec_powm (l5, z1, mpi_const (MPI_C_THREE), ctx);
       ec_mulm (l5, l5, y2, ctx);
       /* l6 = l4 - l5  */
       ec_subm (l6, l4, l5, ctx);
@@ -564,19 +921,19 @@ _gcry_mpi_ec_add_points (mpi_point_t *result,
           ec_mulm (z3, z1, z2, ctx);
           ec_mulm (z3, z3, l3, ctx);
           /* x3 = l6^2 - l7 l3^2  */
-          ec_powm (t1, l6, ctx->two, ctx);
-          ec_powm (t2, l3, ctx->two, ctx);
+          ec_pow2 (t1, l6, ctx);
+          ec_pow2 (t2, l3, ctx);
           ec_mulm (t2, t2, l7, ctx);
           ec_subm (x3, t1, t2, ctx);
           /* l9 = l7 l3^2 - 2 x3  */
-          ec_mulm (t1, x3, ctx->two, ctx);
+          ec_mul2 (t1, x3, ctx);
           ec_subm (l9, t2, t1, ctx);
           /* y3 = (l9 l6 - l8 l3^3)/2  */
           ec_mulm (l9, l9, l6, ctx);
-          ec_powm (t1, l3, ctx->three, ctx); /* fixme: Use saved value*/
+          ec_powm (t1, l3, mpi_const (MPI_C_THREE), ctx); /* fixme: Use saved value*/
           ec_mulm (t1, t1, l8, ctx);
           ec_subm (y3, l9, t1, ctx);
-          ec_mulm (y3, y3, ctx->two_inv_p, ctx);
+          ec_mulm (y3, y3, ec_get_two_inv_p (ctx), ctx);
         }
     }
 
@@ -603,36 +960,190 @@ _gcry_mpi_ec_add_points (mpi_point_t *result,
 }
 
 
+/* RESULT = P1 + P2  (Montgomery version).*/
+static void
+add_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_add_points", "Montgomery");
+}
+
+
+/* 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)
+{
+#define X1 (p1->x)
+#define Y1 (p1->y)
+#define Z1 (p1->z)
+#define X2 (p2->x)
+#define Y2 (p2->y)
+#define Z2 (p2->z)
+#define X3 (result->x)
+#define Y3 (result->y)
+#define Z3 (result->z)
+#define A (ctx->t.scratch[0])
+#define B (ctx->t.scratch[1])
+#define C (ctx->t.scratch[2])
+#define D (ctx->t.scratch[3])
+#define E (ctx->t.scratch[4])
+#define F (ctx->t.scratch[5])
+#define G (ctx->t.scratch[6])
+#define tmp (ctx->t.scratch[7])
+
+  /* Compute: (X_3 : Y_3 : Z_3) = (X_1 : Y_1 : Z_1) + (X_2 : Y_2 : Z_3)  */
+
+  /* A = Z1 · Z2 */
+  ec_mulm (A, Z1, Z2, ctx);
+
+  /* B = A^2 */
+  ec_pow2 (B, A, ctx);
+
+  /* C = X1 · X2 */
+  ec_mulm (C, X1, X2, ctx);
+
+  /* D = Y1 · Y2 */
+  ec_mulm (D, Y1, Y2, ctx);
+
+  /* E = d · C · D */
+  ec_mulm (E, ctx->b, C, ctx);
+  ec_mulm (E, E, D, ctx);
+
+  /* F = B - E */
+  ec_subm (F, B, E, ctx);
+
+  /* G = B + E */
+  ec_addm (G, B, E, ctx);
+
+  /* X_3 = A · F · ((X_1 + Y_1) · (X_2 + Y_2) - C - D) */
+  ec_addm (tmp, X1, Y1, ctx);
+  ec_addm (X3, X2, Y2, ctx);
+  ec_mulm (X3, X3, tmp, ctx);
+  ec_subm (X3, X3, C, ctx);
+  ec_subm (X3, X3, D, ctx);
+  ec_mulm (X3, X3, F, ctx);
+  ec_mulm (X3, X3, A, ctx);
+
+  /* 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);
+    }
+  else
+    {
+      ec_mulm (Y3, ctx->a, C, ctx);
+      ec_subm (Y3, D, Y3, ctx);
+    }
+  ec_mulm (Y3, Y3, G, ctx);
+  ec_mulm (Y3, Y3, A, ctx);
+
+  /* Z_3 = F · G */
+  ec_mulm (Z3, F, G, ctx);
+
+
+#undef X1
+#undef Y1
+#undef Z1
+#undef X2
+#undef Y2
+#undef Z2
+#undef X3
+#undef Y3
+#undef Z3
+#undef A
+#undef B
+#undef C
+#undef D
+#undef E
+#undef F
+#undef G
+#undef tmp
+}
+
+
+/* RESULT = P1 + P2 */
+void
+_gcry_mpi_ec_add_points (mpi_point_t result,
+                         mpi_point_t p1, mpi_point_t p2,
+                         mpi_ec_t ctx)
+{
+  switch (ctx->model)
+    {
+    case MPI_EC_WEIERSTRASS:
+      add_points_weierstrass (result, p1, p2, ctx);
+      break;
+    case MPI_EC_MONTGOMERY:
+      add_points_montgomery (result, p1, p2, ctx);
+      break;
+    case MPI_EC_TWISTEDEDWARDS:
+      add_points_twistededwards (result, p1, p2, ctx);
+      break;
+    }
+}
+
 
 /* Scalar point multiplication - the main function for ECC.  If takes
    an integer SCALAR and a POINT as well as the usual context CTX.
    RESULT will be set to the resulting point. */
 void
-_gcry_mpi_ec_mul_point (mpi_point_t *result,
-                        gcry_mpi_t scalar, mpi_point_t *point,
+_gcry_mpi_ec_mul_point (mpi_point_t result,
+                        gcry_mpi_t scalar, mpi_point_t point,
                         mpi_ec_t ctx)
 {
-#if 0
-  /* Simple left to right binary method.  GECC Algorithm 3.27 */
-  unsigned int nbits;
-  int i;
-
-  nbits = mpi_get_nbits (scalar);
-  mpi_set_ui (result->x, 1);
-  mpi_set_ui (result->y, 1);
-  mpi_set_ui (result->z, 0);
+  gcry_mpi_t x1, y1, z1, k, h, yy;
+  unsigned int i, loops;
+  mpi_point_struct p1, p2, p1inv;
 
-  for (i=nbits-1; i >= 0; i--)
+  if (ctx->model == MPI_EC_TWISTEDEDWARDS)
     {
-      _gcry_mpi_ec_dup_point (result, result, ctx);
-      if (mpi_test_bit (scalar, i) == 1)
-        _gcry_mpi_ec_add_points (result, result, point, ctx);
-    }
+      /* Simple left to right binary method.  GECC Algorithm 3.27 */
+      unsigned int nbits;
+      int j;
 
-#else
-  gcry_mpi_t x1, y1, z1, k, h, yy;
-  unsigned int i, loops;
-  mpi_point_t p1, p2, p1inv;
+      nbits = mpi_get_nbits (scalar);
+      mpi_set_ui (result->x, 0);
+      mpi_set_ui (result->y, 1);
+      mpi_set_ui (result->z, 1);
+
+      if (mpi_is_secure (scalar))
+        {
+          /* If SCALAR is in secure memory we assume that it is the
+             secret key we use constant time operation.  */
+          mpi_point_struct tmppnt;
+
+          point_init (&tmppnt);
+          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_free (&tmppnt);
+        }
+      else
+        {
+          for (j=nbits-1; j >= 0; j--)
+            {
+              _gcry_mpi_ec_dup_point (result, result, ctx);
+              if (mpi_test_bit (scalar, j))
+                _gcry_mpi_ec_add_points (result, result, point, ctx);
+            }
+        }
+      return;
+    }
 
   x1 = mpi_alloc_like (ctx->p);
   y1 = mpi_alloc_like (ctx->p);
@@ -640,7 +1151,7 @@ _gcry_mpi_ec_mul_point (mpi_point_t *result,
   k  = mpi_copy (scalar);
   yy = mpi_copy (point->y);
 
-  if ( mpi_is_neg (k) )
+  if ( mpi_has_sign (k) )
     {
       k->sign = 0;
       ec_invm (yy, yy, ctx);
@@ -666,14 +1177,27 @@ _gcry_mpi_ec_mul_point (mpi_point_t *result,
       mpi_free (z2);
       mpi_free (z3);
     }
-  z1 = mpi_copy (ctx->one);
+  z1 = mpi_copy (mpi_const (MPI_C_ONE));
 
-  mpi_mul (h, k, ctx->three); /* h = 3k */
+  mpi_mul (h, k, mpi_const (MPI_C_THREE)); /* h = 3k */
   loops = mpi_get_nbits (h);
-
-  mpi_set (result->x, point->x);
-  mpi_set (result->y, yy); mpi_free (yy); yy = NULL;
-  mpi_set (result->z, point->z);
+  if (loops < 2)
+    {
+      /* If SCALAR is zero, the above mpi_mul sets H to zero and thus
+         LOOPs will be zero.  To avoid an underflow of I in the main
+         loop we set LOOP to 2 and the result to (0,0,0).  */
+      loops = 2;
+      mpi_clear (result->x);
+      mpi_clear (result->y);
+      mpi_clear (result->z);
+    }
+  else
+    {
+      mpi_set (result->x, point->x);
+      mpi_set (result->y, yy);
+      mpi_set (result->z, point->z);
+    }
+  mpi_free (yy); yy = NULL;
 
   p1.x = x1; x1 = NULL;
   p1.y = y1; y1 = NULL;
@@ -704,5 +1228,73 @@ _gcry_mpi_ec_mul_point (mpi_point_t *result,
   point_free (&p1inv);
   mpi_free (h);
   mpi_free (k);
-#endif
+}
+
+
+/* Return true if POINT is on the curve described by CTX.  */
+int
+_gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx)
+{
+  int res = 0;
+  gcry_mpi_t x, y, w;
+
+  x = mpi_new (0);
+  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);
+
+        /* y^2 == x^3 + a·x + b */
+        ec_pow2 (y, y, ctx);
+
+        ec_pow3 (xxx, x, ctx);
+        ec_mulm (w, ctx->a, x, ctx);
+        ec_addm (w, w, ctx->b, ctx);
+        ec_addm (w, w, xxx, ctx);
+
+        if (!mpi_cmp (y, w))
+          res = 1;
+
+        _gcry_mpi_release (xxx);
+      }
+      break;
+    case MPI_EC_MONTGOMERY:
+      log_fatal ("%s: %s not yet supported\n",
+                 "_gcry_mpi_ec_curve_point", "Montgomery");
+      break;
+    case MPI_EC_TWISTEDEDWARDS:
+      {
+        /* 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);
+          }
+        else
+          ec_mulm (w, ctx->a, x, ctx);
+        ec_addm (w, w, y, ctx);
+        ec_subm (w, w, mpi_const (MPI_C_ONE), ctx);
+        ec_mulm (x, x, y, ctx);
+        ec_mulm (x, x, ctx->b, ctx);
+        ec_subm (w, w, x, ctx);
+        if (!mpi_cmp_ui (w, 0))
+          res = 1;
+      }
+      break;
+    }
+
+  _gcry_mpi_release (w);
+  _gcry_mpi_release (x);
+  _gcry_mpi_release (y);
+
+  return res;
 }
index be88cae..4f33937 100644 (file)
@@ -2,7 +2,7 @@
    Note: I added some stuff for use with gnupg
 
 Copyright (C) 1991, 1992, 1993, 1994, 1996, 1998,
-              2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+              2000, 2001, 2002, 2003, 2004, 2011 Free Software Foundation, Inc.
 
 This file is free software; you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
@@ -184,28 +184,53 @@ extern UDItype __udiv_qrnnd ();
 /***************************************
  **************  ARM  ******************
  ***************************************/
-#if defined (__arm__) && W_TYPE_SIZE == 32
+#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
+   /* could not detect? */
+# endif
+#endif
 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
   __asm__ ("adds %1, %4, %5\n"                                          \
           "adc  %0, %2, %3"                                            \
-          : "=r" ((USItype)(sh)),                                      \
-            "=&r" ((USItype)(sl))                                      \
+          : "=r" ((sh)),                                               \
+            "=&r" ((sl))                                               \
           : "%r" ((USItype)(ah)),                                      \
             "rI" ((USItype)(bh)),                                      \
             "%r" ((USItype)(al)),                                      \
-            "rI" ((USItype)(bl)))
+            "rI" ((USItype)(bl)) __CLOBBER_CC)
 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
   __asm__ ("subs %1, %4, %5\n"                                          \
           "sbc  %0, %2, %3"                                            \
-          : "=r" ((USItype)(sh)),                                      \
-            "=&r" ((USItype)(sl))                                      \
+          : "=r" ((sh)),                                               \
+            "=&r" ((sl))                                               \
           : "r" ((USItype)(ah)),                                       \
             "rI" ((USItype)(bh)),                                      \
             "r" ((USItype)(al)),                                       \
-            "rI" ((USItype)(bl)))
-#if defined __ARM_ARCH_2__ || defined __ARM_ARCH_3__
+            "rI" ((USItype)(bl)) __CLOBBER_CC)
+#if (defined __ARM_ARCH && __ARM_ARCH <= 3)
 #define umul_ppmm(xh, xl, a, b) \
-  __asm__ ("%@ Inlined umul_ppmm\n"                                     \
+  __asm__ ("@ Inlined umul_ppmm\n"                                      \
        "mov    %|r0, %2, lsr #16               @ AAAA\n"               \
        "mov    %|r2, %3, lsr #16               @ BBBB\n"               \
        "bic    %|r1, %2, %|r0, lsl #16         @ aaaa\n"               \
@@ -218,26 +243,69 @@ extern UDItype __udiv_qrnnd ();
        "addcs  %|r2, %|r2, #65536\n"                                   \
        "adds   %1, %|r1, %|r0, lsl #16\n"                              \
        "adc    %0, %|r2, %|r0, lsr #16"                                \
-          : "=&r" ((USItype)(xh)),                                     \
-            "=r" ((USItype)(xl))                                       \
+          : "=&r" ((xh)),                                              \
+            "=r" ((xl))                                                \
           : "r" ((USItype)(a)),                                        \
             "r" ((USItype)(b))                                         \
-          : "r0", "r1", "r2")
-#else
+          : "r0", "r1", "r2" __AND_CLOBBER_CC)
+#else /* __ARM_ARCH >= 4 */
 #define umul_ppmm(xh, xl, a, b)                                         \
-  __asm__ ("%@ Inlined umul_ppmm\n"                                     \
-          "umull %r1, %r0, %r2, %r3"                                   \
-                  : "=&r" ((USItype)(xh)),                             \
-                    "=r" ((USItype)(xl))                               \
+  __asm__ ("@ Inlined umul_ppmm\n"                                      \
+          "umull %1, %0, %2, %3"                                       \
+                  : "=&r" ((xh)),                                      \
+                    "=r" ((xl))                                        \
                   : "r" ((USItype)(a)),                                \
-                    "r" ((USItype)(b))                                 \
-                  : "r0", "r1")
-#endif
+                    "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) \
+  __asm__ ("clz %0, %1"                                                 \
+                  : "=r" ((count))                                     \
+                  : "r" ((USItype)(x)))
+#endif /* __ARM_ARCH >= 5 */
 #endif /* __arm__ */
 
 /***************************************
+ **********  ARM64 / Aarch64  **********
+ ***************************************/
+#if defined(__aarch64__) && W_TYPE_SIZE == 64
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  __asm__ ("adds %1, %4, %5\n"                                          \
+           "adc  %0, %2, %3\n"                                          \
+           : "=r" ((sh)),                                               \
+             "=&r" ((sl))                                               \
+           : "r" ((UDItype)(ah)),                                       \
+             "r" ((UDItype)(bh)),                                       \
+             "r" ((UDItype)(al)),                                       \
+             "r" ((UDItype)(bl)) __CLOBBER_CC)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  __asm__ ("subs %1, %4, %5\n"                                          \
+           "sbc  %0, %2, %3\n"                                          \
+           : "=r" ((sh)),                                               \
+             "=&r" ((sl))                                               \
+           : "r" ((UDItype)(ah)),                                       \
+             "r" ((UDItype)(bh)),                                       \
+             "r" ((UDItype)(al)),                                       \
+             "r" ((UDItype)(bl)) __CLOBBER_CC)
+#define umul_ppmm(ph, pl, m0, m1) \
+  do {                                                                  \
+    UDItype __m0 = (m0), __m1 = (m1), __ph;                             \
+    (pl) = __m0 * __m1;                                                 \
+    __asm__ ("umulh %0,%1,%2"                                           \
+             : "=r" (__ph)                                              \
+             : "r" (__m0),                                              \
+               "r" (__m1));                                             \
+    (ph) = __ph; \
+  } while (0)
+#define count_leading_zeros(count, x) \
+  __asm__ ("clz %0, %1\n"                                               \
+           : "=r" ((count))                                             \
+           : "r" ((UDItype)(x)))
+#endif /* __aarch64__ */
+
+/***************************************
  **************  CLIPPER  **************
  ***************************************/
 #if defined (__clipper__) && W_TYPE_SIZE == 32
@@ -437,43 +505,48 @@ extern USItype __udiv_qrnnd ();
 #define add_ssaaaa(sh, sl, ah, al, bh, bl) \
   __asm__ ("addl %5,%1\n"                                               \
           "adcl %3,%0"                                                 \
-          : "=r" ((USItype)(sh)),                                      \
-            "=&r" ((USItype)(sl))                                      \
+          : "=r" ((sh)),                                               \
+            "=&r" ((sl))                                               \
           : "%0" ((USItype)(ah)),                                      \
             "g" ((USItype)(bh)),                                       \
             "%1" ((USItype)(al)),                                      \
-            "g" ((USItype)(bl)))
+            "g" ((USItype)(bl))                                        \
+          __CLOBBER_CC)
 #define sub_ddmmss(sh, sl, ah, al, bh, bl) \
   __asm__ ("subl %5,%1\n"                                               \
           "sbbl %3,%0"                                                 \
-          : "=r" ((USItype)(sh)),                                      \
-            "=&r" ((USItype)(sl))                                      \
+          : "=r" ((sh)),                                               \
+            "=&r" ((sl))                                               \
           : "0" ((USItype)(ah)),                                       \
             "g" ((USItype)(bh)),                                       \
             "1" ((USItype)(al)),                                       \
-            "g" ((USItype)(bl)))
+            "g" ((USItype)(bl))                                        \
+          __CLOBBER_CC)
 #define umul_ppmm(w1, w0, u, v) \
   __asm__ ("mull %3"                                                    \
-          : "=a" ((USItype)(w0)),                                      \
-            "=d" ((USItype)(w1))                                       \
+          : "=a" ((w0)),                                               \
+            "=d" ((w1))                                                \
           : "%0" ((USItype)(u)),                                       \
-            "rm" ((USItype)(v)))
+            "rm" ((USItype)(v))                                        \
+          __CLOBBER_CC)
 #define udiv_qrnnd(q, r, n1, n0, d) \
   __asm__ ("divl %4"                                                    \
-          : "=a" ((USItype)(q)),                                       \
-            "=d" ((USItype)(r))                                        \
+          : "=a" ((q)),                                                \
+            "=d" ((r))                                                 \
           : "0" ((USItype)(n0)),                                       \
             "1" ((USItype)(n1)),                                       \
-            "rm" ((USItype)(d)))
+            "rm" ((USItype)(d))                                        \
+          __CLOBBER_CC)
 #define count_leading_zeros(count, x) \
   do {                                                                 \
     USItype __cbtmp;                                                   \
     __asm__ ("bsrl %1,%0"                                               \
-            : "=r" (__cbtmp) : "rm" ((USItype)(x)));                   \
+            : "=r" (__cbtmp) : "rm" ((USItype)(x))                     \
+            __CLOBBER_CC);                                             \
     (count) = __cbtmp ^ 31;                                            \
   } while (0)
 #define count_trailing_zeros(count, x) \
-  __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)))
+  __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)) __CLOBBER_CC)
 #ifndef UMUL_TIME
 #define UMUL_TIME 40
 #endif
@@ -482,6 +555,69 @@ extern USItype __udiv_qrnnd ();
 #endif
 #endif /* 80x86 */
 
+/***************************************
+ *********** AMD64 / x86-64 ************
+ ***************************************/
+#if defined(__x86_64) && W_TYPE_SIZE == 64
+#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
+  __asm__ ("addq %5,%1\n"                                               \
+          "adcq %3,%0"                                                 \
+          : "=r" ((sh)),                                               \
+            "=&r" ((sl))                                               \
+          : "0" ((UDItype)(ah)),                                       \
+            "g"  ((UDItype)(bh)),                                      \
+            "1" ((UDItype)(al)),                                       \
+            "g"  ((UDItype)(bl))                                       \
+          __CLOBBER_CC)
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+  __asm__ ("subq %5,%1\n"                                               \
+          "sbbq %3,%0"                                                 \
+          : "=r" ((sh)),                                               \
+            "=&r" ((sl))                                               \
+          : "0" ((UDItype)(ah)),                                       \
+            "g" ((UDItype)(bh)),                                       \
+            "1" ((UDItype)(al)),                                       \
+            "g" ((UDItype)(bl))                                        \
+          __CLOBBER_CC)
+#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) \
+  __asm__ ("divq %4"                                                    \
+          : "=a" ((q)),                                                \
+            "=d" ((r))                                                 \
+          : "0" ((UDItype)(n0)),                                       \
+            "1" ((UDItype)(n1)),                                       \
+            "rm" ((UDItype)(d))                                        \
+          __CLOBBER_CC)
+#define count_leading_zeros(count, x) \
+  do {                                                                  \
+    UDItype __cbtmp;                                                    \
+    __asm__ ("bsrq %1,%0"                                               \
+             : "=r" (__cbtmp) : "rm" ((UDItype)(x))                     \
+             __CLOBBER_CC);                                             \
+    (count) = __cbtmp ^ 63;                                             \
+  } while (0)
+#define count_trailing_zeros(count, x) \
+  do {                                                                  \
+    UDItype __cbtmp;                                                    \
+    __asm__ ("bsfq %1,%0"                                               \
+             : "=r" (__cbtmp) : "rm" ((UDItype)(x))                     \
+             __CLOBBER_CC);                                             \
+    (count) = __cbtmp;                                                  \
+  } while (0)
+#ifndef UMUL_TIME
+#define UMUL_TIME 40
+#endif
+#ifndef UDIV_TIME
+#define UDIV_TIME 40
+#endif
+#endif /* __x86_64 */
+
 
 /***************************************
  **************  I860  *****************
@@ -714,7 +850,8 @@ extern USItype __udiv_qrnnd ();
  **************  MIPS  *****************
  ***************************************/
 #if defined (__mips__) && W_TYPE_SIZE == 32
-#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
+#if defined (__clang__) || (__GNUC__ >= 5) || (__GNUC__ == 4 && \
+                                               __GNUC_MINOR__ >= 4)
 #define umul_ppmm(w1, w0, u, v) \
   do {                                                                  \
     UDItype _r;                                                         \
@@ -826,22 +963,22 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
   do {                                                                 \
     if (__builtin_constant_p (bh) && (bh) == 0)                        \
       __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2"           \
-            : "=r" ((USItype)(sh)),                                    \
-              "=&r" ((USItype)(sl))                                    \
+            : "=r" ((sh)),                                             \
+              "=&r" ((sl))                                             \
             : "%r" ((USItype)(ah)),                                    \
               "%r" ((USItype)(al)),                                    \
               "rI" ((USItype)(bl)));                                   \
     else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0)         \
       __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2"           \
-            : "=r" ((USItype)(sh)),                                    \
-              "=&r" ((USItype)(sl))                                    \
+            : "=r" ((sh)),                                             \
+              "=&r" ((sl))                                             \
             : "%r" ((USItype)(ah)),                                    \
               "%r" ((USItype)(al)),                                    \
               "rI" ((USItype)(bl)));                                   \
     else                                                               \
       __asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3"          \
-            : "=r" ((USItype)(sh)),                                    \
-              "=&r" ((USItype)(sl))                                    \
+            : "=r" ((sh)),                                             \
+              "=&r" ((sl))                                             \
             : "%r" ((USItype)(ah)),                                    \
               "r" ((USItype)(bh)),                                     \
               "%r" ((USItype)(al)),                                    \
@@ -851,36 +988,36 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
   do {                                                                 \
     if (__builtin_constant_p (ah) && (ah) == 0)                        \
       __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2"       \
-              : "=r" ((USItype)(sh)),                                  \
-                "=&r" ((USItype)(sl))                                  \
+              : "=r" ((sh)),                                           \
+                "=&r" ((sl))                                           \
               : "r" ((USItype)(bh)),                                   \
                 "rI" ((USItype)(al)),                                  \
                 "r" ((USItype)(bl)));                                  \
     else if (__builtin_constant_p (ah) && (ah) ==~(USItype) 0)         \
       __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2"       \
-              : "=r" ((USItype)(sh)),                                  \
-                "=&r" ((USItype)(sl))                                  \
+              : "=r" ((sh)),                                  \
+                "=&r" ((sl))                                  \
               : "r" ((USItype)(bh)),                                   \
                 "rI" ((USItype)(al)),                                  \
                 "r" ((USItype)(bl)));                                  \
     else if (__builtin_constant_p (bh) && (bh) == 0)                   \
       __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2"         \
-              : "=r" ((USItype)(sh)),                                  \
-                "=&r" ((USItype)(sl))                                  \
+              : "=r" ((sh)),                                           \
+                "=&r" ((sl))                                           \
               : "r" ((USItype)(ah)),                                   \
                 "rI" ((USItype)(al)),                                  \
                 "r" ((USItype)(bl)));                                  \
     else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0)         \
       __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2"         \
-              : "=r" ((USItype)(sh)),                                  \
-                "=&r" ((USItype)(sl))                                  \
+              : "=r" ((sh)),                                           \
+                "=&r" ((sl))                                           \
               : "r" ((USItype)(ah)),                                   \
                 "rI" ((USItype)(al)),                                  \
                 "r" ((USItype)(bl)));                                  \
     else                                                               \
       __asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2"      \
-              : "=r" ((USItype)(sh)),                                  \
-                "=&r" ((USItype)(sl))                                  \
+              : "=r" ((sh)),                                           \
+                "=&r" ((sl))                                           \
               : "r" ((USItype)(ah)),                                   \
                 "r" ((USItype)(bh)),                                   \
                 "rI" ((USItype)(al)),                                  \
@@ -888,7 +1025,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
   } while (0)
 #define count_leading_zeros(count, x) \
   __asm__ ("{cntlz|cntlzw} %0,%1"                                       \
-          : "=r" ((USItype)(count))                                    \
+          : "=r" ((count))                                             \
           : "r" ((USItype)(x)))
 #define COUNT_LEADING_ZEROS_0 32
 #if defined (_ARCH_PPC)
@@ -896,7 +1033,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
   do {                                                                 \
     USItype __m0 = (m0), __m1 = (m1);                                  \
     __asm__ ("mulhwu %0,%1,%2"                                          \
-            : "=r" ((USItype) ph)                                      \
+            : "=r" (ph)                                                \
             : "%r" (__m0),                                             \
               "r" (__m1));                                             \
     (pl) = __m0 * __m1;                                                \
@@ -918,8 +1055,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI)));
   do {                                                                 \
     USItype __m0 = (m0), __m1 = (m1);                                  \
     __asm__ ("mul %0,%2,%3"                                             \
-            : "=r" ((USItype)(xh)),                                    \
-              "=q" ((USItype)(xl))                                     \
+            : "=r" ((xh)),                                             \
+              "=q" ((xl))                                              \
             : "r" (__m0),                                              \
               "r" (__m1));                                             \
     (xh) += ((((SItype) __m0 >> 31) & __m1)                            \
index 98abc56..53f476e 100644 (file)
@@ -36,7 +36,7 @@
  * result in W. U and V may be the same.
  */
 void
-gcry_mpi_add_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
+_gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
 {
     mpi_ptr_t wp, up;
     mpi_size_t usize, wsize;
@@ -85,7 +85,7 @@ gcry_mpi_add_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
 
 
 void
-gcry_mpi_add(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+_gcry_mpi_add(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
 {
     mpi_ptr_t wp, up, vp;
     mpi_size_t usize, vsize, wsize;
@@ -162,7 +162,7 @@ gcry_mpi_add(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
  * result in W.
  */
 void
-gcry_mpi_sub_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
+_gcry_mpi_sub_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
 {
     mpi_ptr_t wp, up;
     mpi_size_t usize, wsize;
@@ -211,25 +211,25 @@ gcry_mpi_sub_ui(gcry_mpi_t w, gcry_mpi_t u, unsigned long v )
 }
 
 void
-gcry_mpi_sub(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+_gcry_mpi_sub(gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
 {
   gcry_mpi_t vv = mpi_copy (v);
   vv->sign = ! vv->sign;
-  gcry_mpi_add (w, u, vv);
+  mpi_add (w, u, vv);
   mpi_free (vv);
 }
 
 
 void
-gcry_mpi_addm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+_gcry_mpi_addm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
 {
-    gcry_mpi_add(w, u, v);
-    _gcry_mpi_fdiv_r( w, w, m );
+  mpi_add (w, u, v);
+  mpi_mod (w, w, m);
 }
 
 void
-gcry_mpi_subm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+_gcry_mpi_subm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
 {
-    gcry_mpi_sub(w, u, v);
-    _gcry_mpi_fdiv_r( w, w, m );
+  mpi_sub (w, u, v);
+  mpi_mod (w, w, m);
 }
index cdc6b0b..fcafda0 100644 (file)
@@ -1,5 +1,6 @@
 /* mpi-bit.c  -  MPI bit level functions
  * Copyright (C) 1998, 1999, 2001, 2002, 2006 Free Software Foundation, Inc.
+ * Copyright (C) 2013  g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
@@ -67,7 +68,7 @@ _gcry_mpi_normalize( gcry_mpi_t a )
  * Return the number of bits in A.
  */
 unsigned int
-gcry_mpi_get_nbits( gcry_mpi_t a )
+_gcry_mpi_get_nbits (gcry_mpi_t a)
 {
     unsigned n;
 
@@ -94,7 +95,7 @@ gcry_mpi_get_nbits( gcry_mpi_t a )
  * Test whether bit N is set.
  */
 int
-gcry_mpi_test_bit( gcry_mpi_t a, unsigned int n )
+_gcry_mpi_test_bit( gcry_mpi_t a, unsigned int n )
 {
     unsigned int limbno, bitno;
     mpi_limb_t limb;
@@ -113,10 +114,16 @@ gcry_mpi_test_bit( gcry_mpi_t a, unsigned int n )
  * Set bit N of A.
  */
 void
-gcry_mpi_set_bit( gcry_mpi_t a, unsigned int n )
+_gcry_mpi_set_bit( gcry_mpi_t a, unsigned int n )
 {
   unsigned int limbno, bitno;
 
+  if (mpi_is_immutable (a))
+    {
+      mpi_immutable_failed ();
+      return;
+    }
+
   limbno = n / BITS_PER_MPI_LIMB;
   bitno  = n % BITS_PER_MPI_LIMB;
 
@@ -132,10 +139,16 @@ gcry_mpi_set_bit( gcry_mpi_t a, unsigned int n )
  * Set bit N of A. and clear all bits above
  */
 void
-gcry_mpi_set_highbit( gcry_mpi_t a, unsigned int n )
+_gcry_mpi_set_highbit( gcry_mpi_t a, unsigned int n )
 {
   unsigned int limbno, bitno;
 
+  if (mpi_is_immutable (a))
+    {
+      mpi_immutable_failed ();
+      return;
+    }
+
   limbno = n / BITS_PER_MPI_LIMB;
   bitno  = n % BITS_PER_MPI_LIMB;
 
@@ -154,36 +167,47 @@ gcry_mpi_set_highbit( gcry_mpi_t a, unsigned int n )
  * clear bit N of A and all bits above
  */
 void
-gcry_mpi_clear_highbit( gcry_mpi_t a, unsigned int n )
+_gcry_mpi_clear_highbit( gcry_mpi_t a, unsigned int n )
 {
-    unsigned int limbno, bitno;
+  unsigned int limbno, bitno;
 
-    limbno = n / BITS_PER_MPI_LIMB;
-    bitno  = n % BITS_PER_MPI_LIMB;
+  if (mpi_is_immutable (a))
+    {
+      mpi_immutable_failed ();
+      return;
+    }
 
-    if( limbno >= a->nlimbs )
-       return; /* not allocated, therefore no need to clear bits
-                  :-) */
+  limbno = n / BITS_PER_MPI_LIMB;
+  bitno  = n % BITS_PER_MPI_LIMB;
+
+  if( limbno >= a->nlimbs )
+    return; /* not allocated, therefore no need to clear bits :-) */
 
-    for( ; bitno < BITS_PER_MPI_LIMB; bitno++ )
-       a->d[limbno] &= ~(A_LIMB_1 << bitno);
-    a->nlimbs = limbno+1;
+  for( ; bitno < BITS_PER_MPI_LIMB; bitno++ )
+    a->d[limbno] &= ~(A_LIMB_1 << bitno);
+  a->nlimbs = limbno+1;
 }
 
 /****************
  * Clear bit N of A.
  */
 void
-gcry_mpi_clear_bit( gcry_mpi_t a, unsigned int n )
+_gcry_mpi_clear_bit( gcry_mpi_t a, unsigned int n )
 {
-    unsigned int limbno, bitno;
+  unsigned int limbno, bitno;
 
-    limbno = n / BITS_PER_MPI_LIMB;
-    bitno  = n % BITS_PER_MPI_LIMB;
+  if (mpi_is_immutable (a))
+    {
+      mpi_immutable_failed ();
+      return;
+    }
 
-    if( limbno >= a->nlimbs )
-       return; /* don't need to clear this bit, it's to far to left */
-    a->d[limbno] &= ~(A_LIMB_1 << bitno);
+  limbno = n / BITS_PER_MPI_LIMB;
+  bitno  = n % BITS_PER_MPI_LIMB;
+
+  if (limbno >= a->nlimbs)
+    return; /* Don't need to clear this bit, it's far too left.  */
+  a->d[limbno] &= ~(A_LIMB_1 << bitno);
 }
 
 
@@ -194,19 +218,26 @@ gcry_mpi_clear_bit( gcry_mpi_t a, unsigned int n )
 void
 _gcry_mpi_rshift_limbs( gcry_mpi_t a, unsigned int count )
 {
-    mpi_ptr_t ap = a->d;
-    mpi_size_t n = a->nlimbs;
-    unsigned int i;
+  mpi_ptr_t ap = a->d;
+  mpi_size_t n = a->nlimbs;
+  unsigned int i;
 
-    if( count >= n ) {
-       a->nlimbs = 0;
-       return;
+  if (mpi_is_immutable (a))
+    {
+      mpi_immutable_failed ();
+      return;
     }
 
-    for( i = 0; i < n - count; i++ )
-       ap[i] = ap[i+count];
-    ap[i] = 0;
-    a->nlimbs -= count;
+  if (count >= n)
+    {
+      a->nlimbs = 0;
+      return;
+    }
+
+  for( i = 0; i < n - count; i++ )
+    ap[i] = ap[i+count];
+  ap[i] = 0;
+  a->nlimbs -= count;
 }
 
 
@@ -214,13 +245,19 @@ _gcry_mpi_rshift_limbs( gcry_mpi_t a, unsigned int count )
  * Shift A by N bits to the right.
  */
 void
-gcry_mpi_rshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
+_gcry_mpi_rshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
 {
   mpi_size_t xsize;
   unsigned int i;
   unsigned int nlimbs = (n/BITS_PER_MPI_LIMB);
   unsigned int nbits = (n%BITS_PER_MPI_LIMB);
 
+  if (mpi_is_immutable (x))
+    {
+      mpi_immutable_failed ();
+      return;
+    }
+
   if ( x == a )
     {
       /* In-place operation.  */
@@ -323,11 +360,17 @@ _gcry_mpi_lshift_limbs (gcry_mpi_t a, unsigned int count)
  * Shift A by N bits to the left.
  */
 void
-gcry_mpi_lshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
+_gcry_mpi_lshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
 {
   unsigned int nlimbs = (n/BITS_PER_MPI_LIMB);
   unsigned int nbits = (n%BITS_PER_MPI_LIMB);
 
+  if (mpi_is_immutable (x))
+    {
+      mpi_immutable_failed ();
+      return;
+    }
+
   if (x == a && !n)
     return;  /* In-place shift with an amount of zero.  */
 
@@ -357,7 +400,7 @@ gcry_mpi_lshift ( gcry_mpi_t x, gcry_mpi_t a, unsigned int n )
       /* We use a very dump approach: Shift left by the number of
          limbs plus one and than fix it up by an rshift.  */
       _gcry_mpi_lshift_limbs (x, nlimbs+1);
-      gcry_mpi_rshift (x, x, BITS_PER_MPI_LIMB - nbits);
+      mpi_rshift (x, x, BITS_PER_MPI_LIMB - nbits);
     }
 
   MPN_NORMALIZE (x->d, x->nlimbs);
index 30e1fce..838a7c9 100644 (file)
@@ -24,7 +24,7 @@
 #include "mpi-internal.h"
 
 int
-gcry_mpi_cmp_ui (gcry_mpi_t u, unsigned long v)
+_gcry_mpi_cmp_ui (gcry_mpi_t u, unsigned long v)
 {
   mpi_limb_t limb = v;
 
@@ -55,7 +55,7 @@ gcry_mpi_cmp_ui (gcry_mpi_t u, unsigned long v)
 
 
 int
-gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v)
+_gcry_mpi_cmp (gcry_mpi_t u, gcry_mpi_t v)
 {
   mpi_size_t usize;
   mpi_size_t vsize;
index a6ee300..9ac99c3 100644 (file)
@@ -50,7 +50,7 @@ _gcry_mpi_fdiv_r( gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor )
     _gcry_mpi_tdiv_r( rem, dividend, divisor );
 
     if( ((divisor_sign?1:0) ^ (dividend->sign?1:0)) && rem->nlimbs )
-       gcry_mpi_add( rem, rem, divisor);
+       mpi_add (rem, rem, divisor);
 
     if( temp_divisor )
        mpi_free(temp_divisor);
@@ -103,8 +103,8 @@ _gcry_mpi_fdiv_qr( gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mp
     _gcry_mpi_tdiv_qr( quot, rem, dividend, divisor );
 
     if( (divisor_sign ^ dividend->sign) && rem->nlimbs ) {
-       gcry_mpi_sub_ui( quot, quot, 1 );
-       gcry_mpi_add( rem, rem, divisor);
+       mpi_sub_ui( quot, quot, 1 );
+       mpi_add( rem, rem, divisor);
     }
 
     if( temp_divisor )
@@ -328,7 +328,8 @@ _gcry_mpi_divisible_ui(gcry_mpi_t dividend, ulong divisor )
 
 
 void
-gcry_mpi_div (gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor, int round)
+_gcry_mpi_div (gcry_mpi_t quot, gcry_mpi_t rem, gcry_mpi_t dividend,
+               gcry_mpi_t divisor, int round)
 {
   if (!round)
     {
index 5cbefa1..77ca05a 100644 (file)
@@ -28,7 +28,7 @@
  * Return: true if this 1, false in all other cases
  */
 int
-gcry_mpi_gcd( gcry_mpi_t g, gcry_mpi_t xa, gcry_mpi_t xb )
+_gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t xa, gcry_mpi_t xb)
 {
     gcry_mpi_t a, b;
 
@@ -38,14 +38,15 @@ gcry_mpi_gcd( gcry_mpi_t g, gcry_mpi_t xa, gcry_mpi_t xb )
     /* TAOCP Vol II, 4.5.2, Algorithm A */
     a->sign = 0;
     b->sign = 0;
-    while( gcry_mpi_cmp_ui( b, 0 ) ) {
-       _gcry_mpi_fdiv_r( g, a, b ); /* g used as temorary variable */
+    while (mpi_cmp_ui (b, 0))
+      {
+       _gcry_mpi_fdiv_r( g, a, b ); /* G is used as temporary variable. */
        mpi_set(a,b);
        mpi_set(b,g);
-    }
+      }
     mpi_set(g, a);
 
     mpi_free(a);
     mpi_free(b);
-    return !gcry_mpi_cmp_ui( g, 1);
+    return !mpi_cmp_ui( g, 1);
 }
index 88d9f56..94e2aec 100644 (file)
 #ifndef G10_MPI_INLINE_H
 #define G10_MPI_INLINE_H
 
+/* Starting with gcc 4.3 "extern inline" conforms in c99 mode to the
+   c99 semantics.  To keep the useful old semantics we use an
+   attribute.  */
 #ifndef G10_MPI_INLINE_DECL
-#define G10_MPI_INLINE_DECL  extern __inline__
+# ifdef __GNUC_STDC_INLINE__
+#  define G10_MPI_INLINE_DECL  extern inline __attribute__ ((__gnu_inline__))
+# else
+#  define G10_MPI_INLINE_DECL  extern __inline__
+# endif
 #endif
 
 G10_MPI_INLINE_DECL  mpi_limb_t
index e75b7c6..898ca47 100644 (file)
@@ -92,7 +92,7 @@ typedef int mpi_size_t;        /* (must be a signed type) */
     do {                               \
        mpi_size_t _i;                  \
        for( _i = 0; _i < (n); _i++ )   \
-           (d)[_i] = (d)[_i];          \
+           (d)[_i] = (s)[_i];          \
     } while (0)
 
 #define MPN_COPY_DECR( d, s, n ) \
@@ -145,7 +145,8 @@ typedef int mpi_size_t;        /* (must be a signed type) */
  */
 #define UDIV_QRNND_PREINV(q, r, nh, nl, d, di) \
     do {                                                           \
-       mpi_limb_t _q, _ql, _r;                                     \
+        mpi_limb_t _ql GCC_ATTR_UNUSED;                               \
+       mpi_limb_t _q, _r;                                          \
        mpi_limb_t _xh, _xl;                                        \
        umul_ppmm (_q, _ql, (nh), (di));                            \
        _q += (nh);     /* DI is 2**BITS_PER_MPI_LIMB too small */  \
index 5d26946..ee6813b 100644 (file)
@@ -29,7 +29,7 @@
  *             1 = (a*x) mod n
  */
 int
-gcry_mpi_invm( gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t n )
+_gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t n)
 {
 #if 0
     gcry_mpi_t u, v, u1, u2, u3, v1, v2, v3, q, t1, t2, t3;
@@ -165,6 +165,11 @@ gcry_mpi_invm( gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t n )
     int sign;
     int odd ;
 
+    if (!mpi_cmp_ui (a, 0))
+        return 0; /* Inverse does not exists.  */
+    if (!mpi_cmp_ui (n, 1))
+        return 0; /* Inverse does not exists.  */
+
     u = mpi_copy(a);
     v = mpi_copy(n);
 
index 7ebfe6d..8862472 100644 (file)
@@ -47,7 +47,6 @@ void
 _gcry_mpi_mod (gcry_mpi_t rem, gcry_mpi_t dividend, gcry_mpi_t divisor)
 {
   _gcry_mpi_fdiv_r (rem, dividend, divisor);
-  rem->sign = 0;
 }
 
 
@@ -63,7 +62,7 @@ _gcry_mpi_barrett_init (gcry_mpi_t m, int copy)
   gcry_mpi_t tmp;
 
   mpi_normalize (m);
-  ctx = gcry_xcalloc (1, sizeof *ctx);
+  ctx = xcalloc (1, sizeof *ctx);
 
   if (copy)
     {
@@ -100,7 +99,7 @@ _gcry_mpi_barrett_free (mpi_barrett_t ctx)
         mpi_free (ctx->r3);
       if (ctx->m_copied)
         mpi_free (ctx->m);
-      gcry_free (ctx);
+      xfree (ctx);
     }
 }
 
@@ -111,7 +110,7 @@ _gcry_mpi_barrett_free (mpi_barrett_t ctx)
    _gcry_mpi_barrett_init must have been called to do the
    precalculations.  CTX is the context created by this precalculation
    and also conveys M.  If the Barret reduction could no be done a
-   starightforward reduction method is used.
+   straightforward reduction method is used.
 
    We assume that these conditions are met:
    Input:  x =(x_2k-1 ...x_0)_b
@@ -126,6 +125,7 @@ _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx)
   gcry_mpi_t y = ctx->y;
   gcry_mpi_t r1 = ctx->r1;
   gcry_mpi_t r2 = ctx->r2;
+  int sign;
 
   mpi_normalize (x);
   if (mpi_get_nlimbs (x) > 2*k )
@@ -134,6 +134,9 @@ _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx)
       return;
     }
 
+  sign = x->sign;
+  x->sign = 0;
+
   /* 1. q1 = floor( x / b^k-1)
    *    q2 = q1 * y
    *    q3 = floor( q2 / b^k+1 )
@@ -157,7 +160,7 @@ _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx)
     r2->nlimbs = k+1;
   mpi_sub ( r, r1, r2 );
 
-  if ( mpi_is_neg( r ) )
+  if ( mpi_has_sign ( r ) )
     {
       if (!ctx->r3)
         {
@@ -172,6 +175,7 @@ _gcry_mpi_mod_barrett (gcry_mpi_t r, gcry_mpi_t x, mpi_barrett_t ctx)
   while ( mpi_cmp( r, m ) >= 0 )
     mpi_sub ( r, r, m );
 
+  x->sign = sign;
 }
 
 
@@ -179,6 +183,6 @@ void
 _gcry_mpi_mul_barrett (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v,
                        mpi_barrett_t ctx)
 {
-  gcry_mpi_mul (w, u, v);
+  mpi_mul (w, u, v);
   mpi_mod_barrett (w, w, ctx);
 }
index ca5b3f1..43bd641 100644 (file)
@@ -39,7 +39,7 @@ static void barrett_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m
 static gcry_mpi_t init_barrett( gcry_mpi_t m, int *k, gcry_mpi_t *r1, gcry_mpi_t *r2 );
 static int calc_barrett( gcry_mpi_t r, gcry_mpi_t x, gcry_mpi_t m, gcry_mpi_t y, int k, gcry_mpi_t r1, gcry_mpi_t r2  );
 #else
-#define barrett_mulm( w, u, v, m, y, k, r1, r2 ) gcry_mpi_mulm( (w), (u), (v), (m) )
+#define barrett_mulm( w, u, v, m, y, k, r1, r2 ) _gcry_mpi_mulm( (w), (u), (v), (m) )
 #endif
 
 
@@ -89,7 +89,7 @@ _gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray,
     gcry_assert (t);
     gcry_assert (k < 10);
 
-    G = gcry_xcalloc( (1<<k) , sizeof *G );
+    G = xcalloc( (1<<k) , sizeof *G );
 #ifdef USE_BARRETT
     barrett_y = init_barrett( m, &barrett_k, &barrett_r1, &barrett_r2 );
 #endif
@@ -130,7 +130,7 @@ _gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray,
 #endif
     for(i=0; i < (1<<k); i++ )
        mpi_free(G[i]);
-    gcry_free(G);
+    xfree(G);
 }
 
 
@@ -204,7 +204,7 @@ calc_barrett( gcry_mpi_t r, gcry_mpi_t x, gcry_mpi_t m, gcry_mpi_t y, int k, gcr
        r2->nlimbs = k+1;
     mpi_sub( r, r1, r2 );
 
-    if( mpi_is_neg( r ) ) {
+    if( mpi_has_sign (r) ) {
        gcry_mpi_t tmp;
 
        tmp = mpi_alloc( k + 2 );
index 9aefd21..4f4d709 100644 (file)
@@ -31,7 +31,7 @@
 
 
 void
-gcry_mpi_mul_ui( gcry_mpi_t prod, gcry_mpi_t mult, unsigned long small_mult )
+_gcry_mpi_mul_ui (gcry_mpi_t prod, gcry_mpi_t mult, unsigned long small_mult)
 {
     mpi_size_t size, prod_size;
     mpi_ptr_t  prod_ptr;
@@ -61,7 +61,7 @@ gcry_mpi_mul_ui( gcry_mpi_t prod, gcry_mpi_t mult, unsigned long small_mult )
 
 
 void
-gcry_mpi_mul_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt)
+_gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt)
 {
     mpi_size_t usize, wsize, limb_cnt;
     mpi_ptr_t wp;
@@ -107,7 +107,7 @@ gcry_mpi_mul_2exp( gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt)
 
 
 void
-gcry_mpi_mul( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
+_gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
 {
     mpi_size_t usize, vsize, wsize;
     mpi_ptr_t up, vp, wp;
@@ -205,8 +205,8 @@ gcry_mpi_mul( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v)
 
 
 void
-gcry_mpi_mulm( gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
+_gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m)
 {
-    gcry_mpi_mul(w, u, v);
-    _gcry_mpi_fdiv_r( w, w, m );
+  mpi_mul (w, u, v);
+  _gcry_mpi_tdiv_r (w, w, m);
 }
index 33bbebe..0f0947f 100644 (file)
@@ -1,6 +1,7 @@
 /* mpi-pow.c  -  MPI functions for exponentiation
  * Copyright (C) 1994, 1996, 1998, 2000, 2002
  *               2003  Free Software Foundation, Inc.
+ *               2013  g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
 #include "longlong.h"
 
 
+/*
+ * When you need old implementation, please add compilation option
+ * -DUSE_ALGORITHM_SIMPLE_EXPONENTIATION
+ * or expose this line:
+#define USE_ALGORITHM_SIMPLE_EXPONENTIATION 1
+ */
+
+#if defined(USE_ALGORITHM_SIMPLE_EXPONENTIATION)
 /****************
  * RES = BASE ^ EXPO mod MOD
  */
 void
-gcry_mpi_powm (gcry_mpi_t res,
-               gcry_mpi_t base, gcry_mpi_t expo, gcry_mpi_t mod)
+_gcry_mpi_powm (gcry_mpi_t res,
+                gcry_mpi_t base, gcry_mpi_t expo, gcry_mpi_t mod)
 {
   /* Pointer to the limbs of the arguments, their size and signs. */
   mpi_ptr_t  rp, ep, mp, bp;
@@ -76,14 +85,19 @@ gcry_mpi_powm (gcry_mpi_t res,
   ep = expo->d;
 
   if (!msize)
-    msize = 1 / msize;     /* Provoke a signal.  */
+    _gcry_divide_by_zero();
 
   if (!esize)
     {
       /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0 depending
-        on if MOD equals 1.  */
-      rp[0] = 1;
+         on if MOD equals 1.  */
       res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1;
+      if (res->nlimbs)
+        {
+          RESIZE_IF_NEEDED (res, 1);
+          rp = res->d;
+          rp[0] = 1;
+        }
       res->sign = 0;
       goto leave;
     }
@@ -163,7 +177,7 @@ gcry_mpi_powm (gcry_mpi_t res,
     }
   MPN_COPY ( rp, bp, bsize );
   rsize = bsize;
-  rsign = bsign;
+  rsign = 0;
 
   /* Main processing.  */
   {
@@ -178,7 +192,7 @@ gcry_mpi_powm (gcry_mpi_t res,
     xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec );
 
     memset( &karactx, 0, sizeof karactx );
-    negative_result = (ep[0] & 1) && base->sign;
+    negative_result = (ep[0] & 1) && bsign;
 
     i = esize - 1;
     e = ep[i];
@@ -230,7 +244,13 @@ gcry_mpi_powm (gcry_mpi_t res,
             tp = rp; rp = xp; xp = tp;
             rsize = xsize;
 
-            if ( (mpi_limb_signed_t)e < 0 )
+            /* To mitigate the Yarom/Falkner flush+reload cache
+             * side-channel attack on the RSA secret exponent, we do
+             * the multiplication regardless of the value of the
+             * high-bit of E.  But to avoid this performance penalty
+             * we do it only if the exponent has been stored in secure
+             * memory and we can thus assume it is a secret exponent.  */
+            if (esec || (mpi_limb_signed_t)e < 0)
               {
                 /*mpih_mul( xp, rp, rsize, bp, bsize );*/
                 if( bsize < KARATSUBA_THRESHOLD )
@@ -245,7 +265,9 @@ gcry_mpi_powm (gcry_mpi_t res,
                     _gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize);
                     xsize = msize;
                   }
-
+              }
+            if ( (mpi_limb_signed_t)e < 0 )
+              {
                 tp = rp; rp = xp; xp = tp;
                 rsize = xsize;
               }
@@ -322,3 +344,449 @@ gcry_mpi_powm (gcry_mpi_t res,
   if (tspace)
     _gcry_mpi_free_limb_space( tspace, 0 );
 }
+#else
+/**
+ * Internal function to compute
+ *
+ *    X = R * S mod M
+ *
+ * and set the size of X at the pointer XSIZE_P.
+ * Use karatsuba structure at KARACTX_P.
+ *
+ * Condition:
+ *   RSIZE >= SSIZE
+ *   Enough space for X is allocated beforehand.
+ *
+ * For generic cases, we can/should use gcry_mpi_mulm.
+ * This function is use for specific internal case.
+ */
+static void
+mul_mod (mpi_ptr_t xp, mpi_size_t *xsize_p,
+         mpi_ptr_t rp, mpi_size_t rsize,
+         mpi_ptr_t sp, mpi_size_t ssize,
+         mpi_ptr_t mp, mpi_size_t msize,
+         struct karatsuba_ctx *karactx_p)
+{
+  if( ssize < KARATSUBA_THRESHOLD )
+    _gcry_mpih_mul ( xp, rp, rsize, sp, ssize );
+  else
+    _gcry_mpih_mul_karatsuba_case (xp, rp, rsize, sp, ssize, karactx_p);
+
+   if (rsize + ssize > msize)
+    {
+      _gcry_mpih_divrem (xp + msize, 0, xp, rsize + ssize, mp, msize);
+      *xsize_p = msize;
+    }
+   else
+     *xsize_p = rsize + ssize;
+}
+
+#define SIZE_B_2I3 ((1 << (5 - 1)) - 1)
+
+/****************
+ * RES = BASE ^ EXPO mod MOD
+ *
+ * To mitigate the Yarom/Falkner flush+reload cache side-channel
+ * attack on the RSA secret exponent, we don't use the square
+ * routine but multiplication.
+ *
+ * Reference:
+ *   Handbook of Applied Cryptography
+ *       Algorithm 14.83: Modified left-to-right k-ary exponentiation
+ */
+void
+_gcry_mpi_powm (gcry_mpi_t res,
+                gcry_mpi_t base, gcry_mpi_t expo, gcry_mpi_t mod)
+{
+  /* Pointer to the limbs of the arguments, their size and signs. */
+  mpi_ptr_t  rp, ep, mp, bp;
+  mpi_size_t esize, msize, bsize, rsize;
+  int               msign, bsign, rsign;
+  /* Flags telling the secure allocation status of the arguments.  */
+  int        esec,  msec,  bsec;
+  /* Size of the result including space for temporary values.  */
+  mpi_size_t size;
+  /* Helper.  */
+  int mod_shift_cnt;
+  int negative_result;
+  mpi_ptr_t mp_marker = NULL;
+  mpi_ptr_t bp_marker = NULL;
+  mpi_ptr_t ep_marker = NULL;
+  mpi_ptr_t xp_marker = NULL;
+  unsigned int mp_nlimbs = 0;
+  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_size_t W;
+  mpi_ptr_t base_u;
+  mpi_size_t base_u_size;
+
+  esize = expo->nlimbs;
+  msize = mod->nlimbs;
+  size = 2 * msize;
+  msign = mod->sign;
+
+  if (esize * BITS_PER_MPI_LIMB > 512)
+    W = 5;
+  else if (esize * BITS_PER_MPI_LIMB > 256)
+    W = 4;
+  else if (esize * BITS_PER_MPI_LIMB > 128)
+    W = 3;
+  else if (esize * BITS_PER_MPI_LIMB > 64)
+    W = 2;
+  else
+    W = 1;
+
+  esec = mpi_is_secure(expo);
+  msec = mpi_is_secure(mod);
+  bsec = mpi_is_secure(base);
+
+  rp = res->d;
+  ep = expo->d;
+
+  if (!msize)
+    _gcry_divide_by_zero();
+
+  if (!esize)
+    {
+      /* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0 depending
+         on if MOD equals 1.  */
+      res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1;
+      if (res->nlimbs)
+        {
+          RESIZE_IF_NEEDED (res, 1);
+          rp = res->d;
+          rp[0] = 1;
+        }
+      res->sign = 0;
+      goto leave;
+    }
+
+  /* Normalize MOD (i.e. make its most significant bit set) as
+     required by mpn_divrem.  This will make the intermediate values
+     in the calculation slightly larger, but the correct result is
+     obtained after a final reduction using the original MOD value. */
+  mp_nlimbs = msec? msize:0;
+  mp = mp_marker = mpi_alloc_limb_space(msize, msec);
+  count_leading_zeros (mod_shift_cnt, mod->d[msize-1]);
+  if (mod_shift_cnt)
+    _gcry_mpih_lshift (mp, mod->d, msize, mod_shift_cnt);
+  else
+    MPN_COPY( mp, mod->d, msize );
+
+  bsize = base->nlimbs;
+  bsign = base->sign;
+  if (bsize > msize)
+    {
+      /* The base is larger than the module.  Reduce it.
+
+         Allocate (BSIZE + 1) with space for remainder and quotient.
+         (The quotient is (bsize - msize + 1) limbs.)  */
+      bp_nlimbs = bsec ? (bsize + 1):0;
+      bp = bp_marker = mpi_alloc_limb_space( bsize + 1, bsec );
+      MPN_COPY ( bp, base->d, bsize );
+      /* We don't care about the quotient, store it above the
+       * remainder, at BP + MSIZE.  */
+      _gcry_mpih_divrem( bp + msize, 0, bp, bsize, mp, msize );
+      bsize = msize;
+      /* Canonicalize the base, since we are going to multiply with it
+         quite a few times.  */
+      MPN_NORMALIZE( bp, bsize );
+    }
+  else
+    bp = base->d;
+
+  if (!bsize)
+    {
+      res->nlimbs = 0;
+      res->sign = 0;
+      goto leave;
+    }
+
+
+  /* Make BASE, EXPO and MOD not overlap with RES.  */
+  if ( rp == bp )
+    {
+      /* RES and BASE are identical.  Allocate temp. space for BASE.  */
+      gcry_assert (!bp_marker);
+      bp_nlimbs = bsec? bsize:0;
+      bp = bp_marker = mpi_alloc_limb_space( bsize, bsec );
+      MPN_COPY(bp, rp, bsize);
+    }
+  if ( rp == ep )
+    {
+      /* RES and EXPO are identical.  Allocate temp. space for EXPO.  */
+      ep_nlimbs = esec? esize:0;
+      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)
+    {
+      mpi_resize (res, size);
+      rp = res->d;
+    }
+
+  /* Main processing.  */
+  {
+    mpi_size_t i, j;
+    mpi_ptr_t xp;
+    mpi_size_t xsize;
+    int c;
+    mpi_limb_t e;
+    mpi_limb_t carry_limb;
+    struct karatsuba_ctx karactx;
+    mpi_ptr_t tp;
+
+    xp_nlimbs = msec? (2 * (msize + 1)):0;
+    xp = xp_marker = mpi_alloc_limb_space( 2 * (msize + 1), msec );
+
+    memset( &karactx, 0, sizeof karactx );
+    negative_result = (ep[0] & 1) && bsign;
+
+    /* Precompute B_2I3[], BASE^(2 * i + 3), BASE^3, ^5, ^7, ... */
+    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];
+          }
+
+        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);
+      }
+
+    i = esize - 1;
+
+    /* Main loop.
+
+       Make the result be pointed to alternately by XP and RP.  This
+       helps us avoid block copying, which would otherwise be
+       necessary with the overlap restrictions of
+       _gcry_mpih_divmod. With 50% probability the result after this
+       loop will be in the area originally pointed by RP (==RES->d),
+       and with 50% probability in the area originally pointed to by XP. */
+    rsign = 0;
+    if (W == 1)
+      {
+        rsize = bsize;
+      }
+    else
+      {
+        rsize = msize;
+        MPN_ZERO (rp, rsize);
+      }
+    MPN_COPY ( rp, bp, bsize );
+
+    e = ep[i];
+    count_leading_zeros (c, e);
+    e = (e << c) << 1;
+    c = BITS_PER_MPI_LIMB - 1 - c;
+
+    j = 0;
+
+    for (;;)
+      if (e == 0)
+        {
+          j += c;
+          i--;
+          if ( i < 0 )
+            {
+              c = 0;
+              break;
+            }
+
+          e = ep[i];
+          c = BITS_PER_MPI_LIMB;
+        }
+      else
+        {
+          int c0;
+          mpi_limb_t e0;
+
+          count_leading_zeros (c0, e);
+          e = (e << c0);
+          c -= c0;
+          j += c0;
+
+          if (c >= W)
+            {
+              e0 = (e >> (BITS_PER_MPI_LIMB - W));
+              e = (e << W);
+              c -= W;
+            }
+          else
+            {
+              i--;
+              if ( i < 0 )
+                {
+                  e = (e >> (BITS_PER_MPI_LIMB - c));
+                  break;
+                }
+
+              c0 = c;
+              e0 = (e >> (BITS_PER_MPI_LIMB - W))
+                | (ep[i] >> (BITS_PER_MPI_LIMB - W + c0));
+              e = (ep[i] << (W - c0));
+              c = BITS_PER_MPI_LIMB - W + c0;
+            }
+
+          count_trailing_zeros (c0, e0);
+          e0 = (e0 >> c0) >> 1;
+
+          for (j += W - c0; j; j--)
+            {
+              mul_mod (xp, &xsize, rp, rsize, rp, rsize, mp, msize, &karactx);
+              tp = rp; rp = xp; xp = tp;
+              rsize = xsize;
+            }
+
+          if (e0 == 0)
+            {
+              base_u = bp;
+              base_u_size = bsize;
+            }
+          else
+            {
+              base_u = b_2i3[e0 - 1];
+              base_u_size = b_2i3size[e0 -1];
+            }
+
+          mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size,
+                   mp, msize, &karactx);
+          tp = rp; rp = xp; xp = tp;
+          rsize = xsize;
+
+          j = c0;
+        }
+
+    if (c != 0)
+      {
+        j += c;
+        count_trailing_zeros (c, e);
+        e = (e >> c);
+        j -= c;
+      }
+
+    while (j--)
+      {
+        mul_mod (xp, &xsize, rp, rsize, rp, rsize, mp, msize, &karactx);
+        tp = rp; rp = xp; xp = tp;
+        rsize = xsize;
+      }
+
+    if (e != 0)
+      {
+        if ((e>>1) == 0)
+          {
+            base_u = bp;
+            base_u_size = bsize;
+          }
+        else
+          {
+            base_u = b_2i3[(e>>1) - 1];
+            base_u_size = b_2i3size[(e>>1) -1];
+          }
+
+        mul_mod (xp, &xsize, rp, rsize, base_u, base_u_size,
+                 mp, msize, &karactx);
+        tp = rp; rp = xp; xp = tp;
+        rsize = xsize;
+
+        for (; c; c--)
+          {
+            mul_mod (xp, &xsize, rp, rsize, rp, rsize, mp, msize, &karactx);
+            tp = rp; rp = xp; xp = tp;
+            rsize = xsize;
+          }
+      }
+
+    /* We shifted MOD, the modulo reduction argument, left
+       MOD_SHIFT_CNT steps.  Adjust the result by reducing it with the
+       original MOD.
+
+       Also make sure the result is put in RES->d (where it already
+       might be, see above).  */
+    if ( mod_shift_cnt )
+      {
+        carry_limb = _gcry_mpih_lshift( res->d, rp, rsize, mod_shift_cnt);
+        rp = res->d;
+        if ( carry_limb )
+          {
+            rp[rsize] = carry_limb;
+            rsize++;
+          }
+      }
+    else if (res->d != rp)
+      {
+        MPN_COPY (res->d, rp, rsize);
+        rp = res->d;
+      }
+
+    if ( rsize >= msize )
+      {
+        _gcry_mpih_divrem(rp + msize, 0, rp, rsize, mp, msize);
+        rsize = msize;
+      }
+
+    /* Remove any leading zero words from the result.  */
+    if ( mod_shift_cnt )
+      _gcry_mpih_rshift( rp, rp, rsize, mod_shift_cnt);
+    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 );
+  }
+
+  /* Fixup for negative results.  */
+  if ( negative_result && rsize )
+    {
+      if ( mod_shift_cnt )
+        _gcry_mpih_rshift( mp, mp, msize, mod_shift_cnt);
+      _gcry_mpih_sub( rp, mp, msize, rp, rsize);
+      rsize = msize;
+      rsign = msign;
+      MPN_NORMALIZE(rp, rsize);
+    }
+  gcry_assert (res->d == rp);
+  res->nlimbs = rsize;
+  res->sign = rsign;
+
+ leave:
+  if (mp_marker)
+    _gcry_mpi_free_limb_space( mp_marker, mp_nlimbs );
+  if (bp_marker)
+    _gcry_mpi_free_limb_space( bp_marker, bp_nlimbs );
+  if (ep_marker)
+    _gcry_mpi_free_limb_space( ep_marker, ep_nlimbs );
+  if (xp_marker)
+    _gcry_mpi_free_limb_space( xp_marker, xp_nlimbs );
+}
+#endif
index 2473cd9..e27f7fa 100644 (file)
  *
  * FIXME: This code is VERY ugly!
  */
-int
-_gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx )
-{
-    int i, j;
-    unsigned n;
-    mpi_ptr_t ap;
-    mpi_limb_t limb;
+/* int */
+/* _gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx ) */
+/* { */
+/*     int i, j; */
+/*     unsigned n; */
+/*     mpi_ptr_t ap; */
+/*     mpi_limb_t limb; */
 
-    ap = a->d;
-    for(n=0,i=0; i < a->nlimbs; i++ ) {
-       limb = ap[i];
-       for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ )
-           if( n == idx )
-               return (limb >> j*8) & 0xff;
-    }
-    return -1;
-}
+/*     ap = a->d; */
+/*     for(n=0,i=0; i < a->nlimbs; i++ ) { */
+/*     limb = ap[i]; */
+/*     for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ ) */
+/*         if( n == idx ) */
+/*             return (limb >> j*8) & 0xff; */
+/*     } */
+/*     return -1; */
+/* } */
 
 
 /****************
  * Put a value at position IDX into A. idx counts from lsb to msb
  */
-void
-_gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int xc )
-{
-    int i, j;
-    unsigned n;
-    mpi_ptr_t ap;
-    mpi_limb_t limb, c;
+/* void */
+/* _gcry_mpi_putbyte( gcry_mpi_t a, unsigned idx, int xc ) */
+/* { */
+/*     int i, j; */
+/*     unsigned n; */
+/*     mpi_ptr_t ap; */
+/*     mpi_limb_t limb, c; */
 
-    c = xc & 0xff;
-    ap = a->d;
-    for(n=0,i=0; i < a->alloced; i++ ) {
-       limb = ap[i];
-       for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ )
-           if( n == idx ) {
-             #if BYTES_PER_MPI_LIMB == 4
-               if( j == 0 )
-                   limb = (limb & 0xffffff00) | c;
-               else if( j == 1 )
-                   limb = (limb & 0xffff00ff) | (c<<8);
-               else if( j == 2 )
-                   limb = (limb & 0xff00ffff) | (c<<16);
-               else
-                   limb = (limb & 0x00ffffff) | (c<<24);
-             #elif BYTES_PER_MPI_LIMB == 8
-               if( j == 0 )
-                   limb = (limb & 0xffffffffffffff00) | c;
-               else if( j == 1 )
-                   limb = (limb & 0xffffffffffff00ff) | (c<<8);
-               else if( j == 2 )
-                   limb = (limb & 0xffffffffff00ffff) | (c<<16);
-               else if( j == 3 )
-                   limb = (limb & 0xffffffff00ffffff) | (c<<24);
-               else if( j == 4 )
-                   limb = (limb & 0xffffff00ffffffff) | (c<<32);
-               else if( j == 5 )
-                   limb = (limb & 0xffff00ffffffffff) | (c<<40);
-               else if( j == 6 )
-                   limb = (limb & 0xff00ffffffffffff) | (c<<48);
-               else
-                   limb = (limb & 0x00ffffffffffffff) | (c<<56);
-             #else
-                #error please enhance this function, its ugly - i know.
-             #endif
-               if( a->nlimbs <= i )
-                   a->nlimbs = i+1;
-               ap[i] = limb;
-               return;
-           }
-    }
-    abort(); /* index out of range */
-}
+/*     c = xc & 0xff; */
+/*     ap = a->d; */
+/*     for(n=0,i=0; i < a->alloced; i++ ) { */
+/*     limb = ap[i]; */
+/*     for( j=0; j < BYTES_PER_MPI_LIMB; j++, n++ ) */
+/*         if( n == idx ) { */
+/*           #if BYTES_PER_MPI_LIMB == 4 */
+/*             if( j == 0 ) */
+/*                 limb = (limb & 0xffffff00) | c; */
+/*             else if( j == 1 ) */
+/*                 limb = (limb & 0xffff00ff) | (c<<8); */
+/*             else if( j == 2 ) */
+/*                 limb = (limb & 0xff00ffff) | (c<<16); */
+/*             else */
+/*                 limb = (limb & 0x00ffffff) | (c<<24); */
+/*           #elif BYTES_PER_MPI_LIMB == 8 */
+/*             if( j == 0 ) */
+/*                 limb = (limb & 0xffffffffffffff00) | c; */
+/*             else if( j == 1 ) */
+/*                 limb = (limb & 0xffffffffffff00ff) | (c<<8); */
+/*             else if( j == 2 ) */
+/*                 limb = (limb & 0xffffffffff00ffff) | (c<<16); */
+/*             else if( j == 3 ) */
+/*                 limb = (limb & 0xffffffff00ffffff) | (c<<24); */
+/*             else if( j == 4 ) */
+/*                 limb = (limb & 0xffffff00ffffffff) | (c<<32); */
+/*             else if( j == 5 ) */
+/*                 limb = (limb & 0xffff00ffffffffff) | (c<<40); */
+/*             else if( j == 6 ) */
+/*                 limb = (limb & 0xff00ffffffffffff) | (c<<48); */
+/*             else */
+/*                 limb = (limb & 0x00ffffffffffffff) | (c<<56); */
+/*           #else */
+/*              #error please enhance this function, its ugly - i know. */
+/*           #endif */
+/*             if( a->nlimbs <= i ) */
+/*                 a->nlimbs = i+1; */
+/*             ap[i] = limb; */
+/*             return; */
+/*         } */
+/*     } */
+/*     abort(); /\* index out of range *\/ */
+/* } */
 
 
 /****************
index f499796..58a4240 100644 (file)
@@ -1,6 +1,7 @@
 /* mpicoder.c  -  Coder for the external representation of MPIs
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
  *               2008 Free Software Foundation, Inc.
+ * Copyright (C) 2013 g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
@@ -175,63 +176,21 @@ mpi_fromstr (gcry_mpi_t val, const char *str)
 }
 
 
-/* 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)
-{
-  int i;
-
-  log_printf (" ");
-  if (!a)
-    log_printf ("[MPI_NULL]");
-  else
-    {
-      if (a->sign)
-        log_printf ( "-");
-#if BYTES_PER_MPI_LIMB == 2
-# define X "4"
-#elif BYTES_PER_MPI_LIMB == 4
-# define X "8"
-#elif BYTES_PER_MPI_LIMB == 8
-# define X "16"
-#elif BYTES_PER_MPI_LIMB == 16
-# define X "32"
-#else
-# error please define the format here
-#endif
-      for (i=a->nlimbs; i > 0 ; i-- )
-        {
-          log_printf (i != a->nlimbs? "%0" X "lX":"%lX", (ulong)a->d[i-1]);
-        }
-#undef X
-      if (!a->nlimbs)
-        log_printf ("0");
-    }
-}
-
-/* Convience function used internally. */
-void
-_gcry_log_mpidump (const char *text, gcry_mpi_t a)
-{
-  log_printf ("%s:", text);
-  gcry_mpi_dump (a);
-  log_printf ("\n");
-}
-
-
 /* Return an allocated buffer with the MPI (msb first).  NBYTES
-   receives the length of this buffer.  Caller must free the return
-   string.  This function returns an allocated buffer with NBYTES set
-   to zero if the value of A is zero.  If sign is not NULL, it will be
-   set to the sign of the A.  On error NULL is returned and ERRNO set
-   appropriately.  */
+   receives the length of this buffer.  If FILL_LE is not 0, the
+   returned value is stored as little endian and right padded with
+   zeroes so that the returned buffer has at least FILL_LE bytes.
+
+   Caller must free the return string.  This function returns an
+   allocated buffer with NBYTES set to zero if the value of A is zero.
+   If sign is not NULL, it will be set to the sign of the A.  On error
+   NULL is returned and ERRNO set appropriately.  */
 static unsigned char *
-do_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign, int force_secure)
+do_get_buffer (gcry_mpi_t a, unsigned int fill_le,
+               unsigned int *nbytes, int *sign, int force_secure)
 {
   unsigned char *p, *buffer;
+  unsigned int length, tmp;
   mpi_limb_t alimb;
   int i;
   size_t n;
@@ -241,8 +200,10 @@ do_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign, int force_secure)
 
   *nbytes = a->nlimbs * BYTES_PER_MPI_LIMB;
   n = *nbytes? *nbytes:1; /* Allocate at least one byte.  */
-  p = buffer = (force_secure || mpi_is_secure(a))? gcry_malloc_secure (n)
-                                                : gcry_malloc (n);
+  if (n < fill_le)
+    n = fill_le;
+  p = buffer = (force_secure || mpi_is_secure(a))? xtrymalloc_secure (n)
+                                                : xtrymalloc (n);
   if (!buffer)
     return NULL;
 
@@ -268,9 +229,27 @@ do_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign, int force_secure)
 #endif
     }
 
+  if (fill_le)
+    {
+      length = *nbytes;
+      /* Reverse buffer and pad with zeroes.  */
+      for (i=0; i < length/2; i++)
+        {
+          tmp = buffer[i];
+          buffer[i] = buffer[length-1-i];
+          buffer[length-1-i] = tmp;
+        }
+      /* Pad with zeroes.  */
+      for (p = buffer + length; length < fill_le; length++)
+        *p++ = 0;
+      *nbytes = length;
+
+      return buffer;
+    }
+
   /* This is sub-optimal but we need to do the shift operation because
      the caller has to free the returned buffer.  */
-  for (p=buffer; !*p && *nbytes; p++, --*nbytes)
+  for (p=buffer; *nbytes && !*p; p++, --*nbytes)
     ;
   if (p != buffer)
     memmove (buffer,p, *nbytes);
@@ -279,15 +258,17 @@ do_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign, int force_secure)
 
 
 byte *
-_gcry_mpi_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign)
+_gcry_mpi_get_buffer (gcry_mpi_t a, unsigned int fill_le,
+                      unsigned int *r_nbytes, int *sign)
 {
-  return do_get_buffer (a, nbytes, sign, 0);
+  return do_get_buffer (a, fill_le, r_nbytes, sign, 0);
 }
 
 byte *
-_gcry_mpi_get_secure_buffer (gcry_mpi_t a, unsigned *nbytes, int *sign)
+_gcry_mpi_get_secure_buffer (gcry_mpi_t a, unsigned int fill_le,
+                             unsigned int *r_nbytes, int *sign)
 {
-  return do_get_buffer (a, nbytes, sign, 1);
+  return do_get_buffer (a, fill_le, r_nbytes, sign, 1);
 }
 
 
@@ -305,6 +286,12 @@ _gcry_mpi_set_buffer (gcry_mpi_t a, const void *buffer_arg,
   int nlimbs;
   int i;
 
+  if (mpi_is_immutable (a))
+    {
+      mpi_immutable_failed ();
+      return;
+    }
+
   nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
   RESIZE_IF_NEEDED(a, nlimbs);
   a->sign = sign;
@@ -366,18 +353,77 @@ _gcry_mpi_set_buffer (gcry_mpi_t a, const void *buffer_arg,
 }
 
 
+static void
+onecompl (gcry_mpi_t a)
+{
+  mpi_ptr_t ap;
+  mpi_size_t n;
+  unsigned int i;
+  unsigned int nbits = mpi_get_nbits (a);
+
+  if (mpi_is_immutable (a))
+    {
+      mpi_immutable_failed ();
+      return;
+    }
+
+  mpi_normalize (a);
+  ap = a->d;
+  n = a->nlimbs;
+
+  for( i = 0; i < n; i++ )
+    ap[i] ^= (mpi_limb_t)(-1);
+
+  a->sign = 0;
+  mpi_clear_highbit (a, nbits-1);
+}
+
+
+/* Perform a two's complement operation on buffer P of size N bytes.  */
+static void
+twocompl (unsigned char *p, unsigned int n)
+{
+  int i;
+
+  for (i=n-1; i >= 0 && !p[i]; i--)
+    ;
+  if (i >= 0)
+    {
+      if ((p[i] & 0x01))
+        p[i] = (((p[i] ^ 0xfe) | 0x01) & 0xff);
+      else if ((p[i] & 0x02))
+        p[i] = (((p[i] ^ 0xfc) | 0x02) & 0xfe);
+      else if ((p[i] & 0x04))
+        p[i] = (((p[i] ^ 0xf8) | 0x04) & 0xfc);
+      else if ((p[i] & 0x08))
+        p[i] = (((p[i] ^ 0xf0) | 0x08) & 0xf8);
+      else if ((p[i] & 0x10))
+        p[i] = (((p[i] ^ 0xe0) | 0x10) & 0xf0);
+      else if ((p[i] & 0x20))
+        p[i] = (((p[i] ^ 0xc0) | 0x20) & 0xe0);
+      else if ((p[i] & 0x40))
+        p[i] = (((p[i] ^ 0x80) | 0x40) & 0xc0);
+      else
+        p[i] = 0x80;
+
+      for (i--; i >= 0; i--)
+        p[i] ^= 0xff;
+    }
+}
+
+
 /* 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.  */
-gcry_error_t
-gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
-               const void *buffer_arg, size_t buflen, size_t *nscanned)
+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)
 {
   const unsigned char *buffer = (const unsigned char*)buffer_arg;
   struct gcry_mpi *a = NULL;
   unsigned int len;
-  int secure = (buffer && gcry_is_secure (buffer));
+  int secure = (buffer && _gcry_is_secure (buffer));
 
   if (format == GCRYMPI_FMT_SSH)
     len = 0;
@@ -393,15 +439,14 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
                 : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
       if (len)
         {
+          _gcry_mpi_set_buffer (a, s, len, 0);
           a->sign = !!(*s & 0x80);
           if (a->sign)
             {
-              /* FIXME: we have to convert from 2compl to magnitude format */
-              mpi_free (a);
-              return gcry_error (GPG_ERR_INTERNAL);
+              onecompl (a);
+              mpi_add_ui (a, a, 1);
+              a->sign = 1;
            }
-          else
-            _gcry_mpi_set_buffer (a, s, len, 0);
        }
       if (ret_mpi)
         {
@@ -410,6 +455,8 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
        }
       else
         mpi_free(a);
+      if (nscanned)
+        *nscanned = len;
       return 0;
     }
   else if (format == GCRYMPI_FMT_USG)
@@ -427,6 +474,8 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
        }
       else
         mpi_free(a);
+      if (nscanned)
+        *nscanned = len;
       return 0;
     }
   else if (format == GCRYMPI_FMT_PGP)
@@ -444,7 +493,7 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
           mpi_free(a);
           a = NULL;
         }
-      return a? 0 : gcry_error (GPG_ERR_INV_OBJ);
+      return a? 0 : GPG_ERR_INV_OBJ;
     }
   else if (format == GCRYMPI_FMT_SSH)
     {
@@ -456,29 +505,28 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
          allow the BUFLEN argument to act as a sanitiy check.  Same
          below. */
       if (len && len < 4)
-        return gcry_error (GPG_ERR_TOO_SHORT);
+        return GPG_ERR_TOO_SHORT;
 
       n = (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
       s += 4;
       if (len)
         len -= 4;
       if (len && n > len)
-        return gcry_error (GPG_ERR_TOO_LARGE);
+        return GPG_ERR_TOO_LARGE;
 
       a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1)
                                     /BYTES_PER_MPI_LIMB)
                 : mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
       if (n)
         {
+          _gcry_mpi_set_buffer( a, s, n, 0 );
           a->sign = !!(*s & 0x80);
           if (a->sign)
             {
-              /* FIXME: we have to convert from 2compl to magnitude format */
-              mpi_free(a);
-              return gcry_error (GPG_ERR_INTERNAL);
+              onecompl (a);
+              mpi_add_ui (a, a, 1);
+              a->sign = 1;
            }
-          else
-            _gcry_mpi_set_buffer( a, s, n, 0 );
        }
       if (nscanned)
         *nscanned = n+4;
@@ -495,13 +543,13 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
     {
       /* We can only handle C strings for now.  */
       if (buflen)
-        return gcry_error (GPG_ERR_INV_ARG);
+        return GPG_ERR_INV_ARG;
 
       a = secure? mpi_alloc_secure (0) : mpi_alloc(0);
       if (mpi_fromstr (a, (const char *)buffer))
         {
           mpi_free (a);
-          return gcry_error (GPG_ERR_INV_OBJ);
+          return GPG_ERR_INV_OBJ;
         }
       if (ret_mpi)
         {
@@ -510,10 +558,12 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
        }
       else
         mpi_free(a);
+      if (nscanned)
+        *nscanned = strlen ((const char*)buffer);
       return 0;
     }
   else
-    return gcry_error (GPG_ERR_INV_ARG);
+    return GPG_ERR_INV_ARG;
 }
 
 
@@ -523,18 +573,29 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
    receives the actual length of the external representation unless it
    has been passed as NULL.  BUFFER may be NULL to query the required
    length.  */
-gcry_error_t
-gcry_mpi_print (enum gcry_mpi_format format,
-                unsigned char *buffer, size_t buflen,
-                size_t *nwritten, struct gcry_mpi *a)
+gcry_err_code_t
+_gcry_mpi_print (enum gcry_mpi_format format,
+                 unsigned char *buffer, size_t buflen,
+                 size_t *nwritten, struct gcry_mpi *a)
 {
   unsigned int nbits = mpi_get_nbits (a);
   size_t len;
   size_t dummy_nwritten;
+  int negative;
 
   if (!nwritten)
     nwritten = &dummy_nwritten;
 
+  /* Libgcrypt does no always care to set clear the sign if the value
+     is 0.  For printing this is a bit of a surprise, in particular
+     because if some of the formats don't support negative numbers but
+     should be able to print a zero.  Thus we need this extra test
+     for a negative number.  */
+  if (a->sign && _gcry_mpi_cmp_ui (a, 0))
+    negative = 1;
+  else
+    negative = 0;
+
   len = buflen;
   *nwritten = 0;
   if (format == GCRYMPI_FMT_STD)
@@ -543,33 +604,46 @@ gcry_mpi_print (enum gcry_mpi_format format,
       int extra = 0;
       unsigned int n;
 
-      if (a->sign)
-        return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */
-
-      tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+      tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
       if (!tmp)
-        return gpg_error_from_syserror ();
-      if (n && (*tmp & 0x80))
+        return gpg_err_code_from_syserror ();
+
+      if (negative)
+        {
+          twocompl (tmp, n);
+          if (!(*tmp & 0x80))
+            {
+              /* Need to extend the sign.  */
+              n++;
+              extra = 2;
+            }
+        }
+      else if (n && (*tmp & 0x80))
         {
+          /* Positive but the high bit of the returned buffer is set.
+             Thus we need to print an extra leading 0x00 so that the
+             output is interpreted as a positive number.  */
           n++;
-          extra=1;
+          extra = 1;
        }
 
       if (buffer && n > len)
         {
           /* The provided buffer is too short. */
-          gcry_free (tmp);
-          return gcry_error (GPG_ERR_TOO_SHORT);
+          xfree (tmp);
+          return GPG_ERR_TOO_SHORT;
        }
       if (buffer)
         {
           unsigned char *s = buffer;
 
-          if (extra)
+          if (extra == 1)
             *s++ = 0;
-          memcpy (s, tmp, n-extra);
+          else if (extra)
+            *s++ = 0xff;
+          memcpy (s, tmp, n-!!extra);
        }
-      gcry_free(tmp);
+      xfree (tmp);
       *nwritten = n;
       return 0;
     }
@@ -580,17 +654,18 @@ gcry_mpi_print (enum gcry_mpi_format format,
       /* Note:  We ignore the sign for this format.  */
       /* FIXME: for performance reasons we should put this into
         mpi_aprint because we can then use the buffer directly.  */
+
       if (buffer && n > len)
-        return gcry_error (GPG_ERR_TOO_SHORT);
+        return GPG_ERR_TOO_SHORT;
       if (buffer)
         {
           unsigned char *tmp;
 
-          tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+          tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
           if (!tmp)
-            return gpg_error_from_syserror ();
+            return gpg_err_code_from_syserror ();
           memcpy (buffer, tmp, n);
-          gcry_free (tmp);
+          xfree (tmp);
        }
       *nwritten = n;
       return 0;
@@ -600,11 +675,11 @@ gcry_mpi_print (enum gcry_mpi_format format,
       unsigned int n = (nbits + 7)/8;
 
       /* The PGP format can only handle unsigned integers.  */
-      if( a->sign )
-        return gcry_error (GPG_ERR_INV_ARG);
+      if (negative)
+        return GPG_ERR_INV_ARG;
 
       if (buffer && n+2 > len)
-        return gcry_error (GPG_ERR_TOO_SHORT);
+        return GPG_ERR_TOO_SHORT;
 
       if (buffer)
         {
@@ -614,11 +689,11 @@ gcry_mpi_print (enum gcry_mpi_format format,
           s[0] = nbits >> 8;
           s[1] = nbits;
 
-          tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+          tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
           if (!tmp)
-            return gpg_error_from_syserror ();
+            return gpg_err_code_from_syserror ();
           memcpy (s+2, tmp, n);
-          gcry_free (tmp);
+          xfree (tmp);
        }
       *nwritten = n+2;
       return 0;
@@ -629,13 +704,21 @@ gcry_mpi_print (enum gcry_mpi_format format,
       int extra = 0;
       unsigned int n;
 
-      if (a->sign)
-        return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet.  */
-
-      tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+      tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
       if (!tmp)
-        return gpg_error_from_syserror ();
-      if (n && (*tmp & 0x80))
+        return gpg_err_code_from_syserror ();
+
+      if (negative)
+        {
+          twocompl (tmp, n);
+          if (!(*tmp & 0x80))
+            {
+              /* Need to extend the sign.  */
+              n++;
+              extra = 2;
+            }
+        }
+      else if (n && (*tmp & 0x80))
         {
           n++;
           extra=1;
@@ -643,8 +726,8 @@ gcry_mpi_print (enum gcry_mpi_format format,
 
       if (buffer && n+4 > len)
         {
-          gcry_free(tmp);
-          return gcry_error (GPG_ERR_TOO_SHORT);
+          xfree(tmp);
+          return GPG_ERR_TOO_SHORT;
        }
 
       if (buffer)
@@ -655,12 +738,13 @@ gcry_mpi_print (enum gcry_mpi_format format,
           *s++ = n >> 16;
           *s++ = n >> 8;
           *s++ = n;
-          if (extra)
+          if (extra == 1)
             *s++ = 0;
-
-          memcpy (s, tmp, n-extra);
+          else if (extra)
+            *s++ = 0xff;
+          memcpy (s, tmp, n-!!extra);
        }
-      gcry_free (tmp);
+      xfree (tmp);
       *nwritten = 4+n;
       return 0;
     }
@@ -671,22 +755,22 @@ gcry_mpi_print (enum gcry_mpi_format format,
       int extra = 0;
       unsigned int n = 0;
 
-      tmp = _gcry_mpi_get_buffer (a, &n, NULL);
+      tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
       if (!tmp)
-        return gpg_error_from_syserror ();
+        return gpg_err_code_from_syserror ();
       if (!n || (*tmp & 0x80))
         extra = 2;
 
-      if (buffer && 2*n + extra + !!a->sign + 1 > len)
+      if (buffer && 2*n + extra + negative + 1 > len)
         {
-          gcry_free(tmp);
-          return gcry_error (GPG_ERR_TOO_SHORT);
+          xfree(tmp);
+          return GPG_ERR_TOO_SHORT;
        }
       if (buffer)
         {
           unsigned char *s = buffer;
 
-          if (a->sign)
+          if (negative)
             *s++ = '-';
           if (extra)
             {
@@ -707,13 +791,13 @@ gcry_mpi_print (enum gcry_mpi_format format,
        }
       else
         {
-          *nwritten = 2*n + extra + !!a->sign + 1;
+          *nwritten = 2*n + extra + negative + 1;
        }
-      gcry_free (tmp);
+      xfree (tmp);
       return 0;
     }
   else
-    return gcry_error (GPG_ERR_INV_ARG);
+    return GPG_ERR_INV_ARG;
 }
 
 
@@ -722,29 +806,89 @@ gcry_mpi_print (enum gcry_mpi_format format,
  * The caller has to supply the address of a pointer.  NWRITTEN may be
  * NULL.
  */
-gcry_error_t
-gcry_mpi_aprint (enum gcry_mpi_format format,
-                 unsigned char **buffer, size_t *nwritten,
-                struct gcry_mpi *a)
+gcry_err_code_t
+_gcry_mpi_aprint (enum gcry_mpi_format format,
+                  unsigned char **buffer, size_t *nwritten,
+                  struct gcry_mpi *a)
 {
   size_t n;
-  gcry_error_t rc;
+  gcry_err_code_t rc;
 
   *buffer = NULL;
-  rc = gcry_mpi_print (format, NULL, 0, &n, a);
+  rc = _gcry_mpi_print (format, NULL, 0, &n, a);
   if (rc)
     return rc;
 
-  *buffer = mpi_is_secure(a) ? gcry_malloc_secure (n) : gcry_malloc (n);
+  *buffer = mpi_is_secure(a) ? xtrymalloc_secure (n?n:1) : xtrymalloc (n?n:1);
   if (!*buffer)
-    return gpg_error_from_syserror ();
-  rc = gcry_mpi_print( format, *buffer, n, &n, a );
+    return gpg_err_code_from_syserror ();
+  /* If the returned buffer will have a length of 0, we nevertheless
+     allocated 1 byte (malloc needs it anyway) and store a 0.  */
+  if (!n)
+    **buffer = 0;
+  rc = _gcry_mpi_print( format, *buffer, n, &n, a );
   if (rc)
     {
-      gcry_free(*buffer);
+      xfree (*buffer);
       *buffer = NULL;
     }
   else if (nwritten)
     *nwritten = n;
   return rc;
 }
+
+
+/* Turn VALUE into an octet string and store it in an allocated buffer
+   at R_FRAME or - if R_RAME is NULL - copy it into the caller
+   provided buffer SPACE; either SPACE or R_FRAME may be used.  If
+   SPACE if not NULL, the caller must provide a buffer of at least
+   NBYTES.  If the resulting octet string is shorter than NBYTES pad
+   it to the left with zeroes.  If VALUE does not fit into NBYTES
+   return an error code.  */
+gpg_err_code_t
+_gcry_mpi_to_octet_string (unsigned char **r_frame, void *space,
+                           gcry_mpi_t value, size_t nbytes)
+{
+  gpg_err_code_t rc;
+  size_t nframe, noff, n;
+  unsigned char *frame;
+
+  if (!r_frame == !space)
+    return GPG_ERR_INV_ARG;  /* Only one may be used.  */
+
+  if (r_frame)
+    *r_frame = NULL;
+
+  rc = _gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &nframe, value);
+  if (rc)
+    return rc;
+  if (nframe > nbytes)
+    return GPG_ERR_TOO_LARGE; /* Value too long to fit into NBYTES.  */
+
+  noff = (nframe < nbytes)? nbytes - nframe : 0;
+  n = nframe + noff;
+  if (space)
+    frame = space;
+  else
+    {
+      frame = mpi_is_secure (value)? xtrymalloc_secure (n) : xtrymalloc (n);
+      if (!frame)
+        {
+          rc = gpg_err_code_from_syserror ();
+          return rc;
+        }
+    }
+  if (noff)
+    memset (frame, 0, noff);
+  nframe += noff;
+  rc = _gcry_mpi_print (GCRYMPI_FMT_USG, frame+noff, nframe-noff, NULL, value);
+  if (rc)
+    {
+      xfree (frame);
+      return rc;
+    }
+
+  if (r_frame)
+    *r_frame = frame;
+  return 0;
+}
index 224b810..57c1b58 100644 (file)
@@ -48,7 +48,7 @@ _gcry_mpih_mod_1(mpi_ptr_t dividend_ptr, mpi_size_t dividend_size,
 {
     mpi_size_t i;
     mpi_limb_t n1, n0, r;
-    int dummy;
+    mpi_limb_t dummy GCC_ATTR_UNUSED;
 
     /* Botch: Should this be handled at all?  Rely on callers? */
     if( !dividend_size )
@@ -212,9 +212,8 @@ _gcry_mpih_divrem( mpi_ptr_t qp, mpi_size_t qextra_limbs,
 
     switch(dsize) {
       case 0:
-       /* We are asked to divide by zero, so go ahead and do it!  (To make
-          the compiler not remove this statement, return the value.)  */
-       return 1 / dsize;
+       _gcry_divide_by_zero();
+       break;
 
       case 1:
        {
@@ -397,7 +396,7 @@ _gcry_mpih_divmod_1( mpi_ptr_t quot_ptr,
 {
     mpi_size_t i;
     mpi_limb_t n1, n0, r;
-    int dummy;
+    mpi_limb_t dummy GCC_ATTR_UNUSED;
 
     if( !dividend_size )
        return 0;
index b8e0561..8b6f06a 100644 (file)
@@ -353,7 +353,7 @@ _gcry_mpih_mul_n( mpi_ptr_t prodp,
            _gcry_mpih_sqr_n_basecase( prodp, up, size );
        else {
            mpi_ptr_t tspace;
-           secure = gcry_is_secure( up );
+           secure = _gcry_is_secure( up );
            tspace = mpi_alloc_limb_space( 2 * size, secure );
            _gcry_mpih_sqr_n( prodp, up, size, tspace );
            _gcry_mpi_free_limb_space (tspace, 2 * size );
@@ -364,7 +364,7 @@ _gcry_mpih_mul_n( mpi_ptr_t prodp,
            mul_n_basecase( prodp, up, vp, size );
        else {
            mpi_ptr_t tspace;
-           secure = gcry_is_secure( up ) || gcry_is_secure( vp );
+           secure = _gcry_is_secure( up ) || _gcry_is_secure( vp );
            tspace = mpi_alloc_limb_space( 2 * size, secure );
            mul_n (prodp, up, vp, size, tspace);
            _gcry_mpi_free_limb_space (tspace, 2 * size );
@@ -386,9 +386,9 @@ _gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp,
        if( ctx->tspace )
            _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs );
         ctx->tspace_nlimbs = 2 * vsize;
-       ctx->tspace = mpi_alloc_limb_space2 * vsize,
-                                           (gcry_is_secure( up )
-                                            || gcry_is_secure( vp )) );
+       ctx->tspace = mpi_alloc_limb_space (2 * vsize,
+                                           (_gcry_is_secure (up)
+                                             || _gcry_is_secure (vp)));
        ctx->tspace_size = vsize;
     }
 
@@ -402,8 +402,9 @@ _gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp,
            if( ctx->tp )
                _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs );
             ctx->tp_nlimbs = 2 * vsize;
-           ctx->tp = mpi_alloc_limb_space( 2 * vsize, gcry_is_secure( up )
-                                                     || gcry_is_secure( vp ) );
+           ctx->tp = mpi_alloc_limb_space (2 * vsize,
+                                            (_gcry_is_secure (up)
+                                             || _gcry_is_secure (vp)));
            ctx->tp_size = vsize;
        }
 
@@ -423,7 +424,7 @@ _gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp,
        }
        else {
            if( !ctx->next ) {
-               ctx->next = gcry_xcalloc( 1, sizeof *ctx );
+               ctx->next = xcalloc( 1, sizeof *ctx );
            }
            _gcry_mpih_mul_karatsuba_case( ctx->tspace,
                                        vp, vsize,
@@ -452,7 +453,7 @@ _gcry_mpih_release_karatsuba_ctx( struct karatsuba_ctx *ctx )
             _gcry_mpi_free_limb_space( ctx->tp, ctx->tp_nlimbs );
        if( ctx->tspace )
            _gcry_mpi_free_limb_space( ctx->tspace, ctx->tspace_nlimbs );
-       gcry_free( ctx );
+       xfree( ctx );
     }
 }
 
index 76630a6..1f1754a 100644 (file)
@@ -1,6 +1,7 @@
 /* mpiutil.ac  -  Utility functions for MPI
  * Copyright (C) 1998, 2000, 2001, 2002, 2003,
  *               2007  Free Software Foundation, Inc.
+ * Copyright (C) 2013  g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
 #include "mpi-internal.h"
 #include "mod-source-info.h"
 
+/* Constatns allocated right away at strtartup.  */
+static gcry_mpi_t constants[MPI_NUMBER_OF_CONSTANTS];
+
+
 
 const char *
 _gcry_mpi_get_hw_config (void)
@@ -35,6 +40,34 @@ _gcry_mpi_get_hw_config (void)
 }
 
 
+/* Initialize the MPI subsystem.  This is called early and allows to
+   do some initialization without taking care of threading issues.  */
+gcry_err_code_t
+_gcry_mpi_init (void)
+{
+  int idx;
+  unsigned long value;
+
+  for (idx=0; idx < MPI_NUMBER_OF_CONSTANTS; idx++)
+    {
+      switch (idx)
+        {
+        case MPI_C_ZERO:  value = 0; break;
+        case MPI_C_ONE:   value = 1; break;
+        case MPI_C_TWO:   value = 2; break;
+        case MPI_C_THREE: value = 3; break;
+        case MPI_C_FOUR:  value = 4; break;
+        case MPI_C_EIGHT: value = 8; break;
+        default: log_bug ("invalid mpi_const selector %d\n", idx);
+        }
+      constants[idx] = mpi_alloc_set_ui (value);
+      constants[idx]->flags = (16|32);
+    }
+
+  return 0;
+}
+
+
 /****************
  * Note:  It was a bad idea to use the number of limbs to allocate
  *       because on a alpha the limbs are large but we normally need
@@ -48,7 +81,7 @@ _gcry_mpi_alloc( unsigned nlimbs )
 {
     gcry_mpi_t a;
 
-    a = gcry_xmalloc( sizeof *a );
+    a = xmalloc( sizeof *a );
     a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 0 ) : NULL;
     a->alloced = nlimbs;
     a->nlimbs = 0;
@@ -69,7 +102,7 @@ _gcry_mpi_alloc_secure( unsigned nlimbs )
 {
     gcry_mpi_t a;
 
-    a = gcry_xmalloc( sizeof *a );
+    a = xmalloc( sizeof *a );
     a->d = nlimbs? mpi_alloc_limb_space( nlimbs, 1 ) : NULL;
     a->alloced = nlimbs;
     a->flags = 1;
@@ -87,7 +120,7 @@ _gcry_mpi_alloc_limb_space( unsigned int nlimbs, int secure )
     size_t len;
 
     len = (nlimbs ? nlimbs : 1) * sizeof (mpi_limb_t);
-    p = secure ? gcry_xmalloc_secure (len) : gcry_xmalloc (len);
+    p = secure ? xmalloc_secure (len) : xmalloc (len);
     if (! nlimbs)
       *p = 0;
 
@@ -107,7 +140,7 @@ _gcry_mpi_free_limb_space( mpi_ptr_t a, unsigned int nlimbs)
          implemented in user provided allocation functions. */
       if (len)
         wipememory (a, len);
-      gcry_free(a);
+      xfree(a);
     }
 }
 
@@ -143,7 +176,7 @@ _gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs)
   /* Actually resize the limb space.  */
   if (a->d)
     {
-      a->d = gcry_xrealloc (a->d, nlimbs * sizeof (mpi_limb_t));
+      a->d = xrealloc (a->d, nlimbs * sizeof (mpi_limb_t));
       for (i=a->alloced; i < nlimbs; i++)
         a->d[i] = 0;
     }
@@ -151,10 +184,10 @@ _gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs)
     {
       if (a->flags & 1)
        /* Secure memory is wanted.  */
-       a->d = gcry_xcalloc_secure (nlimbs , sizeof (mpi_limb_t));
+       a->d = xcalloc_secure (nlimbs , sizeof (mpi_limb_t));
       else
        /* Standard memory.  */
-       a->d = gcry_xcalloc (nlimbs , sizeof (mpi_limb_t));
+       a->d = xcalloc (nlimbs , sizeof (mpi_limb_t));
     }
   a->alloced = nlimbs;
 }
@@ -162,8 +195,13 @@ _gcry_mpi_resize (gcry_mpi_t a, unsigned nlimbs)
 void
 _gcry_mpi_clear( gcry_mpi_t a )
 {
-    a->nlimbs = 0;
-    a->flags = 0;
+  if (mpi_is_immutable (a))
+    {
+      mpi_immutable_failed ();
+      return;
+    }
+  a->nlimbs = 0;
+  a->flags = 0;
 }
 
 
@@ -172,17 +210,33 @@ _gcry_mpi_free( gcry_mpi_t a )
 {
   if (!a )
     return;
+  if ((a->flags & 32))
+    return; /* Never release a constant. */
   if ((a->flags & 4))
-    gcry_free( a->d );
+    xfree( a->d );
   else
     {
       _gcry_mpi_free_limb_space(a->d, a->alloced);
     }
-  if ((a->flags & ~7))
-    log_bug("invalid flag value in mpi\n");
-  gcry_free(a);
+  /* Check that the flags makes sense.  We better allow for bit 1
+     (value 2) for backward ABI compatibility.  */
+  if ((a->flags & ~(1|2|4|16
+                    |GCRYMPI_FLAG_USER1
+                    |GCRYMPI_FLAG_USER2
+                    |GCRYMPI_FLAG_USER3
+                    |GCRYMPI_FLAG_USER4)))
+    log_bug("invalid flag value in mpi_free\n");
+  xfree (a);
+}
+
+
+void
+_gcry_mpi_immutable_failed (void)
+{
+  log_info ("Warning: trying to change an immutable MPI\n");
 }
 
+
 static void
 mpi_set_secure( gcry_mpi_t a )
 {
@@ -205,13 +259,19 @@ mpi_set_secure( gcry_mpi_t a )
 
 
 gcry_mpi_t
-gcry_mpi_set_opaque( gcry_mpi_t a, void *p, unsigned int nbits )
+_gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits)
 {
   if (!a)
     a = mpi_alloc(0);
 
+  if (mpi_is_immutable (a))
+    {
+      mpi_immutable_failed ();
+      return a;
+    }
+
   if( a->flags & 4 )
-    gcry_free( a->d );
+    xfree (a->d);
   else
     _gcry_mpi_free_limb_space (a->d, a->alloced);
 
@@ -219,13 +279,31 @@ gcry_mpi_set_opaque( gcry_mpi_t a, void *p, unsigned int nbits )
   a->alloced = 0;
   a->nlimbs = 0;
   a->sign  = nbits;
-  a->flags = 4;
+  a->flags = 4 | (a->flags & (GCRYMPI_FLAG_USER1|GCRYMPI_FLAG_USER2
+                              |GCRYMPI_FLAG_USER3|GCRYMPI_FLAG_USER4));
+  if (_gcry_is_secure (a->d))
+    a->flags |= 1;
   return a;
 }
 
 
+gcry_mpi_t
+_gcry_mpi_set_opaque_copy (gcry_mpi_t a, const void *p, unsigned int nbits)
+{
+  void *d;
+  unsigned int n;
+
+  n = (nbits+7)/8;
+  d = _gcry_is_secure (p)? xtrymalloc_secure (n) : xtrymalloc (n);
+  if (!d)
+    return NULL;
+  memcpy (d, p, n);
+  return mpi_set_opaque (a, d, nbits);
+}
+
+
 void *
-gcry_mpi_get_opaque( gcry_mpi_t a, unsigned int *nbits )
+_gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits)
 {
     if( !(a->flags & 4) )
        log_bug("mpi_get_opaque on normal mpi\n");
@@ -235,21 +313,39 @@ gcry_mpi_get_opaque( gcry_mpi_t a, unsigned int *nbits )
 }
 
 
+void *
+_gcry_mpi_get_opaque_copy (gcry_mpi_t a, unsigned int *nbits)
+{
+  const void *s;
+  void *d;
+  unsigned int n;
+
+  s = mpi_get_opaque (a, nbits);
+  if (!s && nbits)
+    return NULL;
+  n = (*nbits+7)/8;
+  d = _gcry_is_secure (s)? xtrymalloc_secure (n) : xtrymalloc (n);
+  if (d)
+    memcpy (d, s, n);
+  return d;
+}
+
 /****************
  * Note: This copy function should not interpret the MPI
  *      but copy it transparently.
  */
 gcry_mpi_t
-gcry_mpi_copy( gcry_mpi_t a )
+_gcry_mpi_copy (gcry_mpi_t a)
 {
     int i;
     gcry_mpi_t b;
 
     if( a && (a->flags & 4) ) {
-       void *p = gcry_is_secure(a->d)? gcry_xmalloc_secure( (a->sign+7)/8 )
-                                    : gcry_xmalloc( (a->sign+7)/8 );
+       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 );
-       b = gcry_mpi_set_opaque( NULL, p, a->sign );
+       b = mpi_set_opaque( NULL, p, a->sign );
+        b->flags &= ~(16|32); /* Reset the immutable and constant flags.  */
     }
     else if( a ) {
        b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
@@ -257,6 +353,7 @@ gcry_mpi_copy( gcry_mpi_t a )
        b->nlimbs = a->nlimbs;
        b->sign = a->sign;
        b->flags  = a->flags;
+        b->flags &= ~(16|32); /* Reset the immutable and constant flags.  */
        for(i=0; i < b->nlimbs; i++ )
            b->d[i] = a->d[i];
     }
@@ -266,6 +363,47 @@ gcry_mpi_copy( gcry_mpi_t a )
 }
 
 
+/* Return true if A is negative.  */
+int
+_gcry_mpi_is_neg (gcry_mpi_t a)
+{
+  if (a->sign && _gcry_mpi_cmp_ui (a, 0))
+    return 1;
+  else
+    return 0;
+}
+
+
+/* W = - U */
+void
+_gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u)
+{
+  if (w != u)
+    mpi_set (w, u);
+  else if (mpi_is_immutable (w))
+    {
+      mpi_immutable_failed ();
+      return;
+    }
+
+  w->sign = !u->sign;
+}
+
+
+/* W = [W] */
+void
+_gcry_mpi_abs (gcry_mpi_t w)
+{
+  if (mpi_is_immutable (w))
+    {
+      mpi_immutable_failed ();
+      return;
+    }
+
+  w->sign = 0;
+}
+
+
 /****************
  * This function allocates an MPI which is optimized to hold
  * a value as large as the one given in the argument and allocates it
@@ -278,10 +416,10 @@ _gcry_mpi_alloc_like( gcry_mpi_t a )
 
     if( a && (a->flags & 4) ) {
        int n = (a->sign+7)/8;
-       void *p = gcry_is_secure(a->d)? gcry_malloc_secure( n )
-                                    : gcry_malloc( n );
+       void *p = _gcry_is_secure(a->d)? xtrymalloc_secure (n)
+                                       : xtrymalloc (n);
        memcpy( p, a->d, n );
-       b = gcry_mpi_set_opaque( NULL, p, a->sign );
+       b = mpi_set_opaque( NULL, p, a->sign );
     }
     else if( a ) {
        b = mpi_is_secure(a)? mpi_alloc_secure( a->nlimbs )
@@ -296,8 +434,31 @@ _gcry_mpi_alloc_like( gcry_mpi_t a )
 }
 
 
+/* Set U into W and release U.  If W is NULL only U will be released. */
+void
+_gcry_mpi_snatch (gcry_mpi_t w, gcry_mpi_t u)
+{
+  if (w)
+    {
+      if (mpi_is_immutable (w))
+        {
+          mpi_immutable_failed ();
+          return;
+        }
+      _gcry_mpi_assign_limb_space (w, u->d, u->alloced);
+      w->nlimbs = u->nlimbs;
+      w->sign   = u->sign;
+      w->flags  = u->flags;
+      u->alloced = 0;
+      u->nlimbs = 0;
+      u->d = NULL;
+    }
+  _gcry_mpi_free (u);
+}
+
+
 gcry_mpi_t
-gcry_mpi_set( gcry_mpi_t w, gcry_mpi_t u)
+_gcry_mpi_set (gcry_mpi_t w, gcry_mpi_t u)
 {
   mpi_ptr_t wp, up;
   mpi_size_t usize = u->nlimbs;
@@ -305,24 +466,35 @@ gcry_mpi_set( gcry_mpi_t w, gcry_mpi_t u)
 
   if (!w)
     w = _gcry_mpi_alloc( mpi_get_nlimbs(u) );
+  if (mpi_is_immutable (w))
+    {
+      mpi_immutable_failed ();
+      return w;
+    }
   RESIZE_IF_NEEDED(w, usize);
   wp = w->d;
   up = u->d;
   MPN_COPY( wp, up, usize );
   w->nlimbs = usize;
   w->flags = u->flags;
+  w->flags &= ~(16|32); /* Reset the immutable and constant flags.  */
   w->sign = usign;
   return w;
 }
 
 
 gcry_mpi_t
-gcry_mpi_set_ui( gcry_mpi_t w, unsigned long u)
+_gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u)
 {
   if (!w)
     w = _gcry_mpi_alloc (1);
   /* FIXME: If U is 0 we have no need to resize and thus possible
      allocating the the limbs. */
+  if (mpi_is_immutable (w))
+    {
+      mpi_immutable_failed ();
+      return w;
+    }
   RESIZE_IF_NEEDED(w, 1);
   w->d[0] = u;
   w->nlimbs = u? 1:0;
@@ -350,15 +522,6 @@ _gcry_mpi_get_ui (gcry_mpi_t w, unsigned long *u)
   return err;
 }
 
-gcry_error_t
-gcry_mpi_get_ui (gcry_mpi_t w, unsigned long *u)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-
-  err = _gcry_mpi_get_ui (w, u);
-
-  return gcry_error (err);
-}
 
 gcry_mpi_t
 _gcry_mpi_alloc_set_ui( unsigned long u)
@@ -371,7 +534,7 @@ _gcry_mpi_alloc_set_ui( unsigned long u)
 }
 
 void
-gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b)
+_gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b)
 {
     struct gcry_mpi tmp;
 
@@ -380,7 +543,7 @@ gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b)
 
 
 gcry_mpi_t
-gcry_mpi_new( unsigned int nbits )
+_gcry_mpi_new (unsigned int nbits)
 {
     return _gcry_mpi_alloc ( (nbits+BITS_PER_MPI_LIMB-1)
                              / BITS_PER_MPI_LIMB );
@@ -388,58 +551,85 @@ gcry_mpi_new( unsigned int nbits )
 
 
 gcry_mpi_t
-gcry_mpi_snew( unsigned int nbits )
+_gcry_mpi_snew (unsigned int nbits)
 {
   return _gcry_mpi_alloc_secure ( (nbits+BITS_PER_MPI_LIMB-1)
                                   / BITS_PER_MPI_LIMB );
 }
 
 void
-gcry_mpi_release( gcry_mpi_t a )
+_gcry_mpi_release( gcry_mpi_t a )
 {
     _gcry_mpi_free( a );
 }
 
 void
-gcry_mpi_randomize( gcry_mpi_t w,
-                   unsigned int nbits, enum gcry_random_level level )
+_gcry_mpi_randomize (gcry_mpi_t w,
+                     unsigned int nbits, enum gcry_random_level level)
 {
   unsigned char *p;
   size_t nbytes = (nbits+7)/8;
 
+  if (mpi_is_immutable (w))
+    {
+      mpi_immutable_failed ();
+      return;
+    }
   if (level == GCRY_WEAK_RANDOM)
     {
-      p = mpi_is_secure(w) ? gcry_xmalloc_secure (nbytes)
-                           : gcry_xmalloc (nbytes);
-      gcry_create_nonce (p, nbytes);
+      p = mpi_is_secure(w) ? xmalloc_secure (nbytes)
+                           : xmalloc (nbytes);
+      _gcry_create_nonce (p, nbytes);
     }
   else
     {
-      p = mpi_is_secure(w) ? gcry_random_bytes_secure (nbytes, level)
-                           : gcry_random_bytes (nbytes, level);
+      p = mpi_is_secure(w) ? _gcry_random_bytes_secure (nbytes, level)
+                           : _gcry_random_bytes (nbytes, level);
     }
   _gcry_mpi_set_buffer( w, p, nbytes, 0 );
-  gcry_free (p);
+  xfree (p);
 }
 
 
 void
-gcry_mpi_set_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
+_gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
 {
-    switch( flag ) {
-      case GCRYMPI_FLAG_SECURE:  mpi_set_secure(a); break;
-      case GCRYMPI_FLAG_OPAQUE:
-      default: log_bug("invalid flag value\n");
+  switch (flag)
+    {
+    case GCRYMPI_FLAG_SECURE:     mpi_set_secure(a); break;
+    case GCRYMPI_FLAG_CONST:      a->flags |= (16|32); break;
+    case GCRYMPI_FLAG_IMMUTABLE:  a->flags |= 16; break;
+
+    case GCRYMPI_FLAG_USER1:
+    case GCRYMPI_FLAG_USER2:
+    case GCRYMPI_FLAG_USER3:
+    case GCRYMPI_FLAG_USER4:      a->flags |= flag; break;
+
+    case GCRYMPI_FLAG_OPAQUE:
+    default: log_bug("invalid flag value\n");
     }
 }
 
 void
-gcry_mpi_clear_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
+_gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
 {
   (void)a; /* Not yet used. */
 
   switch (flag)
     {
+    case GCRYMPI_FLAG_IMMUTABLE:
+      if (!(a->flags & 32))
+        a->flags &= ~16;
+      break;
+
+    case GCRYMPI_FLAG_USER1:
+    case GCRYMPI_FLAG_USER2:
+    case GCRYMPI_FLAG_USER3:
+    case GCRYMPI_FLAG_USER4:
+      a->flags &= ~flag;
+      break;
+
+    case GCRYMPI_FLAG_CONST:
     case GCRYMPI_FLAG_SECURE:
     case GCRYMPI_FLAG_OPAQUE:
     default: log_bug("invalid flag value\n");
@@ -447,14 +637,34 @@ gcry_mpi_clear_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
 }
 
 int
-gcry_mpi_get_flag( gcry_mpi_t a, enum gcry_mpi_flag flag )
+_gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
 {
   switch (flag)
     {
-    case GCRYMPI_FLAG_SECURE: return (a->flags & 1);
-    case GCRYMPI_FLAG_OPAQUE: return (a->flags & 4);
+    case GCRYMPI_FLAG_SECURE:    return !!(a->flags & 1);
+    case GCRYMPI_FLAG_OPAQUE:    return !!(a->flags & 4);
+    case GCRYMPI_FLAG_IMMUTABLE: return !!(a->flags & 16);
+    case GCRYMPI_FLAG_CONST:     return !!(a->flags & 32);
+    case GCRYMPI_FLAG_USER1:
+    case GCRYMPI_FLAG_USER2:
+    case GCRYMPI_FLAG_USER3:
+    case GCRYMPI_FLAG_USER4:     return !!(a->flags & flag);
     default: log_bug("invalid flag value\n");
     }
   /*NOTREACHED*/
   return 0;
 }
+
+
+/* Return a constant MPI descripbed by NO which is one of the
+   MPI_C_xxx macros.  There is no need to copy this returned value; it
+   may be used directly.  */
+gcry_mpi_t
+_gcry_mpi_const (enum gcry_mpi_constants no)
+{
+  if ((int)no < 0 || no > MPI_NUMBER_OF_CONSTANTS)
+    log_bug("invalid mpi_const selector %d\n", no);
+  if (!constants[no])
+    log_bug("MPI subsystem not initialized\n");
+  return constants[no];
+}
similarity index 92%
rename from random/ChangeLog
rename to random/ChangeLog-2011
index 7784d44..cd45c3d 100644 (file)
@@ -1,3 +1,15 @@
+2011-12-01  Werner Koch  <wk@g10code.com>
+
+       NB: ChangeLog files are no longer manually maintained.  Starting
+       on December 1st, 2011 we put change information only in the GIT
+       commit log, and generate a top-level ChangeLog file from logs at
+       "make dist".  See doc/HACKING for details.
+
+2011-09-08  Werner Koch  <wk@g10code.com>
+
+       * rndlinux.c (_gcry_rndlinux_gather_random): Don't use select if
+       the fd number is too high.  Reported by Jakub Bogusz.
+
 2010-10-18  Werner Koch  <wk@g10code.com>
 
        * rndw32.c (registry_poll): Disable performace fata gathering if
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
index 603226d..c9d587a 100644 (file)
@@ -35,6 +35,7 @@ random.c random.h \
 rand-internal.h \
 random-csprng.c \
 random-fips.c \
+random-system.c \
 rndhw.c
 
 if USE_RANDOM_DAEMON
index 89b80db..215441f 100644 (file)
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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; \
+    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;; \
+    esac; \
+    test $$am__dry = yes; \
+  }
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -56,50 +73,74 @@ 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 ChangeLog
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.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/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/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
        $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
-       $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+       $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/acinclude.m4 \
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES =
 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 rndhw.c random-daemon.c
+       random-csprng.c random-fips.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 \
-       rndhw.lo $(am__objects_1)
+       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
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
 am__depfiles_maybe = depfiles
 am__mv = mv -f
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
-       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+       $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(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 = @
 CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
-       $(LDFLAGS) -o $@
+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   " $@;
 SOURCES = $(librandom_la_SOURCES) $(EXTRA_librandom_la_SOURCES)
 DIST_SOURCES = $(am__librandom_la_SOURCES_DIST) \
        $(EXTRA_librandom_la_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AR = @AR@
 AS = @AS@
 AUTOCONF = @AUTOCONF@
@@ -114,6 +155,7 @@ CCAS = @CCAS@
 CCASDEPMODE = @CCASDEPMODE@
 CCASFLAGS = @CCASFLAGS@
 CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
@@ -133,6 +175,8 @@ FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
 FGREP = @FGREP@
 GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
 GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_HWF_MODULES = @GCRYPT_HWF_MODULES@
+GCRYPT_KDFS = @GCRYPT_KDFS@
 GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
 GCRYPT_RANDOM = @GCRYPT_RANDOM@
 GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
@@ -158,14 +202,19 @@ 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@
 MKDIR_P = @MKDIR_P@
 MPI_SFLAGS = @MPI_SFLAGS@
 NM = @NM@
@@ -188,16 +237,19 @@ PTH_CONFIG = @PTH_CONFIG@
 PTH_LIBS = @PTH_LIBS@
 RANLIB = @RANLIB@
 RC = @RC@
+RUN_LARGE_DATA_TESTS = @RUN_LARGE_DATA_TESTS@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
 SYS_SOCKET_H = @SYS_SOCKET_H@
 VERSION = @VERSION@
+VERSION_NUMBER = @VERSION_NUMBER@
 abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
@@ -233,7 +285,6 @@ libdir = @libdir@
 libexecdir = @libexecdir@
 localedir = @localedir@
 localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 oldincludedir = @oldincludedir@
@@ -259,7 +310,8 @@ 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 rndhw.c $(am__append_1)
+       random-csprng.c random-fips.c random-system.c rndhw.c \
+       $(am__append_1)
 EXTRA_librandom_la_SOURCES = \
 rndlinux.c \
 rndegd.c \
@@ -310,8 +362,8 @@ clean-noinstLTLIBRARIES:
          echo "rm -f \"$${dir}/so_locations\""; \
          rm -f "$${dir}/so_locations"; \
        done
-librandom.la: $(librandom_la_OBJECTS) $(librandom_la_DEPENDENCIES) 
-       $(LINK)  $(librandom_la_OBJECTS) $(librandom_la_LIBADD) $(LIBS)
+librandom.la: $(librandom_la_OBJECTS) $(librandom_la_DEPENDENCIES) $(EXTRA_librandom_la_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK)  $(librandom_la_OBJECTS) $(librandom_la_LIBADD) $(LIBS)
 
 mostlyclean-compile:
        -rm -f *.$(OBJEXT)
@@ -322,6 +374,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-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@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndhw.Plo@am__quote@
@@ -331,25 +384,25 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndw32ce.Plo@am__quote@
 
 .c.o:
-@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@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@  $(COMPILE) -c $<
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
 
 .c.obj:
-@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@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@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
 
 .c.lo:
-@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
 mostlyclean-libtool:
        -rm -f *.lo
@@ -453,10 +506,15 @@ install-am: all-am
 
 installcheck: installcheck-am
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-         `test -z '$(STRIP)' || \
-           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+       if test -z '$(STRIP)'; then \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+             install; \
+       else \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+           "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+       fi
 mostlyclean-generic:
 
 clean-generic:
index a04a2d4..79b23ac 100644 (file)
@@ -44,6 +44,7 @@ void _gcry_random_progress (const char *what, int printchar,
 
 /*-- random-csprng.c --*/
 void _gcry_rngcsprng_initialize (int full);
+void _gcry_rngcsprng_close_fds (void);
 void _gcry_rngcsprng_dump_stats (void);
 void _gcry_rngcsprng_secure_alloc (void);
 void _gcry_rngcsprng_enable_quick_gen (void);
@@ -61,18 +62,14 @@ void _gcry_rngcsprng_randomize (void *buffer, size_t length,
 void _gcry_rngcsprng_set_seed_file (const char *name);
 void _gcry_rngcsprng_update_seed_file (void);
 void _gcry_rngcsprng_fast_poll (void);
-void _gcry_rngcsprng_create_nonce (void *buffer, size_t length);
 
-/*-- random-rngcsprng.c --*/
+/*-- 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_get_bytes (size_t nbytes,
-                               enum gcry_random_level level);
-void *_gcry_rngfips_get_bytes_secure (size_t nbytes,
-                                      enum gcry_random_level level);
 void _gcry_rngfips_randomize (void *buffer, size_t length,
                                 enum gcry_random_level level);
 void _gcry_rngfips_create_nonce (void *buffer, size_t length);
@@ -92,6 +89,15 @@ gcry_err_code_t _gcry_rngfips_run_external_test (void *context,
 void _gcry_rngfips_deinit_external_test (void *context);
 
 
+/*-- random-system.c --*/
+void _gcry_rngsystem_initialize (int full);
+void _gcry_rngsystem_close_fds (void);
+void _gcry_rngsystem_dump_stats (void);
+int  _gcry_rngsystem_is_faked (void);
+gcry_error_t _gcry_rngsystem_add_bytes (const void *buf, size_t buflen,
+                                        int quality);
+void _gcry_rngsystem_randomize (void *buffer, size_t length,
+                                enum gcry_random_level level);
 
 
 
index 096a674..87235d8 100644 (file)
@@ -1,6 +1,6 @@
 /* random-csprng.c - CSPRNG style random number generator (libgcrypt classic)
  * Copyright (C) 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- *               2007, 2008, 2010  Free Software Foundation, Inc.
+ *               2007, 2008, 2010, 2012  Free Software Foundation, Inc.
  *
  * This file is part of Libgcrypt.
  *
@@ -154,7 +154,7 @@ static int allow_seed_file_update;
 static int secure_alloc;
 
 /* This function pointer is set to the actual entropy gathering
-   function during initailization.  After initialization it is
+   function during initialization.  After initialization it is
    guaranteed to point to function.  (On systems without a random
    gatherer module a dummy function is used).*/
 static int (*slow_gather_fnc)(void (*)(const void*, size_t,
@@ -181,7 +181,7 @@ static int quick_test;
 static int faked_rng;
 
 /* This is the lock we use to protect all pool operations.  */
-static ath_mutex_t pool_lock = ATH_MUTEX_INITIALIZER;
+static ath_mutex_t 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
@@ -189,10 +189,6 @@ static ath_mutex_t pool_lock = ATH_MUTEX_INITIALIZER;
    test suite.  */
 static int pool_is_locked;
 
-/* This is the lock we use to protect the buffer used by the nonce
-   generation.  */
-static ath_mutex_t nonce_buffer_lock = ATH_MUTEX_INITIALIZER;
-
 
 /* We keep some counters in this structure for the sake of the
    _gcry_random_dump_stats () function.  */
@@ -272,11 +268,6 @@ initialize_basics(void)
       if (err)
         log_fatal ("failed to create the pool lock: %s\n", strerror (err) );
 
-      err = ath_mutex_init (&nonce_buffer_lock);
-      if (err)
-        log_fatal ("failed to create the nonce buffer lock: %s\n",
-                   strerror (err) );
-
 #ifdef USE_RANDOM_DAEMON
       _gcry_daemon_initialize_basics ();
 #endif /*USE_RANDOM_DAEMON*/
@@ -331,11 +322,11 @@ initialize(void)
          use this extra space (which is allocated in secure memory) as
          a temporary hash buffer */
       rndpool = (secure_alloc
-                 ? gcry_xcalloc_secure (1, POOLSIZE + BLOCKLEN)
-                 : gcry_xcalloc (1, POOLSIZE + BLOCKLEN));
+                 ? xcalloc_secure (1, POOLSIZE + BLOCKLEN)
+                 : xcalloc (1, POOLSIZE + BLOCKLEN));
       keypool = (secure_alloc
-                 ? gcry_xcalloc_secure (1, POOLSIZE + BLOCKLEN)
-                 : gcry_xcalloc (1, POOLSIZE + BLOCKLEN));
+                 ? xcalloc_secure (1, POOLSIZE + BLOCKLEN)
+                 : xcalloc (1, POOLSIZE + BLOCKLEN));
 
       /* Setup the slow entropy gathering function.  The code requires
          that this function exists. */
@@ -370,6 +361,20 @@ _gcry_rngcsprng_initialize (int full)
 }
 
 
+/* Try to close the FDs of the random gather module.  This is
+   currently only implemented for rndlinux. */
+void
+_gcry_rngcsprng_close_fds (void)
+{
+  lock_pool ();
+#if USE_RNDLINUX
+  _gcry_rndlinux_gather_random (NULL, 0, 0, 0);
+  pool_filled = 0; /* Force re-open on next use.  */
+#endif
+  unlock_pool ();
+}
+
+
 void
 _gcry_rngcsprng_dump_stats (void)
 {
@@ -671,7 +676,7 @@ _gcry_rngcsprng_set_seed_file (const char *name)
 {
   if (seed_file_name)
     BUG ();
-  seed_file_name = gcry_xstrdup (name);
+  seed_file_name = xstrdup (name);
 }
 
 
@@ -1307,7 +1312,7 @@ gather_faked (void (*add)(const void*, size_t, enum random_origins),
 #endif
     }
 
-  p = buffer = gcry_xmalloc( length );
+  p = buffer = xmalloc( length );
   n = length;
 #ifdef HAVE_RAND
   while ( n-- )
@@ -1317,92 +1322,6 @@ gather_faked (void (*add)(const void*, size_t, enum random_origins),
     *p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1);
 #endif
   add_randomness ( buffer, length, origin );
-  gcry_free (buffer);
+  xfree (buffer);
   return 0; /* okay */
 }
-
-
-/* Create an unpredicable nonce of LENGTH bytes in BUFFER. */
-void
-_gcry_rngcsprng_create_nonce (void *buffer, size_t length)
-{
-  static unsigned char nonce_buffer[20+8];
-  static int nonce_buffer_initialized = 0;
-  static volatile pid_t my_pid; /* The volatile is there to make sure the
-                                   compiler does not optimize the code away
-                                   in case the getpid function is badly
-                                   attributed. */
-  volatile pid_t apid;
-  unsigned char *p;
-  size_t n;
-  int err;
-
-  /* Make sure we are initialized. */
-  initialize ();
-
-#ifdef USE_RANDOM_DAEMON
-  if (allow_daemon
-      && !_gcry_daemon_create_nonce (daemon_socket_name, buffer, length))
-    return; /* The daemon succeeded. */
-  allow_daemon = 0; /* Daemon failed - switch off. */
-#endif /*USE_RANDOM_DAEMON*/
-
-  /* Acquire the nonce buffer lock. */
-  err = ath_mutex_lock (&nonce_buffer_lock);
-  if (err)
-    log_fatal ("failed to acquire the nonce buffer lock: %s\n",
-               strerror (err));
-
-  apid = getpid ();
-  /* The first time initialize our buffer. */
-  if (!nonce_buffer_initialized)
-    {
-      time_t atime = time (NULL);
-      pid_t xpid = apid;
-
-      my_pid = apid;
-
-      if ((sizeof apid + sizeof atime) > sizeof nonce_buffer)
-        BUG ();
-
-      /* Initialize the first 20 bytes with a reasonable value so that
-         a failure of gcry_randomize won't affect us too much.  Don't
-         care about the uninitialized remaining bytes. */
-      p = nonce_buffer;
-      memcpy (p, &xpid, sizeof xpid);
-      p += sizeof xpid;
-      memcpy (p, &atime, sizeof atime);
-
-      /* Initialize the never changing private part of 64 bits. */
-      gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM);
-
-      nonce_buffer_initialized = 1;
-    }
-  else if ( my_pid != apid )
-    {
-      /* We forked. Need to reseed the buffer - doing this for the
-         private part should be sufficient. */
-      gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM);
-      /* Update the pid so that we won't run into here again and
-         again. */
-      my_pid = apid;
-    }
-
-  /* Create the nonce by hashing the entire buffer, returning the hash
-     and updating the first 20 bytes of the buffer with this hash. */
-  for (p = buffer; length > 0; length -= n, p += n)
-    {
-      _gcry_sha1_hash_buffer (nonce_buffer,
-                              nonce_buffer, sizeof nonce_buffer);
-      n = length > 20? 20 : length;
-      memcpy (p, nonce_buffer, n);
-    }
-
-
-  /* Release the nonce buffer lock. */
-  err = ath_mutex_unlock (&nonce_buffer_lock);
-  if (err)
-    log_fatal ("failed to release the nonce buffer lock: %s\n",
-               strerror (err));
-
-}
index d8bfe4c..98a0153 100644 (file)
@@ -28,6 +28,7 @@
    sensitive data.
  */
 
+#error This dameon needs to be fixed due to the ath changes
 
 #include <config.h>
 #include <stdio.h>
@@ -269,7 +270,7 @@ call_daemon (const char *socketname,
       if (rc == -1)
        {
          err = gcry_error_from_errno (errno);
-         log_error ("read error: %s\n", gcry_strerror (err));
+         log_error ("read error: %s\n", _gcry_strerror (err));
          break;
        }
       if (nread && buf[0])
@@ -307,7 +308,7 @@ call_daemon (const char *socketname,
       if (rc == -1)
        {
          err = gcry_error_from_errno (errno);
-         log_error ("read error: %s\n", gcry_strerror (err));
+         log_error ("read error: %s\n", _gcry_strerror (err));
          break;
        }
 
@@ -344,17 +345,4 @@ _gcry_daemon_randomize (const char *socketname,
   return err ? -1 : 0;
 }
 
-
-/* Internal function to fill BUFFER with NBYTES of data usable for a
-   nonce.  Returns 0 on success. */
-int
-_gcry_daemon_create_nonce (const char *socketname, void *buffer, size_t length)
-{
-  gcry_error_t err;
-
-  err = call_daemon (socketname, buffer, length, 1, 0);
-
-  return err ? -1 : 0;
-}
-
 /* END */
index 307d2b2..d00825e 100644 (file)
@@ -72,7 +72,7 @@
    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 = ATH_MUTEX_INITIALIZER;
+static ath_mutex_t fips_rng_lock;
 static int fips_rng_is_locked;
 
 
@@ -192,7 +192,7 @@ basic_initialization (void)
   static int initialized;
   int my_errno;
 
-  if (!initialized)
+  if (initialized)
     return;
   initialized = 1;
 
@@ -390,9 +390,9 @@ encrypt_aes (gcry_cipher_hd_t key,
 
   gcry_assert (length == 16);
 
-  err = gcry_cipher_encrypt (key, output, length, input, length);
+  err = _gcry_cipher_encrypt (key, output, length, input, length);
   if (err)
-    log_fatal ("AES encryption in RNG failed: %s\n", gcry_strerror (err));
+    log_fatal ("AES encryption in RNG failed: %s\n", _gcry_strerror (err));
 }
 
 
@@ -555,7 +555,7 @@ get_entropy (size_t nbytes)
   int rc;
 
   gcry_assert (!entropy_collect_buffer);
-  entropy_collect_buffer = gcry_xmalloc_secure (nbytes);
+  entropy_collect_buffer = xmalloc_secure (nbytes);
   entropy_collect_buffer_size = nbytes;
   entropy_collect_buffer_len = 0;
 
@@ -577,7 +577,7 @@ get_entropy (size_t nbytes)
 
   if (rc < 0 || entropy_collect_buffer_len != entropy_collect_buffer_size)
     {
-      gcry_free (entropy_collect_buffer);
+      xfree (entropy_collect_buffer);
       entropy_collect_buffer = NULL;
       log_fatal ("error getting entropy data\n");
     }
@@ -595,25 +595,25 @@ static gcry_cipher_hd_t
 x931_generate_key (int for_nonce)
 {
   gcry_cipher_hd_t hd;
-  gpg_error_t err;
+  gpg_err_code_t rc;
   void *buffer;
 
   gcry_assert (fips_rng_is_locked);
 
   /* Allocate a cipher context.  */
-  err = gcry_cipher_open (&hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB,
+  rc = _gcry_cipher_open (&hd, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB,
                           GCRY_CIPHER_SECURE);
-  if (err)
+  if (rc)
     {
       log_error ("error creating cipher context for RNG: %s\n",
-                 gcry_strerror (err));
+                 _gcry_strerror (rc));
       return NULL;
     }
 
   /* Get a key from the standard RNG or from the entropy source.  */
   if (for_nonce)
     {
-      buffer = gcry_xmalloc (X931_AES_KEYLEN);
+      buffer = xmalloc (X931_AES_KEYLEN);
       get_random (buffer, X931_AES_KEYLEN, std_rng_context);
     }
   else
@@ -623,13 +623,13 @@ x931_generate_key (int for_nonce)
 
   /* Set the key and delete the buffer because the key is now part of
      the cipher context.  */
-  err = gcry_cipher_setkey (hd, buffer, X931_AES_KEYLEN);
+  rc = _gcry_cipher_setkey (hd, buffer, X931_AES_KEYLEN);
   wipememory (buffer, X931_AES_KEYLEN);
-  gcry_free (buffer);
-  if (err)
+  xfree (buffer);
+  if (rc)
     {
-      log_error ("error creating key for RNG: %s\n", gcry_strerror (err));
-      gcry_cipher_close (hd);
+      log_error ("error creating key for RNG: %s\n", _gcry_strerror (rc));
+      _gcry_cipher_close (hd);
       return NULL;
     }
 
@@ -651,7 +651,7 @@ x931_generate_seed (unsigned char *seed_buffer, size_t length)
 
   memcpy (seed_buffer, buffer, X931_AES_KEYLEN);
   wipememory (buffer, X931_AES_KEYLEN);
-  gcry_free (buffer);
+  xfree (buffer);
 }
 
 
@@ -753,17 +753,17 @@ _gcry_rngfips_initialize (int full)
   if (!tempvalue_for_x931_aes_driver)
     {
       tempvalue_for_x931_aes_driver
-        = gcry_xmalloc_secure (TEMPVALUE_FOR_X931_AES_DRIVER_SIZE);
+        = 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 = gcry_xcalloc (1, sizeof *nonce_context);
+      nonce_context = xcalloc (1, sizeof *nonce_context);
       setup_guards (nonce_context);
 
-      std_rng_context = gcry_xcalloc_secure (1, sizeof *std_rng_context);
+      std_rng_context = xcalloc_secure (1, sizeof *std_rng_context);
       setup_guards (std_rng_context);
 
-      strong_rng_context = gcry_xcalloc_secure (1, sizeof *strong_rng_context);
+      strong_rng_context = xcalloc_secure (1, sizeof *strong_rng_context);
       setup_guards (strong_rng_context);
     }
   else
@@ -780,6 +780,19 @@ _gcry_rngfips_initialize (int full)
 }
 
 
+/* 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)
@@ -897,13 +910,13 @@ selftest_kat (selftest_report_func_t report)
     };
   int tvidx, ridx;
   rng_context_t test_ctx;
-  gpg_error_t err;
+  gpg_err_code_t rc;
   const char *errtxt = NULL;
   unsigned char result[16];
 
   gcry_assert (tempvalue_for_x931_aes_driver);
 
-  test_ctx = gcry_xcalloc (1, sizeof *test_ctx);
+  test_ctx = xcalloc (1, sizeof *test_ctx);
   setup_guards (test_ctx);
 
   lock_rng ();
@@ -911,17 +924,17 @@ selftest_kat (selftest_report_func_t report)
   for (tvidx=0; tvidx < DIM (tv); tvidx++)
     {
       /* Setup the key.  */
-      err = gcry_cipher_open (&test_ctx->cipher_hd,
+      rc = _gcry_cipher_open (&test_ctx->cipher_hd,
                               GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB,
                               GCRY_CIPHER_SECURE);
-      if (err)
+      if (rc)
         {
           errtxt = "error creating cipher context for RNG";
           goto leave;
         }
 
-      err = gcry_cipher_setkey (test_ctx->cipher_hd, tv[tvidx].key, 16);
-      if (err)
+      rc = _gcry_cipher_setkey (test_ctx->cipher_hd, tv[tvidx].key, 16);
+      if (rc)
         {
           errtxt = "error setting key for RNG";
           goto leave;
@@ -969,7 +982,7 @@ selftest_kat (selftest_report_func_t report)
           goto leave;
         }
 
-      gcry_cipher_close (test_ctx->cipher_hd);
+      _gcry_cipher_close (test_ctx->cipher_hd);
       test_ctx->cipher_hd = NULL;
       test_ctx->is_seeded = 0;
       check_guards (test_ctx);
@@ -977,9 +990,9 @@ selftest_kat (selftest_report_func_t report)
 
  leave:
   unlock_rng ();
-  gcry_cipher_close (test_ctx->cipher_hd);
+  _gcry_cipher_close (test_ctx->cipher_hd);
   check_guards (test_ctx);
-  gcry_free (test_ctx);
+  xfree (test_ctx);
   if (report && errtxt)
     report ("random", 0, "KAT", errtxt);
   return errtxt? GPG_ERR_SELFTEST_FAILED : 0;
@@ -1000,7 +1013,7 @@ _gcry_rngfips_selftest (selftest_report_func_t report)
        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);
+    _gcry_randomize (buffer, sizeof buffer, GCRY_STRONG_RANDOM);
   }
 
   ec = selftest_kat (report);
@@ -1022,7 +1035,7 @@ _gcry_rngfips_init_external_test (void **r_context, unsigned int flags,
                                   const void *seed, size_t seedlen,
                                   const void *dt, size_t dtlen)
 {
-  gpg_error_t err;
+  gpg_err_code_t rc;
   rng_context_t test_ctx;
 
   _gcry_rngfips_initialize (1);  /* Auto-initialize if needed.  */
@@ -1033,20 +1046,20 @@ _gcry_rngfips_init_external_test (void **r_context, unsigned int flags,
       || !dt   || dtlen   != 16 )
     return GPG_ERR_INV_ARG;
 
-  test_ctx = gcry_calloc (1, sizeof *test_ctx + dtlen);
+  test_ctx = xtrycalloc (1, sizeof *test_ctx + dtlen);
   if (!test_ctx)
     return gpg_err_code_from_syserror ();
   setup_guards (test_ctx);
 
   /* Setup the key.  */
-  err = gcry_cipher_open (&test_ctx->cipher_hd,
+  rc = _gcry_cipher_open (&test_ctx->cipher_hd,
                           GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB,
                           GCRY_CIPHER_SECURE);
-  if (err)
+  if (rc)
     goto leave;
 
-  err = gcry_cipher_setkey (test_ctx->cipher_hd, key, keylen);
-  if (err)
+  rc = _gcry_cipher_setkey (test_ctx->cipher_hd, key, keylen);
+  if (rc)
     goto leave;
 
   test_ctx->key_init_pid = getpid ();
@@ -1071,18 +1084,18 @@ _gcry_rngfips_init_external_test (void **r_context, unsigned int flags,
 
   check_guards (test_ctx);
   /* All fine.  */
-  err = 0;
+  rc = 0;
 
  leave:
-  if (err)
+  if (rc)
     {
-      gcry_cipher_close (test_ctx->cipher_hd);
-      gcry_free (test_ctx);
+      _gcry_cipher_close (test_ctx->cipher_hd);
+      xfree (test_ctx);
       *r_context = NULL;
     }
   else
     *r_context = test_ctx;
-  return gcry_err_code (err);
+  return rc;
 }
 
 
@@ -1110,7 +1123,7 @@ _gcry_rngfips_deinit_external_test (void *context)
 
   if (test_ctx)
     {
-      gcry_cipher_close (test_ctx->cipher_hd);
-      gcry_free (test_ctx);
+      _gcry_cipher_close (test_ctx->cipher_hd);
+      xfree (test_ctx);
     }
 }
diff --git a/random/random-system.c b/random/random-system.c
new file mode 100644 (file)
index 0000000..3962ab8
--- /dev/null
@@ -0,0 +1,256 @@
+/* random-system.c - wrapper around the system's RNG
+ * Copyright (C) 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/>.
+ */
+
+/*
+   This RNG is merely wrapper around the system's native RNG.  For
+   example on Unix systems it directly uses /dev/{u,}random.
+ */
+
+#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 system_rng_lock;
+static int system_rng_is_locked;
+
+
+/* --- Local prototypes ---  */
+
+
+
+\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 (&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
+     used for the random levels.  */
+  gcry_assert (GCRY_WEAK_RANDOM == 0
+               && GCRY_STRONG_RANDOM == 1
+               && GCRY_VERY_STRONG_RANDOM == 2);
+
+}
+
+
+/* Acquire the system_rng_lock.  */
+static void
+lock_rng (void)
+{
+  int my_errno;
+
+  my_errno = ath_mutex_lock (&system_rng_lock);
+  if (my_errno)
+    log_fatal ("failed to acquire the System RNG lock: %s\n",
+               strerror (my_errno));
+  system_rng_is_locked = 1;
+}
+
+
+/* Release the system_rng_lock.  */
+static void
+unlock_rng (void)
+{
+  int my_errno;
+
+  system_rng_is_locked = 0;
+  my_errno = ath_mutex_unlock (&system_rng_lock);
+  if (my_errno)
+    log_fatal ("failed to release the System RNG lock: %s\n",
+               strerror (my_errno));
+}
+
+
+/* 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 _gcry_rnd*_gather_random.  */
+static void
+read_cb (const void *buffer, size_t length, enum random_origins origin)
+{
+  const unsigned char *p = buffer;
+
+  (void)origin;
+
+  gcry_assert (system_rng_is_locked);
+  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++;
+    }
+}
+
+
+/* Fill BUFFER with LENGTH bytes of random at quality LEVEL.  The
+   function either succeeds or terminates the process in case of a
+   fatal error. */
+static void
+get_random (void *buffer, size_t length, int level)
+{
+  int rc;
+
+  gcry_assert (buffer);
+
+  read_cb_buffer = buffer;
+  read_cb_size   = length;
+  read_cb_len    = 0;
+
+#if USE_RNDLINUX
+  rc = _gcry_rndlinux_gather_random (read_cb, 0, length, level);
+#elif USE_RNDUNIX
+  rc = _gcry_rndunix_gather_random (read_cb, 0, length, level);
+#elif USE_RNDW32
+  do
+    {
+      rc = _gcry_rndw32_gather_random (read_cb, 0, length, level);
+    }
+  while (rc >= 0 && read_cb_len < read_cb_size);
+#else
+  rc = -1;
+#endif
+
+  if (rc < 0 || read_cb_len != read_cb_size)
+    {
+      log_fatal ("error reading random from system RNG (rc=%d)\n", rc);
+    }
+}
+
+
+\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_rngsystem_initialize (int full)
+{
+  basic_initialization ();
+  if (!full)
+    return;
+  /* Nothing more to initialize.  */
+  return;
+}
+
+
+/* Try to close the FDs of the random gather module.  This is
+   currently only implemented for rndlinux. */
+void
+_gcry_rngsystem_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_rngsystem_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_rngsystem_is_faked (void)
+{
+  return 0;  /* Faked random is not supported.  */
+}
+
+
+/* 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_rngsystem_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_rngsystem_randomize (void *buffer, size_t length,
+                           enum gcry_random_level level)
+{
+  _gcry_rngsystem_initialize (1);  /* Auto-initialize if needed.  */
+
+  if (level != GCRY_VERY_STRONG_RANDOM)
+    level = GCRY_STRONG_RANDOM;
+
+  lock_rng ();
+  get_random (buffer, length, level);
+  unlock_rng ();
+}
index 40661ab..ff9d6d2 100644 (file)
@@ -1,5 +1,5 @@
 /* random.c - Random number switch
- * Copyright (C) 2008  Free Software Foundation, Inc.
+ * Copyright (C) 2003, 2006, 2008, 2012  Free Software Foundation, Inc.
  *
  * This file is part of Libgcrypt.
  *
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <time.h>
+#include <sys/types.h>
+#include <unistd.h>
 
 #include "g10lib.h"
 #include "random.h"
 #include "rand-internal.h"
+#include "cipher.h"         /* For _gcry_sha1_hash_buffer().  */
 #include "ath.h"
 
 
 static void (*progress_cb) (void *,const char*,int,int, int );
 static void *progress_cb_data;
 
+/* Flags indicating the requested RNG types.  */
+static struct
+{
+  int standard;
+  int fips;
+  int system;
+} rng_types;
+
+
+/* This is the lock we use to protect the buffer used by the nonce
+   generation.  */
+static ath_mutex_t nonce_buffer_lock;
 
 
 \f
@@ -66,6 +82,55 @@ _gcry_random_progress (const char *what, int printchar, int current, int total)
 }
 
 
+/* Set the preferred RNG type.  This may be called at any time even
+   before gcry_check_version.  Thus we can't assume any thread system
+   initialization.  A type of 0 is used to indicate that any Libgcrypt
+   initialization has been done.*/
+void
+_gcry_set_preferred_rng_type (int type)
+{
+  static int any_init;
+
+  if (!type)
+    {
+      any_init = 1;
+    }
+  else if (type == GCRY_RNG_TYPE_STANDARD)
+    {
+      rng_types.standard = 1;
+    }
+  else if (any_init)
+    {
+      /* After any initialization has been done we only allow to
+         upgrade to the standard RNG (handled above).  All other
+         requests are ignored.  The idea is that the application needs
+         to declare a preference for a weaker RNG as soon as possible
+         and before any library sets a preference.  We assume that a
+         library which uses Libgcrypt calls an init function very
+         early.  This way --- even if the library gets initialized
+         early by the application --- it is unlikely that it can
+         select a lower priority RNG.
+
+         This scheme helps to ensure that existing unmodified
+         applications (e.g. gpg2), which don't known about the new RNG
+         selection system, will continue to use the standard RNG and
+         not be tricked by some library to use a lower priority RNG.
+         There are some loopholes here but at least most GnuPG stuff
+         should be save because it calls src_c{gcry_control
+         (GCRYCTL_SUSPEND_SECMEM_WARN);} quite early and thus inhibits
+         switching to a low priority RNG.
+       */
+    }
+  else if (type == GCRY_RNG_TYPE_FIPS)
+    {
+      rng_types.fips = 1;
+    }
+  else if (type == GCRY_RNG_TYPE_SYSTEM)
+    {
+      rng_types.system = 1;
+    }
+}
+
 
 /* Initialize this random subsystem.  If FULL is false, this function
    merely calls the basic initialization of the module and does not do
@@ -75,13 +140,74 @@ _gcry_random_progress (const char *what, int printchar, int current, int total)
 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);
+  else if (rng_types.standard)
+    _gcry_rngcsprng_initialize (full);
+  else if (rng_types.fips)
+    _gcry_rngfips_initialize (full);
+  else if (rng_types.system)
+    _gcry_rngsystem_initialize (full);
   else
     _gcry_rngcsprng_initialize (full);
 }
 
 
+/* If possible close file descriptors used by the RNG. */
+void
+_gcry_random_close_fds (void)
+{
+  /* Note that we can't do that directly because each random system
+     has its own lock functions which need to be used for accessing
+     the entropy gatherer.  */
+
+  if (fips_mode ())
+    _gcry_rngfips_close_fds ();
+  else if (rng_types.standard)
+    _gcry_rngcsprng_close_fds ();
+  else if (rng_types.fips)
+    _gcry_rngfips_close_fds ();
+  else if (rng_types.system)
+    _gcry_rngsystem_close_fds ();
+  else
+    _gcry_rngcsprng_close_fds ();
+}
+
+
+/* Return the current RNG type.  IGNORE_FIPS_MODE is a flag used to
+   skip the test for FIPS.  This is useful, so that we are able to
+   return the type of the RNG even before we have setup FIPS mode
+   (note that FIPS mode is enabled by default until it is switched off
+   by the initialization).  This is mostly useful for the regression
+   test.  */
+int
+_gcry_get_rng_type (int ignore_fips_mode)
+{
+  if (!ignore_fips_mode && fips_mode ())
+    return GCRY_RNG_TYPE_FIPS;
+  else if (rng_types.standard)
+    return GCRY_RNG_TYPE_STANDARD;
+  else if (rng_types.fips)
+    return GCRY_RNG_TYPE_FIPS;
+  else if (rng_types.system)
+    return GCRY_RNG_TYPE_SYSTEM;
+  else
+    return GCRY_RNG_TYPE_STANDARD;
+}
+
+
 void
 _gcry_random_dump_stats (void)
 {
@@ -154,13 +280,19 @@ _gcry_random_is_faked (void)
 /* 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_random_add_bytes (const void *buf, size_t buflen, int quality)
+gcry_err_code_t
+_gcry_random_add_bytes (const void *buf, size_t buflen, int quality)
 {
   if (fips_mode ())
     return 0; /* No need for this in fips mode.  */
-  else
-    return _gcry_rngcsprng_add_bytes (buf, buflen, quality);
+  else if (rng_types.standard)
+    return gpg_err_code (_gcry_rngcsprng_add_bytes (buf, buflen, quality));
+  else if (rng_types.fips)
+    return 0;
+  else if (rng_types.system)
+    return 0;
+  else /* default */
+    return gpg_err_code (_gcry_rngcsprng_add_bytes (buf, buflen, quality));
 }
 
 
@@ -170,7 +302,13 @@ do_randomize (void *buffer, size_t length, enum gcry_random_level level)
 {
   if (fips_mode ())
     _gcry_rngfips_randomize (buffer, length, level);
-  else
+  else if (rng_types.standard)
+    _gcry_rngcsprng_randomize (buffer, length, level);
+  else if (rng_types.fips)
+    _gcry_rngfips_randomize (buffer, length, level);
+  else if (rng_types.system)
+    _gcry_rngsystem_randomize (buffer, length, level);
+  else /* default */
     _gcry_rngcsprng_randomize (buffer, length, level);
 }
 
@@ -178,11 +316,11 @@ do_randomize (void *buffer, size_t length, enum gcry_random_level level)
    Returns a pointer to a newly allocated and randomized buffer of
    LEVEL and NBYTES length.  Caller must free the buffer.  */
 void *
-gcry_random_bytes (size_t nbytes, enum gcry_random_level level)
+_gcry_random_bytes (size_t nbytes, enum gcry_random_level level)
 {
   void *buffer;
 
-  buffer = gcry_xmalloc (nbytes);
+  buffer = xmalloc (nbytes);
   do_randomize (buffer, nbytes, level);
   return buffer;
 }
@@ -192,14 +330,14 @@ gcry_random_bytes (size_t nbytes, enum gcry_random_level level)
    this version of the function returns the random in a buffer allocated
    in secure memory.  Caller must free the buffer. */
 void *
-gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level)
+_gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level)
 {
   void *buffer;
 
   /* Historical note (1.3.0--1.4.1): The buffer was only allocated
      in secure memory if the pool in random-csprng.c was also set to
      use secure memory.  */
-  buffer = gcry_xmalloc_secure (nbytes);
+  buffer = xmalloc_secure (nbytes);
   do_randomize (buffer, nbytes, level);
   return buffer;
 }
@@ -211,7 +349,7 @@ gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level)
    usage, GCRY_VERY_STRONG_RANDOM is good for key generation stuff but
    may be very slow.  */
 void
-gcry_randomize (void *buffer, size_t length, enum gcry_random_level level)
+_gcry_randomize (void *buffer, size_t length, enum gcry_random_level level)
 {
   do_randomize (buffer, length, level);
 }
@@ -225,7 +363,13 @@ _gcry_set_random_seed_file (const char *name)
 {
   if (fips_mode ())
     ; /* No need for this in fips mode.  */
-  else
+  else if (rng_types.standard)
+    _gcry_rngcsprng_set_seed_file (name);
+  else if (rng_types.fips)
+    ;
+  else if (rng_types.system)
+    ;
+  else /* default */
     _gcry_rngcsprng_set_seed_file (name);
 }
 
@@ -237,7 +381,13 @@ _gcry_update_random_seed_file (void)
 {
   if (fips_mode ())
     ; /* No need for this in fips mode.  */
-  else
+  else if (rng_types.standard)
+    _gcry_rngcsprng_update_seed_file ();
+  else if (rng_types.fips)
+    ;
+  else if (rng_types.system)
+    ;
+  else /* default */
     _gcry_rngcsprng_update_seed_file ();
 }
 
@@ -255,7 +405,13 @@ _gcry_fast_random_poll (void)
 {
   if (fips_mode ())
     ; /* No need for this in fips mode.  */
-  else
+  else if (rng_types.standard)
+    _gcry_rngcsprng_fast_poll ();
+  else if (rng_types.fips)
+    ;
+  else if (rng_types.system)
+    ;
+  else /* default */
     _gcry_rngcsprng_fast_poll ();
 }
 
@@ -263,12 +419,92 @@ _gcry_fast_random_poll (void)
 
 /* Create an unpredicable nonce of LENGTH bytes in BUFFER. */
 void
-gcry_create_nonce (void *buffer, size_t length)
+_gcry_create_nonce (void *buffer, size_t length)
 {
+  static unsigned char nonce_buffer[20+8];
+  static int nonce_buffer_initialized = 0;
+  static volatile pid_t my_pid; /* The volatile is there to make sure the
+                                   compiler does not optimize the code away
+                                   in case the getpid function is badly
+                                   attributed. */
+  volatile pid_t apid;
+  unsigned char *p;
+  size_t n;
+  int err;
+
+  /* First check whether we shall use the FIPS nonce generator.  This
+     is only done in FIPS mode, in all other modes, we use our own
+     nonce generator which is seeded by the RNG actual in use.  */
   if (fips_mode ())
-    _gcry_rngfips_create_nonce (buffer, length);
-  else
-    _gcry_rngcsprng_create_nonce (buffer, length);
+    {
+      _gcry_rngfips_create_nonce (buffer, length);
+      return;
+    }
+
+  /* This is the nonce generator, which formerly lived in
+     random-csprng.c.  It is now used by all RNG types except when in
+     FIPS mode (not that this means it is also used if the FIPS RNG
+     has been selected but we are not in fips mode).  */
+
+  /* Make sure we are initialized. */
+  _gcry_random_initialize (1);
+
+  /* Acquire the nonce buffer lock. */
+  err = ath_mutex_lock (&nonce_buffer_lock);
+  if (err)
+    log_fatal ("failed to acquire the nonce buffer lock: %s\n",
+               strerror (err));
+
+  apid = getpid ();
+  /* The first time initialize our buffer. */
+  if (!nonce_buffer_initialized)
+    {
+      time_t atime = time (NULL);
+      pid_t xpid = apid;
+
+      my_pid = apid;
+
+      if ((sizeof apid + sizeof atime) > sizeof nonce_buffer)
+        BUG ();
+
+      /* Initialize the first 20 bytes with a reasonable value so that
+         a failure of gcry_randomize won't affect us too much.  Don't
+         care about the uninitialized remaining bytes. */
+      p = nonce_buffer;
+      memcpy (p, &xpid, sizeof xpid);
+      p += sizeof xpid;
+      memcpy (p, &atime, sizeof atime);
+
+      /* Initialize the never changing private part of 64 bits. */
+      _gcry_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM);
+
+      nonce_buffer_initialized = 1;
+    }
+  else if ( my_pid != apid )
+    {
+      /* We forked. Need to reseed the buffer - doing this for the
+         private part should be sufficient. */
+      do_randomize (nonce_buffer+20, 8, GCRY_WEAK_RANDOM);
+      /* Update the pid so that we won't run into here again and
+         again. */
+      my_pid = apid;
+    }
+
+  /* Create the nonce by hashing the entire buffer, returning the hash
+     and updating the first 20 bytes of the buffer with this hash. */
+  for (p = buffer; length > 0; length -= n, p += n)
+    {
+      _gcry_sha1_hash_buffer (nonce_buffer,
+                              nonce_buffer, sizeof nonce_buffer);
+      n = length > 20? 20 : length;
+      memcpy (p, nonce_buffer, n);
+    }
+
+  /* Release the nonce buffer lock. */
+  err = ath_mutex_unlock (&nonce_buffer_lock);
+  if (err)
+    log_fatal ("failed to release the nonce buffer lock: %s\n",
+               strerror (err));
 }
 
 
index 7a9585c..2bc8cab 100644 (file)
 void _gcry_register_random_progress (void (*cb)(void *,const char*,int,int,int),
                                      void *cb_data );
 
+void _gcry_set_preferred_rng_type (int type);
 void _gcry_random_initialize (int full);
+void _gcry_random_close_fds (void);
+int  _gcry_get_rng_type (int ignore_fips_mode);
 void _gcry_random_dump_stats(void);
 void _gcry_secure_random_alloc(void);
 void _gcry_enable_quick_random_gen (void);
@@ -61,8 +64,6 @@ void _gcry_daemon_initialize_basics (void);
 int _gcry_daemon_randomize (const char *socketname,
                             void *buffer, size_t length,
                             enum gcry_random_level level);
-int _gcry_daemon_create_nonce (const char *socketname,
-                               void *buffer, size_t length);
 #endif /*USE_RANDOM_DAEMON*/
 
 #endif /*G10_RANDOM_H*/
index 464edf3..d43fcbc 100644 (file)
@@ -129,10 +129,10 @@ _gcry_rndegd_set_socket_name (const char *name)
   newname = my_make_filename (name, NULL);
   if (strlen (newname)+1 >= sizeof addr.sun_path)
     {
-      gcry_free (newname);
+      xfree (newname);
       return gpg_error_from_syserror ();
     }
-  gcry_free (user_socket_name);
+  xfree (user_socket_name);
   user_socket_name = newname;
   return 0;
 }
@@ -195,7 +195,7 @@ _gcry_rndegd_connect_socket (int nofail)
       close (fd);
       fd = -1;
     }
-  gcry_free(name);
+  xfree (name);
   if (fd != -1)
     egd_socket = fd;
   return fd;
index 82faab4..e625512 100644 (file)
@@ -1,5 +1,6 @@
 /* rndhw.c  - Access to the external random daemon
  * Copyright (C) 2007  Free Software Foundation, Inc.
+ * Copyright (C) 2012  Dmitry Kasatkin
  *
  * This file is part of Libgcrypt.
  *
 
 #undef USE_PADLOCK
 #ifdef ENABLE_PADLOCK_SUPPORT
-# if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__)
-# define USE_PADLOCK
+# 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*/
 
+#undef USE_DRNG
+#ifdef ENABLE_DRNG_SUPPORT
+# ifdef HAVE_GCC_ATTRIBUTE_ALIGNED
+#  if (defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4) || defined(__x86_64__)
+#   define USE_DRNG 1
+#  endif
+# endif
+#endif /*ENABLE_RDRAND_SUPPORT*/
+
+typedef void (*add_fn_t)(const void*, size_t, enum random_origins);
+
 /* Keep track on whether the RNG has problems.  */
 static volatile int rng_failed;
 
@@ -55,6 +69,16 @@ poll_padlock (void (*add)(const void*, size_t, enum random_origins),
   nbytes = 0;
   while (nbytes < 64)
     {
+#if defined(__x86_64__) && defined(__LP64__)
+      asm volatile
+        ("movq %1, %%rdi\n\t"         /* Set buffer.  */
+         "xorq %%rdx, %%rdx\n\t"      /* Request up to 8 bytes.  */
+         ".byte 0x0f, 0xa7, 0xc0\n\t" /* XSTORE RNG. */
+         : "=a" (status)
+         : "g" (p)
+         : "%rdx", "%rdi", "cc"
+         );
+#else
       asm volatile
         ("movl %1, %%edi\n\t"         /* Set buffer.  */
          "xorl %%edx, %%edx\n\t"      /* Request up to 8 bytes.  */
@@ -63,6 +87,7 @@ poll_padlock (void (*add)(const void*, size_t, enum random_origins),
          : "g" (p)
          : "%edx", "%edi", "cc"
          );
+#endif
       if ((status & (1<<6))         /* RNG still enabled.  */
           && !(status & (1<<13))    /* von Neumann corrector is enabled.  */
           && !(status & (1<<14))    /* String filter is disabled.  */
@@ -95,6 +120,56 @@ poll_padlock (void (*add)(const void*, size_t, enum random_origins),
 #endif /*USE_PADLOCK*/
 
 
+#ifdef USE_DRNG
+# define RDRAND_RETRY_LOOPS    10
+# define RDRAND_INT    ".byte 0x0f,0xc7,0xf0"
+# if defined(__x86_64__) && defined(__LP64__)
+#  define RDRAND_LONG  ".byte 0x48,0x0f,0xc7,0xf0"
+# else
+#  define RDRAND_LONG  RDRAND_INT
+# endif
+static inline int
+rdrand_long (unsigned long *v)
+{
+  int ok;
+  asm volatile ("1: " RDRAND_LONG "\n\t"
+                "jc 2f\n\t"
+                "decl %0\n\t"
+                "jnz 1b\n\t"
+                "2:"
+                : "=r" (ok), "=a" (*v)
+                : "0" (RDRAND_RETRY_LOOPS)
+                : "cc");
+  return ok;
+}
+
+
+static inline int
+rdrand_nlong (unsigned long *v, int count)
+{
+  while (count--)
+    if (!rdrand_long(v++))
+      return 0;
+  return 1;
+}
+
+
+static size_t
+poll_drng (add_fn_t add, enum random_origins origin, int fast)
+{
+  volatile char buffer[64] __attribute__ ((aligned (8)));
+  unsigned int nbytes = sizeof (buffer);
+
+  (void)fast;
+
+  if (!rdrand_nlong ((unsigned long *)buffer, sizeof(buffer)/sizeof(long)))
+    return 0;
+  (*add)((void *)buffer, nbytes, origin);
+  return nbytes;
+}
+#endif /*USE_DRNG*/
+
+
 int
 _gcry_rndhw_failed_p (void)
 {
@@ -111,6 +186,10 @@ _gcry_rndhw_poll_fast (void (*add)(const void*, size_t, enum random_origins),
   (void)add;
   (void)origin;
 
+#ifdef USE_DRNG
+  if ((_gcry_get_hw_features () & HWF_INTEL_RDRAND))
+    poll_drng (add, origin, 1);
+#endif
 #ifdef USE_PADLOCK
   if ((_gcry_get_hw_features () & HWF_PADLOCK_RNG))
     poll_padlock (add, origin, 1);
@@ -129,6 +208,10 @@ _gcry_rndhw_poll_slow (void (*add)(const void*, size_t, enum random_origins),
   (void)add;
   (void)origin;
 
+#ifdef USE_DRNG
+  if ((_gcry_get_hw_features () & HWF_INTEL_RDRAND))
+    nbytes += poll_drng (add, origin, 0);
+#endif
 #ifdef USE_PADLOCK
   if ((_gcry_get_hw_features () & HWF_PADLOCK_RNG))
     nbytes += poll_padlock (add, origin, 0);
index 5b84a19..89ac203 100644 (file)
@@ -36,7 +36,7 @@
 #include "g10lib.h"
 #include "rand-internal.h"
 
-static int open_device ( const char *name );
+static int open_device (const char *name, int retry);
 
 
 static int
@@ -54,15 +54,30 @@ set_cloexec_flag (int fd)
 
 
 /*
- * Used to open the /dev/random devices (Linux, xBSD, Solaris (if it exists)).
+ * Used to open the /dev/random devices (Linux, xBSD, Solaris (if it
+ * exists)).  If RETRY is true, the function does not terminate with
+ * a fatal error but retries until it is able to reopen the device.
  */
 static int
-open_device ( const char *name )
+open_device (const char *name, int retry)
 {
   int fd;
 
-  fd = open ( name, O_RDONLY );
-  if ( fd == -1 )
+  if (retry)
+    _gcry_random_progress ("open_dev_random", 'X', 1, 0);
+ again:
+  fd = open (name, O_RDONLY);
+  if (fd == -1 && retry)
+    {
+      struct timeval tv;
+
+      tv.tv_sec = 5;
+      tv.tv_usec = 0;
+      _gcry_random_progress ("wait_dev_random", 'X', 0, (int)tv.tv_sec);
+      select (0, NULL, NULL, NULL, &tv);
+      goto again;
+    }
+  if (fd == -1)
     log_fatal ("can't open %s: %s\n", name, strerror(errno) );
 
   if (set_cloexec_flag (fd))
@@ -84,6 +99,10 @@ open_device ( const char *name )
 }
 
 
+/* Note that the caller needs to make sure that this function is only
+   called by one thread at a time.  The function returns 0 on success
+   or true on failure (in which case the caller will signal a fatal
+   error).  */
 int
 _gcry_rndlinux_gather_random (void (*add)(const void*, size_t,
                                           enum random_origins),
@@ -92,6 +111,7 @@ _gcry_rndlinux_gather_random (void (*add)(const void*, size_t,
 {
   static int fd_urandom = -1;
   static int fd_random = -1;
+  static unsigned char ever_opened;
   int fd;
   int n;
   byte buffer[768];
@@ -101,6 +121,23 @@ _gcry_rndlinux_gather_random (void (*add)(const void*, size_t,
   int any_need_entropy = 0;
   int delay;
 
+  if (!add)
+    {
+      /* Special mode to close the descriptors.  */
+      if (fd_random != -1)
+        {
+          close (fd_random);
+          fd_random = -1;
+        }
+      if (fd_urandom != -1)
+        {
+          close (fd_urandom);
+          fd_urandom = -1;
+        }
+      return 0;
+    }
+
+
   /* First read from a hardware source.  However let it account only
      for up to 50% of the requested bytes.  */
   n_hw = _gcry_rndhw_poll_slow (add, origin);
@@ -109,17 +146,29 @@ _gcry_rndlinux_gather_random (void (*add)(const void*, size_t,
   if (length > 1)
     length -= n_hw;
 
-  /* Open the requested device.  */
+  /* Open the requested device.  The first time a device is to be
+     opened we fail with a fatal error if the device does not exists.
+     In case the device has ever been closed, further open requests
+     will however retry indefinitely.  The rationale for this behaviour is
+     that we always require the device to be existent but want a more
+     graceful behaviour if the rarely needed close operation has been
+     used and the device needs to be re-opened later. */
   if (level >= 2)
     {
-      if( fd_random == -1 )
-        fd_random = open_device ( NAME_OF_DEV_RANDOM );
+      if (fd_random == -1)
+        {
+          fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1));
+          ever_opened |= 1;
+        }
       fd = fd_random;
     }
   else
     {
-      if( fd_urandom == -1 )
-        fd_urandom = open_device ( NAME_OF_DEV_URANDOM );
+      if (fd_urandom == -1)
+        {
+          fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2));
+          ever_opened |= 2;
+        }
       fd = fd_urandom;
     }
 
@@ -134,29 +183,45 @@ _gcry_rndlinux_gather_random (void (*add)(const void*, size_t,
       struct timeval tv;
       int rc;
 
-      FD_ZERO(&rfds);
-      FD_SET(fd, &rfds);
-      tv.tv_sec = delay;
-      tv.tv_usec = delay? 0 : 100000;
-      if ( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) )
+      /* If we collected some bytes update the progress indicator.  We
+         do this always and not just if the select timed out because
+         often just a few bytes are gathered within the timeout
+         period.  */
+      if (any_need_entropy || last_so_far != (want - length) )
+        {
+          last_so_far = want - length;
+          _gcry_random_progress ("need_entropy", 'X',
+                                 (int)last_so_far, (int)want);
+          any_need_entropy = 1;
+        }
+
+      /* If the system has no limit on the number of file descriptors
+         and we encounter an fd which is larger than the fd_set size,
+         we don't use the select at all.  The select code is only used
+         to emit progress messages.  A better solution would be to
+         fall back to poll() if available.  */
+#ifdef FD_SETSIZE
+      if (fd < FD_SETSIZE)
+#endif
         {
-          if (!any_need_entropy || last_so_far != (want - length) )
+          FD_ZERO(&rfds);
+          FD_SET(fd, &rfds);
+          tv.tv_sec = delay;
+          tv.tv_usec = delay? 0 : 100000;
+          if ( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) )
             {
-              last_so_far = want - length;
-              _gcry_random_progress ("need_entropy", 'X',
-                                     (int)last_so_far, (int)want);
               any_need_entropy = 1;
-           }
-          delay = 3; /* Use 3 seconds henceforth.  */
-         continue;
-       }
-      else if( rc == -1 )
-        {
-          log_error ("select() error: %s\n", strerror(errno));
-          if (!delay)
-            delay = 1; /* Use 1 second if we encounter an error before
-                          we have ever blocked.  */
-          continue;
+              delay = 3; /* Use 3 seconds henceforth.  */
+              continue;
+            }
+          else if( rc == -1 )
+            {
+              log_error ("select() error: %s\n", strerror(errno));
+              if (!delay)
+                delay = 1; /* Use 1 second if we encounter an error before
+                              we have ever blocked.  */
+              continue;
+            }
         }
 
       do
index cc5eb14..1b810d7 100644 (file)
@@ -551,7 +551,8 @@ slow_poll(FILE *dbgfp, int dbgall, size_t *nbytes )
 #else
 #error O_NONBLOCK is missing
 #endif
-
+            /* FIXME: We need to make sure that the fd is less than
+               FD_SETSIZE.  */
            FD_SET(dataSources[i].pipeFD, &fds);
            dataSources[i].length = 0;
 
index f8a83b6..c495131 100644 (file)
@@ -78,6 +78,7 @@
 #include <stdint.h>
 #endif
 
+#include <winsock2.h>
 #include <windows.h>
 
 
@@ -430,7 +431,7 @@ registry_poll (void (*add)(const void*, size_t, enum random_origins),
     }
   else
     {
-      pPerfData = gcry_xmalloc (cbPerfData);
+      pPerfData = xmalloc (cbPerfData);
       for (iterations=0; iterations < 10; iterations++)
         {
           dwSize = cbPerfData;
@@ -450,7 +451,7 @@ registry_poll (void (*add)(const void*, size_t, enum random_origins),
           else if (status == ERROR_MORE_DATA)
             {
               cbPerfData += PERFORMANCE_BUFFER_STEP;
-              pPerfData = gcry_xrealloc (pPerfData, cbPerfData);
+              pPerfData = xrealloc (pPerfData, cbPerfData);
             }
           else
             {
@@ -468,7 +469,7 @@ registry_poll (void (*add)(const void*, size_t, enum random_origins),
               break;
             }
         }
-      gcry_free (pPerfData);
+      xfree (pPerfData);
     }
 
   /* Although this isn't documented in the Win32 API docs, it's necessary
@@ -654,7 +655,7 @@ slow_gatherer ( void (*add)(const void*, size_t, enum random_origins),
      This scan typically yields around 20 pieces of data, there's nothing
      in the range 65...128 so chances are there won't be anything above
      there either.  */
-  buffer = gcry_xmalloc (PERFORMANCE_BUFFER_SIZE);
+  buffer = xmalloc (PERFORMANCE_BUFFER_SIZE);
   for (dwType = 0; dwType < 64; dwType++)
     {
       switch (dwType)
@@ -758,7 +759,7 @@ slow_gatherer ( void (*add)(const void*, size_t, enum random_origins),
         }
       gcry_assert (i < 100);
     }
-  gcry_free (buffer);
+  xfree (buffer);
 
   /* We couldn't get enough results from the kernel, fall back to the
      somewhat troublesome registry poll.  */
similarity index 96%
rename from src/ChangeLog
rename to src/ChangeLog-2011
index 8506532..3571fb1 100644 (file)
@@ -1,3 +1,73 @@
+2011-12-01  Werner Koch  <wk@g10code.com>
+
+       NB: ChangeLog files are no longer manually maintained.  Starting
+       on December 1st, 2011 we put change information only in the GIT
+       commit log, and generate a top-level ChangeLog file from logs at
+       "make dist".  See doc/HACKING for details.
+
+2011-09-16  Werner Koch  <wk@g10code.com>
+
+       Change ATH code and turn the thread initialization callbacks in
+       the API into dummy functions.
+
+       * global.c (global_init): Call _gcry_pimegen_init.
+
+       * gcrypt.h.in (GCRY_THREAD_OPTI ON_VERSION): Bump to 1.
+       (GCRY_THREAD_OPTION_PTH_IMPL): Simplify.
+       (GCRY_THREAD_OPTION_PTHREAD_IMPL): Simplify.
+
+       * ath.c (ath_read, ath_write): Remove.  They are only used in the
+       optional random-daemon.
+       (ath_select, ath_waitpid, ath_accept, ath_connect, ath_sendmsg)
+       (ath_recvmsg): Remove.  They are not used.
+       * ath.h: Remove prototypes and corresponding structure fields.
+
+2011-03-11  Werner Koch  <wk@g10code.com>
+
+       * ath.c (mutex_init): Rename second arg to FORCE and invert
+       logic.  Change all callers.
+
+2011-09-15  Werner Koch  <wk@g10code.com>
+
+       * gcrypt.h.in (enum gcry_thread_option): Remove deprecated enum.
+       (gcry_md_start_debug, gcry_md_stop_debug): Remove deprecated these
+       macros.
+
+2011-09-15  Werner Koch  <wk@g10code.com>
+
+       Removal of the gcry_ac and the module register interfaces.
+
+       * Makefile.am (include_HEADERS): Remove gcrypt-module.h.
+       (libgcrypt_la_SOURCES): Add gcrypt-module.h which is now internal
+       header.
+       * gcrypt-module.h (gcry_md_register, gcry_md_unregister): Remove.
+       (gcry_pk_register, gcry_pk_unregister): Remove.
+       (gcry_cipher_register, gcry_cipher_unregister): Remove.
+       * visibility.h: Include gcrypt-module.h.
+       * gcrypt.h.in: Do not include gcrypt-module.h.
+       * gcrypt.h.in: Remove all gcry_ac symbols.
+       (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
+       * visibility.h: Remove all gcry_ac symbols.
+       (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
+       (gcry_cipher_register, gcry_cipher_unregister, gcry_pk_register)
+       (gcry_pk_unregister, gcry_md_register, gcry_md_unregister): Remove.
+       * visibility.c: Remove all gcry_ac wrappers.
+       (gcry_pk_list, gcry_cipher_list, gcry_md_list): Remove.
+       (gcry_cipher_register, gcry_cipher_unregister, gcry_pk_register)
+       (gcry_pk_unregister, gcry_md_register, gcry_md_unregister): Remove.
+       * libgcrypt.vers: Remove all gcry_ac symbols.
+       (GCRYPT_1.2): Rename to GCRYPT_1.6.
+       (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
+       * libgcrypt.def: Remove all gcry_ac symbols.
+       (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
+       * global.c (global_init): Remove comment code with a call to
+       _gcry_ac_init.
+
+2011-09-15  Werner Koch  <wk@g10code.com>
+
+       * hmac256.c (main): Fix endless loop when using pipe input and
+       option --binary.
+
 2011-06-10  Werner Koch  <wk@g10code.com>
 
        * sexp.c (vsexp_sscan): Add new format specifiers 'M' and 'u'.
 
        * types.h: Moved from ../include to here.
 
-       Major change:
+       Major change:
        Removed all GnuPG stuff and renamed this piece of software
        to gcrypt.
 
@@ -2322,3 +2392,7 @@ Tue Dec  8 13:15:16 CET 1998  Werner Koch  <wk@isil.d.shuttle.de>
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
index 9168022..2d4800f 100644 (file)
@@ -26,10 +26,10 @@ EXTRA_DIST = Manifest libgcrypt-config.in libgcrypt.m4 libgcrypt.vers \
 bin_SCRIPTS = libgcrypt-config
 m4datadir = $(datadir)/aclocal
 m4data_DATA = libgcrypt.m4
-include_HEADERS = gcrypt.h gcrypt-module.h
+include_HEADERS = gcrypt.h
 
 lib_LTLIBRARIES = libgcrypt.la
-bin_PROGRAMS = dumpsexp hmac256
+bin_PROGRAMS = dumpsexp hmac256 mpicalc
 if USE_RANDOM_DAEMON
 sbin_PROGRAMS = gcryptrnd
 bin_PROGRAMS += getrandom
@@ -44,6 +44,8 @@ arch_gpg_error_cflags =
 arch_gpg_error_libs   =
 endif
 
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+AM_CCASFLAGS = $(NOEXECSTACK_FLAGS)
 
 if HAVE_LD_VERSION_SCRIPT
   libgcrypt_version_script_cmd = -Wl,--version-script=$(srcdir)/libgcrypt.vers
@@ -52,14 +54,20 @@ else
 endif
 
 libgcrypt_la_CFLAGS = $(GPG_ERROR_CFLAGS)
-libgcrypt_la_SOURCES = g10lib.h visibility.c visibility.h types.h \
+libgcrypt_la_SOURCES = \
+        gcrypt-int.h g10lib.h visibility.c visibility.h types.h \
        cipher.h cipher-proto.h \
-       misc.c global.c sexp.c hwfeatures.c \
+       misc.c global.c sexp.c hwfeatures.c hwf-common.h \
        stdmem.c stdmem.h secmem.c secmem.h \
-       mpi.h missing-string.c module.c fips.c \
-       hmac256.c hmac256.h \
+       mpi.h missing-string.c fips.c \
+       hmac256.c hmac256.h context.c context.h \
+       ec-context.h \
        ath.h ath.c
 
+EXTRA_libgcrypt_la_SOURCES = hwf-x86.c hwf-arm.c
+gcrypt_hwf_modules = @GCRYPT_HWF_MODULES@
+
+
 if HAVE_W32_SYSTEM
 
 RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
@@ -76,6 +84,7 @@ no_undefined = -no-undefined
 export_symbols = -export-symbols $(srcdir)/libgcrypt.def
 
 install-def-file:
+       -$(INSTALL) -d $(DESTDIR)$(libdir)
        $(INSTALL) $(srcdir)/libgcrypt.def $(DESTDIR)$(libdir)/libgcrypt.def
 
 uninstall-def-file:
@@ -101,12 +110,14 @@ libgcrypt_la_LDFLAGS = $(no_undefined) $(export_symbols) \
        $(libgcrypt_version_script_cmd) -version-info \
        @LIBGCRYPT_LT_CURRENT@:@LIBGCRYPT_LT_REVISION@:@LIBGCRYPT_LT_AGE@
 libgcrypt_la_DEPENDENCIES = \
+         $(gcrypt_hwf_modules) \
        ../cipher/libcipher.la \
        ../random/librandom.la \
        ../mpi/libmpi.la \
        ../compat/libcompat.la \
        $(srcdir)/libgcrypt.vers $(gcrypt_deps)
 libgcrypt_la_LIBADD = $(gcrypt_res) \
+        $(gcrypt_hwf_modules) \
        ../cipher/libcipher.la \
        ../random/librandom.la \
        ../mpi/libmpi.la \
@@ -115,16 +126,20 @@ libgcrypt_la_LIBADD = $(gcrypt_res) \
 
 dumpsexp_SOURCES = dumpsexp.c
 dumpsexp_CFLAGS = $(arch_gpg_error_cflags)
-dumpsexp_LDADD = $(arch_gpg_error_libs)
+dumpsexp_LDADD = $(arch_gpg_error_libs) $(LIBTHREAD)
+
+mpicalc_SOURCES = mpicalc.c
+mpicalc_CFLAGS = $(GPG_ERROR_CFLAGS)
+mpicalc_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(LIBTHREAD)
 
 hmac256_SOURCES = hmac256.c
 hmac256_CFLAGS = -DSTANDALONE $(arch_gpg_error_cflags)
-hmac256_LDADD = $(arch_gpg_error_libs)
+hmac256_LDADD = $(arch_gpg_error_libs) $(LIBTHREAD)
 
 if USE_RANDOM_DAEMON
 gcryptrnd_SOURCES = gcryptrnd.c
 gcryptrnd_CFLAGS = $(GPG_ERROR_CFLAGS) $(PTH_CFLAGS)
-gcryptrnd_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(PTH_LIBS)
+gcryptrnd_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(PTH_LIBS) $(LIBTHREAD)
 
 getrandom_SOURCES = getrandom.c
 endif USE_RANDOM_DAEMON
index 4fb04bc..24ad6b4 100644 (file)
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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; \
+    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;; \
+    esac; \
+    test $$am__dry = yes; \
+  }
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -57,25 +74,26 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-bin_PROGRAMS = dumpsexp$(EXEEXT) hmac256$(EXEEXT) $(am__EXEEXT_1)
+bin_PROGRAMS = dumpsexp$(EXEEXT) hmac256$(EXEEXT) mpicalc$(EXEEXT) \
+       $(am__EXEEXT_1)
 @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 \
-       ChangeLog
+       $(srcdir)/libgcrypt-config.in $(srcdir)/versioninfo.rc.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.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/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/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
        $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
-       $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+       $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/acinclude.m4 \
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
 CONFIG_CLEAN_FILES = gcrypt.h libgcrypt-config versioninfo.rc
 CONFIG_CLEAN_VPATH_FILES =
@@ -100,6 +118,12 @@ am__nobase_list = $(am__nobase_strip_setup); \
 am__base_list = \
   sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
   sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
+am__uninstall_files_from_dir = { \
+  test -z "$$files" \
+    || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
+    || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
+         $(am__cd) "$$dir" && rm -f $$files; }; \
+  }
 am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
        "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(bindir)" \
        "$(DESTDIR)$(m4datadir)" "$(DESTDIR)$(includedir)"
@@ -110,11 +134,14 @@ am_libgcrypt_la_OBJECTS = libgcrypt_la-visibility.lo \
        libgcrypt_la-misc.lo libgcrypt_la-global.lo \
        libgcrypt_la-sexp.lo libgcrypt_la-hwfeatures.lo \
        libgcrypt_la-stdmem.lo libgcrypt_la-secmem.lo \
-       libgcrypt_la-missing-string.lo libgcrypt_la-module.lo \
-       libgcrypt_la-fips.lo libgcrypt_la-hmac256.lo \
+       libgcrypt_la-missing-string.lo libgcrypt_la-fips.lo \
+       libgcrypt_la-hmac256.lo libgcrypt_la-context.lo \
        libgcrypt_la-ath.lo
 libgcrypt_la_OBJECTS = $(am_libgcrypt_la_OBJECTS)
-libgcrypt_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+AM_V_lt = $(am__v_lt_@AM_V@)
+am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
+am__v_lt_0 = --silent
+libgcrypt_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(libgcrypt_la_CFLAGS) \
        $(CFLAGS) $(libgcrypt_la_LDFLAGS) $(LDFLAGS) -o $@
 @USE_RANDOM_DAEMON_TRUE@am__EXEEXT_1 = getrandom$(EXEEXT)
@@ -122,18 +149,19 @@ 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)
-dumpsexp_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-       --mode=link $(CCLD) $(dumpsexp_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
-       $(LDFLAGS) -o $@
+dumpsexp_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2)
+dumpsexp_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+       $(LIBTOOLFLAGS) --mode=link $(CCLD) $(dumpsexp_CFLAGS) \
+       $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
 am__gcryptrnd_SOURCES_DIST = gcryptrnd.c
 @USE_RANDOM_DAEMON_TRUE@am_gcryptrnd_OBJECTS =  \
 @USE_RANDOM_DAEMON_TRUE@       gcryptrnd-gcryptrnd.$(OBJEXT)
 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) --tag=CC $(AM_LIBTOOLFLAGS) \
+gcryptrnd_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(gcryptrnd_CFLAGS) \
        $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
 am__getrandom_SOURCES_DIST = getrandom.c
@@ -142,29 +170,56 @@ getrandom_OBJECTS = $(am_getrandom_OBJECTS)
 getrandom_LDADD = $(LDADD)
 am_hmac256_OBJECTS = hmac256-hmac256.$(OBJEXT)
 hmac256_OBJECTS = $(am_hmac256_OBJECTS)
-hmac256_DEPENDENCIES = $(am__DEPENDENCIES_3)
-hmac256_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-       --mode=link $(CCLD) $(hmac256_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
-       $(LDFLAGS) -o $@
+hmac256_DEPENDENCIES = $(am__DEPENDENCIES_3) $(am__DEPENDENCIES_2)
+hmac256_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+       $(LIBTOOLFLAGS) --mode=link $(CCLD) $(hmac256_CFLAGS) \
+       $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+am_mpicalc_OBJECTS = mpicalc-mpicalc.$(OBJEXT)
+mpicalc_OBJECTS = $(am_mpicalc_OBJECTS)
+mpicalc_DEPENDENCIES = libgcrypt.la $(am__DEPENDENCIES_2) \
+       $(am__DEPENDENCIES_2)
+mpicalc_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+       $(LIBTOOLFLAGS) --mode=link $(CCLD) $(mpicalc_CFLAGS) \
+       $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
 SCRIPTS = $(bin_SCRIPTS)
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
 am__depfiles_maybe = depfiles
 am__mv = mv -f
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
-       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+       $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(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 = @
 CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
-       $(LDFLAGS) -o $@
-SOURCES = $(libgcrypt_la_SOURCES) $(dumpsexp_SOURCES) \
-       $(gcryptrnd_SOURCES) $(getrandom_SOURCES) $(hmac256_SOURCES)
-DIST_SOURCES = $(libgcrypt_la_SOURCES) $(dumpsexp_SOURCES) \
-       $(am__gcryptrnd_SOURCES_DIST) $(am__getrandom_SOURCES_DIST) \
-       $(hmac256_SOURCES)
+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   " $@;
+SOURCES = $(libgcrypt_la_SOURCES) $(EXTRA_libgcrypt_la_SOURCES) \
+       $(dumpsexp_SOURCES) $(gcryptrnd_SOURCES) $(getrandom_SOURCES) \
+       $(hmac256_SOURCES) $(mpicalc_SOURCES)
+DIST_SOURCES = $(libgcrypt_la_SOURCES) $(EXTRA_libgcrypt_la_SOURCES) \
+       $(dumpsexp_SOURCES) $(am__gcryptrnd_SOURCES_DIST) \
+       $(am__getrandom_SOURCES_DIST) $(hmac256_SOURCES) \
+       $(mpicalc_SOURCES)
+am__can_run_installinfo = \
+  case $$AM_UPDATE_INFO_DIR in \
+    n|no|NO) false;; \
+    *) (install-info --version) >/dev/null 2>&1;; \
+  esac
 DATA = $(m4data_DATA)
 HEADERS = $(include_HEADERS)
 ETAGS = etags
@@ -172,6 +227,7 @@ CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AR = @AR@
 AS = @AS@
 AUTOCONF = @AUTOCONF@
@@ -186,6 +242,7 @@ CCAS = @CCAS@
 CCASDEPMODE = @CCASDEPMODE@
 CCASFLAGS = @CCASFLAGS@
 CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
@@ -205,6 +262,8 @@ FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
 FGREP = @FGREP@
 GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
 GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_HWF_MODULES = @GCRYPT_HWF_MODULES@
+GCRYPT_KDFS = @GCRYPT_KDFS@
 GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
 GCRYPT_RANDOM = @GCRYPT_RANDOM@
 GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
@@ -230,14 +289,19 @@ 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@
 MKDIR_P = @MKDIR_P@
 MPI_SFLAGS = @MPI_SFLAGS@
 NM = @NM@
@@ -260,16 +324,19 @@ PTH_CONFIG = @PTH_CONFIG@
 PTH_LIBS = @PTH_LIBS@
 RANLIB = @RANLIB@
 RC = @RC@
+RUN_LARGE_DATA_TESTS = @RUN_LARGE_DATA_TESTS@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
 SYS_SOCKET_H = @SYS_SOCKET_H@
 VERSION = @VERSION@
+VERSION_NUMBER = @VERSION_NUMBER@
 abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
@@ -305,7 +372,6 @@ libdir = @libdir@
 libexecdir = @libexecdir@
 localedir = @localedir@
 localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 oldincludedir = @oldincludedir@
@@ -327,7 +393,7 @@ EXTRA_DIST = Manifest libgcrypt-config.in libgcrypt.m4 libgcrypt.vers \
 bin_SCRIPTS = libgcrypt-config
 m4datadir = $(datadir)/aclocal
 m4data_DATA = libgcrypt.m4
-include_HEADERS = gcrypt.h gcrypt-module.h
+include_HEADERS = gcrypt.h
 lib_LTLIBRARIES = libgcrypt.la
 @HAVE_W32CE_SYSTEM_FALSE@arch_gpg_error_cflags = 
 
@@ -335,17 +401,23 @@ lib_LTLIBRARIES = libgcrypt.la
 @HAVE_W32CE_SYSTEM_TRUE@arch_gpg_error_cflags = $(GPG_ERROR_CFLAGS)
 @HAVE_W32CE_SYSTEM_FALSE@arch_gpg_error_libs = 
 @HAVE_W32CE_SYSTEM_TRUE@arch_gpg_error_libs = $(GPG_ERROR_LIBS)
+AM_CFLAGS = $(GPG_ERROR_CFLAGS)
+AM_CCASFLAGS = $(NOEXECSTACK_FLAGS)
 @HAVE_LD_VERSION_SCRIPT_FALSE@libgcrypt_version_script_cmd = 
 @HAVE_LD_VERSION_SCRIPT_TRUE@libgcrypt_version_script_cmd = -Wl,--version-script=$(srcdir)/libgcrypt.vers
 libgcrypt_la_CFLAGS = $(GPG_ERROR_CFLAGS)
-libgcrypt_la_SOURCES = g10lib.h visibility.c visibility.h types.h \
+libgcrypt_la_SOURCES = \
+        gcrypt-int.h g10lib.h visibility.c visibility.h types.h \
        cipher.h cipher-proto.h \
-       misc.c global.c sexp.c hwfeatures.c \
+       misc.c global.c sexp.c hwfeatures.c hwf-common.h \
        stdmem.c stdmem.h secmem.c secmem.h \
-       mpi.h missing-string.c module.c fips.c \
-       hmac256.c hmac256.h \
+       mpi.h missing-string.c fips.c \
+       hmac256.c hmac256.h context.c context.h \
+       ec-context.h \
        ath.h ath.c
 
+EXTRA_libgcrypt_la_SOURCES = hwf-x86.c hwf-arm.c
+gcrypt_hwf_modules = @GCRYPT_HWF_MODULES@
 @HAVE_W32_SYSTEM_TRUE@RCCOMPILE = $(RC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
 @HAVE_W32_SYSTEM_TRUE@ $(libgcrypt_la_CPPFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS)
 
@@ -365,6 +437,7 @@ libgcrypt_la_LDFLAGS = $(no_undefined) $(export_symbols) \
        @LIBGCRYPT_LT_CURRENT@:@LIBGCRYPT_LT_REVISION@:@LIBGCRYPT_LT_AGE@
 
 libgcrypt_la_DEPENDENCIES = \
+         $(gcrypt_hwf_modules) \
        ../cipher/libcipher.la \
        ../random/librandom.la \
        ../mpi/libmpi.la \
@@ -372,6 +445,7 @@ libgcrypt_la_DEPENDENCIES = \
        $(srcdir)/libgcrypt.vers $(gcrypt_deps)
 
 libgcrypt_la_LIBADD = $(gcrypt_res) \
+        $(gcrypt_hwf_modules) \
        ../cipher/libcipher.la \
        ../random/librandom.la \
        ../mpi/libmpi.la \
@@ -379,13 +453,16 @@ libgcrypt_la_LIBADD = $(gcrypt_res) \
 
 dumpsexp_SOURCES = dumpsexp.c
 dumpsexp_CFLAGS = $(arch_gpg_error_cflags)
-dumpsexp_LDADD = $(arch_gpg_error_libs)
+dumpsexp_LDADD = $(arch_gpg_error_libs) $(LIBTHREAD)
+mpicalc_SOURCES = mpicalc.c
+mpicalc_CFLAGS = $(GPG_ERROR_CFLAGS)
+mpicalc_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(LIBTHREAD)
 hmac256_SOURCES = hmac256.c
 hmac256_CFLAGS = -DSTANDALONE $(arch_gpg_error_cflags)
-hmac256_LDADD = $(arch_gpg_error_libs)
+hmac256_LDADD = $(arch_gpg_error_libs) $(LIBTHREAD)
 @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)
+@USE_RANDOM_DAEMON_TRUE@gcryptrnd_LDADD = libgcrypt.la $(GPG_ERROR_LIBS) $(PTH_LIBS) $(LIBTHREAD)
 @USE_RANDOM_DAEMON_TRUE@getrandom_SOURCES = getrandom.c
 all: all-am
 
@@ -429,7 +506,6 @@ versioninfo.rc: $(top_builddir)/config.status $(srcdir)/versioninfo.rc.in
        cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 install-libLTLIBRARIES: $(lib_LTLIBRARIES)
        @$(NORMAL_INSTALL)
-       test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
        @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
        list2=; for p in $$list; do \
          if test -f $$p; then \
@@ -437,6 +513,8 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES)
          else :; fi; \
        done; \
        test -z "$$list2" || { \
+         echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
+         $(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
          echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
          $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
        }
@@ -458,12 +536,15 @@ clean-libLTLIBRARIES:
          echo "rm -f \"$${dir}/so_locations\""; \
          rm -f "$${dir}/so_locations"; \
        done
-libgcrypt.la: $(libgcrypt_la_OBJECTS) $(libgcrypt_la_DEPENDENCIES) 
-       $(libgcrypt_la_LINK) -rpath $(libdir) $(libgcrypt_la_OBJECTS) $(libgcrypt_la_LIBADD) $(LIBS)
+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)
        @$(NORMAL_INSTALL)
-       test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
        @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
+       if test -n "$$list"; then \
+         echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+         $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+       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; \
@@ -505,8 +586,11 @@ clean-binPROGRAMS:
        rm -f $$list
 install-sbinPROGRAMS: $(sbin_PROGRAMS)
        @$(NORMAL_INSTALL)
-       test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)"
        @list='$(sbin_PROGRAMS)'; test -n "$(sbindir)" || list=; \
+       if test -n "$$list"; then \
+         echo " $(MKDIR_P) '$(DESTDIR)$(sbindir)'"; \
+         $(MKDIR_P) "$(DESTDIR)$(sbindir)" || exit 1; \
+       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; \
@@ -546,22 +630,28 @@ 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) 
+dumpsexp$(EXEEXT): $(dumpsexp_OBJECTS) $(dumpsexp_DEPENDENCIES) $(EXTRA_dumpsexp_DEPENDENCIES) 
        @rm -f dumpsexp$(EXEEXT)
-       $(dumpsexp_LINK) $(dumpsexp_OBJECTS) $(dumpsexp_LDADD) $(LIBS)
-gcryptrnd$(EXEEXT): $(gcryptrnd_OBJECTS) $(gcryptrnd_DEPENDENCIES) 
+       $(AM_V_CCLD)$(dumpsexp_LINK) $(dumpsexp_OBJECTS) $(dumpsexp_LDADD) $(LIBS)
+gcryptrnd$(EXEEXT): $(gcryptrnd_OBJECTS) $(gcryptrnd_DEPENDENCIES) $(EXTRA_gcryptrnd_DEPENDENCIES) 
        @rm -f gcryptrnd$(EXEEXT)
-       $(gcryptrnd_LINK) $(gcryptrnd_OBJECTS) $(gcryptrnd_LDADD) $(LIBS)
-getrandom$(EXEEXT): $(getrandom_OBJECTS) $(getrandom_DEPENDENCIES) 
+       $(AM_V_CCLD)$(gcryptrnd_LINK) $(gcryptrnd_OBJECTS) $(gcryptrnd_LDADD) $(LIBS)
+getrandom$(EXEEXT): $(getrandom_OBJECTS) $(getrandom_DEPENDENCIES) $(EXTRA_getrandom_DEPENDENCIES) 
        @rm -f getrandom$(EXEEXT)
-       $(LINK) $(getrandom_OBJECTS) $(getrandom_LDADD) $(LIBS)
-hmac256$(EXEEXT): $(hmac256_OBJECTS) $(hmac256_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK) $(getrandom_OBJECTS) $(getrandom_LDADD) $(LIBS)
+hmac256$(EXEEXT): $(hmac256_OBJECTS) $(hmac256_DEPENDENCIES) $(EXTRA_hmac256_DEPENDENCIES) 
        @rm -f hmac256$(EXEEXT)
-       $(hmac256_LINK) $(hmac256_OBJECTS) $(hmac256_LDADD) $(LIBS)
+       $(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)
 install-binSCRIPTS: $(bin_SCRIPTS)
        @$(NORMAL_INSTALL)
-       test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
        @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
+       if test -n "$$list"; then \
+         echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
+         $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
+       fi; \
        for p in $$list; do \
          if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
          if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
@@ -589,9 +679,7 @@ uninstall-binSCRIPTS:
        @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
        files=`for p in $$list; do echo "$$p"; done | \
               sed -e 's,.*/,,;$(transform)'`; \
-       test -n "$$list" || exit 0; \
-       echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
-       cd "$(DESTDIR)$(bindir)" && rm -f $$files
+       dir='$(DESTDIR)$(bindir)'; $(am__uninstall_files_from_dir)
 
 mostlyclean-compile:
        -rm -f *.$(OBJEXT)
@@ -604,164 +692,195 @@ distclean-compile:
 @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@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-hmac256.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-hwf-arm.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-hwf-x86.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-hwfeatures.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-misc.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-missing-string.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-module.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-secmem.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-sexp.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-stdmem.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libgcrypt_la-visibility.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpicalc-mpicalc.Po@am__quote@
 
 .c.o:
-@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@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@  $(COMPILE) -c $<
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
 
 .c.obj:
-@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@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@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
 
 .c.lo:
-@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
 libgcrypt_la-visibility.lo: visibility.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-visibility.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-visibility.Tpo -c -o libgcrypt_la-visibility.lo `test -f 'visibility.c' || echo '$(srcdir)/'`visibility.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/libgcrypt_la-visibility.Tpo $(DEPDIR)/libgcrypt_la-visibility.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='visibility.c' object='libgcrypt_la-visibility.lo' libtool=yes @AMDEPBACKSLASH@
+@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-visibility.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-visibility.Tpo -c -o libgcrypt_la-visibility.lo `test -f 'visibility.c' || echo '$(srcdir)/'`visibility.c
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-visibility.Tpo $(DEPDIR)/libgcrypt_la-visibility.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='visibility.c' object='libgcrypt_la-visibility.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-visibility.lo `test -f 'visibility.c' || echo '$(srcdir)/'`visibility.c
+@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-visibility.lo `test -f 'visibility.c' || echo '$(srcdir)/'`visibility.c
 
 libgcrypt_la-misc.lo: misc.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-misc.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-misc.Tpo -c -o libgcrypt_la-misc.lo `test -f 'misc.c' || echo '$(srcdir)/'`misc.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/libgcrypt_la-misc.Tpo $(DEPDIR)/libgcrypt_la-misc.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='misc.c' object='libgcrypt_la-misc.lo' libtool=yes @AMDEPBACKSLASH@
+@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-misc.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-misc.Tpo -c -o libgcrypt_la-misc.lo `test -f 'misc.c' || echo '$(srcdir)/'`misc.c
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-misc.Tpo $(DEPDIR)/libgcrypt_la-misc.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='misc.c' object='libgcrypt_la-misc.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-misc.lo `test -f 'misc.c' || echo '$(srcdir)/'`misc.c
+@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-misc.lo `test -f 'misc.c' || echo '$(srcdir)/'`misc.c
 
 libgcrypt_la-global.lo: global.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-global.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-global.Tpo -c -o libgcrypt_la-global.lo `test -f 'global.c' || echo '$(srcdir)/'`global.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/libgcrypt_la-global.Tpo $(DEPDIR)/libgcrypt_la-global.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='global.c' object='libgcrypt_la-global.lo' libtool=yes @AMDEPBACKSLASH@
+@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-global.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-global.Tpo -c -o libgcrypt_la-global.lo `test -f 'global.c' || echo '$(srcdir)/'`global.c
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-global.Tpo $(DEPDIR)/libgcrypt_la-global.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='global.c' object='libgcrypt_la-global.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-global.lo `test -f 'global.c' || echo '$(srcdir)/'`global.c
+@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-global.lo `test -f 'global.c' || echo '$(srcdir)/'`global.c
 
 libgcrypt_la-sexp.lo: sexp.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-sexp.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-sexp.Tpo -c -o libgcrypt_la-sexp.lo `test -f 'sexp.c' || echo '$(srcdir)/'`sexp.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/libgcrypt_la-sexp.Tpo $(DEPDIR)/libgcrypt_la-sexp.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='sexp.c' object='libgcrypt_la-sexp.lo' libtool=yes @AMDEPBACKSLASH@
+@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-sexp.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-sexp.Tpo -c -o libgcrypt_la-sexp.lo `test -f 'sexp.c' || echo '$(srcdir)/'`sexp.c
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-sexp.Tpo $(DEPDIR)/libgcrypt_la-sexp.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='sexp.c' object='libgcrypt_la-sexp.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-sexp.lo `test -f 'sexp.c' || echo '$(srcdir)/'`sexp.c
+@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-sexp.lo `test -f 'sexp.c' || echo '$(srcdir)/'`sexp.c
 
 libgcrypt_la-hwfeatures.lo: hwfeatures.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-hwfeatures.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-hwfeatures.Tpo -c -o libgcrypt_la-hwfeatures.lo `test -f 'hwfeatures.c' || echo '$(srcdir)/'`hwfeatures.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/libgcrypt_la-hwfeatures.Tpo $(DEPDIR)/libgcrypt_la-hwfeatures.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='hwfeatures.c' object='libgcrypt_la-hwfeatures.lo' libtool=yes @AMDEPBACKSLASH@
+@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-hwfeatures.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-hwfeatures.Tpo -c -o libgcrypt_la-hwfeatures.lo `test -f 'hwfeatures.c' || echo '$(srcdir)/'`hwfeatures.c
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-hwfeatures.Tpo $(DEPDIR)/libgcrypt_la-hwfeatures.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='hwfeatures.c' object='libgcrypt_la-hwfeatures.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-hwfeatures.lo `test -f 'hwfeatures.c' || echo '$(srcdir)/'`hwfeatures.c
+@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-hwfeatures.lo `test -f 'hwfeatures.c' || echo '$(srcdir)/'`hwfeatures.c
 
 libgcrypt_la-stdmem.lo: stdmem.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-stdmem.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-stdmem.Tpo -c -o libgcrypt_la-stdmem.lo `test -f 'stdmem.c' || echo '$(srcdir)/'`stdmem.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/libgcrypt_la-stdmem.Tpo $(DEPDIR)/libgcrypt_la-stdmem.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='stdmem.c' object='libgcrypt_la-stdmem.lo' libtool=yes @AMDEPBACKSLASH@
+@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-stdmem.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-stdmem.Tpo -c -o libgcrypt_la-stdmem.lo `test -f 'stdmem.c' || echo '$(srcdir)/'`stdmem.c
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-stdmem.Tpo $(DEPDIR)/libgcrypt_la-stdmem.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='stdmem.c' object='libgcrypt_la-stdmem.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-stdmem.lo `test -f 'stdmem.c' || echo '$(srcdir)/'`stdmem.c
+@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-stdmem.lo `test -f 'stdmem.c' || echo '$(srcdir)/'`stdmem.c
 
 libgcrypt_la-secmem.lo: secmem.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-secmem.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-secmem.Tpo -c -o libgcrypt_la-secmem.lo `test -f 'secmem.c' || echo '$(srcdir)/'`secmem.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/libgcrypt_la-secmem.Tpo $(DEPDIR)/libgcrypt_la-secmem.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='secmem.c' object='libgcrypt_la-secmem.lo' libtool=yes @AMDEPBACKSLASH@
+@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-secmem.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-secmem.Tpo -c -o libgcrypt_la-secmem.lo `test -f 'secmem.c' || echo '$(srcdir)/'`secmem.c
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-secmem.Tpo $(DEPDIR)/libgcrypt_la-secmem.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='secmem.c' object='libgcrypt_la-secmem.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-secmem.lo `test -f 'secmem.c' || echo '$(srcdir)/'`secmem.c
+@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-secmem.lo `test -f 'secmem.c' || echo '$(srcdir)/'`secmem.c
 
 libgcrypt_la-missing-string.lo: missing-string.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-missing-string.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-missing-string.Tpo -c -o libgcrypt_la-missing-string.lo `test -f 'missing-string.c' || echo '$(srcdir)/'`missing-string.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/libgcrypt_la-missing-string.Tpo $(DEPDIR)/libgcrypt_la-missing-string.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='missing-string.c' object='libgcrypt_la-missing-string.lo' libtool=yes @AMDEPBACKSLASH@
+@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-missing-string.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-missing-string.Tpo -c -o libgcrypt_la-missing-string.lo `test -f 'missing-string.c' || echo '$(srcdir)/'`missing-string.c
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-missing-string.Tpo $(DEPDIR)/libgcrypt_la-missing-string.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='missing-string.c' object='libgcrypt_la-missing-string.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-missing-string.lo `test -f 'missing-string.c' || echo '$(srcdir)/'`missing-string.c
-
-libgcrypt_la-module.lo: module.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-module.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-module.Tpo -c -o libgcrypt_la-module.lo `test -f 'module.c' || echo '$(srcdir)/'`module.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/libgcrypt_la-module.Tpo $(DEPDIR)/libgcrypt_la-module.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='module.c' object='libgcrypt_la-module.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-module.lo `test -f 'module.c' || echo '$(srcdir)/'`module.c
+@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-missing-string.lo `test -f 'missing-string.c' || echo '$(srcdir)/'`missing-string.c
 
 libgcrypt_la-fips.lo: fips.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-fips.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-fips.Tpo -c -o libgcrypt_la-fips.lo `test -f 'fips.c' || echo '$(srcdir)/'`fips.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/libgcrypt_la-fips.Tpo $(DEPDIR)/libgcrypt_la-fips.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='fips.c' object='libgcrypt_la-fips.lo' libtool=yes @AMDEPBACKSLASH@
+@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-fips.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-fips.Tpo -c -o libgcrypt_la-fips.lo `test -f 'fips.c' || echo '$(srcdir)/'`fips.c
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-fips.Tpo $(DEPDIR)/libgcrypt_la-fips.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='fips.c' object='libgcrypt_la-fips.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-fips.lo `test -f 'fips.c' || echo '$(srcdir)/'`fips.c
+@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-fips.lo `test -f 'fips.c' || echo '$(srcdir)/'`fips.c
 
 libgcrypt_la-hmac256.lo: hmac256.c
-@am__fastdepCC_TRUE@   $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -MT libgcrypt_la-hmac256.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-hmac256.Tpo -c -o libgcrypt_la-hmac256.lo `test -f 'hmac256.c' || echo '$(srcdir)/'`hmac256.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/libgcrypt_la-hmac256.Tpo $(DEPDIR)/libgcrypt_la-hmac256.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='hmac256.c' object='libgcrypt_la-hmac256.lo' libtool=yes @AMDEPBACKSLASH@
+@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-hmac256.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-hmac256.Tpo -c -o libgcrypt_la-hmac256.lo `test -f 'hmac256.c' || echo '$(srcdir)/'`hmac256.c
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-hmac256.Tpo $(DEPDIR)/libgcrypt_la-hmac256.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='hmac256.c' object='libgcrypt_la-hmac256.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-hmac256.lo `test -f 'hmac256.c' || echo '$(srcdir)/'`hmac256.c
+
+libgcrypt_la-context.lo: context.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-context.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-context.Tpo -c -o libgcrypt_la-context.lo `test -f 'context.c' || echo '$(srcdir)/'`context.c
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-context.Tpo $(DEPDIR)/libgcrypt_la-context.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='context.c' object='libgcrypt_la-context.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libgcrypt_la_CFLAGS) $(CFLAGS) -c -o libgcrypt_la-hmac256.lo `test -f 'hmac256.c' || echo '$(srcdir)/'`hmac256.c
+@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@   $(LIBTOOL)  --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__mv) $(DEPDIR)/libgcrypt_la-ath.Tpo $(DEPDIR)/libgcrypt_la-ath.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='ath.c' object='libgcrypt_la-ath.lo' libtool=yes @AMDEPBACKSLASH@
+@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
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='hwf-x86.c' object='libgcrypt_la-hwf-x86.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-hwf-x86.lo `test -f 'hwf-x86.c' || echo '$(srcdir)/'`hwf-x86.c
+
+libgcrypt_la-hwf-arm.lo: hwf-arm.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-arm.lo -MD -MP -MF $(DEPDIR)/libgcrypt_la-hwf-arm.Tpo -c -o libgcrypt_la-hwf-arm.lo `test -f 'hwf-arm.c' || echo '$(srcdir)/'`hwf-arm.c
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/libgcrypt_la-hwf-arm.Tpo $(DEPDIR)/libgcrypt_la-hwf-arm.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='hwf-arm.c' object='libgcrypt_la-hwf-arm.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL)  --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
+@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-hwf-arm.lo `test -f 'hwf-arm.c' || echo '$(srcdir)/'`hwf-arm.c
 
 dumpsexp-dumpsexp.o: dumpsexp.c
-@am__fastdepCC_TRUE@   $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumpsexp_CFLAGS) $(CFLAGS) -MT dumpsexp-dumpsexp.o -MD -MP -MF $(DEPDIR)/dumpsexp-dumpsexp.Tpo -c -o dumpsexp-dumpsexp.o `test -f 'dumpsexp.c' || echo '$(srcdir)/'`dumpsexp.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/dumpsexp-dumpsexp.Tpo $(DEPDIR)/dumpsexp-dumpsexp.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='dumpsexp.c' object='dumpsexp-dumpsexp.o' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumpsexp_CFLAGS) $(CFLAGS) -MT dumpsexp-dumpsexp.o -MD -MP -MF $(DEPDIR)/dumpsexp-dumpsexp.Tpo -c -o dumpsexp-dumpsexp.o `test -f 'dumpsexp.c' || echo '$(srcdir)/'`dumpsexp.c
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/dumpsexp-dumpsexp.Tpo $(DEPDIR)/dumpsexp-dumpsexp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='dumpsexp.c' object='dumpsexp-dumpsexp.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumpsexp_CFLAGS) $(CFLAGS) -c -o dumpsexp-dumpsexp.o `test -f 'dumpsexp.c' || echo '$(srcdir)/'`dumpsexp.c
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumpsexp_CFLAGS) $(CFLAGS) -c -o dumpsexp-dumpsexp.o `test -f 'dumpsexp.c' || echo '$(srcdir)/'`dumpsexp.c
 
 dumpsexp-dumpsexp.obj: dumpsexp.c
-@am__fastdepCC_TRUE@   $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumpsexp_CFLAGS) $(CFLAGS) -MT dumpsexp-dumpsexp.obj -MD -MP -MF $(DEPDIR)/dumpsexp-dumpsexp.Tpo -c -o dumpsexp-dumpsexp.obj `if test -f 'dumpsexp.c'; then $(CYGPATH_W) 'dumpsexp.c'; else $(CYGPATH_W) '$(srcdir)/dumpsexp.c'; fi`
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/dumpsexp-dumpsexp.Tpo $(DEPDIR)/dumpsexp-dumpsexp.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='dumpsexp.c' object='dumpsexp-dumpsexp.obj' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumpsexp_CFLAGS) $(CFLAGS) -MT dumpsexp-dumpsexp.obj -MD -MP -MF $(DEPDIR)/dumpsexp-dumpsexp.Tpo -c -o dumpsexp-dumpsexp.obj `if test -f 'dumpsexp.c'; then $(CYGPATH_W) 'dumpsexp.c'; else $(CYGPATH_W) '$(srcdir)/dumpsexp.c'; fi`
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/dumpsexp-dumpsexp.Tpo $(DEPDIR)/dumpsexp-dumpsexp.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='dumpsexp.c' object='dumpsexp-dumpsexp.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumpsexp_CFLAGS) $(CFLAGS) -c -o dumpsexp-dumpsexp.obj `if test -f 'dumpsexp.c'; then $(CYGPATH_W) 'dumpsexp.c'; else $(CYGPATH_W) '$(srcdir)/dumpsexp.c'; fi`
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(dumpsexp_CFLAGS) $(CFLAGS) -c -o dumpsexp-dumpsexp.obj `if test -f 'dumpsexp.c'; then $(CYGPATH_W) 'dumpsexp.c'; else $(CYGPATH_W) '$(srcdir)/dumpsexp.c'; fi`
 
 gcryptrnd-gcryptrnd.o: gcryptrnd.c
-@am__fastdepCC_TRUE@   $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gcryptrnd_CFLAGS) $(CFLAGS) -MT gcryptrnd-gcryptrnd.o -MD -MP -MF $(DEPDIR)/gcryptrnd-gcryptrnd.Tpo -c -o gcryptrnd-gcryptrnd.o `test -f 'gcryptrnd.c' || echo '$(srcdir)/'`gcryptrnd.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/gcryptrnd-gcryptrnd.Tpo $(DEPDIR)/gcryptrnd-gcryptrnd.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='gcryptrnd.c' object='gcryptrnd-gcryptrnd.o' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gcryptrnd_CFLAGS) $(CFLAGS) -MT gcryptrnd-gcryptrnd.o -MD -MP -MF $(DEPDIR)/gcryptrnd-gcryptrnd.Tpo -c -o gcryptrnd-gcryptrnd.o `test -f 'gcryptrnd.c' || echo '$(srcdir)/'`gcryptrnd.c
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/gcryptrnd-gcryptrnd.Tpo $(DEPDIR)/gcryptrnd-gcryptrnd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='gcryptrnd.c' object='gcryptrnd-gcryptrnd.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gcryptrnd_CFLAGS) $(CFLAGS) -c -o gcryptrnd-gcryptrnd.o `test -f 'gcryptrnd.c' || echo '$(srcdir)/'`gcryptrnd.c
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gcryptrnd_CFLAGS) $(CFLAGS) -c -o gcryptrnd-gcryptrnd.o `test -f 'gcryptrnd.c' || echo '$(srcdir)/'`gcryptrnd.c
 
 gcryptrnd-gcryptrnd.obj: gcryptrnd.c
-@am__fastdepCC_TRUE@   $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gcryptrnd_CFLAGS) $(CFLAGS) -MT gcryptrnd-gcryptrnd.obj -MD -MP -MF $(DEPDIR)/gcryptrnd-gcryptrnd.Tpo -c -o gcryptrnd-gcryptrnd.obj `if test -f 'gcryptrnd.c'; then $(CYGPATH_W) 'gcryptrnd.c'; else $(CYGPATH_W) '$(srcdir)/gcryptrnd.c'; fi`
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/gcryptrnd-gcryptrnd.Tpo $(DEPDIR)/gcryptrnd-gcryptrnd.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='gcryptrnd.c' object='gcryptrnd-gcryptrnd.obj' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gcryptrnd_CFLAGS) $(CFLAGS) -MT gcryptrnd-gcryptrnd.obj -MD -MP -MF $(DEPDIR)/gcryptrnd-gcryptrnd.Tpo -c -o gcryptrnd-gcryptrnd.obj `if test -f 'gcryptrnd.c'; then $(CYGPATH_W) 'gcryptrnd.c'; else $(CYGPATH_W) '$(srcdir)/gcryptrnd.c'; fi`
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/gcryptrnd-gcryptrnd.Tpo $(DEPDIR)/gcryptrnd-gcryptrnd.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='gcryptrnd.c' object='gcryptrnd-gcryptrnd.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gcryptrnd_CFLAGS) $(CFLAGS) -c -o gcryptrnd-gcryptrnd.obj `if test -f 'gcryptrnd.c'; then $(CYGPATH_W) 'gcryptrnd.c'; else $(CYGPATH_W) '$(srcdir)/gcryptrnd.c'; fi`
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(gcryptrnd_CFLAGS) $(CFLAGS) -c -o gcryptrnd-gcryptrnd.obj `if test -f 'gcryptrnd.c'; then $(CYGPATH_W) 'gcryptrnd.c'; else $(CYGPATH_W) '$(srcdir)/gcryptrnd.c'; fi`
 
 hmac256-hmac256.o: hmac256.c
-@am__fastdepCC_TRUE@   $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hmac256_CFLAGS) $(CFLAGS) -MT hmac256-hmac256.o -MD -MP -MF $(DEPDIR)/hmac256-hmac256.Tpo -c -o hmac256-hmac256.o `test -f 'hmac256.c' || echo '$(srcdir)/'`hmac256.c
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/hmac256-hmac256.Tpo $(DEPDIR)/hmac256-hmac256.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='hmac256.c' object='hmac256-hmac256.o' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hmac256_CFLAGS) $(CFLAGS) -MT hmac256-hmac256.o -MD -MP -MF $(DEPDIR)/hmac256-hmac256.Tpo -c -o hmac256-hmac256.o `test -f 'hmac256.c' || echo '$(srcdir)/'`hmac256.c
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/hmac256-hmac256.Tpo $(DEPDIR)/hmac256-hmac256.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='hmac256.c' object='hmac256-hmac256.o' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hmac256_CFLAGS) $(CFLAGS) -c -o hmac256-hmac256.o `test -f 'hmac256.c' || echo '$(srcdir)/'`hmac256.c
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hmac256_CFLAGS) $(CFLAGS) -c -o hmac256-hmac256.o `test -f 'hmac256.c' || echo '$(srcdir)/'`hmac256.c
 
 hmac256-hmac256.obj: hmac256.c
-@am__fastdepCC_TRUE@   $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hmac256_CFLAGS) $(CFLAGS) -MT hmac256-hmac256.obj -MD -MP -MF $(DEPDIR)/hmac256-hmac256.Tpo -c -o hmac256-hmac256.obj `if test -f 'hmac256.c'; then $(CYGPATH_W) 'hmac256.c'; else $(CYGPATH_W) '$(srcdir)/hmac256.c'; fi`
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/hmac256-hmac256.Tpo $(DEPDIR)/hmac256-hmac256.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='hmac256.c' object='hmac256-hmac256.obj' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hmac256_CFLAGS) $(CFLAGS) -MT hmac256-hmac256.obj -MD -MP -MF $(DEPDIR)/hmac256-hmac256.Tpo -c -o hmac256-hmac256.obj `if test -f 'hmac256.c'; then $(CYGPATH_W) 'hmac256.c'; else $(CYGPATH_W) '$(srcdir)/hmac256.c'; fi`
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/hmac256-hmac256.Tpo $(DEPDIR)/hmac256-hmac256.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='hmac256.c' object='hmac256-hmac256.obj' libtool=no @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hmac256_CFLAGS) $(CFLAGS) -c -o hmac256-hmac256.obj `if test -f 'hmac256.c'; then $(CYGPATH_W) 'hmac256.c'; else $(CYGPATH_W) '$(srcdir)/hmac256.c'; fi`
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(hmac256_CFLAGS) $(CFLAGS) -c -o hmac256-hmac256.obj `if test -f 'hmac256.c'; then $(CYGPATH_W) 'hmac256.c'; else $(CYGPATH_W) '$(srcdir)/hmac256.c'; fi`
+
+mpicalc-mpicalc.o: mpicalc.c
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mpicalc_CFLAGS) $(CFLAGS) -MT mpicalc-mpicalc.o -MD -MP -MF $(DEPDIR)/mpicalc-mpicalc.Tpo -c -o mpicalc-mpicalc.o `test -f 'mpicalc.c' || echo '$(srcdir)/'`mpicalc.c
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/mpicalc-mpicalc.Tpo $(DEPDIR)/mpicalc-mpicalc.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='mpicalc.c' object='mpicalc-mpicalc.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) $(mpicalc_CFLAGS) $(CFLAGS) -c -o mpicalc-mpicalc.o `test -f 'mpicalc.c' || echo '$(srcdir)/'`mpicalc.c
+
+mpicalc-mpicalc.obj: mpicalc.c
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(mpicalc_CFLAGS) $(CFLAGS) -MT mpicalc-mpicalc.obj -MD -MP -MF $(DEPDIR)/mpicalc-mpicalc.Tpo -c -o mpicalc-mpicalc.obj `if test -f 'mpicalc.c'; then $(CYGPATH_W) 'mpicalc.c'; else $(CYGPATH_W) '$(srcdir)/mpicalc.c'; fi`
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/mpicalc-mpicalc.Tpo $(DEPDIR)/mpicalc-mpicalc.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='mpicalc.c' object='mpicalc-mpicalc.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) $(mpicalc_CFLAGS) $(CFLAGS) -c -o mpicalc-mpicalc.obj `if test -f 'mpicalc.c'; then $(CYGPATH_W) 'mpicalc.c'; else $(CYGPATH_W) '$(srcdir)/mpicalc.c'; fi`
 
 mostlyclean-libtool:
        -rm -f *.lo
@@ -770,8 +889,11 @@ clean-libtool:
        -rm -rf .libs _libs
 install-m4dataDATA: $(m4data_DATA)
        @$(NORMAL_INSTALL)
-       test -z "$(m4datadir)" || $(MKDIR_P) "$(DESTDIR)$(m4datadir)"
        @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \
+       if test -n "$$list"; then \
+         echo " $(MKDIR_P) '$(DESTDIR)$(m4datadir)'"; \
+         $(MKDIR_P) "$(DESTDIR)$(m4datadir)" || exit 1; \
+       fi; \
        for p in $$list; do \
          if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
          echo "$$d$$p"; \
@@ -785,13 +907,14 @@ uninstall-m4dataDATA:
        @$(NORMAL_UNINSTALL)
        @list='$(m4data_DATA)'; test -n "$(m4datadir)" || list=; \
        files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-       test -n "$$files" || exit 0; \
-       echo " ( cd '$(DESTDIR)$(m4datadir)' && rm -f" $$files ")"; \
-       cd "$(DESTDIR)$(m4datadir)" && rm -f $$files
+       dir='$(DESTDIR)$(m4datadir)'; $(am__uninstall_files_from_dir)
 install-includeHEADERS: $(include_HEADERS)
        @$(NORMAL_INSTALL)
-       test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
        @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
+       if test -n "$$list"; then \
+         echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
+         $(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
+       fi; \
        for p in $$list; do \
          if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
          echo "$$d$$p"; \
@@ -805,9 +928,7 @@ uninstall-includeHEADERS:
        @$(NORMAL_UNINSTALL)
        @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
        files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
-       test -n "$$files" || exit 0; \
-       echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \
-       cd "$(DESTDIR)$(includedir)" && rm -f $$files
+       dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
 
 ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
        list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
@@ -911,10 +1032,15 @@ install-am: all-am
 
 installcheck: installcheck-am
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-         `test -z '$(STRIP)' || \
-           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+       if test -z '$(STRIP)'; then \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+             install; \
+       else \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+           "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+       fi
 mostlyclean-generic:
 
 clean-generic:
@@ -1028,6 +1154,7 @@ uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
 @HAVE_W32_SYSTEM_TRUE@ $(LTRCCOMPILE) -i "$<" -o "$@"
 
 @HAVE_W32_SYSTEM_TRUE@install-def-file:
+@HAVE_W32_SYSTEM_TRUE@ -$(INSTALL) -d $(DESTDIR)$(libdir)
 @HAVE_W32_SYSTEM_TRUE@ $(INSTALL) $(srcdir)/libgcrypt.def $(DESTDIR)$(libdir)/libgcrypt.def
 
 @HAVE_W32_SYSTEM_TRUE@uninstall-def-file:
index 656ed89..9085d3e 100644 (file)
--- a/src/ath.c
+++ b/src/ath.c
-/* ath.c - Thread-safeness library.
  Copyright (C) 2002, 2003, 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
-   General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with Libgcrypt; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  02111-1307, USA.  */
+/* ath.c - 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>  /* Right: We need to use assert and not gcry_assert.  */
+#include <assert.h>
+#include <stdlib.h>
 #include <unistd.h>
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#else
-# include <sys/time.h>
-#endif
-#include <sys/types.h>
-#ifndef _WIN32
-#include <sys/wait.h>
-#endif
 #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
-/* The interface table.  */
-static struct ath_ops ops;
-
-/* True if we should use the external callbacks.  */
-static int ops_set;
-
+/* 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.  */
-#define MUTEX_UNLOCKED ((ath_mutex_t) 0)
-#define MUTEX_LOCKED   ((ath_mutex_t) 1)
-#define MUTEX_DESTROYED        ((ath_mutex_t) 2)
+/* 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)
-/* Return the version number from the option field.  */
-#define GET_VERSION(a)   (((a) >> 8)& 0xff)
 
 
 \f
-/* The lock we take while checking for lazy lock initialization.  */
-static ath_mutex_t check_init_lock = ATH_MUTEX_INITIALIZER;
+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 (ops_set)
-    {
-      if (ops.init)
-       err = (*ops.init) ();
-      if (err)
-       return err;
-      err = (*ops.mutex_init) (&check_init_lock);
-    }
-  return err;
-}
-
+  if (thread_model)
+    return 0; /* Already initialized - no error.  */
 
-/* Initialize the locking library.  Returns 0 if the operation was
-   successful, EINVAL if the operation table was invalid and EBUSY if
-   we already were initialized.  */
-gpg_err_code_t
-ath_install (struct ath_ops *ath_ops, int check_only)
-{
-  if (check_only)
+  if (0)
+    ;
+#if USE_POSIX_THREADS_WEAK
+  else if (pthread_cancel)
     {
-      unsigned int option = 0;
-
-      /* Check if the requested thread option is compatible to the
-        thread option we are already committed to.  */
-      if (ath_ops)
-       option = ath_ops->option;
-
-      if (!ops_set && GET_OPTION (option))
-       return GPG_ERR_NOT_SUPPORTED;
-
-      if (GET_OPTION (ops.option) == ATH_THREAD_OPTION_USER
-         || GET_OPTION (option) == ATH_THREAD_OPTION_USER
-         || GET_OPTION (ops.option) != GET_OPTION (option)
-          || GET_VERSION (ops.option) != GET_VERSION (option))
-       return GPG_ERR_NOT_SUPPORTED;
-
-      return 0;
+      thread_model = ath_model_pthreads_weak;
     }
-
-  if (ath_ops)
+#endif
+  else
     {
-      /* It is convenient to not require DESTROY.  */
-      if (!ath_ops->mutex_init || !ath_ops->mutex_lock
-         || !ath_ops->mutex_unlock)
-       return GPG_ERR_INV_ARG;
-
-      ops = *ath_ops;
-      ops_set = 1;
+#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*/
     }
-  else
-    ops_set = 0;
-
-  return 0;
-}
-
-
-static int
-mutex_init (ath_mutex_t *lock, int just_check)
-{
-  int err = 0;
 
-  if (just_check)
-    (*ops.mutex_lock) (&check_init_lock);
-  if (*lock == ATH_MUTEX_INITIALIZER || !just_check)
-    err = (*ops.mutex_init) (lock);
-  if (just_check)
-    (*ops.mutex_unlock) (&check_init_lock);
   return err;
 }
 
 
-int
-ath_mutex_init (ath_mutex_t *lock)
-{
-  if (ops_set)
-    return mutex_init (lock, 0);
-
-#ifndef NDEBUG
-  *lock = MUTEX_UNLOCKED;
-#endif
-  return 0;
-}
-
-
-int
-ath_mutex_destroy (ath_mutex_t *lock)
+/* 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 (ops_set)
+  if (r_model)
+    *r_model = thread_model;
+  switch (thread_model)
     {
-      if (!ops.mutex_destroy)
-       return 0;
-
-      (*ops.mutex_lock) (&check_init_lock);
-      if (*lock == ATH_MUTEX_INITIALIZER)
-       {
-         (*ops.mutex_unlock) (&check_init_lock);
-         return 0;
-       }
-      (*ops.mutex_unlock) (&check_init_lock);
-      return (*ops.mutex_destroy) (lock);
+    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 "?";
     }
-
-#ifndef NDEBUG
-  assert (*lock == MUTEX_UNLOCKED);
-
-  *lock = MUTEX_DESTROYED;
-#endif
-  return 0;
 }
 
 
-int
-ath_mutex_lock (ath_mutex_t *lock)
+/* 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)
 {
-  if (ops_set)
+  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)
     {
-      int ret = mutex_init (lock, 1);
-      if (ret)
-       return ret;
-      return (*ops.mutex_lock) (lock);
+      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*/
 
-#ifndef NDEBUG
-  assert (*lock == MUTEX_UNLOCKED);
-
-  *lock = MUTEX_LOCKED;
-#endif
-  return 0;
+  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_unlock (ath_mutex_t *lock)
+ath_mutex_init (ath_mutex_t *lock)
 {
-  if (ops_set)
+  int err;
+
+  switch (thread_model)
     {
-      int ret = mutex_init (lock, 1);
-      if (ret)
-       return ret;
-      return (*ops.mutex_unlock) (lock);
+    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;
     }
 
-#ifndef NDEBUG
-  assert (*lock == MUTEX_LOCKED);
-
-  *lock = MUTEX_UNLOCKED;
-#endif
-  return 0;
-}
-
-
-ssize_t
-ath_read (int fd, void *buf, size_t nbytes)
-{
-  if (ops_set && ops.read)
-    return (*ops.read) (fd, buf, nbytes);
-  else
-    return read (fd, buf, nbytes);
+  return err;
 }
 
 
-ssize_t
-ath_write (int fd, const void *buf, size_t nbytes)
+/* 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)
 {
-  if (ops_set && ops.write)
-    return (*ops.write) (fd, buf, nbytes);
-  else
-    return write (fd, buf, nbytes);
-}
-
+  int err;
 
-ssize_t
-#ifdef _WIN32
-ath_select (int nfd, void *rset, void *wset, void *eset,
-           struct timeval *timeout)
-#else
-ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
-           struct timeval *timeout)
-#endif
-{
-  if (ops_set && ops.select)
-    return (*ops.select) (nfd, rset, wset, eset, timeout);
-  else
-#ifdef _WIN32
-    return -1;
-#else
-    return select (nfd, rset, wset, eset, timeout);
-#endif
-}
+  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;
+    }
 
-ssize_t
-ath_waitpid (pid_t pid, int *status, int options)
-{
-  if (ops_set && ops.waitpid)
-    return (*ops.waitpid) (pid, status, options);
-  else
-#ifdef _WIN32
-    return -1;
-#else
-    return waitpid (pid, status, options);
-#endif
+  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
-#ifdef _WIN32
-ath_accept (int s, void *addr, int *length_ptr)
-#else
-ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr)
-#endif
+ath_mutex_lock (ath_mutex_t *lock)
 {
-  if (ops_set && ops.accept)
-    return (*ops.accept) (s, addr, length_ptr);
-  else
-#ifdef _WIN32
-    return -1;
-#else
-    return accept (s, addr, length_ptr);
-#endif
-}
+  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;
+    }
 
-int
-#ifdef _WIN32
-ath_connect (int s, void *addr, int length)
-#else
-ath_connect (int s, struct sockaddr *addr, socklen_t length)
-#endif
-{
-  if (ops_set && ops.connect)
-    return (*ops.connect) (s, addr, length);
-  else
-#ifdef _WIN32
-    return -1;
-#else
-    return connect (s, addr, length);
-#endif
+  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
-#ifdef _WIN32
-ath_sendmsg (int s, const void *msg, int flags)
-#else
-ath_sendmsg (int s, const struct msghdr *msg, int flags)
-#endif
+ath_mutex_unlock (ath_mutex_t *lock)
 {
-  if (ops_set && ops.sendmsg)
-    return (*ops.sendmsg) (s, msg, flags);
-  else
-#ifdef _WIN32
-    return -1;
-#else
-    return sendmsg (s, msg, flags);
-#endif
-}
+  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;
+    }
 
-int
-#ifdef _WIN32
-ath_recvmsg (int s, void *msg, int flags)
-#else
-ath_recvmsg (int s, struct msghdr *msg, int flags)
-#endif
-{
-  if (ops_set && ops.recvmsg)
-    return (*ops.recvmsg) (s, msg, flags);
-  else
-#ifdef _WIN32
-    return -1;
-#else
-    return recvmsg (s, msg, flags);
-#endif
+  return err;
 }
index 8769551..a132e0b 100644 (file)
--- a/src/ath.h
+++ b/src/ath.h
@@ -1,22 +1,21 @@
 /* ath.h - Thread-safeness library.
-   Copyright (C) 2002, 2003, 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
-   General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with Libgcrypt; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
-   02111-1307, USA.  */
+ * 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
@@ -24,6 +23,7 @@
 #include <config.h>
 
 #ifdef _WIN32
+# include <winsock2.h>
 # include <windows.h>
 #else /* !_WIN32 */
 # ifdef HAVE_SYS_SELECT_H
 #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)
-#define ath_read _ATH_PREFIX(ath_read)
-#define ath_write _ATH_PREFIX(ath_write)
-#define ath_select _ATH_PREFIX(ath_select)
-#define ath_waitpid _ATH_PREFIX(ath_waitpid)
-#define ath_connect _ATH_PREFIX(ath_connect)
-#define ath_accept _ATH_PREFIX(ath_accept)
-#define ath_sendmsg _ATH_PREFIX(ath_sendmsg)
-#define ath_recvmsg _ATH_PREFIX(ath_recvmsg)
 #endif
 
 \f
@@ -83,65 +76,18 @@ struct ath_ops
   */
   unsigned int option;
 
-  int (*init) (void);
-  int (*mutex_init) (void **priv);
-  int (*mutex_destroy) (void *priv);
-  int (*mutex_lock) (void *priv);
-  int (*mutex_unlock) (void *priv);
-  ssize_t (*read) (int fd, void *buf, size_t nbytes);
-  ssize_t (*write) (int fd, const void *buf, size_t nbytes);
-#ifdef _WIN32
-  ssize_t (*select) (int nfd, void *rset, void *wset, void *eset,
-                    struct timeval *timeout);
-  ssize_t (*waitpid) (pid_t pid, int *status, int options);
-  int (*accept) (int s, void  *addr, int *length_ptr);
-  int (*connect) (int s, void *addr, int length);
-  int (*sendmsg) (int s, const void *msg, int flags);
-  int (*recvmsg) (int s, void *msg, int flags);
-#else
-  ssize_t (*select) (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
-                    struct timeval *timeout);
-  ssize_t (*waitpid) (pid_t pid, int *status, int options);
-  int (*accept) (int s, struct sockaddr *addr, socklen_t *length_ptr);
-  int (*connect) (int s, struct sockaddr *addr, socklen_t length);
-  int (*sendmsg) (int s, const struct msghdr *msg, int flags);
-  int (*recvmsg) (int s, struct msghdr *msg, int flags);
-#endif
 };
 
-gpg_err_code_t ath_install (struct ath_ops *ath_ops, int check_only);
+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;
-#define ATH_MUTEX_INITIALIZER 0
 
 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);
 
-/* Replacement for the POSIX functions, which can be used to allow
-   other (user-level) threads to run.  */
-ssize_t ath_read (int fd, void *buf, size_t nbytes);
-ssize_t ath_write (int fd, const void *buf, size_t nbytes);
-#ifdef _WIN32
-ssize_t ath_select (int nfd, void *rset, void *wset, void *eset,
-                   struct timeval *timeout);
-ssize_t ath_waitpid (pid_t pid, int *status, int options);
-int ath_accept (int s, void *addr, int *length_ptr);
-int ath_connect (int s, void *addr, int length);
-int ath_sendmsg (int s, const void *msg, int flags);
-int ath_recvmsg (int s, void *msg, int flags);
-#else
-ssize_t ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
-                   struct timeval *timeout);
-ssize_t ath_waitpid (pid_t pid, int *status, int options);
-int ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr);
-int ath_connect (int s, struct sockaddr *addr, socklen_t length);
-int ath_sendmsg (int s, const struct msghdr *msg, int flags);
-int ath_recvmsg (int s, struct msghdr *msg, int flags);
-#endif
-
 #endif /* ATH_H */
index 347681f..8267791 100644 (file)
 #ifndef G10_CIPHER_PROTO_H
 #define G10_CIPHER_PROTO_H
 
+
+enum pk_encoding;
+
+
 /* Definition of a function used to report selftest failures.
    DOMAIN is a string describing the function block:
           "cipher", "digest", "pubkey or "random",
@@ -38,77 +42,207 @@ typedef void (*selftest_report_func_t)(const char *domain,
 typedef gpg_err_code_t (*selftest_func_t)
      (int algo, int extended, selftest_report_func_t report);
 
+\f
+/*
+ *
+ * Public key related definitions.
+ *
+ */
 
-/* An extended type of the generate function.  */
-typedef gcry_err_code_t (*pk_ext_generate_t)
-     (int algo,
-      unsigned int nbits,
-      unsigned long evalue,
-      gcry_sexp_t genparms,
-      gcry_mpi_t *skey,
-      gcry_mpi_t **retfactors,
-      gcry_sexp_t *extrainfo);
+/* Type for the pk_generate function.  */
+typedef gcry_err_code_t (*gcry_pk_generate_t) (gcry_sexp_t genparms,
+                                               gcry_sexp_t *r_skey);
+
+/* Type for the pk_check_secret_key function.  */
+typedef gcry_err_code_t (*gcry_pk_check_secret_key_t) (gcry_sexp_t keyparms);
+
+/* Type for the pk_encrypt function.  */
+typedef gcry_err_code_t (*gcry_pk_encrypt_t) (gcry_sexp_t *r_ciph,
+                                              gcry_sexp_t s_data,
+                                              gcry_sexp_t keyparms);
+
+/* Type for the pk_decrypt function.  */
+typedef gcry_err_code_t (*gcry_pk_decrypt_t) (gcry_sexp_t *r_plain,
+                                              gcry_sexp_t s_data,
+                                              gcry_sexp_t keyparms);
+
+/* Type for the pk_sign function.  */
+typedef gcry_err_code_t (*gcry_pk_sign_t) (gcry_sexp_t *r_sig,
+                                           gcry_sexp_t s_data,
+                                           gcry_sexp_t keyparms);
+
+/* Type for the pk_verify function.  */
+typedef gcry_err_code_t (*gcry_pk_verify_t) (gcry_sexp_t s_sig,
+                                             gcry_sexp_t s_data,
+                                             gcry_sexp_t keyparms);
+
+/* Type for the pk_get_nbits function.  */
+typedef unsigned (*gcry_pk_get_nbits_t) (gcry_sexp_t keyparms);
 
-/* The type used to compute the keygrip.  */
-typedef gpg_err_code_t (*pk_comp_keygrip_t)
-     (gcry_md_hd_t md, gcry_sexp_t keyparm);
 
-/* The type used to query ECC curve parameters.  */
-typedef gcry_err_code_t (*pk_get_param_t)
-     (const char *name, gcry_mpi_t *pkey);
+/* The type used to compute the keygrip.  */
+typedef gpg_err_code_t (*pk_comp_keygrip_t) (gcry_md_hd_t md,
+                                             gcry_sexp_t keyparm);
 
 /* The type used to query an ECC curve name.  */
-typedef const char *(*pk_get_curve_t)(gcry_mpi_t *pkey, int iterator,
+typedef const char *(*pk_get_curve_t)(gcry_sexp_t keyparms, int iterator,
                                       unsigned int *r_nbits);
 
 /* The type used to query ECC curve parameters by name.  */
 typedef gcry_sexp_t (*pk_get_curve_param_t)(const char *name);
 
+
+/* Module specification structure for public key algoritms.  */
+typedef struct gcry_pk_spec
+{
+  int algo;
+  struct {
+    unsigned int disabled:1;
+    unsigned int fips:1;
+  } flags;
+  int use;
+  const char *name;
+  const char **aliases;
+  const char *elements_pkey;
+  const char *elements_skey;
+  const char *elements_enc;
+  const char *elements_sig;
+  const char *elements_grip;
+  gcry_pk_generate_t generate;
+  gcry_pk_check_secret_key_t check_secret_key;
+  gcry_pk_encrypt_t encrypt;
+  gcry_pk_decrypt_t decrypt;
+  gcry_pk_sign_t sign;
+  gcry_pk_verify_t verify;
+  gcry_pk_get_nbits_t get_nbits;
+  selftest_func_t selftest;
+  pk_comp_keygrip_t comp_keygrip;
+  pk_get_curve_t get_curve;
+  pk_get_curve_param_t get_curve_param;
+} gcry_pk_spec_t;
+
+
+\f
+/*
+ *
+ * Symmetric cipher related definitions.
+ *
+ */
+
+/* Type for the cipher_setkey function.  */
+typedef gcry_err_code_t (*gcry_cipher_setkey_t) (void *c,
+                                                const unsigned char *key,
+                                                unsigned keylen);
+
+/* Type for the cipher_encrypt function.  */
+typedef unsigned int (*gcry_cipher_encrypt_t) (void *c,
+                                              unsigned char *outbuf,
+                                              const unsigned char *inbuf);
+
+/* Type for the cipher_decrypt function.  */
+typedef unsigned int (*gcry_cipher_decrypt_t) (void *c,
+                                              unsigned char *outbuf,
+                                              const unsigned char *inbuf);
+
+/* Type for the cipher_stencrypt function.  */
+typedef void (*gcry_cipher_stencrypt_t) (void *c,
+                                        unsigned char *outbuf,
+                                        const unsigned char *inbuf,
+                                        size_t n);
+
+/* Type for the cipher_stdecrypt function.  */
+typedef void (*gcry_cipher_stdecrypt_t) (void *c,
+                                        unsigned char *outbuf,
+                                        const unsigned char *inbuf,
+                                        size_t n);
+
 /* The type used to convey additional information to a cipher.  */
 typedef gpg_err_code_t (*cipher_set_extra_info_t)
      (void *c, int what, const void *buffer, size_t buflen);
 
+/* The type used to set an IV directly in the algorithm module.  */
+typedef void (*cipher_setiv_func_t)(void *c, const byte *iv, size_t ivlen);
 
-/* Extra module specification structures.  These are used for internal
-   modules which provide more functions than available through the
-   public algorithm register APIs.  */
-typedef struct cipher_extra_spec
+/* A structure to map OIDs to encryption modes.  */
+typedef struct gcry_cipher_oid_spec
 {
+  const char *oid;
+  int mode;
+} gcry_cipher_oid_spec_t;
+
+
+/* Module specification structure for ciphers.  */
+typedef struct gcry_cipher_spec
+{
+  int algo;
+  struct {
+    unsigned int disabled:1;
+    unsigned int fips:1;
+  } flags;
+  const char *name;
+  const char **aliases;
+  gcry_cipher_oid_spec_t *oids;
+  size_t blocksize;
+  size_t keylen;
+  size_t contextsize;
+  gcry_cipher_setkey_t setkey;
+  gcry_cipher_encrypt_t encrypt;
+  gcry_cipher_decrypt_t decrypt;
+  gcry_cipher_stencrypt_t stencrypt;
+  gcry_cipher_stdecrypt_t stdecrypt;
   selftest_func_t selftest;
   cipher_set_extra_info_t set_extra_info;
-} cipher_extra_spec_t;
+  cipher_setiv_func_t setiv;
+} gcry_cipher_spec_t;
+
+
+\f
+/*
+ *
+ * Message digest related definitions.
+ *
+ */
 
-typedef struct md_extra_spec
+/* Type for the md_init function.  */
+typedef void (*gcry_md_init_t) (void *c, unsigned int flags);
+
+/* Type for the md_write function.  */
+typedef void (*gcry_md_write_t) (void *c, const void *buf, size_t nbytes);
+
+/* Type for the md_final function.  */
+typedef void (*gcry_md_final_t) (void *c);
+
+/* Type for the md_read function.  */
+typedef unsigned char *(*gcry_md_read_t) (void *c);
+
+typedef struct gcry_md_oid_spec
 {
-  selftest_func_t selftest;
-} md_extra_spec_t;
+  const char *oidstring;
+} gcry_md_oid_spec_t;
 
-typedef struct pk_extra_spec
+/* Module specification structure for message digests.  */
+typedef struct gcry_md_spec
 {
+  int algo;
+  struct {
+    unsigned int disabled:1;
+    unsigned int fips:1;
+  } flags;
+  const char *name;
+  unsigned char *asnoid;
+  int asnlen;
+  gcry_md_oid_spec_t *oids;
+  int mdlen;
+  gcry_md_init_t init;
+  gcry_md_write_t write;
+  gcry_md_final_t final;
+  gcry_md_read_t read;
+  size_t contextsize; /* allocate this amount of context */
   selftest_func_t selftest;
-  pk_ext_generate_t ext_generate;
-  pk_comp_keygrip_t comp_keygrip;
-  pk_get_param_t get_param;
-  pk_get_curve_t get_curve;
-  pk_get_curve_param_t get_curve_param;
-} pk_extra_spec_t;
-
-
+} gcry_md_spec_t;
 
-/* The private register functions. */
-gcry_error_t _gcry_cipher_register (gcry_cipher_spec_t *cipher,
-                                    cipher_extra_spec_t *extraspec,
-                                    int *algorithm_id,
-                                    gcry_module_t *module);
-gcry_error_t _gcry_md_register (gcry_md_spec_t *cipher,
-                                md_extra_spec_t *extraspec,
-                                unsigned int *algorithm_id,
-                                gcry_module_t *module);
-gcry_error_t _gcry_pk_register (gcry_pk_spec_t *cipher,
-                                pk_extra_spec_t *extraspec,
-                                unsigned int *algorithm_id,
-                                gcry_module_t *module);
 
+\f
 /* The selftest functions.  */
 gcry_error_t _gcry_cipher_selftest (int algo, int extended,
                                     selftest_report_func_t report);
@@ -121,4 +255,7 @@ gcry_error_t _gcry_hmac_selftest (int algo, int extended,
 
 gcry_error_t _gcry_random_selftest (selftest_report_func_t report);
 
+
+
+
 #endif /*G10_CIPHER_PROTO_H*/
index 0f923d7..10bfe0c 100644 (file)
 #ifndef G10_CIPHER_H
 #define G10_CIPHER_H
 
-#include <gcrypt.h>
+#include "gcrypt-int.h"
 
 #define DBG_CIPHER _gcry_get_debug_flag( 1 )
 
 #include "../random/random.h"
 
 #define PUBKEY_FLAG_NO_BLINDING    (1 << 0)
+#define PUBKEY_FLAG_RFC6979        (1 << 1)
+#define PUBKEY_FLAG_FIXEDLEN       (1 << 2)
+#define PUBKEY_FLAG_LEGACYRESULT   (1 << 3)
+#define PUBKEY_FLAG_RAW_FLAG       (1 << 4)
+#define PUBKEY_FLAG_TRANSIENT_KEY  (1 << 5)
+#define PUBKEY_FLAG_USE_X931       (1 << 6)
+#define PUBKEY_FLAG_USE_FIPS186    (1 << 7)
+#define PUBKEY_FLAG_USE_FIPS186_2  (1 << 8)
+#define PUBKEY_FLAG_PARAM          (1 << 9)
+#define PUBKEY_FLAG_COMP           (1 << 10)
+#define PUBKEY_FLAG_NOCOMP         (1 << 11)
+#define PUBKEY_FLAG_EDDSA          (1 << 12)
+#define PUBKEY_FLAG_GOST           (1 << 13)
+
 
 enum pk_operation
   {
@@ -70,6 +84,30 @@ struct pk_encoding_ctx
 
 #include "cipher-proto.h"
 
+/* The internal encryption modes. */
+enum gcry_cipher_internal_modes
+  {
+    GCRY_CIPHER_MODE_INTERNAL = 0x10000,
+    GCRY_CIPHER_MODE_CMAC     = 0x10000 + 1   /* Cipher-based MAC. */
+  };
+
+
+/*-- cipher.c --*/
+gcry_err_code_t _gcry_cipher_open_internal (gcry_cipher_hd_t *handle,
+                                           int algo, int mode,
+                                           unsigned int flags);
+
+/*-- cipher-cmac.c --*/
+gcry_err_code_t _gcry_cipher_cmac_authenticate
+/*           */ (gcry_cipher_hd_t c, const unsigned char *abuf, size_t abuflen);
+gcry_err_code_t _gcry_cipher_cmac_get_tag
+/*           */ (gcry_cipher_hd_t c,
+                 unsigned char *outtag, size_t taglen);
+gcry_err_code_t _gcry_cipher_cmac_check_tag
+/*           */ (gcry_cipher_hd_t c,
+                 const unsigned char *intag, size_t taglen);
+gcry_err_code_t _gcry_cipher_cmac_set_subkeys
+/*           */ (gcry_cipher_hd_t c);
 
 /*-- rmd160.c --*/
 void _gcry_rmd160_hash_buffer (void *outbuf,
@@ -77,24 +115,84 @@ void _gcry_rmd160_hash_buffer (void *outbuf,
 /*-- sha1.c --*/
 void _gcry_sha1_hash_buffer (void *outbuf,
                              const void *buffer, size_t length);
+void _gcry_sha1_hash_buffers (void *outbuf,
+                              const gcry_buffer_t *iov, int iovcnt);
 
 /*-- rijndael.c --*/
 void _gcry_aes_cfb_enc (void *context, unsigned char *iv,
                         void *outbuf, const void *inbuf,
-                        unsigned int nblocks);
+                        size_t nblocks);
 void _gcry_aes_cfb_dec (void *context, unsigned char *iv,
                         void *outbuf_arg, const void *inbuf_arg,
-                        unsigned int nblocks);
+                        size_t nblocks);
 void _gcry_aes_cbc_enc (void *context, unsigned char *iv,
                         void *outbuf_arg, const void *inbuf_arg,
-                        unsigned int nblocks, int cbc_mac);
+                        size_t nblocks, int cbc_mac);
 void _gcry_aes_cbc_dec (void *context, unsigned char *iv,
                         void *outbuf_arg, const void *inbuf_arg,
-                        unsigned int nblocks);
+                        size_t nblocks);
 void _gcry_aes_ctr_enc (void *context, unsigned char *ctr,
                         void *outbuf_arg, const void *inbuf_arg,
-                        unsigned int nblocks);
-
+                        size_t nblocks);
+
+/*-- blowfish.c --*/
+void _gcry_blowfish_cfb_dec (void *context, unsigned char *iv,
+                            void *outbuf_arg, const void *inbuf_arg,
+                            size_t nblocks);
+
+void _gcry_blowfish_cbc_dec (void *context, unsigned char *iv,
+                            void *outbuf_arg, const void *inbuf_arg,
+                            size_t nblocks);
+
+void _gcry_blowfish_ctr_enc (void *context, unsigned char *ctr,
+                            void *outbuf_arg, const void *inbuf_arg,
+                            size_t nblocks);
+
+/*-- cast5.c --*/
+void _gcry_cast5_cfb_dec (void *context, unsigned char *iv,
+                         void *outbuf_arg, const void *inbuf_arg,
+                         size_t nblocks);
+
+void _gcry_cast5_cbc_dec (void *context, unsigned char *iv,
+                         void *outbuf_arg, const void *inbuf_arg,
+                         size_t nblocks);
+
+void _gcry_cast5_ctr_enc (void *context, unsigned char *ctr,
+                         void *outbuf_arg, const void *inbuf_arg,
+                         size_t nblocks);
+
+/*-- camellia-glue.c --*/
+void _gcry_camellia_ctr_enc (void *context, unsigned char *ctr,
+                             void *outbuf_arg, const void *inbuf_arg,
+                             size_t nblocks);
+void _gcry_camellia_cbc_dec (void *context, unsigned char *iv,
+                             void *outbuf_arg, const void *inbuf_arg,
+                             size_t nblocks);
+void _gcry_camellia_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,
+                            void *outbuf_arg, const void *inbuf_arg,
+                            size_t nblocks);
+void _gcry_serpent_cbc_dec (void *context, unsigned char *iv,
+                            void *outbuf_arg, const void *inbuf_arg,
+                            size_t nblocks);
+void _gcry_serpent_cfb_dec (void *context, unsigned char *iv,
+                            void *outbuf_arg, const void *inbuf_arg,
+                            size_t nblocks);
+
+/*-- twofish.c --*/
+void _gcry_twofish_ctr_enc (void *context, unsigned char *ctr,
+                            void *outbuf_arg, const void *inbuf_arg,
+                            size_t nblocks);
+void _gcry_twofish_cbc_dec (void *context, unsigned char *iv,
+                            void *outbuf_arg, const void *inbuf_arg,
+                            size_t nblocks);
+void _gcry_twofish_cfb_dec (void *context, unsigned char *iv,
+                            void *outbuf_arg, const void *inbuf_arg,
+                            size_t nblocks);
 
 /*-- dsa.c --*/
 void _gcry_register_pk_dsa_progress (gcry_handler_progress_t cbc, void *cb_data);
@@ -114,7 +212,6 @@ void _gcry_register_primegen_progress (gcry_handler_progress_t cb,
                                        void *cb_data);
 
 /*-- pubkey.c --*/
-const char * _gcry_pk_aliased_algo_name (int algorithm);
 
 /* Declarations for the cipher specifications.  */
 extern gcry_cipher_spec_t _gcry_cipher_spec_blowfish;
@@ -131,21 +228,23 @@ extern gcry_cipher_spec_t _gcry_cipher_spec_serpent128;
 extern gcry_cipher_spec_t _gcry_cipher_spec_serpent192;
 extern gcry_cipher_spec_t _gcry_cipher_spec_serpent256;
 extern gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_40;
+extern gcry_cipher_spec_t _gcry_cipher_spec_rfc2268_128;
 extern gcry_cipher_spec_t _gcry_cipher_spec_seed;
 extern gcry_cipher_spec_t _gcry_cipher_spec_camellia128;
 extern gcry_cipher_spec_t _gcry_cipher_spec_camellia192;
 extern gcry_cipher_spec_t _gcry_cipher_spec_camellia256;
-
-extern cipher_extra_spec_t _gcry_cipher_extraspec_tripledes;
-extern cipher_extra_spec_t _gcry_cipher_extraspec_aes;
-extern cipher_extra_spec_t _gcry_cipher_extraspec_aes192;
-extern cipher_extra_spec_t _gcry_cipher_extraspec_aes256;
-
+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;
 
 /* 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_stribog_256;
+extern gcry_md_spec_t _gcry_digest_spec_stribog_512;
 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;
@@ -159,23 +258,12 @@ extern gcry_md_spec_t _gcry_digest_spec_tiger1;
 extern gcry_md_spec_t _gcry_digest_spec_tiger2;
 extern gcry_md_spec_t _gcry_digest_spec_whirlpool;
 
-extern md_extra_spec_t _gcry_digest_extraspec_sha1;
-extern md_extra_spec_t _gcry_digest_extraspec_sha224;
-extern md_extra_spec_t _gcry_digest_extraspec_sha256;
-extern md_extra_spec_t _gcry_digest_extraspec_sha384;
-extern md_extra_spec_t _gcry_digest_extraspec_sha512;
-
 /* Declarations for the pubkey cipher specifications.  */
 extern gcry_pk_spec_t _gcry_pubkey_spec_rsa;
 extern gcry_pk_spec_t _gcry_pubkey_spec_elg;
+extern gcry_pk_spec_t _gcry_pubkey_spec_elg_e;
 extern gcry_pk_spec_t _gcry_pubkey_spec_dsa;
-extern gcry_pk_spec_t _gcry_pubkey_spec_ecdsa;
-extern gcry_pk_spec_t _gcry_pubkey_spec_ecdh;
-
-extern pk_extra_spec_t _gcry_pubkey_extraspec_rsa;
-extern pk_extra_spec_t _gcry_pubkey_extraspec_dsa;
-extern pk_extra_spec_t _gcry_pubkey_extraspec_elg;
-extern pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa;
+extern gcry_pk_spec_t _gcry_pubkey_spec_ecc;
 
 
 #endif /*G10_CIPHER_H*/
diff --git a/src/context.c b/src/context.c
new file mode 100644 (file)
index 0000000..94e5be9
--- /dev/null
@@ -0,0 +1,137 @@
+/* context.c - Context management
+ * Copyright (C) 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/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include "g10lib.h"
+#include "mpi.h"
+#include "context.h"
+
+#define CTX_MAGIC "cTx"
+#define CTX_MAGIC_LEN 3
+
+
+/* The definition of the generic context object.  The public typedef
+   gcry_ctx_t is used to access it.  */
+struct gcry_context
+{
+  char magic[CTX_MAGIC_LEN]; /* Magic value to cross check that this
+                                is really a context object. */
+  char type;     /* The type of the context (CONTEXT_TYPE_foo).  */
+
+  void (*deinit)(void*); /* Function used to free the private part. */
+  PROPERLY_ALIGNED_TYPE u;
+};
+
+
+/* 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
+   NULL if de-initialization is not required.  Returns NULL and sets
+   ERRNO if memory allocation failed.  */
+gcry_ctx_t
+_gcry_ctx_alloc (int type, size_t length, void (*deinit)(void*))
+{
+  gcry_ctx_t ctx;
+
+  switch (type)
+    {
+    case CONTEXT_TYPE_EC:
+      break;
+    default:
+      log_bug ("bad context type %d given to _gcry_ctx_alloc\n", type);
+      break;
+    }
+
+  if (length < sizeof (PROPERLY_ALIGNED_TYPE))
+    length = sizeof (PROPERLY_ALIGNED_TYPE);
+
+  ctx = xtrycalloc (1, sizeof *ctx - sizeof (PROPERLY_ALIGNED_TYPE) + length);
+  if (!ctx)
+    return NULL;
+  memcpy (ctx->magic, CTX_MAGIC, CTX_MAGIC_LEN);
+  ctx->type = type;
+  ctx->deinit = deinit;
+
+  return ctx;
+}
+
+
+/* Return a pointer to the private part of the context CTX.  TYPE is
+   the requested context type.  Using an explicit type allows to cross
+   check the type and eventually allows to store several private
+   contexts in one context object.  The function does not return an
+   error but aborts if the provided CTX is not valid.  */
+void *
+_gcry_ctx_get_pointer (gcry_ctx_t ctx, int type)
+{
+  if (!ctx || memcmp (ctx->magic, CTX_MAGIC, CTX_MAGIC_LEN))
+    log_fatal ("bad pointer %p passed to _gcry_ctx_get_pointer\n", ctx);
+  if (ctx->type != type)
+    log_fatal ("wrong context type %d request for context %p of type %d\n",
+               type, ctx, ctx->type);
+  return &ctx->u;
+}
+
+/* Return a pointer to the private part of the context CTX.  TYPE is
+   the requested context type.  Using an explicit type allows to cross
+   check the type and eventually allows to store several private
+   contexts in one context object.  In contrast to
+   _gcry_ctx_get_pointer, this function returns NULL if no context for
+   the given type was found.  If CTX is NULL the function does not
+   abort but returns NULL.  */
+void *
+_gcry_ctx_find_pointer (gcry_ctx_t ctx, int type)
+{
+  if (!ctx)
+    return NULL;
+  if (memcmp (ctx->magic, CTX_MAGIC, CTX_MAGIC_LEN))
+    log_fatal ("bad pointer %p passed to _gcry_ctx_get_pointer\n", ctx);
+  if (ctx->type != type)
+    return NULL;
+  return &ctx->u;
+}
+
+
+/* Release the generic context CTX.  */
+void
+_gcry_ctx_release (gcry_ctx_t ctx)
+{
+  if (!ctx)
+    return;
+  if (memcmp (ctx->magic, CTX_MAGIC, CTX_MAGIC_LEN))
+    log_fatal ("bad pointer %p passed to gcry_ctx_relase\n", ctx);
+  switch (ctx->type)
+    {
+    case CONTEXT_TYPE_EC:
+      break;
+    default:
+      log_fatal ("bad context type %d detected in gcry_ctx_relase\n",
+                 ctx->type);
+      break;
+    }
+  if (ctx->deinit)
+    ctx->deinit (&ctx->u);
+  xfree (ctx);
+}
diff --git a/src/context.h b/src/context.h
new file mode 100644 (file)
index 0000000..875de24
--- /dev/null
@@ -0,0 +1,32 @@
+/* context.h - Declarations for the context management
+ * Copyright (C) 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/>.
+ */
+
+#ifndef GCRY_CONTEXT_H
+#define GCRY_CONTEXT_H
+
+/* Context types as used in struct gcry_context.  */
+#define CONTEXT_TYPE_EC 1  /* The context is used with EC functions.  */
+
+
+gcry_ctx_t _gcry_ctx_alloc (int type, size_t length, void (*deinit)(void*));
+void *_gcry_ctx_get_pointer (gcry_ctx_t ctx, int type);
+void *_gcry_ctx_find_pointer (gcry_ctx_t ctx, int type);
+
+
+#endif /*GCRY_CONTEXT_H*/
diff --git a/src/ec-context.h b/src/ec-context.h
new file mode 100644 (file)
index 0000000..60ca759
--- /dev/null
@@ -0,0 +1,84 @@
+/* ec-context.h - Private definitions for CONTEXT_TYPE_EC.
+ * Copyright (C) 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/>.
+ */
+
+#ifndef GCRY_EC_CONTEXT_H
+#define GCRY_EC_CONTEXT_H
+
+/* This context is used with all our EC functions. */
+struct mpi_ec_ctx_s
+{
+  enum gcry_mpi_ec_models model; /* The model describing this curve.  */
+
+  enum ecc_dialects dialect;     /* The ECC dialect used with the curve.  */
+
+  int flags;                     /* Public key flags (not always used).  */
+
+  unsigned int nbits;            /* Number of bits.  */
+
+  /* Domain parameters.  Note that they may not all be set and if set
+     the MPIs may be flaged as constant. */
+  gcry_mpi_t p;         /* Prime specifying the field GF(p).  */
+  gcry_mpi_t a;         /* First coefficient of the Weierstrass equation.  */
+  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.  */
+
+  /* The actual key.  May not be set.  */
+  gcry_mpi_point_t Q;   /* Public key.   */
+  gcry_mpi_t d;         /* Private key.  */
+
+
+  /* This structure is private to mpi/ec.c! */
+  struct {
+    struct {
+      unsigned int a_is_pminus3:1;
+      unsigned int two_inv_p:1;
+    } valid; /* Flags to help setting the helper vars below.  */
+
+    int a_is_pminus3;  /* True if A = P - 3. */
+
+    gcry_mpi_t two_inv_p;
+
+    mpi_barrett_t p_barrett;
+
+    /* Scratch variables.  */
+    gcry_mpi_t scratch[11];
+
+    /* Helper for fast reduction.  */
+    /*   int nist_nbits; /\* If this is a NIST curve, the # of bits.  *\/ */
+    /*   gcry_mpi_t s[10]; */
+    /*   gcry_mpi_t c; */
+  } t;
+};
+
+
+/*-- mpi/ec.c --*/
+void _gcry_mpi_ec_get_reset (mpi_ec_t ec);
+
+
+/*-- cipher/ecc-curves.c --*/
+gcry_mpi_t       _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy);
+gcry_mpi_point_t _gcry_ecc_get_point (const char *name, mpi_ec_t ec);
+gpg_err_code_t   _gcry_ecc_set_mpi (const char *name,
+                                    gcry_mpi_t newvalue, mpi_ec_t ec);
+gpg_err_code_t   _gcry_ecc_set_point (const char *name,
+                                      gcry_mpi_point_t newvalue, mpi_ec_t ec);
+
+
+#endif /*GCRY_EC_CONTEXT_H*/
index 8bc45e7..8148dcd 100644 (file)
@@ -36,7 +36,7 @@
 #include "hmac256.h"
 
 
-/* The name of the file used to foce libgcrypt into fips mode. */
+/* The name of the file used to force libgcrypt into fips mode. */
 #define FIPS_FORCE_FILE "/etc/gcrypt/fips_enabled"
 
 
@@ -69,7 +69,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 = ATH_MUTEX_INITIALIZER;
+static ath_mutex_t 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. */
@@ -274,9 +274,17 @@ _gcry_fips_mode (void)
 int
 _gcry_enforced_fips_mode (void)
 {
+  if (!_gcry_fips_mode ())
+    return 0;
   return enforced_fips_mode;
 }
 
+/* Set a flag telling whether we are in the enforced fips mode.  */
+void
+_gcry_set_enforced_fips_mode (void)
+{
+  enforced_fips_mode = 1;
+}
 
 /* If we do not want to enforce the fips mode, we can set a flag so
    that the application may check whether it is still in fips mode.
@@ -538,7 +546,7 @@ run_pubkey_selftests (int extended)
     {
       GCRY_PK_RSA,
       GCRY_PK_DSA,
-      /* GCRY_PK_ECDSA is not enabled in fips mode.  */
+      /* GCRY_PK_ECC is not enabled in fips mode.  */
       0
     };
   int idx;
@@ -652,7 +660,7 @@ check_binary_integrity (void)
             "integrity check using `%s' failed: %s",
             fname? fname:"[?]", gpg_strerror (err));
 #endif /*HAVE_SYSLOG*/
-  gcry_free (fname);
+  xfree (fname);
   return !!err;
 #else
   return 0;
index 8d98ae3..43dc011 100644 (file)
 #define GCC_ATTR_FORMAT_ARG(a)
 #endif
 
+/* I am not sure since when the unused attribute is really supported.
+   In any case it it only needed for gcc versions which print a
+   warning.  Thus let us require gcc >= 3.5.  */
+#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 5 )
+#define GCC_ATTR_UNUSED  __attribute__ ((unused))
+#else
+#define GCC_ATTR_UNUSED
+#endif
 
 /* Gettext macros.  */
 
@@ -88,6 +96,36 @@ gcry_error_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);
 
+/* Malloc functions and common wrapper macros.  */
+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);
+int   _gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE;
+
+#define xtrymalloc(a)    _gcry_malloc ((a))
+#define xtrycalloc(a,b)  _gcry_calloc ((a),(b))
+#define xtrymalloc_secure(a)   _gcry_malloc_secure ((a))
+#define xtrycalloc_secure(a,b) _gcry_calloc_secure ((a),(b))
+#define xtryrealloc(a,b) _gcry_realloc ((a),(b))
+#define xtrystrdup(a)    _gcry_strdup ((a))
+#define xmalloc(a)       _gcry_xmalloc ((a))
+#define xcalloc(a,b)     _gcry_xcalloc ((a),(b))
+#define xmalloc_secure(a)   _gcry_xmalloc_secure ((a))
+#define xcalloc_secure(a,b) _gcry_xcalloc_secure ((a),(b))
+#define xrealloc(a,b)    _gcry_xrealloc ((a),(b))
+#define xstrdup(a)       _gcry_xstrdup ((a))
+#define xfree(a)         _gcry_free ((a))
+
 
 /*-- src/misc.c --*/
 
@@ -101,8 +139,12 @@ void _gcry_bug (const char *file, int line);
 void _gcry_assert_failed (const char *expr, const char *file, int line);
 #endif
 
+void _gcry_divide_by_zero (void) JNLIB_GCC_A_NR;
+
 const char *_gcry_gettext (const char *key) GCC_ATTR_FORMAT_ARG(1);
 void _gcry_fatal_error(int rc, const char *text ) JNLIB_GCC_A_NR;
+void _gcry_logv (int level,
+                 const char *fmt, va_list arg_ptr) JNLIB_GCC_A_PRINTF(2,0);
 void _gcry_log( int level, const char *fmt, ... ) JNLIB_GCC_A_PRINTF(2,3);
 void _gcry_log_bug( const char *fmt, ... )   JNLIB_GCC_A_NR_PRINTF(1,2);
 void _gcry_log_fatal( const char *fmt, ... ) JNLIB_GCC_A_NR_PRINTF(1,2);
@@ -113,6 +155,8 @@ int  _gcry_log_info_with_dummy_fp (FILE *fp, const char *fmt, ... )
 void _gcry_log_debug( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
 void _gcry_log_printf ( const char *fmt, ... ) JNLIB_GCC_A_PRINTF(1,2);
 void _gcry_log_printhex (const char *text, const void *buffer, size_t length);
+void _gcry_log_printmpi (const char *text, gcry_mpi_t mpi);
+void _gcry_log_printsxp (const char *text, gcry_sexp_t sexp);
 
 void _gcry_set_log_verbosity( int level );
 int _gcry_log_verbosity( int level );
@@ -139,6 +183,11 @@ int _gcry_log_verbosity( int level );
 #define log_debug   _gcry_log_debug
 #define log_printf  _gcry_log_printf
 #define log_printhex _gcry_log_printhex
+#define log_printmpi _gcry_log_printmpi
+#define log_printsxp _gcry_log_printsxp
+
+/* Compatibility macro.  */
+#define log_mpidump _gcry_log_printmpi
 
 
 /*-- src/hwfeatures.c --*/
@@ -148,11 +197,22 @@ int _gcry_log_verbosity( int level );
 #define HWF_PADLOCK_SHA  4
 #define HWF_PADLOCK_MMUL 8
 
+#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_ARM_NEON     4096
 
+
+gpg_err_code_t _gcry_disable_hw_feature (const char *name);
+void _gcry_detect_hw_features (void);
 unsigned int _gcry_get_hw_features (void);
-void _gcry_detect_hw_features (unsigned int);
+const char *_gcry_enum_hw_features (int idx, unsigned int *r_feature);
 
 
 /*-- mpi/mpiutil.c --*/
@@ -167,6 +227,7 @@ const char *_gcry_mpi_get_hw_config (void);
 #endif
 
 /*-- primegen.c --*/
+gcry_err_code_t _gcry_primegen_init (void);
 gcry_mpi_t _gcry_generate_secret_prime (unsigned int nbits,
                                  gcry_random_level_t random_level,
                                  int (*extra_check)(void*, gcry_mpi_t),
@@ -227,7 +288,16 @@ int strcasecmp (const char *a, const char *b) _GCRY_GCC_ATTR_PURE;
 
 /* Stack burning.  */
 
-void _gcry_burn_stack (int bytes);
+#ifdef HAVE_GCC_ASM_VOLATILE_MEMORY
+#define  __gcry_burn_stack_dummy() asm volatile ("":::"memory")
+#else
+void __gcry_burn_stack_dummy (void);
+#endif
+
+void __gcry_burn_stack (unsigned int bytes);
+#define _gcry_burn_stack(bytes) \
+       do { __gcry_burn_stack (bytes); \
+            __gcry_burn_stack_dummy (); } while(0)
 
 
 /* To avoid that a compiler optimizes certain memset calls away, these
@@ -235,10 +305,48 @@ void _gcry_burn_stack (int bytes);
 #define wipememory2(_ptr,_set,_len) do { \
               volatile char *_vptr=(volatile char *)(_ptr); \
               size_t _vlen=(_len); \
-              while(_vlen) { *_vptr=(_set); _vptr++; _vlen--; } \
+              unsigned char _vset=(_set); \
+              fast_wipememory2(_vptr,_vset,_vlen); \
+              while(_vlen) { *_vptr=(_vset); _vptr++; _vlen--; } \
                   } 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
+
+/* 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__)
+#define fast_wipememory2_unaligned_head(_ptr,_set,_len) /*do nothing*/
+#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)
+#endif
+
+/* fast_wipememory2 may leave tail bytes unhandled, in which case tail bytes
+   are handled by wipememory2. */
+#define fast_wipememory2(_vptr,_vset,_vlen) do { \
+              FASTWIPE_T _vset_long = _vset; \
+              fast_wipememory2_unaligned_head(_vptr,_vset,_vlen); \
+              if (_vlen < sizeof(FASTWIPE_T)) \
+                break; \
+              _vset_long *= FASTWIPE_MULT; \
+              do { \
+                volatile FASTWIPE_T *_vptr_long = (volatile void *)_vptr; \
+                *_vptr_long = _vset_long; \
+                _vlen -= sizeof(FASTWIPE_T); \
+                _vptr += sizeof(FASTWIPE_T); \
+              } while (_vlen >= sizeof(FASTWIPE_T)); \
+                  } while (0)
 
 
 /* Digit predicates.  */
@@ -251,70 +359,24 @@ void _gcry_burn_stack (int bytes);
                       || (*(a) >= 'A' && *(a) <= 'F')  \
                       || (*(a) >= 'a' && *(a) <= 'f'))
 
-/* Management for ciphers/digests/pubkey-ciphers.  */
-
-/* Structure for each registered `module'.  */
-struct gcry_module
-{
-  struct gcry_module *next;     /* List pointers.      */
-  struct gcry_module **prevp;
-  void *spec;                  /* Pointer to the subsystem-specific
-                                  specification structure.  */
-  void *extraspec;             /* Pointer to the subsystem-specific
-                                  extra specification structure.  */
-  int flags;                   /* Associated flags.   */
-  int counter;                 /* Use counter.        */
-  unsigned int mod_id;         /* ID of this module.  */
-};
-
-/* Flags for the `flags' member of gcry_module_t.  */
-#define FLAG_MODULE_DISABLED (1 << 0)
-
-gcry_err_code_t _gcry_module_add (gcry_module_t *entries,
-                                  unsigned int id,
-                                  void *spec,
-                                  void *extraspec,
-                                  gcry_module_t *module);
-
-typedef int (*gcry_module_lookup_t) (void *spec, void *data);
-
-/* Lookup a module specification by it's ID.  After a successful
-   lookup, the module has it's resource counter incremented.  */
-gcry_module_t _gcry_module_lookup_id (gcry_module_t entries,
-                                      unsigned int id);
-
-/* Internal function.  Lookup a module specification.  */
-gcry_module_t _gcry_module_lookup (gcry_module_t entries, void *data,
-                                   gcry_module_lookup_t func);
-
-/* Release a module.  In case the use-counter reaches zero, destroy
-   the module.  */
-void _gcry_module_release (gcry_module_t entry);
-
-/* Add a reference to a module.  */
-void _gcry_module_use (gcry_module_t module);
-
-/* Return a list of module IDs.  */
-gcry_err_code_t _gcry_module_list (gcry_module_t modules,
-                                 int *list, int *list_length);
+/* Init functions.  */
 
 gcry_err_code_t _gcry_cipher_init (void);
 gcry_err_code_t _gcry_md_init (void);
 gcry_err_code_t _gcry_pk_init (void);
-gcry_err_code_t _gcry_ac_init (void);
-
-gcry_err_code_t _gcry_pk_module_lookup (int id, gcry_module_t *module);
-void _gcry_pk_module_release (gcry_module_t module);
-gcry_err_code_t _gcry_pk_get_elements (int algo, char **enc, char **sig);
+gcry_err_code_t _gcry_secmem_module_init (void);
+gcry_err_code_t _gcry_mpi_init (void);
 
 /* Memory management.  */
 #define GCRY_ALLOC_FLAG_SECURE (1 << 0)
 
 
 /*-- sexp.c --*/
-gcry_error_t _gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff,
-                                const char *format, va_list arg_ptr);
+gcry_err_code_t _gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff,
+                                   const char *format, va_list arg_ptr);
 char *_gcry_sexp_nth_string (const gcry_sexp_t list, int number);
+gpg_err_code_t _gcry_sexp_vextract_param (gcry_sexp_t sexp, const char *path,
+                                          const char *list, va_list arg_ptr);
 
 
 /*-- fips.c --*/
@@ -326,6 +388,8 @@ int _gcry_fips_mode (void);
 
 int _gcry_enforced_fips_mode (void);
 
+void _gcry_set_enforced_fips_mode (void);
+
 void _gcry_inactivate_fips_mode (const char *text);
 int _gcry_is_fips_mode_inactive (void);
 
@@ -349,7 +413,7 @@ void _gcry_fips_signal_error (const char *srcfile,
 
 int _gcry_fips_is_operational (void);
 #define fips_is_operational()   (_gcry_global_is_operational ())
-#define fips_not_operational()  (GCRY_GPG_ERR_NOT_OPERATIONAL)
+#define fips_not_operational()  (GPG_ERR_NOT_OPERATIONAL)
 
 int _gcry_fips_test_operational (void);
 int _gcry_fips_test_error_or_operational (void);
diff --git a/src/gcrypt-int.h b/src/gcrypt-int.h
new file mode 100644 (file)
index 0000000..65dcb4d
--- /dev/null
@@ -0,0 +1,534 @@
+/* gcrypt-int.h - Internal version of gcrypt.h
+ * Copyright (C) 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/>.
+ */
+
+#ifndef GCRY_GCRYPT_INT_H
+#define GCRY_GCRYPT_INT_H
+
+#ifdef _GCRYPT_H
+#error  gcrypt.h already included
+#endif
+
+#include "gcrypt.h"
+#include "types.h"
+
+/* These error codes are used but not defined in the required
+   libgpg-error 1.11.  Define them here. */
+#if GPG_ERROR_VERSION_NUMBER < 0x010c00  /* 1.12 */
+# define GPG_ERR_NO_CRYPT_CTX      191
+# define GPG_ERR_WRONG_CRYPT_CTX    192
+# define GPG_ERR_BAD_CRYPT_CTX     193
+# define GPG_ERR_CRYPT_CTX_CONFLICT 194
+# define GPG_ERR_BROKEN_PUBKEY      195
+# define GPG_ERR_BROKEN_SECKEY      196
+#endif
+
+#if GPG_ERROR_VERSION_NUMBER < 0x010d00  /* 1.13 */
+# define GPG_ERR_MAC_ALGO           197
+#endif
+
+\f
+/* Context used with elliptic curve functions.  */
+struct mpi_ec_ctx_s;
+typedef struct mpi_ec_ctx_s *mpi_ec_t;
+
+
+\f
+/* Underscore prefixed internal versions of the public functions.
+   They return gpg_err_code and not gpg_error_t.  Some macros also
+   need an underscore prefixed internal version.
+
+   Note that the memory allocation functions and macros (xmalloc etc.)
+   are not defined here but in g10lib.h because this file here is
+   included by some test programs which define theie own xmalloc
+   macros.  */
+
+gpg_err_code_t _gcry_cipher_open (gcry_cipher_hd_t *handle,
+                                  int algo, int mode, unsigned int flags);
+void _gcry_cipher_close (gcry_cipher_hd_t h);
+gpg_err_code_t _gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer,
+                             size_t buflen);
+gpg_err_code_t _gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer,
+                                  size_t *nbytes);
+gpg_err_code_t _gcry_cipher_algo_info (int algo, int what, void *buffer,
+                                       size_t *nbytes);
+const char *_gcry_cipher_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
+int _gcry_cipher_map_name (const char *name) _GCRY_GCC_ATTR_PURE;
+int _gcry_cipher_mode_from_oid (const char *string) _GCRY_GCC_ATTR_PURE;
+gpg_err_code_t _gcry_cipher_encrypt (gcry_cipher_hd_t h,
+                                     void *out, size_t outsize,
+                                     const void *in, size_t inlen);
+gpg_err_code_t _gcry_cipher_decrypt (gcry_cipher_hd_t h,
+                                     void *out, size_t outsize,
+                                     const void *in, size_t inlen);
+gcry_err_code_t _gcry_cipher_setkey (gcry_cipher_hd_t hd,
+                                     const void *key, size_t keylen);
+gcry_err_code_t _gcry_cipher_setiv (gcry_cipher_hd_t hd,
+                                    const void *iv, size_t ivlen);
+gpg_err_code_t _gcry_cipher_authenticate (gcry_cipher_hd_t hd, const void *abuf,
+                                          size_t abuflen);
+gpg_err_code_t _gcry_cipher_gettag (gcry_cipher_hd_t hd, void *outtag,
+                                    size_t taglen);
+gpg_err_code_t _gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag,
+                                      size_t taglen);
+gpg_err_code_t _gcry_cipher_setctr (gcry_cipher_hd_t hd,
+                                    const void *ctr, size_t ctrlen);
+size_t _gcry_cipher_get_algo_keylen (int algo);
+size_t _gcry_cipher_get_algo_blklen (int algo);
+
+#define _gcry_cipher_reset(h)  _gcry_cipher_ctl ((h), GCRYCTL_RESET, NULL, 0)
+
+
+
+\f
+gpg_err_code_t _gcry_pk_encrypt (gcry_sexp_t *result,
+                                 gcry_sexp_t data, gcry_sexp_t pkey);
+gpg_err_code_t _gcry_pk_decrypt (gcry_sexp_t *result,
+                                 gcry_sexp_t data, gcry_sexp_t skey);
+gpg_err_code_t _gcry_pk_sign (gcry_sexp_t *result,
+                              gcry_sexp_t data, gcry_sexp_t skey);
+gpg_err_code_t _gcry_pk_verify (gcry_sexp_t sigval,
+                                gcry_sexp_t data, gcry_sexp_t pkey);
+gpg_err_code_t _gcry_pk_testkey (gcry_sexp_t key);
+gpg_err_code_t _gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms);
+gpg_err_code_t _gcry_pk_ctl (int cmd, void *buffer, size_t buflen);
+gpg_err_code_t _gcry_pk_algo_info (int algo, int what,
+                                   void *buffer, size_t *nbytes);
+const char *_gcry_pk_algo_name (int algorithm) _GCRY_GCC_ATTR_PURE;
+int _gcry_pk_map_name (const char* name) _GCRY_GCC_ATTR_PURE;
+unsigned int _gcry_pk_get_nbits (gcry_sexp_t key) _GCRY_GCC_ATTR_PURE;
+unsigned char *_gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array);
+const char *_gcry_pk_get_curve (gcry_sexp_t key, int iterator,
+                                unsigned int *r_nbits);
+gcry_sexp_t _gcry_pk_get_param (int algo, const char *name);
+gpg_err_code_t _gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp,
+                                      int mode, gcry_ctx_t ctx);
+
+\f
+gpg_err_code_t _gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags);
+void _gcry_md_close (gcry_md_hd_t hd);
+gpg_err_code_t _gcry_md_enable (gcry_md_hd_t hd, int algo);
+gpg_err_code_t _gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd);
+void _gcry_md_reset (gcry_md_hd_t hd);
+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);
+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,
+                                      void *digest,
+                                      const gcry_buffer_t *iov, int iovcnt);
+int _gcry_md_get_algo (gcry_md_hd_t hd);
+unsigned int _gcry_md_get_algo_dlen (int algo);
+int _gcry_md_is_enabled (gcry_md_hd_t a, int algo);
+int _gcry_md_is_secure (gcry_md_hd_t a);
+gpg_err_code_t _gcry_md_info (gcry_md_hd_t h, int what, void *buffer,
+                          size_t *nbytes);
+gpg_err_code_t _gcry_md_algo_info (int algo, int what, void *buffer,
+                                size_t *nbytes);
+const char *_gcry_md_algo_name (int algo) _GCRY_GCC_ATTR_PURE;
+int _gcry_md_map_name (const char* name) _GCRY_GCC_ATTR_PURE;
+gpg_err_code_t _gcry_md_setkey (gcry_md_hd_t hd,
+                                const void *key, size_t keylen);
+void _gcry_md_debug (gcry_md_hd_t hd, const char *suffix);
+
+#define _gcry_md_test_algo(a) \
+            _gcry_md_algo_info ((a), GCRYCTL_TEST_ALGO, NULL, NULL)
+
+#define _gcry_md_final(a) \
+            _gcry_md_ctl ((a), GCRYCTL_FINALIZE, NULL, 0)
+
+#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)
+
+
+\f
+gpg_err_code_t _gcry_mac_open (gcry_mac_hd_t *handle, int algo,
+                            unsigned int flags, gcry_ctx_t ctx);
+void _gcry_mac_close (gcry_mac_hd_t h);
+gpg_err_code_t _gcry_mac_ctl (gcry_mac_hd_t h, int cmd, void *buffer,
+                           size_t buflen);
+gpg_err_code_t _gcry_mac_algo_info (int algo, int what, void *buffer,
+                                 size_t *nbytes);
+gpg_err_code_t _gcry_mac_setkey (gcry_mac_hd_t hd, const void *key,
+                              size_t keylen);
+gpg_err_code_t _gcry_mac_setiv (gcry_mac_hd_t hd, const void *iv,
+                             size_t ivlen);
+gpg_err_code_t _gcry_mac_write (gcry_mac_hd_t hd, const void *buffer,
+                             size_t length);
+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);
+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;
+int _gcry_mac_map_name (const char *name) _GCRY_GCC_ATTR_PURE;
+
+#define _gcry_mac_reset(h)  _gcry_mac_ctl ((h), GCRYCTL_RESET, NULL, 0)
+
+\f
+gpg_err_code_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
+gpg_err_code_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);
+gpg_err_code_t _gcry_prime_group_generator (gcry_mpi_t *r_g,
+                                            gcry_mpi_t prime,
+                                            gcry_mpi_t *factors,
+                                            gcry_mpi_t start_g);
+void _gcry_prime_release_factors (gcry_mpi_t *factors);
+gpg_err_code_t _gcry_prime_check (gcry_mpi_t x, unsigned int flags);
+
+\f
+void _gcry_randomize (void *buffer, size_t length,
+                      enum gcry_random_level level);
+gpg_err_code_t _gcry_random_add_bytes (const void *buffer, size_t length,
+                                    int quality);
+void *_gcry_random_bytes (size_t nbytes, enum gcry_random_level level)
+                         _GCRY_GCC_ATTR_MALLOC;
+void *_gcry_random_bytes_secure (size_t nbytes, enum gcry_random_level level)
+                                _GCRY_GCC_ATTR_MALLOC;
+void _gcry_mpi_randomize (gcry_mpi_t w,
+                         unsigned int nbits, enum gcry_random_level level);
+void _gcry_create_nonce (void *buffer, size_t length);
+
+\f
+void _gcry_ctx_release (gcry_ctx_t ctx);
+
+\f
+const char *_gcry_check_version (const char *req_version);
+
+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);
+void _gcry_set_outofcore_handler (gcry_handler_no_mem_t h, void *opaque);
+void _gcry_set_fatalerror_handler (gcry_handler_error_t fnc, void *opaque);
+void _gcry_set_log_handler (gcry_handler_log_t f, void *opaque);
+void _gcry_set_gettext_handler (const char *(*f)(const char*));
+void _gcry_set_progress_handler (gcry_handler_progress_t cb, void *cb_data);
+
+\f
+/* Return a pointer to a string containing a description of the error
+   code in the error value ERR.  */
+static inline const char *
+_gcry_strerror (gcry_error_t err)
+{
+  return gpg_strerror (err);
+}
+
+/* Return a pointer to a string containing a description of the error
+   source in the error value ERR.  */
+static inline const char *
+_gcry_strsource (gcry_error_t err)
+{
+  return gpg_strsource (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).  */
+static inline gcry_err_code_t
+_gcry_err_code_from_errno (int err)
+{
+  return gpg_err_code_from_errno (err);
+}
+
+/* Retrieve the system error for the error code CODE.  This returns 0
+   if CODE is not a system error code.  */
+static inline int
+_gcry_err_code_to_errno (gcry_err_code_t code)
+{
+  return gpg_err_code_from_errno (code);
+}
+
+/* Return an error value with the error source SOURCE and the system
+   error ERR.  */
+static inline gcry_err_code_t
+_gcry_err_make_from_errno (gpg_err_source_t source, int err)
+{
+  return gpg_err_make_from_errno (source, err);
+}
+
+
+/* Return an error value with the system error ERR.  */
+static inline gcry_err_code_t
+_gcry_error_from_errno (int err)
+{
+  return gpg_error (gpg_err_code_from_errno (err));
+}
+
+
+\f
+gpg_err_code_t _gcry_sexp_new (gcry_sexp_t *retsexp,
+                               const void *buffer, size_t length,
+                               int autodetect);
+gpg_err_code_t _gcry_sexp_create (gcry_sexp_t *retsexp,
+                                  void *buffer, size_t length,
+                                  int autodetect, void (*freefnc) (void *));
+gpg_err_code_t _gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+                              const char *buffer, size_t length);
+gpg_err_code_t _gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff,
+                                 const char *format, ...);
+gpg_err_code_t _gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
+                                       const char *format, void **arg_list);
+void _gcry_sexp_release (gcry_sexp_t sexp);
+size_t _gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
+                            size_t *erroff, gcry_err_code_t *errcode);
+size_t _gcry_sexp_sprint (gcry_sexp_t sexp, int mode, void *buffer,
+                          size_t maxlength);
+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);
+gcry_sexp_t _gcry_sexp_find_token (gcry_sexp_t list,
+                                   const char *tok, size_t toklen);
+int _gcry_sexp_length (const gcry_sexp_t list);
+gcry_sexp_t _gcry_sexp_nth (const gcry_sexp_t list, int number);
+gcry_sexp_t _gcry_sexp_car (const gcry_sexp_t list);
+gcry_sexp_t _gcry_sexp_cdr (const gcry_sexp_t list);
+gcry_sexp_t _gcry_sexp_cadr (const gcry_sexp_t list);
+const char *_gcry_sexp_nth_data (const gcry_sexp_t list, int number,
+                                 size_t *datalen);
+void *_gcry_sexp_nth_buffer (const gcry_sexp_t list, int number,
+                             size_t *rlength);
+char *_gcry_sexp_nth_string (gcry_sexp_t list, int number);
+gcry_mpi_t _gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt);
+gpg_err_code_t _gcry_sexp_extract_param (gcry_sexp_t sexp,
+                                         const char *path,
+                                         const char *list,
+                                         ...) _GCRY_GCC_ATTR_SENTINEL(0);
+
+#define sexp_new(a, b, c, d)         _gcry_sexp_new ((a), (b), (c), (d))
+#define sexp_create(a, b, c, d, e)   _gcry_sexp_create ((a), (b), (c), (d), (e))
+#define sexp_sscan(a, b, c, d)       _gcry_sexp_sscan ((a), (b), (c), (d))
+#define sexp_build                   _gcry_sexp_build
+#define sexp_build_array(a, b, c, d) _gcry_sexp_build_array ((a), (b), (c), (d))
+#define sexp_release(a)              _gcry_sexp_release ((a))
+#define sexp_canon_len(a, b, c, d)   _gcry_sexp_canon_len ((a), (b), (c), (d))
+#define sexp_sprint(a, b, c, d)      _gcry_sexp_sprint ((a), (b), (c), (d))
+#define sexp_dump(a)                 _gcry_sexp_dump ((a))
+#define sexp_cons(a, b)              _gcry_sexp_cons ((a), (b))
+#define sexp_alist(a)                _gcry_sexp_alist ((a))
+#define sexp_vlist                   _gcry_sexp_vlist
+#define sexp_append(a, b)            _gcry_sexp_append ((a), (b))
+#define sexp_prepend(a, b)           _gcry_sexp_prepend ((a), (b))
+#define sexp_find_token(a, b, c)     _gcry_sexp_find_token ((a), (b), (c))
+#define sexp_length(a)               _gcry_sexp_length ((a))
+#define sexp_nth(a, b)               _gcry_sexp_nth ((a), (b))
+#define sexp_car(a)                  _gcry_sexp_car ((a))
+#define sexp_cdr(a)                  _gcry_sexp_cdr ((a))
+#define sexp_cadr(a)                 _gcry_sexp_cadr ((a))
+#define sexp_nth_data(a, b, c)       _gcry_sexp_nth_data ((a), (b), (c))
+#define sexp_nth_buffer(a, b, c)     _gcry_sexp_nth_buffer ((a), (b), (c))
+#define sexp_nth_string(a, b)        _gcry_sexp_nth_string ((a), (b))
+#define sexp_nth_mpi(a, b, c)        _gcry_sexp_nth_mpi ((a), (b), (c))
+#define sexp_extract_param           _gcry_sexp_extract_param
+
+
+\f
+gcry_mpi_t _gcry_mpi_new (unsigned int nbits);
+gcry_mpi_t _gcry_mpi_snew (unsigned int nbits);
+void _gcry_mpi_release (gcry_mpi_t a);
+gcry_mpi_t _gcry_mpi_copy (const gcry_mpi_t a);
+void _gcry_mpi_snatch (gcry_mpi_t w, gcry_mpi_t u);
+gcry_mpi_t _gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u);
+gcry_mpi_t _gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u);
+gcry_err_code_t _gcry_mpi_get_ui (gcry_mpi_t w, ulong *u);
+void _gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b);
+int _gcry_mpi_is_neg (gcry_mpi_t a);
+void _gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u);
+void _gcry_mpi_abs (gcry_mpi_t w);
+int _gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v);
+int _gcry_mpi_cmp_ui (const gcry_mpi_t u, unsigned long v);
+gpg_err_code_t _gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format,
+                              const void *buffer, size_t buflen,
+                              size_t *nscanned);
+gpg_err_code_t _gcry_mpi_print (enum gcry_mpi_format format,
+                               unsigned char *buffer, size_t buflen,
+                               size_t *nwritten,
+                               const gcry_mpi_t a);
+gpg_err_code_t _gcry_mpi_aprint (enum gcry_mpi_format format,
+                                unsigned char **buffer, size_t *nwritten,
+                                const gcry_mpi_t a);
+void _gcry_mpi_dump (const gcry_mpi_t a);
+void _gcry_mpi_add (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+void _gcry_mpi_add_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v);
+void _gcry_mpi_addm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+void _gcry_mpi_sub (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+void _gcry_mpi_sub_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v );
+void _gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+void _gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v);
+void _gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v );
+void _gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m);
+void _gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt);
+void _gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r,
+                   gcry_mpi_t dividend, gcry_mpi_t divisor, int round);
+void _gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor);
+void _gcry_mpi_powm (gcry_mpi_t w,
+                    const gcry_mpi_t b, const gcry_mpi_t e,
+                    const gcry_mpi_t m);
+int _gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b);
+int _gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m);
+gcry_mpi_point_t _gcry_mpi_point_new (unsigned int nbits);
+void _gcry_mpi_point_release (gcry_mpi_point_t point);
+void _gcry_mpi_point_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+                         gcry_mpi_point_t point);
+void _gcry_mpi_point_snatch_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+                                gcry_mpi_point_t 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);
+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_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);
+unsigned int _gcry_mpi_get_nbits (gcry_mpi_t a);
+int _gcry_mpi_test_bit (gcry_mpi_t a, unsigned int n);
+void _gcry_mpi_set_bit (gcry_mpi_t a, unsigned int n);
+void _gcry_mpi_clear_bit (gcry_mpi_t a, unsigned int n);
+void _gcry_mpi_set_highbit (gcry_mpi_t a, unsigned int n);
+void _gcry_mpi_clear_highbit (gcry_mpi_t a, unsigned int n);
+void _gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
+void _gcry_mpi_lshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
+gcry_mpi_t _gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits);
+gcry_mpi_t _gcry_mpi_set_opaque_copy (gcry_mpi_t a,
+                                     const void *p, unsigned int nbits);
+void *_gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits);
+void _gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+void _gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
+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); */
+
+/* We need our internal versions of the macros.  */
+#ifndef GCRYPT_NO_MPI_MACROS
+# error GCRYPT_NO_MPI_MACROS is not defined
+#endif
+
+#define mpi_new(n)             _gcry_mpi_new ((n))
+#define mpi_secure_new( n )    _gcry_mpi_snew ((n))
+#define mpi_snew(n)            _gcry_mpi_snew ((n))
+
+#define mpi_release(a)        \
+  do                          \
+    {                         \
+      _gcry_mpi_release ((a));\
+      (a) = NULL;             \
+    }                         \
+  while (0)
+
+#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_get_ui(a,b)        _gcry_mpi_get_ui( (a), (b) )
+#define mpi_swap(a,b)          _gcry_mpi_swap ((a),(b))
+#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))
+#define mpi_set_flag(a,f)      _gcry_mpi_set_flag ((a), (f))
+#define mpi_set_flag(a,f)      _gcry_mpi_set_flag ((a), (f))
+#define mpi_clear_flag(a,f)    _gcry_mpi_clear_flag ((a), (f))
+#define mpi_get_flag(a,f)      _gcry_mpi_get_flag ((a), (f))
+
+
+#endif /*GCRY_GCRYPT_INT_H*/
diff --git a/src/gcrypt-module.h b/src/gcrypt-module.h
deleted file mode 100644 (file)
index f39e2b5..0000000
+++ /dev/null
@@ -1,240 +0,0 @@
-/* gcrypt-module.h - GNU Cryptographic Library Interface
-   Copyright (C) 2003, 2007 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/>.
- */
-
-/*
-   This file contains the necessary declarations/definitions for
-   working with Libgcrypt modules.
- */
-
-#ifndef _GCRYPT_MODULE_H
-#define _GCRYPT_MODULE_H
-
-#ifdef __cplusplus
-extern "C" {
-#if 0 /* keep Emacsens's auto-indent happy */
-}
-#endif
-#endif
-
-/* The interfaces using the module system reserve a certain range of
-   IDs for application use.  These IDs are not valid within Libgcrypt
-   but Libgcrypt makes sure never to allocate such a module ID.  */
-#define GCRY_MODULE_ID_USER      1024
-#define GCRY_MODULE_ID_USER_LAST 4095
-
-
-/* This type represents a `module'.  */
-typedef struct gcry_module *gcry_module_t;
-
-/* Check that the library fulfills the version requirement.  */
-
-/* Type for the cipher_setkey function.  */
-typedef gcry_err_code_t (*gcry_cipher_setkey_t) (void *c,
-                                                const unsigned char *key,
-                                                unsigned keylen);
-
-/* Type for the cipher_encrypt function.  */
-typedef void (*gcry_cipher_encrypt_t) (void *c,
-                                      unsigned char *outbuf,
-                                      const unsigned char *inbuf);
-
-/* Type for the cipher_decrypt function.  */
-typedef void (*gcry_cipher_decrypt_t) (void *c,
-                                      unsigned char *outbuf,
-                                      const unsigned char *inbuf);
-
-/* Type for the cipher_stencrypt function.  */
-typedef void (*gcry_cipher_stencrypt_t) (void *c,
-                                        unsigned char *outbuf,
-                                        const unsigned char *inbuf,
-                                        unsigned int n);
-
-/* Type for the cipher_stdecrypt function.  */
-typedef void (*gcry_cipher_stdecrypt_t) (void *c,
-                                        unsigned char *outbuf,
-                                        const unsigned char *inbuf,
-                                        unsigned int n);
-
-typedef struct gcry_cipher_oid_spec
-{
-  const char *oid;
-  int mode;
-} gcry_cipher_oid_spec_t;
-
-/* Module specification structure for ciphers.  */
-typedef struct gcry_cipher_spec
-{
-  const char *name;
-  const char **aliases;
-  gcry_cipher_oid_spec_t *oids;
-  size_t blocksize;
-  size_t keylen;
-  size_t contextsize;
-  gcry_cipher_setkey_t setkey;
-  gcry_cipher_encrypt_t encrypt;
-  gcry_cipher_decrypt_t decrypt;
-  gcry_cipher_stencrypt_t stencrypt;
-  gcry_cipher_stdecrypt_t stdecrypt;
-} gcry_cipher_spec_t;
-
-/* Register a new cipher module whose specification can be found in
-   CIPHER.  On success, a new algorithm ID is stored in ALGORITHM_ID
-   and a pointer representing this module is stored in MODULE.  */
-gcry_error_t gcry_cipher_register (gcry_cipher_spec_t *cipher,
-                                  int *algorithm_id,
-                                  gcry_module_t *module)
-  /* */  _GCRY_ATTR_INTERNAL;
-
-
-/* Unregister the cipher identified by MODULE, which must have been
-   registered with gcry_cipher_register.  */
-void gcry_cipher_unregister (gcry_module_t module)
-  /* */  _GCRY_ATTR_INTERNAL;
-
-/* ********************** */
-
-/* Type for the pk_generate function.  */
-typedef gcry_err_code_t (*gcry_pk_generate_t) (int algo,
-                                              unsigned int nbits,
-                                              unsigned long use_e,
-                                              gcry_mpi_t *skey,
-                                              gcry_mpi_t **retfactors);
-
-/* Type for the pk_check_secret_key function.  */
-typedef gcry_err_code_t (*gcry_pk_check_secret_key_t) (int algo,
-                                                      gcry_mpi_t *skey);
-
-/* Type for the pk_encrypt function.  */
-typedef gcry_err_code_t (*gcry_pk_encrypt_t) (int algo,
-                                             gcry_mpi_t *resarr,
-                                             gcry_mpi_t data,
-                                             gcry_mpi_t *pkey,
-                                             int flags);
-
-/* Type for the pk_decrypt function.  */
-typedef gcry_err_code_t (*gcry_pk_decrypt_t) (int algo,
-                                             gcry_mpi_t *result,
-                                             gcry_mpi_t *data,
-                                             gcry_mpi_t *skey,
-                                             int flags);
-
-/* Type for the pk_sign function.  */
-typedef gcry_err_code_t (*gcry_pk_sign_t) (int algo,
-                                          gcry_mpi_t *resarr,
-                                          gcry_mpi_t data,
-                                          gcry_mpi_t *skey);
-
-/* Type for the pk_verify function.  */
-typedef gcry_err_code_t (*gcry_pk_verify_t) (int algo,
-                                            gcry_mpi_t hash,
-                                            gcry_mpi_t *data,
-                                            gcry_mpi_t *pkey,
-                                            int (*cmp) (void *, gcry_mpi_t),
-                                            void *opaquev);
-
-/* Type for the pk_get_nbits function.  */
-typedef unsigned (*gcry_pk_get_nbits_t) (int algo, gcry_mpi_t *pkey);
-
-/* Module specification structure for message digests.  */
-typedef struct gcry_pk_spec
-{
-  const char *name;
-  const char **aliases;
-  const char *elements_pkey;
-  const char *elements_skey;
-  const char *elements_enc;
-  const char *elements_sig;
-  const char *elements_grip;
-  int use;
-  gcry_pk_generate_t generate;
-  gcry_pk_check_secret_key_t check_secret_key;
-  gcry_pk_encrypt_t encrypt;
-  gcry_pk_decrypt_t decrypt;
-  gcry_pk_sign_t sign;
-  gcry_pk_verify_t verify;
-  gcry_pk_get_nbits_t get_nbits;
-} gcry_pk_spec_t;
-
-/* Register a new pubkey module whose specification can be found in
-   PUBKEY.  On success, a new algorithm ID is stored in ALGORITHM_ID
-   and a pointer representhing this module is stored in MODULE.  */
-gcry_error_t gcry_pk_register (gcry_pk_spec_t *pubkey,
-                              unsigned int *algorithm_id,
-                              gcry_module_t *module)
-  /* */  _GCRY_ATTR_INTERNAL;
-
-/* Unregister the pubkey identified by ID, which must have been
-   registered with gcry_pk_register.  */
-void gcry_pk_unregister (gcry_module_t module)
-  /* */  _GCRY_ATTR_INTERNAL;
-
-/* ********************** */
-
-/* Type for the md_init function.  */
-typedef void (*gcry_md_init_t) (void *c);
-
-/* Type for the md_write function.  */
-typedef void (*gcry_md_write_t) (void *c, const void *buf, size_t nbytes);
-
-/* Type for the md_final function.  */
-typedef void (*gcry_md_final_t) (void *c);
-
-/* Type for the md_read function.  */
-typedef unsigned char *(*gcry_md_read_t) (void *c);
-
-typedef struct gcry_md_oid_spec
-{
-  const char *oidstring;
-} gcry_md_oid_spec_t;
-
-/* Module specification structure for message digests.  */
-typedef struct gcry_md_spec
-{
-  const char *name;
-  unsigned char *asnoid;
-  int asnlen;
-  gcry_md_oid_spec_t *oids;
-  int mdlen;
-  gcry_md_init_t init;
-  gcry_md_write_t write;
-  gcry_md_final_t final;
-  gcry_md_read_t read;
-  size_t contextsize; /* allocate this amount of context */
-} gcry_md_spec_t;
-
-/* Register a new digest module whose specification can be found in
-   DIGEST.  On success, a new algorithm ID is stored in ALGORITHM_ID
-   and a pointer representhing this module is stored in MODULE.  */
-gcry_error_t gcry_md_register (gcry_md_spec_t *digest,
-                              unsigned int *algorithm_id,
-                              gcry_module_t *module)
-  /* */  _GCRY_ATTR_INTERNAL;
-
-/* Unregister the digest identified by ID, which must have been
-   registered with gcry_digest_register.  */
-void gcry_md_unregister (gcry_module_t module)
-  /* */  _GCRY_ATTR_INTERNAL;
-
-#if 0 /* keep Emacsens's auto-indent happy */
-{
-#endif
-#ifdef __cplusplus
-}
-#endif
-#endif
index be2ecbe..2dda72c 100644 (file)
@@ -1,23 +1,26 @@
 /* gcrypt.h -  GNU Cryptographic Library Interface              -*- c -*-
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
-                 2007, 2008, 2009, 2010, 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/>.
-
-   File: src/gcrypt.h.  Generated from gcrypt.h.in by configure. */
+ * 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
@@ -61,7 +64,12 @@ extern "C" {
    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.5.0"
+#define GCRYPT_VERSION "1.6.1"
+
+/* The version number of this header.  It may be used to handle minor
+   API incompatibilities.  */
+#define GCRYPT_VERSION_NUMBER 0x010601
+
 
 /* Internal: We can't use the convenience macros for the multi
    precision integer functions when building this library. */
@@ -92,6 +100,12 @@ extern "C" {
 #define _GCRY_GCC_ATTR_MALLOC  __attribute__ ((__malloc__))
 #endif
 
+#define _GCRY_GCC_ATTR_PRINTF(f,a)  __attribute__ ((format (printf,f,a)))
+
+#if _GCRT_GCC_VERSION >= 40000
+#define _GCRY_GCC_ATTR_SENTINEL(a) __attribute__ ((sentinel(a)))
+#endif
+
 #endif /*__GNUC__*/
 
 #ifndef _GCRY_GCC_ATTR_DEPRECATED
@@ -103,6 +117,12 @@ extern "C" {
 #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.  */
@@ -174,13 +194,9 @@ gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err);
 gcry_err_code_t gcry_error_from_errno (int err);
 
 \f
-/* This enum is deprecated; it is only declared for the sake of
-   complete API compatibility.  */
-enum gcry_thread_option
-  {
-    _GCRY_THREAD_OPTION_DUMMY
-  } _GCRY_GCC_ATTR_DEPRECATED;
-
+/* 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.  */
@@ -191,7 +207,7 @@ enum gcry_thread_option
 
 /* The version number encoded in the OPTION field of the struct
    gcry_thread_cbs.  */
-#define GCRY_THREAD_OPTION_VERSION  0
+#define GCRY_THREAD_OPTION_VERSION  1
 
 /* Wrapper for struct ath_ops.  */
 struct gcry_thread_cbs
@@ -199,155 +215,45 @@ 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.
-  */
+       Bits 15 - 8  are used for the version number.  */
   unsigned int option;
+} _GCRY_ATTR_INTERNAL;
 
-  int (*init) (void);
-  int (*mutex_init) (void **priv);
-  int (*mutex_destroy) (void **priv);
-  int (*mutex_lock) (void **priv);
-  int (*mutex_unlock) (void **priv);
-  ssize_t (*read) (int fd, void *buf, size_t nbytes);
-  ssize_t (*write) (int fd, const void *buf, size_t nbytes);
-#ifdef _WIN32
-  ssize_t (*select) (int nfd, void *rset, void *wset, void *eset,
-                    struct timeval *timeout);
-  ssize_t (*waitpid) (pid_t pid, int *status, int options);
-  int (*accept) (int s, void  *addr, int *length_ptr);
-  int (*connect) (int s, void *addr, gcry_socklen_t length);
-  int (*sendmsg) (int s, const void *msg, int flags);
-  int (*recvmsg) (int s, void *msg, int flags);
-#else
-  ssize_t (*select) (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
-                    struct timeval *timeout);
-  ssize_t (*waitpid) (pid_t pid, int *status, int options);
-  int (*accept) (int s, struct sockaddr *addr, gcry_socklen_t *length_ptr);
-  int (*connect) (int s, struct sockaddr *addr, gcry_socklen_t length);
-  int (*sendmsg) (int s, const struct msghdr *msg, int flags);
-  int (*recvmsg) (int s, struct msghdr *msg, int flags);
-#endif
-};
-
-#ifdef _WIN32
-# define _GCRY_THREAD_OPTION_PTH_IMPL_NET                                    \
-static ssize_t gcry_pth_select (int nfd, void *rset, void *wset,             \
-                               void *eset, struct timeval *timeout)          \
-  { return pth_select (nfd, rset, wset, eset, timeout); }                    \
-static ssize_t gcry_pth_waitpid (pid_t pid, int *status, int options)        \
-  { return pth_waitpid (pid, status, options); }                             \
-static int gcry_pth_accept (int s, void *addr,                                \
-                           gcry_socklen_t *length_ptr)                       \
-  { return pth_accept (s, addr, length_ptr); }                               \
-static int gcry_pth_connect (int s, void *addr,                                      \
-                            gcry_socklen_t length)                           \
-  { return pth_connect (s, addr, length); }
-#else /*!_WIN32*/
-# define _GCRY_THREAD_OPTION_PTH_IMPL_NET                                    \
-static ssize_t gcry_pth_select (int nfd, fd_set *rset, fd_set *wset,         \
-                               fd_set *eset, struct timeval *timeout)        \
-  { return pth_select (nfd, rset, wset, eset, timeout); }                    \
-static ssize_t gcry_pth_waitpid (pid_t pid, int *status, int options)        \
-  { return pth_waitpid (pid, status, options); }                             \
-static int gcry_pth_accept (int s, struct sockaddr *addr,                    \
-                           gcry_socklen_t *length_ptr)                       \
-  { return pth_accept (s, addr, length_ptr); }                               \
-static int gcry_pth_connect (int s, struct sockaddr *addr,                   \
-                            gcry_socklen_t length)                           \
-  { return pth_connect (s, addr, length); }
-#endif /*!_WIN32*/
-
+#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))}
 
-#define GCRY_THREAD_OPTION_PTH_IMPL                                          \
-static int gcry_pth_init (void)                                                      \
-{ return (pth_init () == FALSE) ? errno : 0; }                               \
-static int gcry_pth_mutex_init (void **priv)                                 \
-{                                                                            \
-  int err = 0;                                                               \
-  pth_mutex_t *lock = malloc (sizeof (pth_mutex_t));                         \
-                                                                             \
-  if (!lock)                                                                 \
-    err = ENOMEM;                                                            \
-  if (!err)                                                                  \
-    {                                                                        \
-      err = pth_mutex_init (lock);                                           \
-      if (err == FALSE)                                                              \
-       err = errno;                                                          \
-      else                                                                   \
-       err = 0;                                                              \
-      if (err)                                                               \
-       free (lock);                                                          \
-      else                                                                   \
-       *priv = lock;                                                         \
-    }                                                                        \
-  return err;                                                                \
-}                                                                            \
-static int gcry_pth_mutex_destroy (void **lock)                                      \
-  { /* GNU Pth has no destructor function.  */ free (*lock); return 0; }      \
-static int gcry_pth_mutex_lock (void **lock)                                 \
-  { return ((pth_mutex_acquire (*lock, 0, NULL)) == FALSE)                   \
-      ? errno : 0; }                                                         \
-static int gcry_pth_mutex_unlock (void **lock)                               \
-  { return ((pth_mutex_release (*lock)) == FALSE)                            \
-      ? errno : 0; }                                                         \
-static ssize_t gcry_pth_read (int fd, void *buf, size_t nbytes)                      \
-  { return pth_read (fd, buf, nbytes); }                                     \
-static ssize_t gcry_pth_write (int fd, const void *buf, size_t nbytes)       \
-  { return pth_write (fd, buf, nbytes); }                                    \
-_GCRY_THREAD_OPTION_PTH_IMPL_NET                                              \
-                                                                             \
-/* Note: GNU Pth is missing pth_sendmsg and pth_recvmsg.  */                 \
-static struct gcry_thread_cbs gcry_threads_pth = {                            \
-  (GCRY_THREAD_OPTION_PTH | (GCRY_THREAD_OPTION_VERSION << 8)),               \
-  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,       \
-  NULL, NULL }
-
-
-#define GCRY_THREAD_OPTION_PTHREAD_IMPL                                              \
-static int gcry_pthread_mutex_init (void **priv)                             \
-{                                                                            \
-  int err = 0;                                                               \
-  pthread_mutex_t *lock = (pthread_mutex_t*)malloc (sizeof (pthread_mutex_t));\
-                                                                             \
-  if (!lock)                                                                 \
-    err = ENOMEM;                                                            \
-  if (!err)                                                                  \
-    {                                                                        \
-      err = pthread_mutex_init (lock, NULL);                                 \
-      if (err)                                                               \
-       free (lock);                                                          \
-      else                                                                   \
-       *priv = lock;                                                         \
-    }                                                                        \
-  return err;                                                                \
-}                                                                            \
-static int gcry_pthread_mutex_destroy (void **lock)                          \
-  { int err = pthread_mutex_destroy ((pthread_mutex_t*)*lock);                \
-    free (*lock); return err; }                                               \
-static int gcry_pthread_mutex_lock (void **lock)                             \
-  { return pthread_mutex_lock ((pthread_mutex_t*)*lock); }                   \
-static int gcry_pthread_mutex_unlock (void **lock)                           \
-  { return pthread_mutex_unlock ((pthread_mutex_t*)*lock); }                 \
-                                                                             \
-static struct gcry_thread_cbs gcry_threads_pthread = {                       \
-  (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8)),           \
-  NULL, gcry_pthread_mutex_init, gcry_pthread_mutex_destroy,                 \
-  gcry_pthread_mutex_lock, gcry_pthread_mutex_unlock,                         \
-  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
 
 \f
-/* The data object used to hold a multi precision integer.  */
+/* 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.  */
@@ -358,8 +264,7 @@ const char *gcry_check_version (const char *req_version);
 /* Codes used with the gcry_control function. */
 enum gcry_ctl_cmds
   {
-    GCRYCTL_SET_KEY  = 1,
-    GCRYCTL_SET_IV   = 2,
+    /* Note: 1 .. 2 are not anymore used. */
     GCRYCTL_CFB_SYNC = 3,
     GCRYCTL_RESET    = 4,   /* e.g. for MDs */
     GCRYCTL_FINALIZE = 5,
@@ -399,7 +304,7 @@ enum gcry_ctl_cmds
     GCRYCTL_ANY_INITIALIZATION_P = 40,
     GCRYCTL_SET_CBC_CTS = 41,
     GCRYCTL_SET_CBC_MAC = 42,
-    GCRYCTL_SET_CTR = 43,
+    /* Note: 43 is not anymore used. */
     GCRYCTL_ENABLE_QUICK_RANDOM = 44,
     GCRYCTL_SET_RANDOM_SEED_FILE = 45,
     GCRYCTL_UPDATE_RANDOM_SEED_FILE = 46,
@@ -415,7 +320,16 @@ enum gcry_ctl_cmds
     GCRYCTL_FORCE_FIPS_MODE = 56,
     GCRYCTL_SELFTEST = 57,
     /* Note: 58 .. 62 are used internally.  */
-    GCRYCTL_DISABLE_HWF = 63
+    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. */
@@ -534,6 +448,13 @@ gcry_sexp_t gcry_sexp_cadr (const gcry_sexp_t list);
 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
@@ -549,6 +470,12 @@ 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.  */
+gpg_error_t gcry_sexp_extract_param (gcry_sexp_t sexp,
+                                     const char *path,
+                                     const char *list,
+                                     ...) _GCRY_GCC_ATTR_SENTINEL(0);
 
 \f
 /*******************************************
@@ -565,19 +492,33 @@ enum gcry_mpi_format
     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_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
+    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);
@@ -591,6 +532,9 @@ 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);
 
@@ -600,6 +544,15 @@ 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);
@@ -693,6 +646,68 @@ int gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b);
    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);
@@ -719,10 +734,18 @@ void     gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
 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.  WARNING: Never use an opaque MPI for anything thing else then
+   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. */
@@ -737,9 +760,12 @@ void gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
    currently useless as no flags are allowed. */
 void gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
 
-/* Return true when the FLAG is set for A. */
+/* 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
@@ -754,10 +780,14 @@ int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
   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))
@@ -776,6 +806,19 @@ int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
 #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))
@@ -834,7 +877,10 @@ enum gcry_cipher_algos
     GCRY_CIPHER_SEED        = 309,  /* 128 bit cipher described in RFC4269. */
     GCRY_CIPHER_CAMELLIA128 = 310,
     GCRY_CIPHER_CAMELLIA192 = 311,
-    GCRY_CIPHER_CAMELLIA256 = 312
+    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. */
@@ -855,7 +901,9 @@ enum gcry_cipher_modes
     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_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. */
@@ -867,6 +915,11 @@ enum gcry_cipher_flags
     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. */
@@ -924,6 +977,17 @@ gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t 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)
@@ -941,7 +1005,7 @@ gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t hd,
 gpg_error_t gcry_cipher_setctr (gcry_cipher_hd_t hd,
                                 const void *ctr, size_t ctrlen);
 
-/* Retrieved the key length in bytes used with algorithm A. */
+/* 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. */
@@ -951,14 +1015,6 @@ size_t gcry_cipher_get_algo_blklen (int algo);
 #define gcry_cipher_test_algo(a) \
             gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
 
-/* Get a list consisting of the IDs of the loaded cipher modules.  If
-   LIST is zero, write the number of loaded cipher modules to
-   LIST_LENGTH and return.  If LIST is non-zero, the first
-   *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
-   according size.  In case there are less cipher modules than
-   *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
-gcry_error_t gcry_cipher_list (int *list, int *list_length);
-
 \f
 /************************************
  *                                  *
@@ -966,17 +1022,18 @@ gcry_error_t gcry_cipher_list (int *list, int *list_length);
  *                                  *
  ************************************/
 
-/* The algorithms and their IDs we support. */
+/* The algorithms and their IDs we support.  */
 enum gcry_pk_algos
   {
-    GCRY_PK_RSA   = 1,
-    GCRY_PK_RSA_E = 2,      /* (deprecated) */
-    GCRY_PK_RSA_S = 3,      /* (deprecated) */
-    GCRY_PK_ELG_E = 16,
-    GCRY_PK_DSA   = 17,
-    GCRY_PK_ELG   = 20,
-    GCRY_PK_ECDSA = 301,
-    GCRY_PK_ECDH  = 302
+    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. */
@@ -986,6 +1043,10 @@ enum gcry_pk_algos
 #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,
@@ -1033,8 +1094,8 @@ int gcry_pk_map_name (const char* name) _GCRY_GCC_ATTR_PURE;
    public or private KEY.  */
 unsigned int gcry_pk_get_nbits (gcry_sexp_t key) _GCRY_GCC_ATTR_PURE;
 
-/* Please note that keygrip is still experimental and should not be
-   used without contacting the author. */
+/* 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.  */
@@ -1049,13 +1110,9 @@ gcry_sexp_t gcry_pk_get_param (int algo, const char *name);
 #define gcry_pk_test_algo(a) \
             gcry_pk_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
 
-/* Get a list consisting of the IDs of the loaded pubkey modules.  If
-   LIST is zero, write the number of loaded pubkey modules to
-   LIST_LENGTH and return.  If LIST is non-zero, the first
-   *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
-   according size.  In case there are less pubkey modules than
-   *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
-gcry_error_t gcry_pk_list (int *list, int *list_length);
+/* 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
 
@@ -1084,16 +1141,20 @@ enum gcry_md_algos
     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_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_HMAC   = 2,  /* Make an HMAC out of this algorithm.  */
+    GCRY_MD_FLAG_BUGEMU1 = 0x0100
   };
 
 /* (Forward declaration.)  */
@@ -1158,6 +1219,10 @@ unsigned char *gcry_md_read (gcry_md_hd_t hd, int algo);
 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);
@@ -1226,436 +1291,121 @@ void gcry_md_debug (gcry_md_hd_t hd, const char *suffix);
 #define gcry_md_get_asnoid(a,b,n) \
             gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n))
 
-/* Enable debugging for digest object A; i.e. create files named
-   dbgmd-<n>.<string> while hashing.  B is a string used as the suffix
-   for the filename.  This macro is deprecated, use gcry_md_debug. */
-#ifndef GCRYPT_NO_DEPRECATED
-#define gcry_md_start_debug(a,b) \
-            gcry_md_ctl( (a), GCRYCTL_START_DUMP, (b), 0 )
-
-/* Disable the debugging of A.  This macro is deprecated, use
-   gcry_md_debug.  */
-#define gcry_md_stop_debug(a,b) \
-            gcry_md_ctl( (a), GCRYCTL_STOP_DUMP, (b), 0 )
-#endif
-
-/* Get a list consisting of the IDs of the loaded message digest
-   modules.  If LIST is zero, write the number of loaded message
-   digest modules to LIST_LENGTH and return.  If LIST is non-zero, the
-   first *LIST_LENGTH algorithm IDs are stored in LIST, which must be
-   of according size.  In case there are less message digest modules
-   than *LIST_LENGTH, *LIST_LENGTH is updated to the correct
-   number.  */
-gcry_error_t gcry_md_list (int *list, int *list_length);
-
 \f
-/* Alternative interface for asymmetric cryptography.  This interface
-   is deprecated.  */
 
-/* The algorithm IDs. */
-typedef enum gcry_ac_id
-  {
-    GCRY_AC_RSA = 1,
-    GCRY_AC_DSA = 17,
-    GCRY_AC_ELG = 20,
-    GCRY_AC_ELG_E = 16
-  }
-gcry_ac_id_t _GCRY_ATTR_INTERNAL;
+/**********************************************
+ *                                            *
+ *   Message Authentication Code Functions    *
+ *                                            *
+ **********************************************/
 
-/* Key types.  */
-typedef enum gcry_ac_key_type
-  {
-    GCRY_AC_KEY_SECRET,
-    GCRY_AC_KEY_PUBLIC
-  }
-gcry_ac_key_type_t _GCRY_ATTR_INTERNAL;
+/* 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;
 
-/* Encoding methods.  */
-typedef enum gcry_ac_em
+/* Algorithm IDs for the hash functions we know about. Not all of them
+   are implemented. */
+enum gcry_mac_algos
   {
-    GCRY_AC_EME_PKCS_V1_5,
-    GCRY_AC_EMSA_PKCS_V1_5
-  }
-gcry_ac_em_t _GCRY_ATTR_INTERNAL;
+    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
+  };
 
-/* Encryption and Signature schemes.  */
-typedef enum gcry_ac_scheme
+/* Flags used with the open function.  */
+enum gcry_mac_flags
   {
-    GCRY_AC_ES_PKCS_V1_5,
-    GCRY_AC_SSA_PKCS_V1_5
-  }
-gcry_ac_scheme_t _GCRY_ATTR_INTERNAL;
-
-/* AC data.  */
-#define GCRY_AC_FLAG_DEALLOC     (1 << 0)
-#define GCRY_AC_FLAG_COPY        (1 << 1)
-#define GCRY_AC_FLAG_NO_BLINDING (1 << 2)
-
-/* This type represents a `data set'.  */
-typedef struct gcry_ac_data *gcry_ac_data_t _GCRY_ATTR_INTERNAL;
+    GCRY_MAC_FLAG_SECURE = 1,  /* Allocate all buffers in "secure" memory.  */
+  };
 
-/* This type represents a single `key', either a secret one or a
-   public one.  */
-typedef struct gcry_ac_key *gcry_ac_key_t _GCRY_ATTR_INTERNAL;
+/* 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);
 
-/* This type represents a `key pair' containing a secret and a public
-   key.  */
-typedef struct gcry_ac_key_pair *gcry_ac_key_pair_t _GCRY_ATTR_INTERNAL;
+/* Close the MAC handle H and release all resource. */
+void gcry_mac_close (gcry_mac_hd_t h);
 
-/* This type represents a `handle' that is needed by functions
-   performing cryptographic operations.  */
-typedef struct gcry_ac_handle *gcry_ac_handle_t _GCRY_ATTR_INTERNAL;
+/* 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);
 
-typedef gpg_error_t (*gcry_ac_data_read_cb_t) (void *opaque,
-                                              unsigned char *buffer,
-                                              size_t *buffer_n)
-  /* */  _GCRY_ATTR_INTERNAL;
+/* Retrieve various information about the MAC algorithm ALGO. */
+gcry_error_t gcry_mac_algo_info (int algo, int what, void *buffer,
+                                 size_t *nbytes);
 
-typedef gpg_error_t (*gcry_ac_data_write_cb_t) (void *opaque,
-                                               unsigned char *buffer,
-                                               size_t buffer_n)
-  /* */  _GCRY_ATTR_INTERNAL;
+/* 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);
 
-typedef enum
-  {
-    GCRY_AC_IO_READABLE,
-    GCRY_AC_IO_WRITABLE
-  }
-gcry_ac_io_mode_t _GCRY_ATTR_INTERNAL;
+/* 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);
 
-typedef enum
-  {
-    GCRY_AC_IO_STRING,
-    GCRY_AC_IO_CALLBACK
-  }
-gcry_ac_io_type_t _GCRY_ATTR_INTERNAL;
+/* 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);
 
-typedef struct gcry_ac_io
-{
-  /* This is an INTERNAL structure, do NOT use manually.  */
-  gcry_ac_io_mode_t mode _GCRY_ATTR_INTERNAL;
-  gcry_ac_io_type_t type _GCRY_ATTR_INTERNAL;
-  union
-  {
-    union
-    {
-      struct
-      {
-       gcry_ac_data_read_cb_t cb;
-       void *opaque;
-      } callback;
-      struct
-      {
-       unsigned char *data;
-       size_t data_n;
-      } string;
-      void *opaque;
-    } readable;
-    union
-    {
-      struct
-      {
-       gcry_ac_data_write_cb_t cb;
-       void *opaque;
-      } callback;
-      struct
-      {
-       unsigned char **data;
-       size_t *data_n;
-      } string;
-      void *opaque;
-    } writable;
-  } io _GCRY_ATTR_INTERNAL;
-}
-gcry_ac_io_t _GCRY_ATTR_INTERNAL;
+/* 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);
 
-/* The caller of gcry_ac_key_pair_generate can provide one of these
-   structures in order to influence the key generation process in an
-   algorithm-specific way.  */
-typedef struct gcry_ac_key_spec_rsa
-{
-  gcry_mpi_t e;                 /* E to use.  */
-} gcry_ac_key_spec_rsa_t _GCRY_ATTR_INTERNAL;
+/* 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);
 
-/* Structure used for passing data to the implementation of the
-   `EME-PKCS-V1_5' encoding method.  */
-typedef struct gcry_ac_eme_pkcs_v1_5
-{
-  size_t key_size;
-} gcry_ac_eme_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
+/* Retrieve the length in bytes of the MAC yielded by algorithm ALGO. */
+unsigned int gcry_mac_get_algo_maclen (int algo);
 
-typedef enum gcry_md_algos gcry_md_algo_t _GCRY_ATTR_INTERNAL;
+/* Retrieve the default key length in bytes used with algorithm A. */
+unsigned int gcry_mac_get_algo_keylen (int algo);
 
-/* Structure used for passing data to the implementation of the
-   `EMSA-PKCS-V1_5' encoding method.  */
-typedef struct gcry_ac_emsa_pkcs_v1_5
-{
-  gcry_md_algo_t md;
-  size_t em_n;
-} gcry_ac_emsa_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
+/* 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;
 
-/* Structure used for passing data to the implementation of the
-   `SSA-PKCS-V1_5' signature scheme.  */
-typedef struct gcry_ac_ssa_pkcs_v1_5
-{
-  gcry_md_algo_t md;
-} gcry_ac_ssa_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
+/* 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)
 
-#ifndef GCRYPT_NO_DEPRECATED
-/* Returns a new, empty data set in DATA.  */
-gcry_error_t gcry_ac_data_new (gcry_ac_data_t *data)
-  /* */                       _GCRY_ATTR_INTERNAL;
-
-/* Destroy the data set DATA.  */
-void gcry_ac_data_destroy (gcry_ac_data_t data)
-  /* */                       _GCRY_ATTR_INTERNAL;
-
-/* Create a copy of the data set DATA and store it in DATA_CP.  */
-gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *data_cp,
-                                gcry_ac_data_t data)
-  /* */                       _GCRY_ATTR_INTERNAL;
-
-/* Return the number of named MPI values inside of the data set
-   DATA.  */
-unsigned int gcry_ac_data_length (gcry_ac_data_t data)
-  /* */                       _GCRY_ATTR_INTERNAL;
-
-/* Destroy any values contained in the data set DATA.  */
-void gcry_ac_data_clear (gcry_ac_data_t data)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Add the value MPI to DATA with the label NAME.  If FLAGS contains
-   GCRY_AC_FLAG_DATA_COPY, the data set will contain copies of NAME
-   and MPI.  If FLAGS contains GCRY_AC_FLAG_DATA_DEALLOC or
-   GCRY_AC_FLAG_DATA_COPY, the values contained in the data set will
-   be deallocated when they are to be removed from the data set.  */
-gcry_error_t gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
-                               const char *name, gcry_mpi_t mpi)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Store the value labelled with NAME found in DATA in MPI.  If FLAGS
-   contains GCRY_AC_FLAG_COPY, store a copy of the MPI value contained
-   in the data set.  MPI may be NULL.  */
-gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
-                                    const char *name, gcry_mpi_t *mpi)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Stores in NAME and MPI the named MPI value contained in the data
-   set DATA with the index IDX.  If FLAGS contains GCRY_AC_FLAG_COPY,
-   store copies of the values contained in the data set. NAME or MPI
-   may be NULL.  */
-gcry_error_t gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
-                                     unsigned int idx,
-                                     const char **name, gcry_mpi_t *mpi)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Convert the data set DATA into a new S-Expression, which is to be
-   stored in SEXP, according to the identifiers contained in
-   IDENTIFIERS.  */
-gcry_error_t gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
-                                  const char **identifiers)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Create a new data set, which is to be stored in DATA_SET, from the
-   S-Expression SEXP, according to the identifiers contained in
-   IDENTIFIERS.  */
-gcry_error_t gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp,
-                                    const char **identifiers)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Initialize AC_IO according to MODE, TYPE and the variable list of
-   arguments.  The list of variable arguments to specify depends on
-   the given TYPE.  */
-void gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
-                     gcry_ac_io_type_t type, ...)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Initialize AC_IO according to MODE, TYPE and the variable list of
-   arguments AP.  The list of variable arguments to specify depends on
-   the given TYPE.  */
-void gcry_ac_io_init_va (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
-                        gcry_ac_io_type_t type, va_list ap)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Create a new ac handle.  */
-gcry_error_t gcry_ac_open (gcry_ac_handle_t *handle,
-                           gcry_ac_id_t algorithm, unsigned int flags)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Destroy an ac handle.  */
-void gcry_ac_close (gcry_ac_handle_t handle)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Initialize a key from a given data set.  */
-gcry_error_t gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
-                               gcry_ac_key_type_t type, gcry_ac_data_t data)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Generates a new key pair via the handle HANDLE of NBITS bits and
-   stores it in KEY_PAIR.  In case non-standard settings are wanted, a
-   pointer to a structure of type gcry_ac_key_spec_<algorithm>_t,
-   matching the selected algorithm, can be given as KEY_SPEC.
-   MISC_DATA is not used yet.  */
-gcry_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t handle,
-                                        unsigned int nbits, void *spec,
-                                        gcry_ac_key_pair_t *key_pair,
-                                        gcry_mpi_t **misc_data)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Returns the key of type WHICH out of the key pair KEY_PAIR.  */
-gcry_ac_key_t gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair,
-                                        gcry_ac_key_type_t which)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Returns the data set contained in the key KEY.  */
-gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t key)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Verifies that the key KEY is sane via HANDLE.  */
-gcry_error_t gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Stores the number of bits of the key KEY in NBITS via HANDLE.  */
-gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
-                                    gcry_ac_key_t key, unsigned int *nbits)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Writes the 20 byte long key grip of the key KEY to KEY_GRIP via
-   HANDLE.  */
-gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key,
-                                   unsigned char *key_grip)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Destroy a key.  */
-void gcry_ac_key_destroy (gcry_ac_key_t key)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Destroy a key pair.  */
-void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Encodes a message according to the encoding method METHOD.  OPTIONS
-   must be a pointer to a method-specific structure
-   (gcry_ac_em*_t).  */
-gcry_error_t gcry_ac_data_encode (gcry_ac_em_t method,
-                                 unsigned int flags, void *options,
-                                 gcry_ac_io_t *io_read,
-                                 gcry_ac_io_t *io_write)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Decodes a message according to the encoding method METHOD.  OPTIONS
-   must be a pointer to a method-specific structure
-   (gcry_ac_em*_t).  */
-gcry_error_t gcry_ac_data_decode (gcry_ac_em_t method,
-                                 unsigned int flags, void *options,
-                                 gcry_ac_io_t *io_read,
-                                 gcry_ac_io_t *io_write)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Encrypt the plain text MPI value DATA_PLAIN with the key KEY under
-   the control of the flags FLAGS and store the resulting data set
-   into DATA_ENCRYPTED.  */
-gcry_error_t gcry_ac_data_encrypt (gcry_ac_handle_t handle,
-                                   unsigned int flags,
-                                   gcry_ac_key_t key,
-                                   gcry_mpi_t data_plain,
-                                   gcry_ac_data_t *data_encrypted)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Decrypt the decrypted data contained in the data set DATA_ENCRYPTED
-   with the key KEY under the control of the flags FLAGS and store the
-   resulting plain text MPI value in DATA_PLAIN.  */
-gcry_error_t gcry_ac_data_decrypt (gcry_ac_handle_t handle,
-                                   unsigned int flags,
-                                   gcry_ac_key_t key,
-                                   gcry_mpi_t *data_plain,
-                                   gcry_ac_data_t data_encrypted)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Sign the data contained in DATA with the key KEY and store the
-   resulting signature in the data set DATA_SIGNATURE.  */
-gcry_error_t gcry_ac_data_sign (gcry_ac_handle_t handle,
-                                gcry_ac_key_t key,
-                                gcry_mpi_t data,
-                                gcry_ac_data_t *data_signature)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Verify that the signature contained in the data set DATA_SIGNATURE
-   is indeed the result of signing the data contained in DATA with the
-   secret key belonging to the public key KEY.  */
-gcry_error_t gcry_ac_data_verify (gcry_ac_handle_t handle,
-                                  gcry_ac_key_t key,
-                                  gcry_mpi_t data,
-                                  gcry_ac_data_t data_signature)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Encrypts the plain text readable from IO_MESSAGE through HANDLE
-   with the public key KEY according to SCHEME, FLAGS and OPTS.  If
-   OPTS is not NULL, it has to be a pointer to a structure specific to
-   the chosen scheme (gcry_ac_es_*_t).  The encrypted message is
-   written to IO_CIPHER. */
-gcry_error_t gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
-                                         gcry_ac_scheme_t scheme,
-                                         unsigned int flags, void *opts,
-                                         gcry_ac_key_t key,
-                                         gcry_ac_io_t *io_message,
-                                         gcry_ac_io_t *io_cipher)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Decrypts the cipher text readable from IO_CIPHER through HANDLE
-   with the secret key KEY according to SCHEME, @var{flags} and OPTS.
-   If OPTS is not NULL, it has to be a pointer to a structure specific
-   to the chosen scheme (gcry_ac_es_*_t).  The decrypted message is
-   written to IO_MESSAGE.  */
-gcry_error_t gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
-                                         gcry_ac_scheme_t scheme,
-                                         unsigned int flags, void *opts,
-                                         gcry_ac_key_t key,
-                                         gcry_ac_io_t *io_cipher,
-                                         gcry_ac_io_t *io_message)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Signs the message readable from IO_MESSAGE through HANDLE with the
-   secret key KEY according to SCHEME, FLAGS and OPTS.  If OPTS is not
-   NULL, it has to be a pointer to a structure specific to the chosen
-   scheme (gcry_ac_ssa_*_t).  The signature is written to
-   IO_SIGNATURE.  */
-gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
-                                      gcry_ac_scheme_t scheme,
-                                      unsigned int flags, void *opts,
-                                      gcry_ac_key_t key,
-                                      gcry_ac_io_t *io_message,
-                                      gcry_ac_io_t *io_signature)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Verifies through HANDLE that the signature readable from
-   IO_SIGNATURE is indeed the result of signing the message readable
-   from IO_MESSAGE with the secret key belonging to the public key KEY
-   according to SCHEME and OPTS.  If OPTS is not NULL, it has to be an
-   anonymous structure (gcry_ac_ssa_*_t) specific to the chosen
-   scheme.  */
-gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
-                                        gcry_ac_scheme_t scheme,
-                                        unsigned int flags, void *opts,
-                                        gcry_ac_key_t key,
-                                        gcry_ac_io_t *io_message,
-                                        gcry_ac_io_t *io_signature)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Store the textual representation of the algorithm whose id is given
-   in ALGORITHM in NAME.  This function is deprecated; use
-   gcry_pk_algo_name. */
-gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t algorithm,
-                                 const char **name)
-     /* */                      _GCRY_GCC_ATTR_DEPRECATED;
-/* Store the numeric ID of the algorithm whose textual representation
-   is contained in NAME in ALGORITHM.  This function is deprecated;
-   use gcry_pk_map_name. */
-gcry_error_t gcry_ac_name_to_id (const char *name,
-                                 gcry_ac_id_t *algorithm)
-     /* */                      _GCRY_GCC_ATTR_DEPRECATED;
-#endif /*GCRYPT_NO_DEPRECATED*/
+/* 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
 /******************************
@@ -1672,7 +1422,8 @@ enum gcry_kdf_algos
     GCRY_KDF_SALTED_S2K = 17,
     GCRY_KDF_ITERSALTED_S2K = 19,
     GCRY_KDF_PBKDF1 = 33,
-    GCRY_KDF_PBKDF2 = 34
+    GCRY_KDF_PBKDF2 = 34,
+    GCRY_KDF_SCRYPT = 48
   };
 
 /* Derive a key from a passphrase.  */
@@ -1691,6 +1442,14 @@ gpg_error_t gcry_kdf_derive (const void *passphrase, size_t passphraselen,
  *                                  *
  ************************************/
 
+/* 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
@@ -1811,6 +1570,18 @@ gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags);
  *                                  *
  ************************************/
 
+/* 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
   {
@@ -1898,9 +1669,6 @@ int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE;
 #define gcry_fips_mode_active()  !!gcry_control (GCRYCTL_FIPS_MODE_P, 0)
 
 
-/* Include support for Libgcrypt modules.  */
-#include <gcrypt-module.h>
-
 #if 0 /* (Keep Emacsens' auto-indent happy.) */
 {
 #endif
index f67c19a..dbf48e3 100644 (file)
@@ -1,23 +1,26 @@
 /* gcrypt.h -  GNU Cryptographic Library Interface              -*- c -*-
-   Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
-                 2007, 2008, 2009, 2010, 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/>.
-
-   File: @configure_input@ */
+ * 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: @configure_input@
+ */
 
 #ifndef _GCRYPT_H
 #define _GCRYPT_H
@@ -63,6 +66,11 @@ extern "C" {
    matches the installed library.  */
 #define GCRYPT_VERSION "@VERSION@"
 
+/* The version number of this header.  It may be used to handle minor
+   API incompatibilities.  */
+#define GCRYPT_VERSION_NUMBER @VERSION_NUMBER@
+
+
 /* Internal: We can't use the convenience macros for the multi
    precision integer functions when building this library. */
 #ifdef _GCRYPT_IN_LIBGCRYPT
@@ -92,6 +100,12 @@ extern "C" {
 #define _GCRY_GCC_ATTR_MALLOC  __attribute__ ((__malloc__))
 #endif
 
+#define _GCRY_GCC_ATTR_PRINTF(f,a)  __attribute__ ((format (printf,f,a)))
+
+#if _GCRT_GCC_VERSION >= 40000
+#define _GCRY_GCC_ATTR_SENTINEL(a) __attribute__ ((sentinel(a)))
+#endif
+
 #endif /*__GNUC__*/
 
 #ifndef _GCRY_GCC_ATTR_DEPRECATED
@@ -103,6 +117,12 @@ extern "C" {
 #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.  */
@@ -174,13 +194,9 @@ gcry_error_t gcry_err_make_from_errno (gcry_err_source_t source, int err);
 gcry_err_code_t gcry_error_from_errno (int err);
 
 \f
-/* This enum is deprecated; it is only declared for the sake of
-   complete API compatibility.  */
-enum gcry_thread_option
-  {
-    _GCRY_THREAD_OPTION_DUMMY
-  } _GCRY_GCC_ATTR_DEPRECATED;
-
+/* 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.  */
@@ -191,7 +207,7 @@ enum gcry_thread_option
 
 /* The version number encoded in the OPTION field of the struct
    gcry_thread_cbs.  */
-#define GCRY_THREAD_OPTION_VERSION  0
+#define GCRY_THREAD_OPTION_VERSION  1
 
 /* Wrapper for struct ath_ops.  */
 struct gcry_thread_cbs
@@ -199,155 +215,45 @@ 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.
-  */
+       Bits 15 - 8  are used for the version number.  */
   unsigned int option;
+} _GCRY_ATTR_INTERNAL;
 
-  int (*init) (void);
-  int (*mutex_init) (void **priv);
-  int (*mutex_destroy) (void **priv);
-  int (*mutex_lock) (void **priv);
-  int (*mutex_unlock) (void **priv);
-  ssize_t (*read) (int fd, void *buf, size_t nbytes);
-  ssize_t (*write) (int fd, const void *buf, size_t nbytes);
-#ifdef _WIN32
-  ssize_t (*select) (int nfd, void *rset, void *wset, void *eset,
-                    struct timeval *timeout);
-  ssize_t (*waitpid) (pid_t pid, int *status, int options);
-  int (*accept) (int s, void  *addr, int *length_ptr);
-  int (*connect) (int s, void *addr, gcry_socklen_t length);
-  int (*sendmsg) (int s, const void *msg, int flags);
-  int (*recvmsg) (int s, void *msg, int flags);
-#else
-  ssize_t (*select) (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
-                    struct timeval *timeout);
-  ssize_t (*waitpid) (pid_t pid, int *status, int options);
-  int (*accept) (int s, struct sockaddr *addr, gcry_socklen_t *length_ptr);
-  int (*connect) (int s, struct sockaddr *addr, gcry_socklen_t length);
-  int (*sendmsg) (int s, const struct msghdr *msg, int flags);
-  int (*recvmsg) (int s, struct msghdr *msg, int flags);
-#endif
-};
-
-#ifdef _WIN32
-# define _GCRY_THREAD_OPTION_PTH_IMPL_NET                                    \
-static ssize_t gcry_pth_select (int nfd, void *rset, void *wset,             \
-                               void *eset, struct timeval *timeout)          \
-  { return pth_select (nfd, rset, wset, eset, timeout); }                    \
-static ssize_t gcry_pth_waitpid (pid_t pid, int *status, int options)        \
-  { return pth_waitpid (pid, status, options); }                             \
-static int gcry_pth_accept (int s, void *addr,                                \
-                           gcry_socklen_t *length_ptr)                       \
-  { return pth_accept (s, addr, length_ptr); }                               \
-static int gcry_pth_connect (int s, void *addr,                                      \
-                            gcry_socklen_t length)                           \
-  { return pth_connect (s, addr, length); }
-#else /*!_WIN32*/
-# define _GCRY_THREAD_OPTION_PTH_IMPL_NET                                    \
-static ssize_t gcry_pth_select (int nfd, fd_set *rset, fd_set *wset,         \
-                               fd_set *eset, struct timeval *timeout)        \
-  { return pth_select (nfd, rset, wset, eset, timeout); }                    \
-static ssize_t gcry_pth_waitpid (pid_t pid, int *status, int options)        \
-  { return pth_waitpid (pid, status, options); }                             \
-static int gcry_pth_accept (int s, struct sockaddr *addr,                    \
-                           gcry_socklen_t *length_ptr)                       \
-  { return pth_accept (s, addr, length_ptr); }                               \
-static int gcry_pth_connect (int s, struct sockaddr *addr,                   \
-                            gcry_socklen_t length)                           \
-  { return pth_connect (s, addr, length); }
-#endif /*!_WIN32*/
-
+#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))}
 
-#define GCRY_THREAD_OPTION_PTH_IMPL                                          \
-static int gcry_pth_init (void)                                                      \
-{ return (pth_init () == FALSE) ? errno : 0; }                               \
-static int gcry_pth_mutex_init (void **priv)                                 \
-{                                                                            \
-  int err = 0;                                                               \
-  pth_mutex_t *lock = malloc (sizeof (pth_mutex_t));                         \
-                                                                             \
-  if (!lock)                                                                 \
-    err = ENOMEM;                                                            \
-  if (!err)                                                                  \
-    {                                                                        \
-      err = pth_mutex_init (lock);                                           \
-      if (err == FALSE)                                                              \
-       err = errno;                                                          \
-      else                                                                   \
-       err = 0;                                                              \
-      if (err)                                                               \
-       free (lock);                                                          \
-      else                                                                   \
-       *priv = lock;                                                         \
-    }                                                                        \
-  return err;                                                                \
-}                                                                            \
-static int gcry_pth_mutex_destroy (void **lock)                                      \
-  { /* GNU Pth has no destructor function.  */ free (*lock); return 0; }      \
-static int gcry_pth_mutex_lock (void **lock)                                 \
-  { return ((pth_mutex_acquire (*lock, 0, NULL)) == FALSE)                   \
-      ? errno : 0; }                                                         \
-static int gcry_pth_mutex_unlock (void **lock)                               \
-  { return ((pth_mutex_release (*lock)) == FALSE)                            \
-      ? errno : 0; }                                                         \
-static ssize_t gcry_pth_read (int fd, void *buf, size_t nbytes)                      \
-  { return pth_read (fd, buf, nbytes); }                                     \
-static ssize_t gcry_pth_write (int fd, const void *buf, size_t nbytes)       \
-  { return pth_write (fd, buf, nbytes); }                                    \
-_GCRY_THREAD_OPTION_PTH_IMPL_NET                                              \
-                                                                             \
-/* Note: GNU Pth is missing pth_sendmsg and pth_recvmsg.  */                 \
-static struct gcry_thread_cbs gcry_threads_pth = {                            \
-  (GCRY_THREAD_OPTION_PTH | (GCRY_THREAD_OPTION_VERSION << 8)),               \
-  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,       \
-  NULL, NULL }
-
-
-#define GCRY_THREAD_OPTION_PTHREAD_IMPL                                              \
-static int gcry_pthread_mutex_init (void **priv)                             \
-{                                                                            \
-  int err = 0;                                                               \
-  pthread_mutex_t *lock = (pthread_mutex_t*)malloc (sizeof (pthread_mutex_t));\
-                                                                             \
-  if (!lock)                                                                 \
-    err = ENOMEM;                                                            \
-  if (!err)                                                                  \
-    {                                                                        \
-      err = pthread_mutex_init (lock, NULL);                                 \
-      if (err)                                                               \
-       free (lock);                                                          \
-      else                                                                   \
-       *priv = lock;                                                         \
-    }                                                                        \
-  return err;                                                                \
-}                                                                            \
-static int gcry_pthread_mutex_destroy (void **lock)                          \
-  { int err = pthread_mutex_destroy ((pthread_mutex_t*)*lock);                \
-    free (*lock); return err; }                                               \
-static int gcry_pthread_mutex_lock (void **lock)                             \
-  { return pthread_mutex_lock ((pthread_mutex_t*)*lock); }                   \
-static int gcry_pthread_mutex_unlock (void **lock)                           \
-  { return pthread_mutex_unlock ((pthread_mutex_t*)*lock); }                 \
-                                                                             \
-static struct gcry_thread_cbs gcry_threads_pthread = {                       \
-  (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8)),           \
-  NULL, gcry_pthread_mutex_init, gcry_pthread_mutex_destroy,                 \
-  gcry_pthread_mutex_lock, gcry_pthread_mutex_unlock,                         \
-  NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }
 
 \f
-/* The data object used to hold a multi precision integer.  */
+/* 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.  */
@@ -358,8 +264,7 @@ const char *gcry_check_version (const char *req_version);
 /* Codes used with the gcry_control function. */
 enum gcry_ctl_cmds
   {
-    GCRYCTL_SET_KEY  = 1,
-    GCRYCTL_SET_IV   = 2,
+    /* Note: 1 .. 2 are not anymore used. */
     GCRYCTL_CFB_SYNC = 3,
     GCRYCTL_RESET    = 4,   /* e.g. for MDs */
     GCRYCTL_FINALIZE = 5,
@@ -399,7 +304,7 @@ enum gcry_ctl_cmds
     GCRYCTL_ANY_INITIALIZATION_P = 40,
     GCRYCTL_SET_CBC_CTS = 41,
     GCRYCTL_SET_CBC_MAC = 42,
-    GCRYCTL_SET_CTR = 43,
+    /* Note: 43 is not anymore used. */
     GCRYCTL_ENABLE_QUICK_RANDOM = 44,
     GCRYCTL_SET_RANDOM_SEED_FILE = 45,
     GCRYCTL_UPDATE_RANDOM_SEED_FILE = 46,
@@ -415,7 +320,16 @@ enum gcry_ctl_cmds
     GCRYCTL_FORCE_FIPS_MODE = 56,
     GCRYCTL_SELFTEST = 57,
     /* Note: 58 .. 62 are used internally.  */
-    GCRYCTL_DISABLE_HWF = 63
+    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. */
@@ -534,6 +448,13 @@ gcry_sexp_t gcry_sexp_cadr (const gcry_sexp_t list);
 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
@@ -549,6 +470,12 @@ 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.  */
+gpg_error_t gcry_sexp_extract_param (gcry_sexp_t sexp,
+                                     const char *path,
+                                     const char *list,
+                                     ...) _GCRY_GCC_ATTR_SENTINEL(0);
 
 \f
 /*******************************************
@@ -565,19 +492,33 @@ enum gcry_mpi_format
     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_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
+    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);
@@ -591,6 +532,9 @@ 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);
 
@@ -600,6 +544,15 @@ 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);
@@ -693,6 +646,68 @@ int gcry_mpi_gcd (gcry_mpi_t g, gcry_mpi_t a, gcry_mpi_t b);
    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);
@@ -719,10 +734,18 @@ void     gcry_mpi_rshift (gcry_mpi_t x, gcry_mpi_t a, unsigned int n);
 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.  WARNING: Never use an opaque MPI for anything thing else then
+   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. */
@@ -737,9 +760,12 @@ void gcry_mpi_set_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
    currently useless as no flags are allowed. */
 void gcry_mpi_clear_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
 
-/* Return true when the FLAG is set for A. */
+/* 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
@@ -754,10 +780,14 @@ int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
   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))
@@ -776,6 +806,19 @@ int gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag);
 #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))
@@ -834,7 +877,10 @@ enum gcry_cipher_algos
     GCRY_CIPHER_SEED        = 309,  /* 128 bit cipher described in RFC4269. */
     GCRY_CIPHER_CAMELLIA128 = 310,
     GCRY_CIPHER_CAMELLIA192 = 311,
-    GCRY_CIPHER_CAMELLIA256 = 312
+    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. */
@@ -855,7 +901,9 @@ enum gcry_cipher_modes
     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_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. */
@@ -867,6 +915,11 @@ enum gcry_cipher_flags
     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. */
@@ -924,6 +977,17 @@ gcry_error_t gcry_cipher_setkey (gcry_cipher_hd_t 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)
@@ -941,7 +1005,7 @@ gcry_error_t gcry_cipher_setiv (gcry_cipher_hd_t hd,
 gpg_error_t gcry_cipher_setctr (gcry_cipher_hd_t hd,
                                 const void *ctr, size_t ctrlen);
 
-/* Retrieved the key length in bytes used with algorithm A. */
+/* 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. */
@@ -951,14 +1015,6 @@ size_t gcry_cipher_get_algo_blklen (int algo);
 #define gcry_cipher_test_algo(a) \
             gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
 
-/* Get a list consisting of the IDs of the loaded cipher modules.  If
-   LIST is zero, write the number of loaded cipher modules to
-   LIST_LENGTH and return.  If LIST is non-zero, the first
-   *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
-   according size.  In case there are less cipher modules than
-   *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
-gcry_error_t gcry_cipher_list (int *list, int *list_length);
-
 \f
 /************************************
  *                                  *
@@ -966,17 +1022,18 @@ gcry_error_t gcry_cipher_list (int *list, int *list_length);
  *                                  *
  ************************************/
 
-/* The algorithms and their IDs we support. */
+/* The algorithms and their IDs we support.  */
 enum gcry_pk_algos
   {
-    GCRY_PK_RSA   = 1,
-    GCRY_PK_RSA_E = 2,      /* (deprecated) */
-    GCRY_PK_RSA_S = 3,      /* (deprecated) */
-    GCRY_PK_ELG_E = 16,
-    GCRY_PK_DSA   = 17,
-    GCRY_PK_ELG   = 20,
-    GCRY_PK_ECDSA = 301,
-    GCRY_PK_ECDH  = 302
+    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. */
@@ -986,6 +1043,10 @@ enum gcry_pk_algos
 #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,
@@ -1033,8 +1094,8 @@ int gcry_pk_map_name (const char* name) _GCRY_GCC_ATTR_PURE;
    public or private KEY.  */
 unsigned int gcry_pk_get_nbits (gcry_sexp_t key) _GCRY_GCC_ATTR_PURE;
 
-/* Please note that keygrip is still experimental and should not be
-   used without contacting the author. */
+/* 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.  */
@@ -1049,13 +1110,9 @@ gcry_sexp_t gcry_pk_get_param (int algo, const char *name);
 #define gcry_pk_test_algo(a) \
             gcry_pk_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
 
-/* Get a list consisting of the IDs of the loaded pubkey modules.  If
-   LIST is zero, write the number of loaded pubkey modules to
-   LIST_LENGTH and return.  If LIST is non-zero, the first
-   *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
-   according size.  In case there are less pubkey modules than
-   *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
-gcry_error_t gcry_pk_list (int *list, int *list_length);
+/* 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
 
@@ -1084,16 +1141,20 @@ enum gcry_md_algos
     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_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_HMAC   = 2,  /* Make an HMAC out of this algorithm.  */
+    GCRY_MD_FLAG_BUGEMU1 = 0x0100
   };
 
 /* (Forward declaration.)  */
@@ -1158,6 +1219,10 @@ unsigned char *gcry_md_read (gcry_md_hd_t hd, int algo);
 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);
@@ -1226,436 +1291,121 @@ void gcry_md_debug (gcry_md_hd_t hd, const char *suffix);
 #define gcry_md_get_asnoid(a,b,n) \
             gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n))
 
-/* Enable debugging for digest object A; i.e. create files named
-   dbgmd-<n>.<string> while hashing.  B is a string used as the suffix
-   for the filename.  This macro is deprecated, use gcry_md_debug. */
-#ifndef GCRYPT_NO_DEPRECATED
-#define gcry_md_start_debug(a,b) \
-            gcry_md_ctl( (a), GCRYCTL_START_DUMP, (b), 0 )
-
-/* Disable the debugging of A.  This macro is deprecated, use
-   gcry_md_debug.  */
-#define gcry_md_stop_debug(a,b) \
-            gcry_md_ctl( (a), GCRYCTL_STOP_DUMP, (b), 0 )
-#endif
-
-/* Get a list consisting of the IDs of the loaded message digest
-   modules.  If LIST is zero, write the number of loaded message
-   digest modules to LIST_LENGTH and return.  If LIST is non-zero, the
-   first *LIST_LENGTH algorithm IDs are stored in LIST, which must be
-   of according size.  In case there are less message digest modules
-   than *LIST_LENGTH, *LIST_LENGTH is updated to the correct
-   number.  */
-gcry_error_t gcry_md_list (int *list, int *list_length);
-
 \f
-/* Alternative interface for asymmetric cryptography.  This interface
-   is deprecated.  */
 
-/* The algorithm IDs. */
-typedef enum gcry_ac_id
-  {
-    GCRY_AC_RSA = 1,
-    GCRY_AC_DSA = 17,
-    GCRY_AC_ELG = 20,
-    GCRY_AC_ELG_E = 16
-  }
-gcry_ac_id_t _GCRY_ATTR_INTERNAL;
+/**********************************************
+ *                                            *
+ *   Message Authentication Code Functions    *
+ *                                            *
+ **********************************************/
 
-/* Key types.  */
-typedef enum gcry_ac_key_type
-  {
-    GCRY_AC_KEY_SECRET,
-    GCRY_AC_KEY_PUBLIC
-  }
-gcry_ac_key_type_t _GCRY_ATTR_INTERNAL;
+/* 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;
 
-/* Encoding methods.  */
-typedef enum gcry_ac_em
+/* Algorithm IDs for the hash functions we know about. Not all of them
+   are implemented. */
+enum gcry_mac_algos
   {
-    GCRY_AC_EME_PKCS_V1_5,
-    GCRY_AC_EMSA_PKCS_V1_5
-  }
-gcry_ac_em_t _GCRY_ATTR_INTERNAL;
+    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
+  };
 
-/* Encryption and Signature schemes.  */
-typedef enum gcry_ac_scheme
+/* Flags used with the open function.  */
+enum gcry_mac_flags
   {
-    GCRY_AC_ES_PKCS_V1_5,
-    GCRY_AC_SSA_PKCS_V1_5
-  }
-gcry_ac_scheme_t _GCRY_ATTR_INTERNAL;
-
-/* AC data.  */
-#define GCRY_AC_FLAG_DEALLOC     (1 << 0)
-#define GCRY_AC_FLAG_COPY        (1 << 1)
-#define GCRY_AC_FLAG_NO_BLINDING (1 << 2)
-
-/* This type represents a `data set'.  */
-typedef struct gcry_ac_data *gcry_ac_data_t _GCRY_ATTR_INTERNAL;
+    GCRY_MAC_FLAG_SECURE = 1,  /* Allocate all buffers in "secure" memory.  */
+  };
 
-/* This type represents a single `key', either a secret one or a
-   public one.  */
-typedef struct gcry_ac_key *gcry_ac_key_t _GCRY_ATTR_INTERNAL;
+/* 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);
 
-/* This type represents a `key pair' containing a secret and a public
-   key.  */
-typedef struct gcry_ac_key_pair *gcry_ac_key_pair_t _GCRY_ATTR_INTERNAL;
+/* Close the MAC handle H and release all resource. */
+void gcry_mac_close (gcry_mac_hd_t h);
 
-/* This type represents a `handle' that is needed by functions
-   performing cryptographic operations.  */
-typedef struct gcry_ac_handle *gcry_ac_handle_t _GCRY_ATTR_INTERNAL;
+/* 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);
 
-typedef gpg_error_t (*gcry_ac_data_read_cb_t) (void *opaque,
-                                              unsigned char *buffer,
-                                              size_t *buffer_n)
-  /* */  _GCRY_ATTR_INTERNAL;
+/* Retrieve various information about the MAC algorithm ALGO. */
+gcry_error_t gcry_mac_algo_info (int algo, int what, void *buffer,
+                                 size_t *nbytes);
 
-typedef gpg_error_t (*gcry_ac_data_write_cb_t) (void *opaque,
-                                               unsigned char *buffer,
-                                               size_t buffer_n)
-  /* */  _GCRY_ATTR_INTERNAL;
+/* 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);
 
-typedef enum
-  {
-    GCRY_AC_IO_READABLE,
-    GCRY_AC_IO_WRITABLE
-  }
-gcry_ac_io_mode_t _GCRY_ATTR_INTERNAL;
+/* 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);
 
-typedef enum
-  {
-    GCRY_AC_IO_STRING,
-    GCRY_AC_IO_CALLBACK
-  }
-gcry_ac_io_type_t _GCRY_ATTR_INTERNAL;
+/* 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);
 
-typedef struct gcry_ac_io
-{
-  /* This is an INTERNAL structure, do NOT use manually.  */
-  gcry_ac_io_mode_t mode _GCRY_ATTR_INTERNAL;
-  gcry_ac_io_type_t type _GCRY_ATTR_INTERNAL;
-  union
-  {
-    union
-    {
-      struct
-      {
-       gcry_ac_data_read_cb_t cb;
-       void *opaque;
-      } callback;
-      struct
-      {
-       unsigned char *data;
-       size_t data_n;
-      } string;
-      void *opaque;
-    } readable;
-    union
-    {
-      struct
-      {
-       gcry_ac_data_write_cb_t cb;
-       void *opaque;
-      } callback;
-      struct
-      {
-       unsigned char **data;
-       size_t *data_n;
-      } string;
-      void *opaque;
-    } writable;
-  } io _GCRY_ATTR_INTERNAL;
-}
-gcry_ac_io_t _GCRY_ATTR_INTERNAL;
+/* 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);
 
-/* The caller of gcry_ac_key_pair_generate can provide one of these
-   structures in order to influence the key generation process in an
-   algorithm-specific way.  */
-typedef struct gcry_ac_key_spec_rsa
-{
-  gcry_mpi_t e;                 /* E to use.  */
-} gcry_ac_key_spec_rsa_t _GCRY_ATTR_INTERNAL;
+/* 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);
 
-/* Structure used for passing data to the implementation of the
-   `EME-PKCS-V1_5' encoding method.  */
-typedef struct gcry_ac_eme_pkcs_v1_5
-{
-  size_t key_size;
-} gcry_ac_eme_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
+/* Retrieve the length in bytes of the MAC yielded by algorithm ALGO. */
+unsigned int gcry_mac_get_algo_maclen (int algo);
 
-typedef enum gcry_md_algos gcry_md_algo_t _GCRY_ATTR_INTERNAL;
+/* Retrieve the default key length in bytes used with algorithm A. */
+unsigned int gcry_mac_get_algo_keylen (int algo);
 
-/* Structure used for passing data to the implementation of the
-   `EMSA-PKCS-V1_5' encoding method.  */
-typedef struct gcry_ac_emsa_pkcs_v1_5
-{
-  gcry_md_algo_t md;
-  size_t em_n;
-} gcry_ac_emsa_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
+/* 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;
 
-/* Structure used for passing data to the implementation of the
-   `SSA-PKCS-V1_5' signature scheme.  */
-typedef struct gcry_ac_ssa_pkcs_v1_5
-{
-  gcry_md_algo_t md;
-} gcry_ac_ssa_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
+/* 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)
 
-#ifndef GCRYPT_NO_DEPRECATED
-/* Returns a new, empty data set in DATA.  */
-gcry_error_t gcry_ac_data_new (gcry_ac_data_t *data)
-  /* */                       _GCRY_ATTR_INTERNAL;
-
-/* Destroy the data set DATA.  */
-void gcry_ac_data_destroy (gcry_ac_data_t data)
-  /* */                       _GCRY_ATTR_INTERNAL;
-
-/* Create a copy of the data set DATA and store it in DATA_CP.  */
-gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *data_cp,
-                                gcry_ac_data_t data)
-  /* */                       _GCRY_ATTR_INTERNAL;
-
-/* Return the number of named MPI values inside of the data set
-   DATA.  */
-unsigned int gcry_ac_data_length (gcry_ac_data_t data)
-  /* */                       _GCRY_ATTR_INTERNAL;
-
-/* Destroy any values contained in the data set DATA.  */
-void gcry_ac_data_clear (gcry_ac_data_t data)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Add the value MPI to DATA with the label NAME.  If FLAGS contains
-   GCRY_AC_FLAG_DATA_COPY, the data set will contain copies of NAME
-   and MPI.  If FLAGS contains GCRY_AC_FLAG_DATA_DEALLOC or
-   GCRY_AC_FLAG_DATA_COPY, the values contained in the data set will
-   be deallocated when they are to be removed from the data set.  */
-gcry_error_t gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
-                               const char *name, gcry_mpi_t mpi)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Store the value labelled with NAME found in DATA in MPI.  If FLAGS
-   contains GCRY_AC_FLAG_COPY, store a copy of the MPI value contained
-   in the data set.  MPI may be NULL.  */
-gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
-                                    const char *name, gcry_mpi_t *mpi)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Stores in NAME and MPI the named MPI value contained in the data
-   set DATA with the index IDX.  If FLAGS contains GCRY_AC_FLAG_COPY,
-   store copies of the values contained in the data set. NAME or MPI
-   may be NULL.  */
-gcry_error_t gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
-                                     unsigned int idx,
-                                     const char **name, gcry_mpi_t *mpi)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Convert the data set DATA into a new S-Expression, which is to be
-   stored in SEXP, according to the identifiers contained in
-   IDENTIFIERS.  */
-gcry_error_t gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
-                                  const char **identifiers)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Create a new data set, which is to be stored in DATA_SET, from the
-   S-Expression SEXP, according to the identifiers contained in
-   IDENTIFIERS.  */
-gcry_error_t gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp,
-                                    const char **identifiers)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Initialize AC_IO according to MODE, TYPE and the variable list of
-   arguments.  The list of variable arguments to specify depends on
-   the given TYPE.  */
-void gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
-                     gcry_ac_io_type_t type, ...)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Initialize AC_IO according to MODE, TYPE and the variable list of
-   arguments AP.  The list of variable arguments to specify depends on
-   the given TYPE.  */
-void gcry_ac_io_init_va (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
-                        gcry_ac_io_type_t type, va_list ap)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Create a new ac handle.  */
-gcry_error_t gcry_ac_open (gcry_ac_handle_t *handle,
-                           gcry_ac_id_t algorithm, unsigned int flags)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Destroy an ac handle.  */
-void gcry_ac_close (gcry_ac_handle_t handle)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Initialize a key from a given data set.  */
-gcry_error_t gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
-                               gcry_ac_key_type_t type, gcry_ac_data_t data)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Generates a new key pair via the handle HANDLE of NBITS bits and
-   stores it in KEY_PAIR.  In case non-standard settings are wanted, a
-   pointer to a structure of type gcry_ac_key_spec_<algorithm>_t,
-   matching the selected algorithm, can be given as KEY_SPEC.
-   MISC_DATA is not used yet.  */
-gcry_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t handle,
-                                        unsigned int nbits, void *spec,
-                                        gcry_ac_key_pair_t *key_pair,
-                                        gcry_mpi_t **misc_data)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Returns the key of type WHICH out of the key pair KEY_PAIR.  */
-gcry_ac_key_t gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair,
-                                        gcry_ac_key_type_t which)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Returns the data set contained in the key KEY.  */
-gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t key)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Verifies that the key KEY is sane via HANDLE.  */
-gcry_error_t gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Stores the number of bits of the key KEY in NBITS via HANDLE.  */
-gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
-                                    gcry_ac_key_t key, unsigned int *nbits)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Writes the 20 byte long key grip of the key KEY to KEY_GRIP via
-   HANDLE.  */
-gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key,
-                                   unsigned char *key_grip)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Destroy a key.  */
-void gcry_ac_key_destroy (gcry_ac_key_t key)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Destroy a key pair.  */
-void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Encodes a message according to the encoding method METHOD.  OPTIONS
-   must be a pointer to a method-specific structure
-   (gcry_ac_em*_t).  */
-gcry_error_t gcry_ac_data_encode (gcry_ac_em_t method,
-                                 unsigned int flags, void *options,
-                                 gcry_ac_io_t *io_read,
-                                 gcry_ac_io_t *io_write)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Decodes a message according to the encoding method METHOD.  OPTIONS
-   must be a pointer to a method-specific structure
-   (gcry_ac_em*_t).  */
-gcry_error_t gcry_ac_data_decode (gcry_ac_em_t method,
-                                 unsigned int flags, void *options,
-                                 gcry_ac_io_t *io_read,
-                                 gcry_ac_io_t *io_write)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Encrypt the plain text MPI value DATA_PLAIN with the key KEY under
-   the control of the flags FLAGS and store the resulting data set
-   into DATA_ENCRYPTED.  */
-gcry_error_t gcry_ac_data_encrypt (gcry_ac_handle_t handle,
-                                   unsigned int flags,
-                                   gcry_ac_key_t key,
-                                   gcry_mpi_t data_plain,
-                                   gcry_ac_data_t *data_encrypted)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Decrypt the decrypted data contained in the data set DATA_ENCRYPTED
-   with the key KEY under the control of the flags FLAGS and store the
-   resulting plain text MPI value in DATA_PLAIN.  */
-gcry_error_t gcry_ac_data_decrypt (gcry_ac_handle_t handle,
-                                   unsigned int flags,
-                                   gcry_ac_key_t key,
-                                   gcry_mpi_t *data_plain,
-                                   gcry_ac_data_t data_encrypted)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Sign the data contained in DATA with the key KEY and store the
-   resulting signature in the data set DATA_SIGNATURE.  */
-gcry_error_t gcry_ac_data_sign (gcry_ac_handle_t handle,
-                                gcry_ac_key_t key,
-                                gcry_mpi_t data,
-                                gcry_ac_data_t *data_signature)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Verify that the signature contained in the data set DATA_SIGNATURE
-   is indeed the result of signing the data contained in DATA with the
-   secret key belonging to the public key KEY.  */
-gcry_error_t gcry_ac_data_verify (gcry_ac_handle_t handle,
-                                  gcry_ac_key_t key,
-                                  gcry_mpi_t data,
-                                  gcry_ac_data_t data_signature)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Encrypts the plain text readable from IO_MESSAGE through HANDLE
-   with the public key KEY according to SCHEME, FLAGS and OPTS.  If
-   OPTS is not NULL, it has to be a pointer to a structure specific to
-   the chosen scheme (gcry_ac_es_*_t).  The encrypted message is
-   written to IO_CIPHER. */
-gcry_error_t gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
-                                         gcry_ac_scheme_t scheme,
-                                         unsigned int flags, void *opts,
-                                         gcry_ac_key_t key,
-                                         gcry_ac_io_t *io_message,
-                                         gcry_ac_io_t *io_cipher)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Decrypts the cipher text readable from IO_CIPHER through HANDLE
-   with the secret key KEY according to SCHEME, @var{flags} and OPTS.
-   If OPTS is not NULL, it has to be a pointer to a structure specific
-   to the chosen scheme (gcry_ac_es_*_t).  The decrypted message is
-   written to IO_MESSAGE.  */
-gcry_error_t gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
-                                         gcry_ac_scheme_t scheme,
-                                         unsigned int flags, void *opts,
-                                         gcry_ac_key_t key,
-                                         gcry_ac_io_t *io_cipher,
-                                         gcry_ac_io_t *io_message)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Signs the message readable from IO_MESSAGE through HANDLE with the
-   secret key KEY according to SCHEME, FLAGS and OPTS.  If OPTS is not
-   NULL, it has to be a pointer to a structure specific to the chosen
-   scheme (gcry_ac_ssa_*_t).  The signature is written to
-   IO_SIGNATURE.  */
-gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
-                                      gcry_ac_scheme_t scheme,
-                                      unsigned int flags, void *opts,
-                                      gcry_ac_key_t key,
-                                      gcry_ac_io_t *io_message,
-                                      gcry_ac_io_t *io_signature)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Verifies through HANDLE that the signature readable from
-   IO_SIGNATURE is indeed the result of signing the message readable
-   from IO_MESSAGE with the secret key belonging to the public key KEY
-   according to SCHEME and OPTS.  If OPTS is not NULL, it has to be an
-   anonymous structure (gcry_ac_ssa_*_t) specific to the chosen
-   scheme.  */
-gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
-                                        gcry_ac_scheme_t scheme,
-                                        unsigned int flags, void *opts,
-                                        gcry_ac_key_t key,
-                                        gcry_ac_io_t *io_message,
-                                        gcry_ac_io_t *io_signature)
-  /* */ _GCRY_ATTR_INTERNAL;
-
-/* Store the textual representation of the algorithm whose id is given
-   in ALGORITHM in NAME.  This function is deprecated; use
-   gcry_pk_algo_name. */
-gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t algorithm,
-                                 const char **name)
-     /* */                      _GCRY_GCC_ATTR_DEPRECATED;
-/* Store the numeric ID of the algorithm whose textual representation
-   is contained in NAME in ALGORITHM.  This function is deprecated;
-   use gcry_pk_map_name. */
-gcry_error_t gcry_ac_name_to_id (const char *name,
-                                 gcry_ac_id_t *algorithm)
-     /* */                      _GCRY_GCC_ATTR_DEPRECATED;
-#endif /*GCRYPT_NO_DEPRECATED*/
+/* 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
 /******************************
@@ -1672,7 +1422,8 @@ enum gcry_kdf_algos
     GCRY_KDF_SALTED_S2K = 17,
     GCRY_KDF_ITERSALTED_S2K = 19,
     GCRY_KDF_PBKDF1 = 33,
-    GCRY_KDF_PBKDF2 = 34
+    GCRY_KDF_PBKDF2 = 34,
+    GCRY_KDF_SCRYPT = 48
   };
 
 /* Derive a key from a passphrase.  */
@@ -1691,6 +1442,14 @@ gpg_error_t gcry_kdf_derive (const void *passphrase, size_t passphraselen,
  *                                  *
  ************************************/
 
+/* 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
@@ -1811,6 +1570,18 @@ gcry_error_t gcry_prime_check (gcry_mpi_t x, unsigned int flags);
  *                                  *
  ************************************/
 
+/* 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
   {
@@ -1898,9 +1669,6 @@ int gcry_is_secure (const void *a) _GCRY_GCC_ATTR_PURE;
 #define gcry_fips_mode_active()  !!gcry_control (GCRYCTL_FIPS_MODE_P, 0)
 
 
-/* Include support for Libgcrypt modules.  */
-#include <gcrypt-module.h>
-
 #if 0 /* (Keep Emacsens' auto-indent happy.) */
 {
 #endif
index d65b068..6f9cbf9 100644 (file)
@@ -1,6 +1,8 @@
 /* global.c  - global control functions
  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
- *               2004, 2005, 2006, 2008, 2011  Free Software Foundation, Inc.
+ *               2004, 2005, 2006, 2008, 2011,
+ *               2012  Free Software Foundation, Inc.
+ * Copyright (C) 2013 g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
@@ -53,26 +55,6 @@ static int force_fips_mode;
 /* Controlled by global_init().  */
 static int any_init_done;
 
-/* A table to map hardware features to a string.  */
-static struct
-{
-  unsigned int flag;
-  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_AESNI, "intel-aesni" },
-    { 0, NULL}
-  };
-
-/* A bit vector with the hardware features which shall not be used.
-   This variable must be set prior to any initialization.  */
-static unsigned int disabled_hw_features;
-
-
 /* Memory management. */
 
 static gcry_handler_alloc_t alloc_func;
@@ -84,6 +66,8 @@ static gcry_handler_no_mem_t outofcore_handler;
 static void *outofcore_handler_value;
 static int no_secure_memory;
 
+/* Prototypes.  */
+static gpg_err_code_t external_lock_test (int cmd);
 
 \f
 
@@ -101,19 +85,27 @@ global_init (void)
     return;
   any_init_done = 1;
 
+  /* 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)
-    goto fail;
+    {
+      err = gpg_error_from_errno (err);
+      goto fail;
+    }
 
   /* See whether the system is in FIPS mode.  This needs to come as
-     early as possible put after the ATH has been initialized.  */
+     early as possible but after ATH has been initialized.  */
   _gcry_initialize_fips_mode (force_fips_mode);
 
   /* Before we do any other initialization we need to test available
      hardware features.  */
-  _gcry_detect_hw_features (disabled_hw_features);
+  _gcry_detect_hw_features ();
 
+  /* Initialize the modules - this is mainly allocating some memory and
+     creating mutexes.  */
   err = _gcry_cipher_init ();
   if (err)
     goto fail;
@@ -123,15 +115,15 @@ global_init (void)
   err = _gcry_pk_init ();
   if (err)
     goto fail;
-#if 0
-  /* Hmmm, as of now ac_init does nothing. */
-  if ( !fips_mode () )
-    {
-      err = _gcry_ac_init ();
-      if (err)
-        goto fail;
-    }
-#endif
+  err = _gcry_primegen_init ();
+  if (err)
+    goto fail;
+  err = _gcry_secmem_module_init ();
+  if (err)
+    goto fail;
+  err = _gcry_mpi_init ();
+  if (err)
+    goto fail;
 
   return;
 
@@ -229,13 +221,16 @@ parse_version_string( const char *s, int *major, int *minor, int *micro )
    If a NULL is passed to this function, no check is done, but the
    string representation of the library is simply returned.  */
 const char *
-gcry_check_version( const char *req_version )
+_gcry_check_version (const char *req_version)
 {
     const char *ver = VERSION;
     int my_major, my_minor, my_micro;
     int rq_major, rq_minor, rq_micro;
     const char *my_plvl;
 
+    if (req_version && req_version[0] == 1 && req_version[1] == 1)
+        return _gcry_compat_identification ();
+
     /* Initialize library.  */
     global_init ();
 
@@ -271,8 +266,9 @@ gcry_check_version( const char *req_version )
 static void
 print_config ( int (*fnc)(FILE *fp, const char *format, ...), FILE *fp)
 {
-  unsigned int hwf;
+  unsigned int hwfeatures, afeature;
   int i;
+  const char *s;
 
   fnc (fp, "version:%s:\n", VERSION);
   fnc (fp, "ciphers:%s:\n", LIBGCRYPT_CIPHERS);
@@ -292,12 +288,30 @@ print_config ( int (*fnc)(FILE *fp, const char *format, ...), FILE *fp)
                 "w32:"
 #endif
        "\n");
+  fnc (fp, "cpu-arch:"
+#if defined(HAVE_CPU_ARCH_X86)
+       "x86"
+#elif defined(HAVE_CPU_ARCH_ALPHA)
+       "alpha"
+#elif defined(HAVE_CPU_ARCH_SPARC)
+       "sparc"
+#elif defined(HAVE_CPU_ARCH_MIPS)
+       "mips"
+#elif defined(HAVE_CPU_ARCH_M68K)
+       "m68k"
+#elif defined(HAVE_CPU_ARCH_PPC)
+       "ppc"
+#elif defined(HAVE_CPU_ARCH_ARM)
+       "arm"
+#endif
+       ":\n");
   fnc (fp, "mpi-asm:%s:\n", _gcry_mpi_get_hw_config ());
-  hwf = _gcry_get_hw_features ();
+  fnc (fp, "threads:%s:\n", ath_get_model (NULL));
+  hwfeatures = _gcry_get_hw_features ();
   fnc (fp, "hwflist:");
-  for (i=0; hwflist[i].desc; i++)
-    if ( (hwf & hwflist[i].flag) )
-      fnc (fp, "%s:", hwflist[i].desc);
+  for (i=0; (s = _gcry_enum_hw_features (i, &afeature)); i++)
+    if ((hwfeatures & afeature))
+      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
@@ -305,6 +319,19 @@ print_config ( int (*fnc)(FILE *fp, const char *format, ...), FILE *fp)
   fnc (fp, "fips-mode:%c:%c:\n",
        fips_mode ()? 'y':'n',
        _gcry_enforced_fips_mode ()? 'y':'n' );
+  /* The currently used RNG type.  */
+  {
+    i = _gcry_get_rng_type (0);
+    switch (i)
+      {
+      case GCRY_RNG_TYPE_STANDARD: s = "standard"; break;
+      case GCRY_RNG_TYPE_FIPS:     s = "fips"; break;
+      case GCRY_RNG_TYPE_SYSTEM:   s = "system"; break;
+      default: BUG ();
+      }
+    fnc (fp, "rng-type:%s:%d:\n", s, i);
+  }
+
 }
 
 
@@ -312,11 +339,11 @@ print_config ( int (*fnc)(FILE *fp, const char *format, ...), FILE *fp)
 
 /* Command dispatcher function, acting as general control
    function.  */
-gcry_error_t
+gcry_err_code_t
 _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
 {
   static int init_finished = 0;
-  gcry_err_code_t err = 0;
+  gcry_err_code_t rc = 0;
 
   switch (cmd)
     {
@@ -325,6 +352,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
       break;
 
     case GCRYCTL_ENABLE_QUICK_RANDOM:
+      _gcry_set_preferred_rng_type (0);
       _gcry_enable_quick_random_gen ();
       break;
 
@@ -332,7 +360,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
       /* Return an error if the RNG is faked one (e.g. enabled by
          ENABLE_QUICK_RANDOM. */
       if (_gcry_random_is_faked ())
-        err = GPG_ERR_GENERAL;  /* Use as TRUE value.  */
+        rc = GPG_ERR_GENERAL;  /* Use as TRUE value.  */
       break;
 
     case GCRYCTL_DUMP_RANDOM_STATS:
@@ -361,7 +389,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
       global_init ();
       _gcry_secmem_init (va_arg (arg_ptr, unsigned int));
       if ((_gcry_secmem_get_flags () & GCRY_SECMEM_FLAG_NOT_LOCKED))
-        err = GPG_ERR_GENERAL;
+        rc = GPG_ERR_GENERAL;
       break;
 
     case GCRYCTL_TERM_SECMEM:
@@ -370,16 +398,19 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
       break;
 
     case GCRYCTL_DISABLE_SECMEM_WARN:
+      _gcry_set_preferred_rng_type (0);
       _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
                               | GCRY_SECMEM_FLAG_NO_WARNING));
       break;
 
     case GCRYCTL_SUSPEND_SECMEM_WARN:
+      _gcry_set_preferred_rng_type (0);
       _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
                               | GCRY_SECMEM_FLAG_SUSPEND_WARNING));
       break;
 
     case GCRYCTL_RESUME_SECMEM_WARN:
+      _gcry_set_preferred_rng_type (0);
       _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
                               & ~GCRY_SECMEM_FLAG_SUSPEND_WARNING));
       break;
@@ -390,15 +421,18 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
       break;
 
     case GCRYCTL_SET_RANDOM_SEED_FILE:
+      _gcry_set_preferred_rng_type (0);
       _gcry_set_random_seed_file (va_arg (arg_ptr, const char *));
       break;
 
     case GCRYCTL_UPDATE_RANDOM_SEED_FILE:
+      _gcry_set_preferred_rng_type (0);
       if ( fips_is_operational () )
         _gcry_update_random_seed_file ();
       break;
 
     case GCRYCTL_SET_VERBOSITY:
+      _gcry_set_preferred_rng_type (0);
       _gcry_set_log_verbosity (va_arg (arg_ptr, int));
       break;
 
@@ -417,12 +451,12 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
 
     case GCRYCTL_ANY_INITIALIZATION_P:
       if (any_init_done)
-       err = GPG_ERR_GENERAL;
+       rc = GPG_ERR_GENERAL;
       break;
 
     case GCRYCTL_INITIALIZATION_FINISHED_P:
       if (init_finished)
-       err = GPG_ERR_GENERAL; /* Yes.  */
+       rc = GPG_ERR_GENERAL; /* Yes.  */
       break;
 
     case GCRYCTL_INITIALIZATION_FINISHED:
@@ -444,12 +478,14 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
       break;
 
     case GCRYCTL_SET_THREAD_CBS:
-      err = ath_install (va_arg (arg_ptr, void *), any_init_done);
-      if (! err)
+      _gcry_set_preferred_rng_type (0);
+      rc = ath_install (va_arg (arg_ptr, void *));
+      if (!rc)
        global_init ();
       break;
 
     case GCRYCTL_FAST_POLL:
+      _gcry_set_preferred_rng_type (0);
       /* We need to do make sure that the random pool is really
          initialized so that the poll function is not a NOP. */
       _gcry_random_initialize (1);
@@ -460,23 +496,30 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
 
     case GCRYCTL_SET_RNDEGD_SOCKET:
 #if USE_RNDEGD
-      err = _gcry_rndegd_set_socket_name (va_arg (arg_ptr, const char *));
+      _gcry_set_preferred_rng_type (0);
+      rc = _gcry_rndegd_set_socket_name (va_arg (arg_ptr, const char *));
 #else
-      err = gpg_error (GPG_ERR_NOT_SUPPORTED);
+      rc = gpg_error (GPG_ERR_NOT_SUPPORTED);
 #endif
       break;
 
     case GCRYCTL_SET_RANDOM_DAEMON_SOCKET:
+      _gcry_set_preferred_rng_type (0);
       _gcry_set_random_daemon_socket (va_arg (arg_ptr, const char *));
       break;
 
     case GCRYCTL_USE_RANDOM_DAEMON:
       /* We need to do make sure that the random pool is really
          initialized so that the poll function is not a NOP. */
+      _gcry_set_preferred_rng_type (0);
       _gcry_random_initialize (1);
       _gcry_use_random_daemon (!! va_arg (arg_ptr, int));
       break;
 
+    case GCRYCTL_CLOSE_RANDOM_DEVICE:
+      _gcry_random_close_fds ();
+      break;
+
       /* This command dumps information pertaining to the
          configuration of libgcrypt to the given stream.  It may be
          used before the initialization has been finished but not
@@ -484,6 +527,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
     case GCRYCTL_PRINT_CONFIG:
       {
         FILE *fp = va_arg (arg_ptr, FILE *);
+        _gcry_set_preferred_rng_type (0);
         print_config (fp?fprintf:_gcry_log_info_with_dummy_fp, fp);
       }
       break;
@@ -491,15 +535,16 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
     case GCRYCTL_OPERATIONAL_P:
       /* Returns true if the library is in an operational state.  This
          is always true for non-fips mode.  */
+      _gcry_set_preferred_rng_type (0);
       if (_gcry_fips_test_operational ())
-        err = GPG_ERR_GENERAL; /* Used as TRUE value */
+        rc = GPG_ERR_GENERAL; /* Used as TRUE value */
       break;
 
     case GCRYCTL_FIPS_MODE_P:
       if (fips_mode ()
           && !_gcry_is_fips_mode_inactive ()
           && !no_secure_memory)
-       err = GPG_ERR_GENERAL; /* Used as TRUE value */
+       rc = GPG_ERR_GENERAL; /* Used as TRUE value */
       break;
 
     case GCRYCTL_FORCE_FIPS_MODE:
@@ -507,6 +552,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
          the library has already been initialized into fips mode, a
          selftest is triggered.  It is not possible to put the libraty
          into fips mode after having passed the initialization. */
+      _gcry_set_preferred_rng_type (0);
       if (!any_init_done)
         {
           /* Not yet intialized at all.  Set a flag so that we are put
@@ -521,7 +567,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
           if (_gcry_fips_test_error_or_operational ())
             _gcry_fips_run_selftests (1);
           if (_gcry_fips_is_operational ())
-            err = GPG_ERR_GENERAL; /* Used as TRUE value */
+            rc = GPG_ERR_GENERAL; /* Used as TRUE value */
       }
       break;
 
@@ -531,7 +577,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
          extended version of the selftests. Returns 0 on success or an
          error code. */
       global_init ();
-      err = _gcry_fips_run_selftests (1);
+      rc = _gcry_fips_run_selftests (1);
       break;
 
 #if _GCRY_GCC_VERSION >= 40600
@@ -549,10 +595,10 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
         const void *dt     = va_arg (arg_ptr, const void *);
         size_t dtlen       = va_arg (arg_ptr, size_t);
         if (!fips_is_operational ())
-          err = fips_not_operational ();
+          rc = fips_not_operational ();
         else
-          err = _gcry_random_init_external_test (rctx, flags, key, keylen,
-                                                 seed, seedlen, dt, dtlen);
+          rc = _gcry_random_init_external_test (rctx, flags, key, keylen,
+                                                seed, seedlen, dt, dtlen);
       }
       break;
     case 59:  /* Run external random test.  */
@@ -561,9 +607,9 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
         void *buffer  = va_arg (arg_ptr, void *);
         size_t buflen = va_arg (arg_ptr, size_t);
         if (!fips_is_operational ())
-          err = fips_not_operational ();
+          rc = fips_not_operational ();
         else
-          err = _gcry_random_run_external_test (ctx, buffer, buflen);
+          rc = _gcry_random_run_external_test (ctx, buffer, buflen);
       }
       break;
     case 60:  /* Deinit external random test.  */
@@ -572,7 +618,8 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
         _gcry_random_deinit_external_test (ctx);
       }
       break;
-    case 61:  /* RFU */
+    case 61:  /* Run external lock test */
+      rc = external_lock_test (va_arg (arg_ptr, int));
       break;
     case 62:  /* RFU */
       break;
@@ -583,107 +630,76 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, va_list arg_ptr)
     case GCRYCTL_DISABLE_HWF:
       {
         const char *name = va_arg (arg_ptr, const char *);
-        int i;
-
-        for (i=0; hwflist[i].desc; i++)
-          if (!strcmp (hwflist[i].desc, name))
-            {
-              disabled_hw_features |= hwflist[i].flag;
-              break;
-            }
-        if (!hwflist[i].desc)
-          err = GPG_ERR_INV_NAME;
+        rc = _gcry_disable_hw_feature (name);
       }
       break;
 
-    default:
-      /* A call to make sure that the dummy code is linked in.  */
-      _gcry_compat_identification ();
-      err = GPG_ERR_INV_OP;
-    }
-
-  return gcry_error (err);
-}
-
-
-/* Command dispatcher function, acting as general control
-   function.  */
-gcry_error_t
-gcry_control (enum gcry_ctl_cmds cmd, ...)
-{
-  gcry_error_t err;
-  va_list arg_ptr;
-
-  va_start (arg_ptr, cmd);
-  err = _gcry_vcontrol (cmd, arg_ptr);
-  va_end(arg_ptr);
-  return err;
-}
-
-
+    case GCRYCTL_SET_ENFORCED_FIPS_FLAG:
+      if (!any_init_done)
+        {
+          /* Not yet initialized at all.  Set the enforced fips mode flag */
+          _gcry_set_preferred_rng_type (0);
+          _gcry_set_enforced_fips_mode ();
+        }
+      else
+        rc = GPG_ERR_GENERAL;
+      break;
 
-/* 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 gpg_strerror (err);
-}
+    case GCRYCTL_SET_PREFERRED_RNG_TYPE:
+      /* This may be called before gcry_check_version.  */
+      {
+        int i = va_arg (arg_ptr, int);
+        /* Note that we may not pass 0 to _gcry_set_preferred_rng_type.  */
+        if (i > 0)
+          _gcry_set_preferred_rng_type (i);
+      }
+      break;
 
-/* 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)
-{
-  return gpg_strsource (err);
-}
+    case GCRYCTL_GET_CURRENT_RNG_TYPE:
+      {
+        int *ip = va_arg (arg_ptr, int*);
+        if (ip)
+          *ip = _gcry_get_rng_type (!any_init_done);
+      }
+      break;
 
-/* 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)
-{
-  return gpg_err_code_from_errno (err);
-}
+    case GCRYCTL_DISABLE_LOCKED_SECMEM:
+      _gcry_set_preferred_rng_type (0);
+      _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
+                              | GCRY_SECMEM_FLAG_NO_MLOCK));
+      break;
 
+    case GCRYCTL_DISABLE_PRIV_DROP:
+      _gcry_set_preferred_rng_type (0);
+      _gcry_secmem_set_flags ((_gcry_secmem_get_flags ()
+                              | GCRY_SECMEM_FLAG_NO_PRIV_DROP));
+      break;
 
-/* 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 gpg_err_code_from_errno (code);
-}
+    case GCRYCTL_INACTIVATE_FIPS_FLAG:
+    case GCRYCTL_REACTIVATE_FIPS_FLAG:
+      rc = GPG_ERR_NOT_IMPLEMENTED;
+      break;
 
+    default:
+      _gcry_set_preferred_rng_type (0);
+      rc = GPG_ERR_INV_OP;
+    }
 
-/* Return an error value with the error source SOURCE and the system
-   error ERR.  */
-gcry_error_t
-gcry_err_make_from_errno (gpg_err_source_t source, int err)
-{
-  return gpg_err_make_from_errno (source, err);
+  return rc;
 }
 
 
-/* Return an error value with the system error ERR.  */
-gcry_err_code_t
-gcry_error_from_errno (int err)
-{
-  return gcry_error (gpg_err_code_from_errno (err));
-}
-
 
 /* Set custom allocation handlers.  This is in general not useful
  * because the libgcrypt allocation functions are guaranteed to
  * provide proper allocation handlers which zeroize memory if needed.
  * NOTE: All 5 functions should be set.  */
 void
-gcry_set_allocation_handler (gcry_handler_alloc_t new_alloc_func,
-                            gcry_handler_alloc_t new_alloc_secure_func,
-                            gcry_handler_secure_check_t new_is_secure_func,
-                            gcry_handler_realloc_t new_realloc_func,
-                            gcry_handler_free_t new_free_func)
+_gcry_set_allocation_handler (gcry_handler_alloc_t new_alloc_func,
+                              gcry_handler_alloc_t new_alloc_secure_func,
+                              gcry_handler_secure_check_t new_is_secure_func,
+                              gcry_handler_realloc_t new_realloc_func,
+                              gcry_handler_free_t new_free_func)
 {
   global_init ();
 
@@ -719,8 +735,7 @@ gcry_set_allocation_handler (gcry_handler_alloc_t new_alloc_func,
  *     bit 0 set = secure memory has been requested.
  */
 void
-gcry_set_outofcore_handler( int (*f)( void*, size_t, unsigned int ),
-                                                       void *value )
+_gcry_set_outofcore_handler (int (*f)(void*, size_t, unsigned int), void *value)
 {
   global_init ();
 
@@ -785,7 +800,7 @@ do_malloc (size_t n, unsigned int flags, void **mem)
 }
 
 void *
-gcry_malloc (size_t n)
+_gcry_malloc (size_t n)
 {
   void *mem = NULL;
 
@@ -795,7 +810,7 @@ gcry_malloc (size_t n)
 }
 
 void *
-gcry_malloc_secure (size_t n)
+_gcry_malloc_secure (size_t n)
 {
   void *mem = NULL;
 
@@ -805,7 +820,7 @@ gcry_malloc_secure (size_t n)
 }
 
 int
-gcry_is_secure (const void *a)
+_gcry_is_secure (const void *a)
 {
   if (get_no_secure_memory ())
     return 0;
@@ -829,17 +844,17 @@ _gcry_check_heap( const void *a )
 }
 
 void *
-gcry_realloc (void *a, size_t n)
+_gcry_realloc (void *a, size_t n)
 {
   void *p;
 
   /* To avoid problems with non-standard realloc implementations and
      our own secmem_realloc, we divert to malloc and free here.  */
   if (!a)
-    return gcry_malloc (n);
+    return _gcry_malloc (n);
   if (!n)
     {
-      gcry_free (a);
+      xfree (a);
       return NULL;
     }
 
@@ -853,7 +868,7 @@ gcry_realloc (void *a, size_t n)
 }
 
 void
-gcry_free (void *p)
+_gcry_free (void *p)
 {
   int save_errno;
 
@@ -874,7 +889,7 @@ gcry_free (void *p)
 }
 
 void *
-gcry_calloc (size_t n, size_t m)
+_gcry_calloc (size_t n, size_t m)
 {
   size_t bytes;
   void *p;
@@ -887,14 +902,14 @@ gcry_calloc (size_t n, size_t m)
       return NULL;
     }
 
-  p = gcry_malloc (bytes);
+  p = _gcry_malloc (bytes);
   if (p)
     memset (p, 0, bytes);
   return p;
 }
 
 void *
-gcry_calloc_secure (size_t n, size_t m)
+_gcry_calloc_secure (size_t n, size_t m)
 {
   size_t bytes;
   void *p;
@@ -907,7 +922,7 @@ gcry_calloc_secure (size_t n, size_t m)
       return NULL;
     }
 
-  p = gcry_malloc_secure (bytes);
+  p = _gcry_malloc_secure (bytes);
   if (p)
     memset (p, 0, bytes);
   return p;
@@ -919,17 +934,17 @@ gcry_calloc_secure (size_t n, size_t m)
    secure memory as well.  In an out-of-memory condition, NULL is
    returned.  */
 char *
-gcry_strdup (const char *string)
+_gcry_strdup (const char *string)
 {
   char *string_cp = NULL;
   size_t string_n = 0;
 
   string_n = strlen (string);
 
-  if (gcry_is_secure (string))
-    string_cp = gcry_malloc_secure (string_n + 1);
+  if (_gcry_is_secure (string))
+    string_cp = _gcry_malloc_secure (string_n + 1);
   else
-    string_cp = gcry_malloc (string_n + 1);
+    string_cp = _gcry_malloc (string_n + 1);
 
   if (string_cp)
     strcpy (string_cp, string);
@@ -939,11 +954,11 @@ gcry_strdup (const char *string)
 
 
 void *
-gcry_xmalloc( size_t n )
+_gcry_xmalloc( size_t n )
 {
   void *p;
 
-  while ( !(p = gcry_malloc( n )) )
+  while ( !(p = _gcry_malloc( n )) )
     {
       if ( fips_mode ()
            || !outofcore_handler
@@ -956,16 +971,16 @@ gcry_xmalloc( size_t n )
 }
 
 void *
-gcry_xrealloc( void *a, size_t n )
+_gcry_xrealloc( void *a, size_t n )
 {
   void *p;
 
-  while ( !(p = gcry_realloc( a, n )) )
+  while ( !(p = _gcry_realloc( a, n )) )
     {
       if ( fips_mode ()
            || !outofcore_handler
            || !outofcore_handler (outofcore_handler_value, n,
-                                   gcry_is_secure(a)? 3:2 ) )
+                                  _gcry_is_secure(a)? 3:2))
         {
           _gcry_fatal_error (gpg_err_code_from_errno (errno), NULL );
        }
@@ -974,11 +989,11 @@ gcry_xrealloc( void *a, size_t n )
 }
 
 void *
-gcry_xmalloc_secure( size_t n )
+_gcry_xmalloc_secure( size_t n )
 {
   void *p;
 
-  while ( !(p = gcry_malloc_secure( n )) )
+  while ( !(p = _gcry_malloc_secure( n )) )
     {
       if ( fips_mode ()
            || !outofcore_handler
@@ -993,7 +1008,7 @@ gcry_xmalloc_secure( size_t n )
 
 
 void *
-gcry_xcalloc( size_t n, size_t m )
+_gcry_xcalloc( size_t n, size_t m )
 {
   size_t nbytes;
   void *p;
@@ -1005,13 +1020,13 @@ gcry_xcalloc( size_t n, size_t m )
       _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
     }
 
-  p = gcry_xmalloc ( nbytes );
+  p = _gcry_xmalloc ( nbytes );
   memset ( p, 0, nbytes );
   return p;
 }
 
 void *
-gcry_xcalloc_secure( size_t n, size_t m )
+_gcry_xcalloc_secure( size_t n, size_t m )
 {
   size_t nbytes;
   void *p;
@@ -1023,20 +1038,20 @@ gcry_xcalloc_secure( size_t n, size_t m )
       _gcry_fatal_error(gpg_err_code_from_errno (errno), NULL );
     }
 
-  p = gcry_xmalloc_secure ( nbytes );
+  p = _gcry_xmalloc_secure ( nbytes );
   memset ( p, 0, nbytes );
   return p;
 }
 
 char *
-gcry_xstrdup (const char *string)
+_gcry_xstrdup (const char *string)
 {
   char *p;
 
-  while ( !(p = gcry_strdup (string)) )
+  while ( !(p = _gcry_strdup (string)) )
     {
       size_t n = strlen (string);
-      int is_sec = !!gcry_is_secure (string);
+      int is_sec = !!_gcry_is_secure (string);
 
       if (fips_mode ()
           || !outofcore_handler
@@ -1098,8 +1113,8 @@ _gcry_get_debug_flag (unsigned int mask)
             Only used in debugging mode.
 */
 void
-gcry_set_progress_handler (void (*cb)(void *,const char*,int, int, int),
-                           void *cb_data)
+_gcry_set_progress_handler (void (*cb)(void *,const char*,int, int, int),
+                            void *cb_data)
 {
 #if USE_DSA
   _gcry_register_pk_dsa_progress (cb, cb_data);
@@ -1110,3 +1125,48 @@ gcry_set_progress_handler (void (*cb)(void *,const char*,int, int, int),
   _gcry_register_primegen_progress (cb, cb_data);
   _gcry_register_random_progress (cb, cb_data);
 }
+
+
+\f
+/* This is a helper for the regression test suite to test Libgcrypt's locks.
+   It works using a one test lock with CMD controlling what to do:
+
+     30111 - Allocate and init lock
+     30112 - Take lock
+     30113 - Release lock
+     30114 - Destroy lock.
+
+   This function is used by tests/t-lock.c - it is not part of the
+   public API!
+ */
+static gpg_err_code_t
+external_lock_test (int cmd)
+{
+  static ath_mutex_t testlock;
+  gpg_err_code_t rc = 0;
+
+  switch (cmd)
+    {
+    case 30111:  /* Init Lock.  */
+      rc = ath_mutex_init (&testlock);
+      break;
+
+    case 30112:  /* Take Lock.  */
+      rc = ath_mutex_lock (&testlock);
+      break;
+
+    case 30113:  /* Release Lock.  */
+      rc = ath_mutex_unlock (&testlock);
+      break;
+
+    case 30114:  /* Destroy Lock.  */
+      rc = ath_mutex_destroy (&testlock);
+      break;
+
+    default:
+      rc = GPG_ERR_INV_OP;
+      break;
+    }
+
+  return rc;
+}
index f3bc092..94a26da 100644 (file)
@@ -98,18 +98,10 @@ struct hmac256_context
 
 
 /* Rotate a 32 bit word.  */
-#if defined(__GNUC__) && defined(__i386__)
-static inline u32
-ror(u32 x, int n)
+static inline u32 ror(u32 x, int n)
 {
-       __asm__("rorl %%cl,%0"
-               :"=r" (x)
-               :"0" (x),"c" (n));
-       return x;
+       return ( ((x) >> (n)) | ((x) << (32-(n))) );
 }
-#else
-#define ror(x,n) ( ((x) >> (n)) | ((x) << (32-(n))) )
-#endif
 
 #define my_wipememory2(_ptr,_set,_len) do { \
               volatile char *_vptr=(volatile char *)(_ptr); \
@@ -766,6 +758,8 @@ main (int argc, char **argv)
                        pgm, strerror (errno));
               exit (1);
             }
+          if (use_stdin)
+            break;
         }
       else
         {
diff --git a/src/hwf-arm.c b/src/hwf-arm.c
new file mode 100644 (file)
index 0000000..5c99a1d
--- /dev/null
@@ -0,0 +1,115 @@
+/* hwf-arm.c - Detect hardware features - ARM part
+ * Copyright © 2013  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 <stdarg.h>
+#include <unistd.h>
+
+#include "g10lib.h"
+#include "hwf-common.h"
+
+#if !defined (__arm__)
+# error Module build for wrong CPU.
+#endif
+
+#undef HAS_SYS_AT_HWCAP
+#ifdef __linux__
+
+#define HAS_SYS_AT_HWCAP 1
+
+#define AT_HWCAP 16
+#define HWCAP_NEON 4096
+
+static int
+get_hwcap(unsigned int *hwcap)
+{
+  struct { unsigned int a_type; unsigned int a_val; } auxv;
+  FILE *f;
+  int err = -1;
+  static int hwcap_initialized = 0;
+  static unsigned int stored_hwcap;
+
+  if (hwcap_initialized)
+    {
+      *hwcap = stored_hwcap;
+      return 0;
+    }
+
+  f = fopen("/proc/self/auxv", "r");
+  if (!f)
+    {
+      *hwcap = stored_hwcap;
+      return -1;
+    }
+
+  while (fread(&auxv, sizeof(auxv), 1, f) > 0)
+    {
+      if (auxv.a_type != AT_HWCAP)
+        continue;
+
+      stored_hwcap = auxv.a_val;
+      hwcap_initialized = 1;
+      err = 0;
+      break;
+    }
+
+  fclose(f);
+  *hwcap = stored_hwcap;
+  return err;
+}
+
+static unsigned int
+detect_arm_at_hwcap(void)
+{
+  unsigned int hwcap;
+  unsigned int features = 0;
+
+  if (get_hwcap(&hwcap) < 0)
+    return features;
+
+#ifdef ENABLE_NEON_SUPPORT
+  if (hwcap & HWCAP_NEON)
+    features |= HWF_ARM_NEON;
+#endif
+
+  return features;
+}
+
+#endif /* __linux__ */
+
+unsigned int
+_gcry_hwf_detect_arm (void)
+{
+  unsigned int ret = 0;
+
+#if defined (HAS_SYS_AT_HWCAP)
+  ret |= detect_arm_at_hwcap ();
+#else
+  ret |= 0;
+#endif
+
+#if defined(__ARM_NEON__) && defined(ENABLE_NEON_SUPPORT)
+  ret |= HWF_ARM_NEON;
+#endif
+
+  return ret;
+}
diff --git a/src/hwf-common.h b/src/hwf-common.h
new file mode 100644 (file)
index 0000000..8f156b5
--- /dev/null
@@ -0,0 +1,27 @@
+/* hwf-common.h - Declarations for hwf-CPU.c modules
+ * Copyright (C) 2012  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/>.
+ */
+
+#ifndef HWF_COMMON_H
+#define HWF_COMMON_H
+
+unsigned int _gcry_hwf_detect_x86 (void);
+unsigned int _gcry_hwf_detect_arm (void);
+
+
+#endif /*HWF_COMMON_H*/
diff --git a/src/hwf-x86.c b/src/hwf-x86.c
new file mode 100644 (file)
index 0000000..0591b4f
--- /dev/null
@@ -0,0 +1,306 @@
+/* hwf-x86.c - Detect hardware features - x86 part
+ * Copyright (C) 2007, 2011, 2012  Free Software Foundation, Inc.
+ * Copyright (C) 2012  Jussi Kivilinna
+ *
+ * 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 <stdarg.h>
+#include <unistd.h>
+
+#include "g10lib.h"
+#include "hwf-common.h"
+
+#if !defined (__i386__) && !defined (__x86_64__)
+# error Module build for wrong CPU.
+#endif
+
+/* We use the next macro to decide whether we can test for certain
+   features.  */
+#undef HAS_X86_CPUID
+
+#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__)
+# define HAS_X86_CPUID 1
+
+static int
+is_cpuid_available(void)
+{
+  int has_cpuid = 0;
+
+  /* Detect the CPUID feature by testing some undefined behaviour (16
+     vs 32 bit pushf/popf). */
+  asm volatile
+    ("pushf\n\t"                 /* Copy flags to EAX.  */
+     "popl %%eax\n\t"
+     "movl %%eax, %%ecx\n\t"     /* Save flags into ECX.  */
+     "xorl $0x200000, %%eax\n\t" /* Toggle ID bit and copy it to the flags.  */
+     "pushl %%eax\n\t"
+     "popf\n\t"
+     "pushf\n\t"                 /* Copy changed flags again to EAX.  */
+     "popl %%eax\n\t"
+     "pushl %%ecx\n\t"           /* Restore flags from ECX.  */
+     "popf\n\t"
+     "xorl %%eax, %%ecx\n\t"     /* Compare flags against saved flags.  */
+     "jz .Lno_cpuid%=\n\t"       /* Toggling did not work, thus no CPUID.  */
+     "movl $1, %0\n"             /* Worked. true -> HAS_CPUID.  */
+     ".Lno_cpuid%=:\n\t"
+     : "+r" (has_cpuid)
+     :
+     : "%eax", "%ecx", "cc"
+     );
+
+  return has_cpuid;
+}
+
+static void
+get_cpuid(unsigned int in, unsigned int *eax, unsigned int *ebx,
+          unsigned int *ecx, unsigned int *edx)
+{
+  unsigned int regs[4];
+
+  asm volatile
+    ("pushl %%ebx\n\t"           /* Save GOT register.  */
+     "movl %1, %%ebx\n\t"
+     "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])
+     : "0" (in), "1" (0), "2" (0), "3" (0)
+     : "cc"
+     );
+
+  if (eax)
+    *eax = regs[0];
+  if (ebx)
+    *ebx = regs[1];
+  if (ecx)
+    *ecx = regs[2];
+  if (edx)
+    *edx = regs[3];
+}
+
+static unsigned int
+get_xgetbv(void)
+{
+  unsigned int t_eax;
+
+  asm volatile
+    ("xgetbv\n\t"
+     : "=a" (t_eax)
+     : "c" (0)
+    );
+
+  return t_eax;
+}
+
+#endif /* i386 && GNUC */
+
+
+#if defined (__x86_64__) && defined (__GNUC__)
+# define HAS_X86_CPUID 1
+
+static int
+is_cpuid_available(void)
+{
+  return 1;
+}
+
+static void
+get_cpuid(unsigned int in, unsigned int *eax, unsigned int *ebx,
+          unsigned int *ecx, unsigned int *edx)
+{
+  unsigned int regs[4];
+
+  asm volatile
+    ("cpuid\n\t"
+     : "=a" (regs[0]), "=b" (regs[1]), "=c" (regs[2]), "=d" (regs[3])
+     : "0" (in), "1" (0), "2" (0), "3" (0)
+     : "cc"
+     );
+
+  if (eax)
+    *eax = regs[0];
+  if (ebx)
+    *ebx = regs[1];
+  if (ecx)
+    *ecx = regs[2];
+  if (edx)
+    *edx = regs[3];
+}
+
+static unsigned int
+get_xgetbv(void)
+{
+  unsigned int t_eax;
+
+  asm volatile
+    ("xgetbv\n\t"
+     : "=a" (t_eax)
+     : "c" (0)
+    );
+
+  return t_eax;
+}
+
+#endif /* x86-64 && GNUC */
+
+
+#ifdef HAS_X86_CPUID
+static unsigned int
+detect_x86_gnuc (void)
+{
+  char vendor_id[12+1];
+  unsigned int features;
+  unsigned int os_supports_avx_avx2_registers = 0;
+  unsigned int max_cpuid_level;
+  unsigned int result = 0;
+
+  (void)os_supports_avx_avx2_registers;
+
+  if (!is_cpuid_available())
+    return 0;
+
+  get_cpuid(0, &max_cpuid_level,
+            (unsigned int *)&vendor_id[0],
+            (unsigned int *)&vendor_id[8],
+            (unsigned int *)&vendor_id[4]);
+  vendor_id[12] = 0;
+
+  if (0)
+    ; /* Just to make "else if" and ifdef macros look pretty.  */
+#ifdef ENABLE_PADLOCK_SUPPORT
+  else if (!strcmp (vendor_id, "CentaurHauls"))
+    {
+      /* This is a VIA CPU.  Check what PadLock features we have.  */
+
+      /* Check for extended centaur (EAX).  */
+      get_cpuid(0xC0000000, &features, NULL, NULL, NULL);
+
+      /* Has extended centaur features? */
+      if (features > 0xC0000000)
+        {
+           /* Ask for the extended feature flags (EDX). */
+           get_cpuid(0xC0000001, NULL, NULL, NULL, &features);
+
+           /* Test bits 2 and 3 to see whether the RNG exists and is enabled. */
+           if ((features & 0x0C) == 0x0C)
+             result |= HWF_PADLOCK_RNG;
+
+           /* Test bits 6 and 7 to see whether the ACE exists and is enabled. */
+           if ((features & 0xC0) == 0xC0)
+             result |= HWF_PADLOCK_AES;
+
+           /* Test bits 10 and 11 to see whether the PHE exists and is
+              enabled.  */
+           if ((features & 0xC00) == 0xC00)
+             result |= HWF_PADLOCK_SHA;
+
+           /* Test bits 12 and 13 to see whether the MONTMUL exists and is
+              enabled.  */
+           if ((features & 0x3000) == 0x3000)
+             result |= HWF_PADLOCK_MMUL;
+        }
+    }
+#endif /*ENABLE_PADLOCK_SUPPORT*/
+  else if (!strcmp (vendor_id, "GenuineIntel"))
+    {
+      /* This is an Intel CPU.  */
+      result |= HWF_INTEL_CPU;
+    }
+  else if (!strcmp (vendor_id, "AuthenticAMD"))
+    {
+      /* This is an AMD CPU.  */
+    }
+
+  /* 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);
+
+#ifdef ENABLE_PCLMUL_SUPPORT
+  /* Test bit 1 for PCLMUL.  */
+  if (features & 0x00000002)
+     result |= HWF_INTEL_PCLMUL;
+#endif
+  /* Test bit 9 for SSSE3.  */
+  if (features & 0x00000200)
+     result |= HWF_INTEL_SSSE3;
+#ifdef ENABLE_AESNI_SUPPORT
+  /* Test bit 25 for AES-NI.  */
+  if (features & 0x02000000)
+     result |= HWF_INTEL_AESNI;
+#endif /*ENABLE_AESNI_SUPPORT*/
+#if defined(ENABLE_AVX_SUPPORT) || defined(ENABLE_AVX2_SUPPORT)
+  /* Test bit 27 for OSXSAVE (required for AVX/AVX2).  */
+  if (features & 0x08000000)
+    {
+      /* Check that OS has enabled both XMM and YMM state support.  */
+      if ((get_xgetbv() & 0x6) == 0x6)
+        os_supports_avx_avx2_registers = 1;
+    }
+#endif
+#ifdef ENABLE_AVX_SUPPORT
+  /* Test bit 28 for AVX.  */
+  if (features & 0x10000000)
+    if (os_supports_avx_avx2_registers)
+      result |= HWF_INTEL_AVX;
+#endif /*ENABLE_AVX_SUPPORT*/
+#ifdef ENABLE_DRNG_SUPPORT
+  /* Test bit 30 for RDRAND.  */
+  if (features & 0x40000000)
+     result |= HWF_INTEL_RDRAND;
+#endif /*ENABLE_DRNG_SUPPORT*/
+
+  /* Check additional Intel feature flags.  Early Intel P5 processors report
+   * too high max_cpuid_level, so don't check level 7 if processor does not
+   * support SSE3 (as cpuid:7 contains only features for newer processors).
+   * Source: http://www.sandpile.org/x86/cpuid.htm  */
+  if (max_cpuid_level >= 7 && (features & 0x00000001))
+    {
+      /* Get CPUID:7 contains further Intel feature flags. */
+      get_cpuid(7, NULL, &features, NULL, NULL);
+
+      /* Test bit 8 for BMI2.  */
+      if (features & 0x00000100)
+          result |= HWF_INTEL_BMI2;
+
+#ifdef ENABLE_AVX2_SUPPORT
+      /* Test bit 5 for AVX2.  */
+      if (features & 0x00000020)
+        if (os_supports_avx_avx2_registers)
+          result |= HWF_INTEL_AVX2;
+#endif /*ENABLE_AVX_SUPPORT*/
+    }
+
+  return result;
+}
+#endif /* HAS_X86_CPUID */
+
+
+unsigned int
+_gcry_hwf_detect_x86 (void)
+{
+#if defined (HAS_X86_CPUID)
+  return detect_x86_gnuc ();
+#else
+  return 0;
+#endif
+}
index c356798..58099c4 100644 (file)
@@ -1,5 +1,6 @@
 /* hwfeatures.c - Detect hardware features.
  * Copyright (C) 2007, 2011  Free Software Foundation, Inc.
+ * Copyright (C) 2012  g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
 
 #include <config.h>
 #include <stdio.h>
+#include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
 #include <unistd.h>
+#ifdef HAVE_SYSLOG
+# include <syslog.h>
+#endif /*HAVE_SYSLOG*/
 
 #include "g10lib.h"
+#include "hwf-common.h"
+
+/* The name of a file used to globally disable selected features. */
+#define HWF_DENY_FILE "/etc/gcrypt/hwf.deny"
+
+/* A table to map hardware features to a string.  */
+static struct
+{
+  unsigned int flag;
+  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" }
+  };
+
+/* A bit vector with the hardware features which shall not be used.
+   This variable must be set prior to any initialization.  */
+static unsigned int disabled_hw_features;
 
 /* A bit vector describing the hardware features currently
    available. */
 static unsigned int hw_features;
 
+/* Convenience macros.  */
+#define my_isascii(c) (!((c) & 0x80))
+
+
+\f
+/* Disable a feature by name.  This function must be called *before*
+   _gcry_detect_hw_features is called.  */
+gpg_err_code_t
+_gcry_disable_hw_feature (const char *name)
+{
+  int i;
+
+  for (i=0; i < DIM (hwflist); i++)
+    if (!strcmp (hwflist[i].desc, name))
+      {
+        disabled_hw_features |= hwflist[i].flag;
+        return 0;
+      }
+  return GPG_ERR_INV_NAME;
+}
+
 
 /* Return a bit vector describing the available hardware features.
    The HWF_ constants are used to test for them. */
@@ -40,153 +96,106 @@ _gcry_get_hw_features (void)
 }
 
 
-#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__)
+/* Enumerate all features.  The caller is expected to start with an
+   IDX of 0 and then increment IDX until NULL is returned.  */
+const char *
+_gcry_enum_hw_features (int idx, unsigned int *r_feature)
+{
+  if (idx < 0 || idx >= DIM (hwflist))
+    return NULL;
+  if (r_feature)
+    *r_feature = hwflist[idx].flag;
+  return hwflist[idx].desc;
+}
+
+
+/* Read a file with features which shall not be used.  The file is a
+   simple text file where empty lines and lines with the first non
+   white-space character being '#' are ignored.  */
 static void
-detect_ia32_gnuc (void)
+parse_hwf_deny_file (void)
 {
-  /* The code here is only useful for the PadLock engine thus we don't
-     build it if that support has been disabled.  */
-  int has_cpuid = 0;
-  char vendor_id[12+1];
-
-  /* Detect the CPUID feature by testing some undefined behaviour (16
-     vs 32 bit pushf/popf). */
-  asm volatile
-    ("pushf\n\t"                 /* Copy flags to EAX.  */
-     "popl %%eax\n\t"
-     "movl %%eax, %%ecx\n\t"     /* Save flags into ECX.  */
-     "xorl $0x200000, %%eax\n\t" /* Toggle ID bit and copy it to the flags.  */
-     "pushl %%eax\n\t"
-     "popf\n\t"
-     "pushf\n\t"                 /* Copy changed flags again to EAX.  */
-     "popl %%eax\n\t"
-     "pushl %%ecx\n\t"           /* Restore flags from ECX.  */
-     "popf\n\t"
-     "xorl %%eax, %%ecx\n\t"     /* Compare flags against saved flags.  */
-     "jz .Lno_cpuid%=\n\t"       /* Toggling did not work, thus no CPUID.  */
-     "movl $1, %0\n"             /* Worked. true -> HAS_CPUID.  */
-     ".Lno_cpuid%=:\n\t"
-     : "+r" (has_cpuid)
-     :
-     : "%eax", "%ecx", "cc"
-     );
-
-  if (!has_cpuid)
-    return;  /* No way.  */
-
-  asm volatile
-    ("pushl %%ebx\n\t"           /* Save GOT register.  */
-     "xorl  %%eax, %%eax\n\t"    /* 0 -> EAX.  */
-     "cpuid\n\t"                 /* Get vendor ID.  */
-     "movl  %%ebx, (%0)\n\t"     /* EBX,EDX,ECX -> VENDOR_ID.  */
-     "movl  %%edx, 4(%0)\n\t"
-     "movl  %%ecx, 8(%0)\n\t"
-     "popl  %%ebx\n"
-     :
-     : "S" (&vendor_id[0])
-     : "%eax", "%ecx", "%edx", "cc"
-     );
-  vendor_id[12] = 0;
-
-  if (0)
-    ; /* Just to make "else if" and ifdef macros look pretty.  */
-#ifdef ENABLE_PADLOCK_SUPPORT
-  else if (!strcmp (vendor_id, "CentaurHauls"))
-    {
-      /* This is a VIA CPU.  Check what PadLock features we have.  */
-      asm volatile
-        ("pushl %%ebx\n\t"             /* Save GOT register.  */
-         "movl $0xC0000000, %%eax\n\t"  /* Check for extended centaur  */
-         "cpuid\n\t"                    /* feature flags.              */
-         "popl %%ebx\n\t"              /* Restore GOT register. */
-         "cmpl $0xC0000001, %%eax\n\t"
-         "jb .Lready%=\n\t"             /* EAX < 0xC0000000 => no padlock.  */
-
-         "pushl %%ebx\n\t"             /* Save GOT register. */
-         "movl $0xC0000001, %%eax\n\t"  /* Ask for the extended */
-         "cpuid\n\t"                    /* feature flags.       */
-         "popl %%ebx\n\t"              /* Restore GOT register. */
-
-         "movl %%edx, %%eax\n\t"        /* Take copy of feature flags.  */
-         "andl $0x0C, %%eax\n\t"        /* Test bits 2 and 3 to see whether */
-         "cmpl $0x0C, %%eax\n\t"        /* the RNG exists and is enabled.   */
-         "jnz .Lno_rng%=\n\t"
-         "orl $1, %0\n"                 /* Set our HWF_PADLOCK_RNG bit.  */
-
-         ".Lno_rng%=:\n\t"
-         "movl %%edx, %%eax\n\t"        /* Take copy of feature flags.  */
-         "andl $0xC0, %%eax\n\t"        /* Test bits 6 and 7 to see whether */
-         "cmpl $0xC0, %%eax\n\t"        /* the ACE exists and is enabled.   */
-         "jnz .Lno_ace%=\n\t"
-         "orl $2, %0\n"                 /* Set our HWF_PADLOCK_AES bit.  */
-
-         ".Lno_ace%=:\n\t"
-         "movl %%edx, %%eax\n\t"        /* Take copy of feature flags.  */
-         "andl $0xC00, %%eax\n\t"       /* Test bits 10, 11 to see whether  */
-         "cmpl $0xC00, %%eax\n\t"       /* the PHE exists and is enabled.   */
-         "jnz .Lno_phe%=\n\t"
-         "orl $4, %0\n"                 /* Set our HWF_PADLOCK_SHA bit.  */
-
-         ".Lno_phe%=:\n\t"
-         "movl %%edx, %%eax\n\t"        /* Take copy of feature flags.  */
-         "andl $0x3000, %%eax\n\t"      /* Test bits 12, 13 to see whether  */
-         "cmpl $0x3000, %%eax\n\t"      /* MONTMUL exists and is enabled.   */
-         "jnz .Lready%=\n\t"
-         "orl $8, %0\n"                 /* Set our HWF_PADLOCK_MMUL bit.  */
-
-         ".Lready%=:\n"
-         : "+r" (hw_features)
-         :
-         : "%eax", "%edx", "cc"
-         );
-    }
-#endif /*ENABLE_PADLOCK_SUPPORT*/
-  else if (!strcmp (vendor_id, "GenuineIntel"))
-    {
-      /* This is an Intel CPU.  */
-      asm volatile
-        ("pushl %%ebx\n\t"             /* Save GOT register.  */
-         "movl $1, %%eax\n\t"           /* Get CPU info and feature flags.  */
-         "cpuid\n"
-         "popl %%ebx\n\t"              /* Restore GOT register. */
-         "testl $0x02000000, %%ecx\n\t" /* Test bit 25.  */
-         "jz .Lno_aes%=\n\t"            /* No AES support.  */
-         "orl $256, %0\n"               /* Set our HWF_INTEL_AES bit.  */
-
-         ".Lno_aes%=:\n"
-         : "+r" (hw_features)
-         :
-         : "%eax", "%ecx", "%edx", "cc"
-         );
-    }
-  else if (!strcmp (vendor_id, "AuthenticAMD"))
-    {
-      /* This is an AMD CPU.  */
+  const char *fname = HWF_DENY_FILE;
+  FILE *fp;
+  char buffer[256];
+  char *p, *pend;
+  int i, lnr = 0;
+
+  fp = fopen (fname, "r");
+  if (!fp)
+    return;
 
+  for (;;)
+    {
+      if (!fgets (buffer, sizeof buffer, fp))
+        {
+          if (!feof (fp))
+            {
+#ifdef HAVE_SYSLOG
+              syslog (LOG_USER|LOG_WARNING,
+                      "Libgcrypt warning: error reading '%s', line %d",
+                      fname, lnr);
+#endif /*HAVE_SYSLOG*/
+            }
+          fclose (fp);
+          return;
+        }
+      lnr++;
+      for (p=buffer; my_isascii (*p) && isspace (*p); p++)
+        ;
+      pend = strchr (p, '\n');
+      if (pend)
+        *pend = 0;
+      pend = p + (*p? (strlen (p)-1):0);
+      for ( ;pend > p; pend--)
+        if (my_isascii (*pend) && isspace (*pend))
+          *pend = 0;
+      if (!*p || *p == '#')
+        continue;
+
+      for (i=0; i < DIM (hwflist); i++)
+        {
+          if (!strcmp (hwflist[i].desc, p))
+            {
+              disabled_hw_features |= hwflist[i].flag;
+              break;
+            }
+        }
+      if (i == DIM (hwflist))
+        {
+#ifdef HAVE_SYSLOG
+          syslog (LOG_USER|LOG_WARNING,
+                  "Libgcrypt warning: unknown feature in '%s', line %d",
+                  fname, lnr);
+#endif /*HAVE_SYSLOG*/
+        }
     }
 }
-#endif /* __i386__ && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ */
 
 
 /* Detect the available hardware features.  This function is called
    once right at startup and we assume that no other threads are
    running.  */
 void
-_gcry_detect_hw_features (unsigned int disabled_features)
+_gcry_detect_hw_features (void)
 {
   hw_features = 0;
 
   if (fips_mode ())
     return; /* Hardware support is not to be evaluated.  */
 
-#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4
-#ifdef __GNUC__
-  detect_ia32_gnuc ();
-#endif
-#elif defined (__i386__) && SIZEOF_UNSIGNED_LONG == 8
-#ifdef __GNUC__
-#endif
-#endif
+  parse_hwf_deny_file ();
+
+#if defined (HAVE_CPU_ARCH_X86)
+  {
+    hw_features = _gcry_hwf_detect_x86 ();
+  }
+#endif /* HAVE_CPU_ARCH_X86 */
+#if defined (HAVE_CPU_ARCH_ARM)
+  {
+    hw_features = _gcry_hwf_detect_arm ();
+  }
+#endif /* HAVE_CPU_ARCH_ARM */
 
-  hw_features &= ~disabled_features;
+  hw_features &= ~disabled_hw_features;
 }
index 031b941..a90efce 100644 (file)
@@ -132,7 +132,8 @@ EXPORTS
       gcry_cipher_decrypt  @101
       gcry_cipher_get_algo_keylen  @102
       gcry_cipher_get_algo_blklen  @103
-      gcry_cipher_list  @104
+
+;; @104 used to be part of the module register interface
 
       gcry_pk_encrypt  @105
       gcry_pk_decrypt  @106
@@ -146,33 +147,13 @@ EXPORTS
       gcry_pk_map_name  @114
       gcry_pk_get_nbits  @115
       gcry_pk_get_keygrip  @116
-      gcry_pk_list  @117
-
-      gcry_ac_data_new  @118
-      gcry_ac_data_destroy  @119
-      gcry_ac_data_set  @120
-      gcry_ac_data_copy  @121
-      gcry_ac_data_length  @122
-      gcry_ac_data_get_name  @123
-      gcry_ac_data_get_index  @124
-      gcry_ac_data_clear  @125
-      gcry_ac_open  @126
-      gcry_ac_close  @127
-      gcry_ac_key_init  @128
-      gcry_ac_key_pair_generate  @129
-      gcry_ac_key_pair_extract  @130
-      gcry_ac_key_data_get  @131
-      gcry_ac_key_test  @132
-      gcry_ac_key_get_nbits  @133
-      gcry_ac_key_get_grip  @134
-      gcry_ac_key_destroy  @135
-      gcry_ac_key_pair_destroy  @136
-      gcry_ac_data_encrypt  @137
-      gcry_ac_data_decrypt  @138
-      gcry_ac_data_sign  @139
-      gcry_ac_data_verify  @140
-      gcry_ac_id_to_name  @141
-      gcry_ac_name_to_id  @142
+
+;; @117 used to be part of the module register interface
+
+;;
+;; 118 to 142 were used in previous Libgcrypt versions for the gcry_ac
+;; interface
+;;
 
       gcry_md_open  @143
       gcry_md_close  @144
@@ -192,8 +173,7 @@ EXPORTS
       gcry_md_algo_name  @158
       gcry_md_map_name  @159
       gcry_md_setkey  @160
-      gcry_md_list  @161
-
+;; @161 used to be part of the module register interface
       gcry_randomize  @162
       gcry_random_add_bytes  @163
       gcry_random_bytes  @164
@@ -209,21 +189,15 @@ EXPORTS
 
       gcry_md_debug  @172
 
-      gcry_cipher_register  @173
-      gcry_cipher_unregister @174
-      gcry_md_register  @175
-      gcry_md_unregister @176
-      gcry_pk_register  @177
-      gcry_pk_unregister @178
-
-      gcry_ac_data_from_sexp  @179
-      gcry_ac_data_to_sexp  @180
-      gcry_ac_io_init  @181
-      gcry_ac_io_init_va  @182
-      gcry_ac_data_encrypt_scheme  @183
-      gcry_ac_data_decrypt_scheme  @184
-      gcry_ac_data_sign_scheme  @185
-      gcry_ac_data_verify_scheme  @186
+;; @173 used to be part of the module register interface
+;; @174 used to be part of the module register interface
+;; @175 used to be part of the module register interface
+;; @176 used to be part of the module register interface
+;; @177 used to be part of the module register interface
+;; @178 used to be part of the module register interface
+;;
+;; @179 to @186 used to be part of the removed gcry_ac interface
+;;
 
       gcry_sexp_nth_string  @187
 
@@ -237,3 +211,69 @@ EXPORTS
       gcry_pk_get_param     @193
 
       gcry_kdf_derive       @194
+
+      gcry_mpi_snatch       @195
+
+      gcry_mpi_point_new        @196
+      gcry_mpi_point_release    @197
+      gcry_mpi_point_get        @198
+      gcry_mpi_point_snatch_get @199
+      gcry_mpi_point_set        @200
+      gcry_mpi_point_snatch_set @201
+
+      gcry_ctx_release          @202
+
+      gcry_mpi_ec_new           @203
+      gcry_mpi_ec_get_mpi       @204
+      gcry_mpi_ec_get_point     @205
+      gcry_mpi_ec_set_mpi       @206
+      gcry_mpi_ec_set_point     @207
+      gcry_mpi_ec_get_affine    @208
+      gcry_mpi_ec_dup           @209
+      gcry_mpi_ec_add           @210
+      gcry_mpi_ec_mul           @211
+
+      gcry_pubkey_get_sexp      @212
+
+      _gcry_mpi_get_const       @213
+
+      gcry_sexp_nth_buffer      @214
+
+      gcry_mpi_is_neg           @215
+      gcry_mpi_neg              @216
+      gcry_mpi_abs              @217
+
+      gcry_mpi_ec_curve_point   @218
+
+      gcry_md_hash_buffers      @219
+
+      gcry_log_debug            @220
+      gcry_log_debughex         @221
+      gcry_log_debugmpi         @222
+      gcry_log_debugpnt         @223
+      gcry_log_debugsxp         @224
+
+      gcry_sexp_extract_param   @225
+
+      gcry_cipher_authenticate  @226
+      gcry_cipher_gettag        @227
+      gcry_cipher_checktag      @228
+
+      gcry_mpi_set_opaque_copy  @229
+
+      gcry_mac_algo_info        @230
+      gcry_mac_algo_name        @231
+      gcry_mac_map_name         @232
+      gcry_mac_get_algo_maclen  @233
+      gcry_mac_get_algo_keylen  @234
+      gcry_mac_open             @235
+      gcry_mac_close            @236
+      gcry_mac_setkey           @237
+      gcry_mac_setiv            @238
+      gcry_mac_write            @239
+      gcry_mac_read             @240
+      gcry_mac_verify           @241
+      gcry_mac_ctl              @242
+
+
+;; end of file with public symbols for Windows.
index 831dc0c..6cf482f 100644 (file)
@@ -1,5 +1,5 @@
 dnl Autoconf macros for libgcrypt
-dnl       Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+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
@@ -21,7 +21,8 @@ dnl this features allows to prevent build against newer versions of libgcrypt
 dnl with a changed API.
 dnl
 AC_DEFUN([AM_PATH_LIBGCRYPT],
-[ AC_ARG_WITH(libgcrypt-prefix,
+[ 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="")
@@ -98,10 +99,9 @@ AC_DEFUN([AM_PATH_LIBGCRYPT],
     LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags`
     LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs`
     ifelse([$2], , :, [$2])
-    if test x"$host" != x ; then
-      libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none`
-      if test x"$libgcrypt_config_host" != xnone ; then
-        if test x"$libgcrypt_config_host" != x"$host" ; then
+    libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none`
+    if test x"$libgcrypt_config_host" != xnone ; then
+      if test x"$libgcrypt_config_host" != x"$host" ; then
   AC_MSG_WARN([[
 ***
 *** The config script $LIBGCRYPT_CONFIG was
@@ -110,7 +110,6 @@ AC_DEFUN([AM_PATH_LIBGCRYPT],
 *** You may want to use the configure option --with-libgcrypt-prefix
 *** to specify a matching config script.
 ***]])
-        fi
       fi
     fi
   else
index 5a617cc..5118c81 100644 (file)
@@ -1,5 +1,5 @@
 # libgcrypt.vers  - What symbols to export                  -*- std -*-
-# Copyright (C) 2002, 2004, 2008 Free Software Foundation, Inc.
+# Copyright (C) 2002, 2004, 2008, 2011 Free Software Foundation, Inc.
 #
 # This file is part of Libgcrypt.
 #
@@ -20,7 +20,7 @@
 # NOTE: When adding new functions, please make sure to add them to
 # visibility.h and libgcrypt.def as well.
 
-GCRYPT_1.2 {
+GCRYPT_1.6 {
   global:
     gcry_check_version; gcry_control;
     gcry_set_allocation_handler; gcry_set_fatalerror_handler;
@@ -39,41 +39,33 @@ GCRYPT_1.2 {
     gcry_md_algo_info; gcry_md_algo_name; gcry_md_close;
     gcry_md_copy; gcry_md_ctl; gcry_md_enable; gcry_md_get;
     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_list; gcry_md_map_name; gcry_md_open; gcry_md_read;
-    gcry_md_register; gcry_md_reset; gcry_md_setkey;
-    gcry_md_unregister; gcry_md_write; gcry_md_debug;
+    gcry_md_map_name; gcry_md_open; gcry_md_read;
+    gcry_md_reset; gcry_md_setkey;
+    gcry_md_write; gcry_md_debug;
 
     gcry_cipher_algo_info; gcry_cipher_algo_name; gcry_cipher_close;
     gcry_cipher_ctl; gcry_cipher_decrypt; gcry_cipher_encrypt;
     gcry_cipher_get_algo_blklen; gcry_cipher_get_algo_keylen;
-    gcry_cipher_info; gcry_cipher_list; gcry_cipher_map_name;
+    gcry_cipher_info; gcry_cipher_map_name;
     gcry_cipher_mode_from_oid; gcry_cipher_open;
-    gcry_cipher_register; gcry_cipher_unregister;
     gcry_cipher_setkey; gcry_cipher_setiv; gcry_cipher_setctr;
+    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_open; gcry_mac_close; gcry_mac_setkey; gcry_mac_setiv;
+    gcry_mac_write; gcry_mac_read; gcry_mac_verify; gcry_mac_ctl;
 
     gcry_pk_algo_info; gcry_pk_algo_name; gcry_pk_ctl;
     gcry_pk_decrypt; gcry_pk_encrypt; gcry_pk_genkey;
-    gcry_pk_get_keygrip; gcry_pk_get_nbits; gcry_pk_list;
+    gcry_pk_get_keygrip; gcry_pk_get_nbits;
     gcry_pk_map_name; gcry_pk_register; gcry_pk_sign;
-    gcry_pk_testkey; gcry_pk_unregister; gcry_pk_verify;
+    gcry_pk_testkey; gcry_pk_verify;
     gcry_pk_get_curve; gcry_pk_get_param;
 
-    gcry_ac_data_new; gcry_ac_data_destroy; gcry_ac_data_copy;
-    gcry_ac_data_length; gcry_ac_data_clear; gcry_ac_data_set;
-    gcry_ac_data_get_name; gcry_ac_data_get_index; gcry_ac_open;
-    gcry_ac_close; gcry_ac_key_init; gcry_ac_key_pair_generate;
-    gcry_ac_key_pair_extract; gcry_ac_key_data_get; gcry_ac_key_test;
-    gcry_ac_key_get_nbits; gcry_ac_key_get_grip; gcry_ac_key_destroy;
-    gcry_ac_key_pair_destroy; gcry_ac_data_encrypt; gcry_ac_data_decrypt;
-    gcry_ac_data_sign; gcry_ac_data_verify; gcry_ac_id_to_name;
-    gcry_ac_name_to_id; gcry_ac_list; gcry_ac_data_encode;
-    gcry_ac_data_decode; gcry_ac_mpi_to_os; gcry_ac_mpi_to_os_alloc;
-    gcry_ac_os_to_mpi; gcry_ac_data_encrypt_scheme;
-    gcry_ac_data_decrypt_scheme;
-    gcry_ac_data_sign_scheme; gcry_ac_data_verify_scheme;
-    gcry_ac_data_to_sexp; gcry_ac_data_from_sexp;
-    gcry_ac_io_init; gcry_ac_io_init_va;
+    gcry_pubkey_get_sexp;
 
     gcry_kdf_derive;
 
@@ -87,11 +79,12 @@ GCRYPT_1.2 {
     gcry_sexp_build_array; gcry_sexp_cadr; gcry_sexp_canon_len;
     gcry_sexp_car; gcry_sexp_cdr; gcry_sexp_cons; gcry_sexp_create;
     gcry_sexp_dump; gcry_sexp_find_token; gcry_sexp_length;
-    gcry_sexp_new; gcry_sexp_nth; gcry_sexp_nth_data;
+    gcry_sexp_new; gcry_sexp_nth; gcry_sexp_nth_buffer; gcry_sexp_nth_data;
     gcry_sexp_nth_mpi; gcry_sexp_prepend; gcry_sexp_release;
     gcry_sexp_sprint; gcry_sexp_sscan; gcry_sexp_vlist;
-    gcry_sexp_nth_string;
+    gcry_sexp_nth_string; gcry_sexp_extract_param;
 
+    gcry_mpi_is_neg; gcry_mpi_neg; gcry_mpi_abs;
     gcry_mpi_add; gcry_mpi_add_ui; gcry_mpi_addm; gcry_mpi_aprint;
     gcry_mpi_clear_bit; gcry_mpi_clear_flag; gcry_mpi_clear_highbit;
     gcry_mpi_cmp; gcry_mpi_cmp_ui; gcry_mpi_copy; gcry_mpi_div;
@@ -100,10 +93,27 @@ GCRYPT_1.2 {
     gcry_mpi_mul_2exp; gcry_mpi_mul_ui; gcry_mpi_mulm; gcry_mpi_new;
     gcry_mpi_powm; gcry_mpi_print; gcry_mpi_randomize; gcry_mpi_release;
     gcry_mpi_rshift; gcry_mpi_scan; gcry_mpi_set; gcry_mpi_set_bit;
-    gcry_mpi_set_flag; gcry_mpi_set_highbit; gcry_mpi_set_opaque;
+    gcry_mpi_set_flag; gcry_mpi_set_highbit;
+    gcry_mpi_set_opaque; gcry_mpi_set_opaque_copy;
     gcry_mpi_set_ui; gcry_mpi_snew; gcry_mpi_sub; gcry_mpi_sub_ui;
     gcry_mpi_subm; gcry_mpi_swap; gcry_mpi_test_bit;
-    gcry_mpi_lshift;
+    gcry_mpi_lshift; gcry_mpi_snatch;
+    gcry_mpi_point_new; gcry_mpi_point_release;
+    gcry_mpi_point_get; gcry_mpi_point_snatch_get;
+    gcry_mpi_point_set; gcry_mpi_point_snatch_set;
+    gcry_mpi_ec_new;
+    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_log_debug;
+    gcry_log_debughex; gcry_log_debugmpi; gcry_log_debugpnt; gcry_log_debugsxp;
+
+    _gcry_mpi_get_const;
+
+    gcry_ctx_release;
 
   local:
     *;
index 17bd546..b3c56e2 100644 (file)
@@ -19,6 +19,7 @@
  */
 
 #include <config.h>
+#include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -27,6 +28,7 @@
 
 #include "g10lib.h"
 #include "secmem.h"
+#include "mpi.h"
 
 static int verbosity_level = 0;
 
@@ -38,7 +40,7 @@ static void *log_handler_value = 0;
 static const char *(*user_gettext_handler)( const char * ) = NULL;
 
 void
-gcry_set_gettext_handler( const char *(*f)(const char*) )
+_gcry_set_gettext_handler (const char *(*f)(const char*))
 {
     user_gettext_handler = f;
 }
@@ -54,7 +56,7 @@ _gcry_gettext( const char *key )
 }
 
 void
-gcry_set_fatalerror_handler( void (*fnc)(void*,int, const char*), void *value)
+_gcry_set_fatalerror_handler( void (*fnc)(void*,int, const char*), void *value)
 {
     fatal_error_handler_value = value;
     fatal_error_handler = fnc;
@@ -90,8 +92,7 @@ _gcry_fatal_error (int rc, const char *text)
 }
 
 void
-gcry_set_log_handler( void (*f)(void*,int, const char*, va_list ),
-                                                           void *opaque )
+_gcry_set_log_handler (void (*f)(void*,int, const char*, va_list), void *opaque)
 {
     log_handler = f;
     log_handler_value = opaque;
@@ -113,7 +114,7 @@ _gcry_log_verbosity( int level )
  * This is our log function which prints all log messages to stderr or
  * using the function defined with gcry_set_log_handler().
  */
-static void
+void
 _gcry_logv( int level, const char *fmt, va_list arg_ptr )
 {
   if (log_handler)
@@ -266,33 +267,204 @@ _gcry_log_printf (const char *fmt, ...)
     }
 }
 
-/* Print a hexdump of BUFFER.  With TEXT of NULL print just the raw
-   dump, with TEXT an empty string, print a trailing linefeed,
-   otherwise print an entire debug line. */
-void
-_gcry_log_printhex (const char *text, const void *buffer, size_t length)
+
+/* Helper for _gcry_log_printhex and _gcry_log_printmpi.  */
+static void
+do_printhex (const char *text, const char *text2,
+             const void *buffer, size_t length)
 {
+  int wrap = 0;
+  int cnt = 0;
+
   if (text && *text)
-    log_debug ("%s ", text);
+    {
+      wrap = 1;
+      log_debug ("%s:%s", text, text2);
+      if (text2[1] == '[' && length && buffer)
+        {
+          /* Start with a new line so that we get nice output for
+             opaque MPIS:
+               "value: [31 bit]"
+               "        01020300"  */
+          log_printf ("\n");
+          text2 = " ";
+          log_debug ("%*s  ", (int)strlen(text), "");
+        }
+    }
   if (length)
     {
       const unsigned char *p = buffer;
-      log_printf ("%02X", *p);
-      for (length--, p++; length--; p++)
-        log_printf (" %02X", *p);
+      for (; length--; p++)
+        {
+          log_printf ("%02x", *p);
+          if (wrap && ++cnt == 32 && length)
+            {
+              cnt = 0;
+              log_printf (" \\\n");
+              log_debug ("%*s %*s",
+                         (int)strlen(text), "", (int)strlen(text2), "");
+            }
+        }
     }
   if (text)
     log_printf ("\n");
 }
 
 
+/* Print a hexdump of BUFFER.  With TEXT of NULL print just the raw
+   dump without any wrappping, with TEXT an empty string, print a
+   trailing linefeed, otherwise print an entire debug line. */
+void
+_gcry_log_printhex (const char *text, const void *buffer, size_t length)
+{
+  do_printhex (text, " ", buffer, length);
+}
+
+
+/* Print MPI in hex notation.  To make clear that the output is an MPI
+   a sign is always printed. With TEXT of NULL print just the raw dump
+   without any wrapping, with TEXT an empty string, print a trailing
+   linefeed, otherwise print an entire debug line. */
 void
-_gcry_burn_stack (int bytes)
+_gcry_log_printmpi (const char *text, gcry_mpi_t mpi)
 {
-    char buf[64];
+  unsigned char *rawmpi;
+  unsigned int rawmpilen;
+  int sign;
+
+  if (!mpi)
+    do_printhex (text? text:" ", " (null)", NULL, 0);
+  else if (mpi_is_opaque (mpi))
+    {
+      unsigned int nbits;
+      const unsigned char *p;
+      char prefix[30];
+
+      p = mpi_get_opaque (mpi, &nbits);
+      snprintf (prefix, sizeof prefix, " [%u bit]", nbits);
+      do_printhex (text? text:" ", prefix, p, (nbits+7)/8);
+    }
+  else
+    {
+      rawmpi = _gcry_mpi_get_buffer (mpi, 0, &rawmpilen, &sign);
+      if (!rawmpi)
+        do_printhex (text? text:" ", " [out of core]", NULL, 0);
+      else
+        {
+          if (!rawmpilen)
+            do_printhex (text, sign? "-":"+", "", 1);
+          else
+            do_printhex (text, sign? "-":"+", rawmpi, rawmpilen);
+          xfree (rawmpi);
+        }
+    }
+}
+
+
+static int
+count_closing_parens (const char *p)
+{
+  int count = 0;
+
+  for (; *p; p++)
+    if (*p == ')')
+      count++;
+    else if (!strchr ("\n \t", *p))
+      return 0;
+
+  return count;
+}
+
+
+/* Print SEXP in human readabale format.  With TEXT of NULL print just the raw
+   dump without any wrappping, with TEXT an empty string, print a
+   trailing linefeed, otherwise print the full debug output. */
+void
+_gcry_log_printsxp (const char *text, gcry_sexp_t sexp)
+{
+  int with_lf = 0;
+
+  if (text && *text)
+    {
+      if ((with_lf = !!strchr (text, '\n')))
+        log_debug ("%s", text);
+      else
+        log_debug ("%s: ", text);
+    }
+  if (sexp)
+    {
+      int any = 0;
+      int n_closing;
+      char *buf, *pend;
+      const char *p;
+      size_t size;
+
+      size = sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+      p = buf = xmalloc (size);
+      sexp_sprint (sexp, GCRYSEXP_FMT_ADVANCED, buf, size);
+
+      do
+        {
+          if (any && !with_lf)
+            log_debug ("%*s  ", (int)strlen(text), "");
+          else
+            any = 1;
+          pend = strchr (p, '\n');
+          size = pend? (pend - p) : strlen (p);
+          if (with_lf)
+            log_debug ("%.*s", (int)size, p);
+          else
+            log_printf ("%.*s", (int)size, p);
+          if (pend)
+            p = pend + 1;
+          else
+            p += size;
+          n_closing = count_closing_parens (p);
+          if (n_closing)
+            {
+              while (n_closing--)
+                log_printf (")");
+              p = "";
+            }
+          log_printf ("\n");
+        }
+      while (*p);
+      xfree (buf);
+    }
+  else if (text)
+    log_printf ("\n");
+}
+
+
+void
+__gcry_burn_stack (unsigned int bytes)
+{
+#ifdef HAVE_VLA
+    /* (bytes == 0 ? 1 : bytes) == (!bytes + bytes) */
+    unsigned int buflen = ((!bytes + bytes) + 63) & ~63;
+    volatile char buf[buflen];
+
+    wipememory (buf, sizeof buf);
+#else
+    volatile char buf[64];
 
     wipememory (buf, sizeof buf);
-    bytes -= sizeof buf;
-    if (bytes > 0)
-        _gcry_burn_stack (bytes);
+
+    if (bytes > sizeof buf)
+        _gcry_burn_stack (bytes - sizeof buf);
+#endif
+}
+
+#ifndef HAVE_GCC_ASM_VOLATILE_MEMORY
+void
+__gcry_burn_stack_dummy (void)
+{
+}
+#endif
+
+void
+_gcry_divide_by_zero (void)
+{
+    gpg_err_set_errno (EDOM);
+    _gcry_fatal_error (gpg_err_code_from_errno (errno), "divide by zero");
 }
diff --git a/src/module.c b/src/module.c
deleted file mode 100644 (file)
index 32f668d..0000000
+++ /dev/null
@@ -1,212 +0,0 @@
-/* module.c - Module management for libgcrypt.
- * Copyright (C) 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>
-#include <errno.h>
-#include "g10lib.h"
-
-/* Please match these numbers with the allocated algorithm
-   numbers.  */
-#define MODULE_ID_MIN 600
-#define MODULE_ID_LAST 65500
-#define MODULE_ID_USER GCRY_MODULE_ID_USER
-#define MODULE_ID_USER_LAST GCRY_MODULE_ID_USER_LAST
-
-#if MODULE_ID_MIN >= MODULE_ID_USER
-#error Need to implement a different search strategy
-#endif
-
-/* Internal function.  Generate a new, unique module ID for a module
-   that should be inserted into the module chain starting at
-   MODULES.  */
-static gcry_err_code_t
-_gcry_module_id_new (gcry_module_t modules, unsigned int *id_new)
-{
-  unsigned int mod_id;
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  gcry_module_t module;
-
-  /* Search for unused ID.  */
-  for (mod_id = MODULE_ID_MIN; mod_id < MODULE_ID_LAST; mod_id++)
-    {
-      if (mod_id == MODULE_ID_USER)
-        {
-          mod_id = MODULE_ID_USER_LAST;
-          continue;
-        }
-
-      /* Search for a module with the current ID.  */
-      for (module = modules; module; module = module->next)
-       if (mod_id == module->mod_id)
-         break;
-
-      if (! module)
-       /* None found -> the ID is available for use.  */
-       break;
-    }
-
-  if (mod_id < MODULE_ID_LAST)
-    /* Done.  */
-    *id_new = mod_id;
-  else
-    /* No free ID found.  */
-    err = GPG_ERR_INTERNAL;
-
-  return err;
-}
-
-/* Add a module specification to the list ENTRIES.  The new module has
-   it's use-counter set to one.  */
-gcry_err_code_t
-_gcry_module_add (gcry_module_t *entries, unsigned int mod_id,
-                 void *spec, void *extraspec, gcry_module_t *module)
-{
-  gcry_err_code_t err = 0;
-  gcry_module_t entry;
-
-  if (! mod_id)
-    err = _gcry_module_id_new (*entries, &mod_id);
-
-  if (! err)
-    {
-      entry = gcry_malloc (sizeof (struct gcry_module));
-      if (! entry)
-       err = gpg_err_code_from_errno (errno);
-    }
-
-  if (! err)
-    {
-      /* Fill new module entry.  */
-      entry->flags = 0;
-      entry->counter = 1;
-      entry->spec = spec;
-      entry->extraspec = extraspec;
-      entry->mod_id = mod_id;
-
-      /* Link it into the list.  */
-      entry->next = *entries;
-      entry->prevp = entries;
-      if (*entries)
-       (*entries)->prevp = &entry->next;
-      *entries = entry;
-
-      /* And give it to the caller.  */
-      if (module)
-       *module = entry;
-    }
-  return err;
-}
-
-/* Internal function.  Unlink CIPHER_ENTRY from the list of registered
-   ciphers and destroy it.  */
-static void
-_gcry_module_drop (gcry_module_t entry)
-{
-  *entry->prevp = entry->next;
-  if (entry->next)
-    entry->next->prevp = entry->prevp;
-
-  gcry_free (entry);
-}
-
-/* Lookup a module specification by it's ID.  After a successful
-   lookup, the module has it's resource counter incremented.  */
-gcry_module_t
-_gcry_module_lookup_id (gcry_module_t entries, unsigned int mod_id)
-{
-  gcry_module_t entry;
-
-  for (entry = entries; entry; entry = entry->next)
-    if (entry->mod_id == mod_id)
-      {
-       entry->counter++;
-       break;
-      }
-
-  return entry;
-}
-
-/* Lookup a module specification.  After a successful lookup, the
-   module has it's resource counter incremented.  FUNC is a function
-   provided by the caller, which is responsible for identifying the
-   wanted module.  */
-gcry_module_t
-_gcry_module_lookup (gcry_module_t entries, void *data,
-                    gcry_module_lookup_t func)
-{
-  gcry_module_t entry;
-
-  for (entry = entries; entry; entry = entry->next)
-    if ((*func) (entry->spec, data))
-      {
-       entry->counter++;
-       break;
-      }
-
-  return entry;
-}
-
-/* Release a module.  In case the use-counter reaches zero, destroy
-   the module.  Passing MODULE as NULL is a dummy operation (similar
-   to free()). */
-void
-_gcry_module_release (gcry_module_t module)
-{
-  if (module && ! --module->counter)
-    _gcry_module_drop (module);
-}
-
-/* Add a reference to a module.  */
-void
-_gcry_module_use (gcry_module_t module)
-{
-  ++module->counter;
-}
-
-/* If LIST is zero, write the number of modules identified by MODULES
-   to LIST_LENGTH and return.  If LIST is non-zero, the first
-   *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
-   according size.  In case there are less cipher modules than
-   *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
-gcry_err_code_t
-_gcry_module_list (gcry_module_t modules,
-                  int *list, int *list_length)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  gcry_module_t module;
-  int length, i;
-
-  for (module = modules, length = 0; module; module = module->next, length++);
-
-  if (list)
-    {
-      if (length > *list_length)
-       length = *list_length;
-
-      for (module = modules, i = 0; i < length; module = module->next, i++)
-       list[i] = module->mod_id;
-
-      if (length < *list_length)
-       *list_length = length;
-    }
-  else
-    *list_length = length;
-
-  return err;
-}
index 65a4f97..7a57b9a 100644 (file)
--- a/src/mpi.h
+++ b/src/mpi.h
@@ -69,14 +69,16 @@ struct gcry_mpi
   int sign;           /* Indicates a negative number and is also used
                          for opaque MPIs to store the length.  */
   unsigned int flags; /* Bit 0: Array to be allocated in secure memory space.*/
-                      /* Bit 2: the limb is a pointer to some m_alloced data.*/
+                      /* Bit 2: The limb is a pointer to some m_alloced data.*/
+                      /* Bit 4: Immutable MPI - the MPI may not be modified.  */
+                      /* Bit 5: Constant MPI - the MPI will not be freed.  */
   mpi_limb_t *d;      /* Array with the limbs */
 };
 
 #define MPI_NULL NULL
 
 #define mpi_get_nlimbs(a)     ((a)->nlimbs)
-#define mpi_is_neg(a)        ((a)->sign)
+#define mpi_has_sign(a)              ((a)->sign)
 
 /*-- mpiutil.c --*/
 
@@ -104,53 +106,63 @@ struct gcry_mpi
   gcry_mpi_t  _gcry_mpi_copy( gcry_mpi_t a );
 #endif
 
-#define mpi_is_opaque(a) ((a) && ((a)->flags&4))
-#define mpi_is_secure(a) ((a) && ((a)->flags&1))
+void _gcry_mpi_immutable_failed (void);
+#define mpi_immutable_failed() _gcry_mpi_immutable_failed ()
+
+#define mpi_is_const(a)       ((a) && ((a)->flags&32))
+#define mpi_is_immutable(a)   ((a) && ((a)->flags&16))
+#define mpi_is_opaque(a)      ((a) && ((a)->flags&4))
+#define mpi_is_secure(a)      ((a) && ((a)->flags&1))
 #define mpi_clear(a)          _gcry_mpi_clear ((a))
 #define mpi_alloc_like(a)     _gcry_mpi_alloc_like((a))
-#define mpi_set(a,b)          _gcry_mpi_set ((a),(b))
-#define mpi_set_ui(a,b)       _gcry_mpi_set_ui ((a),(b))
-#define mpi_get_ui(a,b)       _gcry_mpi_get_ui ((a),(b))
+
 #define mpi_alloc_set_ui(a)   _gcry_mpi_alloc_set_ui ((a))
 #define mpi_m_check(a)        _gcry_mpi_m_check ((a))
-#define mpi_swap(a,b)         _gcry_mpi_swap ((a),(b))
-#define mpi_new(n)            _gcry_mpi_new ((n))
-#define mpi_snew(n)           _gcry_mpi_snew ((n))
+#define mpi_const(n)          _gcry_mpi_const ((n))
 
 void _gcry_mpi_clear( gcry_mpi_t a );
 gcry_mpi_t  _gcry_mpi_alloc_like( gcry_mpi_t a );
 gcry_mpi_t  _gcry_mpi_alloc_set_ui( unsigned long u);
-gcry_err_code_t _gcry_mpi_get_ui (gcry_mpi_t w, ulong *u);
 void _gcry_mpi_m_check( gcry_mpi_t a );
 void _gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b);
 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,
+                                      const void *p, unsigned int nbits);
+void *_gcry_mpi_get_opaque_copy (gcry_mpi_t a, unsigned int *nbits);
+int _gcry_mpi_is_neg (gcry_mpi_t a);
+void _gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u);
+void _gcry_mpi_abs (gcry_mpi_t w);
+
+/* Constants used to return constant MPIs.  See _gcry_mpi_init if you
+   want to add more constants. */
+#define MPI_NUMBER_OF_CONSTANTS 6
+enum gcry_mpi_constants
+  {
+    MPI_C_ZERO,
+    MPI_C_ONE,
+    MPI_C_TWO,
+    MPI_C_THREE,
+    MPI_C_FOUR,
+    MPI_C_EIGHT
+  };
+
+
+gcry_mpi_t _gcry_mpi_const (enum gcry_mpi_constants no);
+
 
 /*-- mpicoder.c --*/
 void  _gcry_log_mpidump( const char *text, gcry_mpi_t a );
 u32   _gcry_mpi_get_keyid( gcry_mpi_t a, u32 *keyid );
-byte *_gcry_mpi_get_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign );
-byte *_gcry_mpi_get_secure_buffer( gcry_mpi_t a, unsigned *nbytes, int *sign );
+byte *_gcry_mpi_get_buffer (gcry_mpi_t a, unsigned int fill_le,
+                            unsigned int *r_nbytes, int *sign);
+byte *_gcry_mpi_get_secure_buffer (gcry_mpi_t a, unsigned int fill_le,
+                                   unsigned *r_nbytes, int *sign);
 void  _gcry_mpi_set_buffer ( gcry_mpi_t a, const void *buffer,
                              unsigned int nbytes, int sign );
-
-#define log_mpidump _gcry_log_mpidump
-
-/*-- mpi-add.c --*/
-#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))
-
-
-/*-- mpi-mul.c --*/
-#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))
-
+gpg_err_code_t _gcry_mpi_to_octet_string (unsigned char **r_frame,
+                                          void *space,
+                                          gcry_mpi_t value, size_t nbytes);
 
 /*-- mpi-div.c --*/
 #define mpi_fdiv_r_ui(a,b,c)   _gcry_mpi_fdiv_r_ui((a),(b),(c))
@@ -173,14 +185,11 @@ int   _gcry_mpi_divisible_ui(gcry_mpi_t dividend, ulong divisor );
 
 
 /*-- mpi-mod.c --*/
-#define mpi_mod(r,a,m)            _gcry_mpi_mod ((r), (a), (m))
 #define mpi_barrett_init(m,f)     _gcry_mpi_barrett_init ((m),(f))
 #define mpi_barrett_free(c)       _gcry_mpi_barrett_free ((c))
 #define mpi_mod_barrett(r,a,c)    _gcry_mpi_mod_barrett ((r), (a), (c))
 #define mpi_mul_barrett(r,u,v,c)  _gcry_mpi_mul_barrett ((r), (u), (v), (c))
 
-void _gcry_mpi_mod (gcry_mpi_t r, gcry_mpi_t dividend, gcry_mpi_t divisor);
-
 /* Context used with Barrett reduction.  */
 struct barrett_ctx_s;
 typedef struct barrett_ctx_s *mpi_barrett_t;
@@ -192,19 +201,10 @@ void _gcry_mpi_mul_barrett (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v,
                             mpi_barrett_t ctx);
 
 
-
-/*-- mpi-gcd.c --*/
-
 /*-- mpi-mpow.c --*/
 #define mpi_mulpowm(a,b,c,d) _gcry_mpi_mulpowm ((a),(b),(c),(d))
 void _gcry_mpi_mulpowm( gcry_mpi_t res, gcry_mpi_t *basearray, gcry_mpi_t *exparray, gcry_mpi_t mod);
 
-/*-- mpi-cmp.c --*/
-#define mpi_cmp_ui(a,b) gcry_mpi_cmp_ui ((a),(b))
-#define mpi_cmp(a,b)    gcry_mpi_cmp ((a),(b))
-int gcry_mpi_cmp_ui( gcry_mpi_t u, ulong v );
-int gcry_mpi_cmp( gcry_mpi_t u, gcry_mpi_t v );
-
 /*-- mpi-scan.c --*/
 #define mpi_trailing_zeros(a) _gcry_mpi_trailing_zeros ((a))
 int      _gcry_mpi_getbyte( gcry_mpi_t a, unsigned idx );
@@ -213,50 +213,88 @@ unsigned _gcry_mpi_trailing_zeros( gcry_mpi_t a );
 
 /*-- mpi-bit.c --*/
 #define mpi_normalize(a)       _gcry_mpi_normalize ((a))
-#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))
 
 void _gcry_mpi_normalize( gcry_mpi_t a );
 
-/*-- mpi-inv.c --*/
-#define mpi_invm(a,b,c) _gcry_mpi_invm ((a),(b),(c))
-
 /*-- ec.c --*/
 
 /* Object to represent a point in projective coordinates. */
-struct mpi_point_s;
-typedef struct mpi_point_s mpi_point_t;
-struct mpi_point_s
+struct gcry_mpi_point
 {
   gcry_mpi_t x;
   gcry_mpi_t y;
   gcry_mpi_t z;
 };
-
-/* Context used with elliptic curve functions.  */
-struct mpi_ec_ctx_s;
-typedef struct mpi_ec_ctx_s *mpi_ec_t;
-
-void _gcry_mpi_ec_point_init (mpi_point_t *p);
-void _gcry_mpi_ec_point_free (mpi_point_t *p);
-mpi_ec_t _gcry_mpi_ec_init (gcry_mpi_t p, gcry_mpi_t a);
+typedef struct gcry_mpi_point mpi_point_struct;
+typedef struct gcry_mpi_point *mpi_point_t;
+
+void _gcry_mpi_point_init (mpi_point_t p);
+void _gcry_mpi_point_free_parts (mpi_point_t p);
+void _gcry_mpi_get_point (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+                          mpi_point_t point);
+void _gcry_mpi_snatch_point (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+                             mpi_point_t point);
+
+
+/* Models describing an elliptic curve.  */
+enum gcry_mpi_ec_models
+  {
+
+    MPI_EC_WEIERSTRASS = 0,
+    MPI_EC_MONTGOMERY,
+    MPI_EC_TWISTEDEDWARDS
+    /* The equation for Twisted Edwards curves is
+          ax^2 + y^2 = 1 + bx^2y^2
+       Note that we use 'b' instead of the commonly used 'd'.  */
+  };
+
+/* Dialects used with elliptic curves.  It is easier to keep the
+   definition here than in ecc-common.h. */
+enum ecc_dialects
+  {
+    ECC_DIALECT_STANDARD = 0,
+    ECC_DIALECT_ED25519
+  };
+
+
+void _gcry_mpi_point_log (const char *name, mpi_point_t point, mpi_ec_t ctx);
+#define log_printpnt(a,p,c) _gcry_mpi_point_log ((a), (p), (c))
+
+mpi_ec_t _gcry_mpi_ec_p_internal_new (enum gcry_mpi_ec_models model,
+                                      enum ecc_dialects dialect,
+                                      int flags,
+                                      gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b);
+gpg_err_code_t _gcry_mpi_ec_p_new (gcry_ctx_t *r_ctx,
+                                   enum gcry_mpi_ec_models model,
+                                   enum ecc_dialects dialect,
+                                   int flags,
+                                   gcry_mpi_t p, gcry_mpi_t a, gcry_mpi_t b);
 void _gcry_mpi_ec_free (mpi_ec_t ctx);
-int _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t *point,
-                             mpi_ec_t ctx);
-void _gcry_mpi_ec_dup_point (mpi_point_t *result,
-                             mpi_point_t *point, mpi_ec_t ctx);
-void _gcry_mpi_ec_add_points (mpi_point_t *result,
-                              mpi_point_t *p1, mpi_point_t *p2,
+
+void _gcry_mpi_ec_dup_point (mpi_point_t result,
+                             mpi_point_t point, mpi_ec_t ctx);
+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_mul_point (mpi_point_t *result,
-                             gcry_mpi_t scalar, mpi_point_t *point,
+void _gcry_mpi_ec_mul_point (mpi_point_t result,
+                             gcry_mpi_t scalar, mpi_point_t point,
                              mpi_ec_t ctx);
+int  _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx);
+
+gcry_mpi_t _gcry_mpi_ec_ec2os (gcry_mpi_point_t point, mpi_ec_t ectx);
+
+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_err_code_t _gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue,
+                                     gcry_ctx_t ctx);
+gpg_err_code_t _gcry_mpi_ec_set_point (const char *name,
+                                       gcry_mpi_point_t newvalue,
+                                       gcry_ctx_t ctx);
+
+/*-- ecc-curves.c --*/
+gpg_err_code_t _gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
+                                 gcry_sexp_t keyparam, const char *curvename);
 
 
 
diff --git a/src/mpicalc.c b/src/mpicalc.c
new file mode 100644 (file)
index 0000000..b2b4335
--- /dev/null
@@ -0,0 +1,588 @@
+/* mpicalc.c - Simple RPN calculator using gcry_mpi functions
+ * Copyright (C) 1997, 1998, 1999, 2004, 2006, 2013  Werner Koch
+ *
+ * This program 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 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 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/>.
+ */
+
+/*
+   This program is a simple RPN calculator which was originally used
+   to develop the mpi functions of GnuPG.  Values must be given in
+   hex.  Operation is like dc(1) except that the input/output radix is
+   always 16 and you can use a '-' to prefix a negative number.
+   Addition operators: ++ and --.  All operators must be delimited by
+   a blank.
+ */
+
+#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
+
+
+#define MPICALC_VERSION "2.0"
+#define NEED_LIBGCRYPT_VERSION "1.6.0"
+
+#define STACKSIZE  500
+static gcry_mpi_t stack[STACKSIZE];
+static int stackidx;
+
+
+static int
+scan_mpi (gcry_mpi_t retval, const char *string)
+{
+  gpg_error_t err;
+  gcry_mpi_t val;
+
+  err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
+  if (err)
+    {
+      fprintf (stderr, "scanning input failed: %s\n", gpg_strerror (err));
+      return -1;
+    }
+  mpi_set (retval, val);
+  mpi_release (val);
+  return 0;
+}
+
+
+static void
+print_mpi (gcry_mpi_t a)
+{
+  gpg_error_t err;
+  char *buf;
+  void *bufaddr = &buf;
+
+  err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a);
+  if (err)
+    fprintf (stderr, "[error printing number: %s]\n", gpg_strerror (err));
+  else
+    {
+      fputs (buf, stdout);
+      gcry_free (buf);
+    }
+}
+
+
+
+static void
+do_add (void)
+{
+  if (stackidx < 2)
+    {
+      fputs ("stack underflow\n", stderr);
+      return;
+    }
+  mpi_add (stack[stackidx - 2], stack[stackidx - 2], stack[stackidx - 1]);
+  stackidx--;
+}
+
+static void
+do_sub (void)
+{
+  if (stackidx < 2)
+    {
+      fputs ("stack underflow\n", stderr);
+      return;
+    }
+  mpi_sub (stack[stackidx - 2], stack[stackidx - 2], stack[stackidx - 1]);
+  stackidx--;
+}
+
+static void
+do_inc (void)
+{
+  if (stackidx < 1)
+    {
+      fputs ("stack underflow\n", stderr);
+      return;
+    }
+  mpi_add_ui (stack[stackidx - 1], stack[stackidx - 1], 1);
+}
+
+static void
+do_dec (void)
+{
+  if (stackidx < 1)
+    {
+      fputs ("stack underflow\n", stderr);
+      return;
+    }
+  /* mpi_sub_ui( stack[stackidx-1], stack[stackidx-1], 1 ); */
+}
+
+static void
+do_mul (void)
+{
+  if (stackidx < 2)
+    {
+      fputs ("stack underflow\n", stderr);
+      return;
+    }
+  mpi_mul (stack[stackidx - 2], stack[stackidx - 2], stack[stackidx - 1]);
+  stackidx--;
+}
+
+static void
+do_mulm (void)
+{
+  if (stackidx < 3)
+    {
+      fputs ("stack underflow\n", stderr);
+      return;
+    }
+  mpi_mulm (stack[stackidx - 3], stack[stackidx - 3],
+           stack[stackidx - 2], stack[stackidx - 1]);
+  stackidx -= 2;
+}
+
+static void
+do_div (void)
+{
+  if (stackidx < 2)
+    {
+      fputs ("stack underflow\n", stderr);
+      return;
+    }
+  mpi_fdiv (stack[stackidx - 2], NULL,
+            stack[stackidx - 2], stack[stackidx - 1]);
+  stackidx--;
+}
+
+static void
+do_rem (void)
+{
+  if (stackidx < 2)
+    {
+      fputs ("stack underflow\n", stderr);
+      return;
+    }
+  mpi_mod (stack[stackidx - 2],
+           stack[stackidx - 2], stack[stackidx - 1]);
+  stackidx--;
+}
+
+static void
+do_powm (void)
+{
+  gcry_mpi_t a;
+  if (stackidx < 3)
+    {
+      fputs ("stack underflow\n", stderr);
+      return;
+    }
+  a = mpi_new (0);
+  mpi_powm (a, stack[stackidx - 3], stack[stackidx - 2], stack[stackidx - 1]);
+  mpi_release (stack[stackidx - 3]);
+  stack[stackidx - 3] = a;
+  stackidx -= 2;
+}
+
+static void
+do_inv (void)
+{
+  gcry_mpi_t a = mpi_new (0);
+  if (stackidx < 2)
+    {
+      fputs ("stack underflow\n", stderr);
+      return;
+    }
+  mpi_invm (a, stack[stackidx - 2], stack[stackidx - 1]);
+  mpi_set (stack[stackidx - 2], a);
+  mpi_release (a);
+  stackidx--;
+}
+
+static void
+do_gcd (void)
+{
+  gcry_mpi_t a = mpi_new (0);
+  if (stackidx < 2)
+    {
+      fputs ("stack underflow\n", stderr);
+      return;
+    }
+  mpi_gcd (a, stack[stackidx - 2], stack[stackidx - 1]);
+  mpi_set (stack[stackidx - 2], a);
+  mpi_release (a);
+  stackidx--;
+}
+
+static void
+do_rshift (void)
+{
+  if (stackidx < 1)
+    {
+      fputs ("stack underflow\n", stderr);
+      return;
+    }
+  mpi_rshift (stack[stackidx - 1], stack[stackidx - 1], 1);
+}
+
+
+static void
+do_nbits (void)
+{
+  unsigned int n;
+
+  if (stackidx < 1)
+    {
+      fputs ("stack underflow\n", stderr);
+      return;
+    }
+  n = mpi_get_nbits (stack[stackidx - 1]);
+  mpi_set_ui (stack[stackidx - 1], n);
+}
+
+
+static int
+my_getc (void)
+{
+  static int shown;
+  int c;
+
+  for (;;)
+    {
+      if ((c = getc (stdin)) == EOF)
+        return EOF;
+      if (!(c & 0x80))
+        return c;
+
+      if (!shown)
+        {
+          shown = 1;
+          fputs ("note: Non ASCII characters are ignored\n", stderr);
+        }
+    }
+}
+
+
+static void
+print_help (void)
+{
+  fputs ("+   add           [0] := [1] + [0]          {-1}\n"
+         "-   subtract      [0] := [1] - [0]          {-1}\n"
+         "*   multiply      [0] := [1] * [0]          {-1}\n"
+         "/   divide        [0] := [1] - [0]          {-1}\n"
+         "%   modulo        [0] := [1] % [0]          {-1}\n"
+         ">   right shift   [0] := [0] >> 1           {0}\n"
+         "++  increment     [0] := [0]++              {0}\n"
+         "--  decrement     [0] := [0]--              {0}\n"
+         "m   multiply mod  [0] := [2] * [1] mod [0]  {-2}\n"
+         "^   power mod     [0] := [2] ^ [1] mod [0]  {-2}\n"
+         "I   inverse mod   [0] := [1]^-1 mod [0]     {-1}\n"
+         "G   gcd           [0] := gcd([1],[0])       {-1}\n"
+         "i   remove item   [0] := [1]                {-1}\n"
+         "d   dup item      [-1] := [0]               {+1}\n"
+         "r   reverse       [0] := [1], [1] := [0]    {0}\n"
+         "b   # of bits     [0] := nbits([0])         {0}\n"
+         "c   clear stack\n"
+         "p   print top item\n"
+         "f   print the stack\n"
+         "#   ignore until end of line\n"
+         "?   print this help\n"
+         , stdout);
+}
+
+
+
+int
+main (int argc, char **argv)
+{
+  const char *pgm;
+  int last_argc = -1;
+  int print_config = 0;
+  int i, c;
+  int state = 0;
+  char strbuf[1000];
+  int stridx = 0;
+
+  if (argc)
+    {
+      pgm = strrchr (*argv, '/');
+      if (pgm)
+        pgm++;
+      else
+        pgm = *argv;
+      argc--; argv++;
+    }
+  else
+    pgm = "?";
+
+  while (argc && last_argc != argc )
+    {
+      last_argc = argc;
+      if (!strcmp (*argv, "--"))
+        {
+          argc--; argv++;
+          break;
+        }
+      else if (!strcmp (*argv, "--version")
+               || !strcmp (*argv, "--help"))
+        {
+          printf ("%s " MPICALC_VERSION "\n"
+                  "libgcrypt %s\n"
+                  "Copyright (C) 1997, 2013  Werner Koch\n"
+                  "License LGPLv2.1+: GNU LGPL version 2.1 or later "
+                  "<http://gnu.org/licenses/old-licenses/lgpl-2.1.html>\n"
+                  "This is free software: you are free to change and "
+                  "redistribute it.\n"
+                  "There is NO WARRANTY, to the extent permitted by law.\n"
+                  "\n"
+                  "Syntax: mpicalc [options]\n"
+                  "Simple interactive big integer RPN calculator\n"
+                  "\n"
+                  "Options:\n"
+                  "  --version           print version information\n"
+                  "  --print-config      print the Libgcrypt config\n"
+                  "  --disable-hwf NAME  disable feature NAME\n",
+                  pgm, gcry_check_version (NULL));
+          exit (0);
+        }
+      else if (!strcmp (*argv, "--print-config"))
+        {
+          argc--; argv++;
+          print_config = 1;
+        }
+      else if (!strcmp (*argv, "--disable-hwf"))
+        {
+          argc--; argv++;
+          if (argc)
+            {
+              if (gcry_control (GCRYCTL_DISABLE_HWF, *argv, NULL))
+                fprintf (stderr, "%s: unknown hardware feature `%s'"
+                         " - option ignored\n", pgm, *argv);
+              argc--; argv++;
+            }
+        }
+    }
+
+  if (argc)
+    {
+      fprintf (stderr, "usage: %s [options]  (--help for help)\n", pgm);
+      exit (1);
+    }
+
+  if (!gcry_check_version (NEED_LIBGCRYPT_VERSION))
+    {
+      fprintf (stderr, "%s: Libgcrypt is too old (need %s, have %s)\n",
+               pgm, NEED_LIBGCRYPT_VERSION, gcry_check_version (NULL) );
+      exit (1);
+    }
+  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+  if (print_config)
+    {
+      gcry_control (GCRYCTL_PRINT_CONFIG, stdout);
+      exit (0);
+    }
+
+  for (i = 0; i < STACKSIZE; i++)
+    stack[i] = NULL;
+  stackidx = 0;
+
+  while ((c = my_getc ()) != EOF)
+    {
+      if (!state) /* waiting */
+       {
+         if (isdigit (c))
+           {
+             state = 1;
+             ungetc (c, stdin);
+             strbuf[0] = '0';
+             strbuf[1] = 'x';
+             stridx = 2;
+           }
+         else if (isspace (c))
+           ;
+         else
+           {
+             switch (c)
+               {
+                case '#':
+                  state = 2;
+                  break;
+               case '+':
+                 if ((c = my_getc ()) == '+')
+                   do_inc ();
+                 else
+                   {
+                     ungetc (c, stdin);
+                     do_add ();
+                   }
+                 break;
+                case '-':
+                 if ((c = my_getc ()) == '-')
+                   do_dec ();
+                 else if (isdigit (c)
+                           || (c >= 'A' && c <= 'F')
+                           || (c >= 'a' && c <= 'f'))
+                   {
+                     state = 1;
+                     ungetc (c, stdin);
+                     strbuf[0] = '-';
+                     strbuf[1] = '0';
+                     strbuf[2] = 'x';
+                     stridx = 3;
+                   }
+                 else
+                   {
+                     ungetc (c, stdin);
+                     do_sub ();
+                   }
+                 break;
+               case '*':
+                 do_mul ();
+                 break;
+               case 'm':
+                 do_mulm ();
+                 break;
+               case '/':
+                 do_div ();
+                 break;
+               case '%':
+                 do_rem ();
+                 break;
+               case '^':
+                 do_powm ();
+                 break;
+               case '>':
+                 do_rshift ();
+                 break;
+               case 'I':
+                 do_inv ();
+                 break;
+               case 'G':
+                 do_gcd ();
+                 break;
+               case 'i':       /* dummy */
+                 if (!stackidx)
+                   fputs ("stack underflow\n", stderr);
+                 else
+                   {
+                     mpi_release (stack[stackidx - 1]);
+                     stackidx--;
+                   }
+                 break;
+               case 'd':       /* duplicate the tos */
+                 if (!stackidx)
+                   fputs ("stack underflow\n", stderr);
+                 else if (stackidx < STACKSIZE)
+                   {
+                     mpi_release (stack[stackidx]);
+                     stack[stackidx] = mpi_copy (stack[stackidx - 1]);
+                     stackidx++;
+                   }
+                 else
+                   fputs ("stack overflow\n", stderr);
+                 break;
+               case 'r':       /* swap top elements */
+                 if (stackidx < 2)
+                   fputs ("stack underflow\n", stderr);
+                 else if (stackidx < STACKSIZE)
+                   {
+                     gcry_mpi_t tmp = stack[stackidx-1];
+                      stack[stackidx-1] = stack[stackidx - 2];
+                      stack[stackidx-2] = tmp;
+                   }
+                 break;
+                case 'b':
+                  do_nbits ();
+                  break;
+               case 'c':
+                 for (i = 0; i < stackidx; i++)
+                    {
+                      mpi_release (stack[i]); stack[i] = NULL;
+                    }
+                 stackidx = 0;
+                 break;
+               case 'p':       /* print the tos */
+                 if (!stackidx)
+                   puts ("stack is empty");
+                 else
+                   {
+                     print_mpi (stack[stackidx - 1]);
+                     putchar ('\n');
+                   }
+                 break;
+               case 'f':       /* print the stack */
+                 for (i = stackidx - 1; i >= 0; i--)
+                   {
+                     printf ("[%2d]: ", i);
+                     print_mpi (stack[i]);
+                     putchar ('\n');
+                   }
+                 break;
+                case '?':
+                  print_help ();
+                  break;
+               default:
+                 fputs ("invalid operator\n", stderr);
+               }
+           }
+       }
+      else if (state == 1) /* In a number. */
+       {
+         if (!isxdigit (c))
+           {
+              /* Store the number */
+             state = 0;
+             ungetc (c, stdin);
+             if (stridx < sizeof strbuf)
+               strbuf[stridx] = 0;
+
+             if (stackidx < STACKSIZE)
+               {
+                 if (!stack[stackidx])
+                   stack[stackidx] = mpi_new (0);
+                 if (scan_mpi (stack[stackidx], strbuf))
+                   fputs ("invalid number\n", stderr);
+                 else
+                   stackidx++;
+               }
+             else
+               fputs ("stack overflow\n", stderr);
+           }
+         else
+           { /* Store a digit.  */
+             if (stridx < sizeof strbuf - 1)
+               strbuf[stridx++] = c;
+             else if (stridx == sizeof strbuf - 1)
+               {
+                 strbuf[stridx] = 0;
+                 fputs ("input too large - truncated\n", stderr);
+                 stridx++;
+               }
+           }
+       }
+      else if (state == 2) /* In a comment. */
+        {
+          if (c == '\n')
+            state = 0;
+        }
+
+    }
+
+  for (i = 0; i < stackidx; i++)
+    mpi_release (stack[i]);
+  return 0;
+}
index 2beb234..2bf7d8c 100644 (file)
@@ -1,6 +1,7 @@
 /* secmem.c  - memory allocation from a secure heap
  * Copyright (C) 1998, 1999, 2000, 2001, 2002,
  *               2003, 2007 Free Software Foundation, Inc.
+ * Copyright (C) 2013 g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
@@ -78,6 +79,8 @@ static int show_warning;
 static int not_locked;
 static int no_warning;
 static int suspend_warning;
+static int no_mlock;
+static int no_priv_drop;
 
 /* Stats.  */
 static unsigned int cur_alloced, cur_blocks;
@@ -240,11 +243,19 @@ lock_pool (void *p, size_t n)
 #if defined(USE_CAPABILITIES) && defined(HAVE_MLOCK)
   int err;
 
-  cap_set_proc (cap_from_text ("cap_ipc_lock+ep"));
-  err = mlock (p, n);
-  if (err && errno)
-    err = errno;
-  cap_set_proc (cap_from_text ("cap_ipc_lock+p"));
+  {
+    cap_t cap;
+
+    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 (err)
     {
@@ -282,22 +293,27 @@ lock_pool (void *p, size_t n)
     }
   else
     {
-      err = mlock (p, n);
+      err = no_mlock? 0 : mlock (p, n);
       if (err && errno)
        err = errno;
     }
 #else /* !HAVE_BROKEN_MLOCK */
-  err = mlock (p, n);
+  err = no_mlock? 0 : mlock (p, n);
   if (err && errno)
     err = errno;
 #endif /* !HAVE_BROKEN_MLOCK */
 
+  /* Test whether we are running setuid(0).  */
   if (uid && ! geteuid ())
     {
-      /* check that we really dropped the privs.
-       * Note: setuid(0) should always fail */
-      if (setuid (uid) || getuid () != geteuid () || !setuid (0))
-       log_fatal ("failed to reset uid: %s\n", strerror (errno));
+      /* Yes, we are.  */
+      if (!no_priv_drop)
+        {
+          /* Check that we really dropped the privs.
+           * Note: setuid(0) should always fail */
+          if (setuid (uid) || getuid () != geteuid () || !setuid (0))
+            log_fatal ("failed to reset uid: %s\n", strerror (errno));
+        }
     }
 
   if (err)
@@ -339,7 +355,8 @@ lock_pool (void *p, size_t n)
 #else
   (void)p;
   (void)n;
-  log_info ("Please note that you don't have secure memory on this system\n");
+  if (!no_mlock)
+    log_info ("Please note that you don't have secure memory on this system\n");
 #endif
 }
 
@@ -424,6 +441,8 @@ _gcry_secmem_set_flags (unsigned flags)
   was_susp = suspend_warning;
   no_warning = flags & GCRY_SECMEM_FLAG_NO_WARNING;
   suspend_warning = flags & GCRY_SECMEM_FLAG_SUSPEND_WARNING;
+  no_mlock      = flags & GCRY_SECMEM_FLAG_NO_MLOCK;
+  no_priv_drop = flags & GCRY_SECMEM_FLAG_NO_PRIV_DROP;
 
   /* and now issue the warning if it is not longer suspended */
   if (was_susp && !suspend_warning && show_warning)
@@ -445,6 +464,8 @@ _gcry_secmem_get_flags (void)
   flags = no_warning ? GCRY_SECMEM_FLAG_NO_WARNING : 0;
   flags |= suspend_warning ? GCRY_SECMEM_FLAG_SUSPEND_WARNING : 0;
   flags |= not_locked ? GCRY_SECMEM_FLAG_NOT_LOCKED : 0;
+  flags |= no_mlock ? GCRY_SECMEM_FLAG_NO_MLOCK : 0;
+  flags |= no_priv_drop ? GCRY_SECMEM_FLAG_NO_PRIV_DROP : 0;
 
   SECMEM_UNLOCK;
 
@@ -461,7 +482,13 @@ secmem_init (size_t n)
     {
 #ifdef USE_CAPABILITIES
       /* drop all capabilities */
-      cap_set_proc (cap_from_text ("all-eip"));
+      {
+        cap_t cap;
+
+        cap = cap_from_text ("all-eip");
+        cap_set_proc (cap);
+        cap_free (cap);
+      }
 
 #elif !defined(HAVE_DOSISH_SYSTEM)
       uid_t uid;
@@ -506,6 +533,19 @@ _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");
+
+  return 0;
+}
+
+
 static void *
 _gcry_secmem_malloc_internal (size_t size)
 {
index 29e151a..3577381 100644 (file)
@@ -35,5 +35,7 @@ int _gcry_private_is_secure (const void *p);
 #define GCRY_SECMEM_FLAG_NO_WARNING      (1 << 0)
 #define GCRY_SECMEM_FLAG_SUSPEND_WARNING (1 << 1)
 #define GCRY_SECMEM_FLAG_NOT_LOCKED      (1 << 2)
+#define GCRY_SECMEM_FLAG_NO_MLOCK        (1 << 3)
+#define GCRY_SECMEM_FLAG_NO_PRIV_DROP    (1 << 4)
 
 #endif /* G10_SECMEM_H */
index 0877773..0e4af52 100644 (file)
@@ -1,6 +1,7 @@
 /* sexp.c  -  S-Expression handling
  * Copyright (C) 1999, 2000, 2001, 2002, 2003,
  *               2004, 2006, 2007, 2008, 2011  Free Software Foundation, Inc.
+ * Copyright (C) 2013, 2014 g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
 #define GCRYPT_NO_MPI_MACROS 1
 #include "g10lib.h"
 
-typedef struct gcry_sexp *NODE;
+
+/* Notes on the internal memory layout.
+
+   We store an S-expression as one memory buffer with tags, length and
+   value.  The simplest list would thus be:
+
+   /----------+----------+---------+------+-----------+----------\
+   | open_tag | data_tag | datalen | data | close_tag | stop_tag |
+   \----------+----------+---------+------+-----------+----------/
+
+   Expressed more compact and with an example:
+
+   /----+----+----+---+----+----\
+   | OT | DT | DL | D | CT | ST |  "(foo)"
+   \----+----+----+---+----+----/
+
+   The open tag must always be the first tag of a list as requires by
+   the S-expression specs.  At least data element (data_tag, datalen,
+   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
+   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.
+   The length of each data must be greater than 0 and has a current
+   limit to 65535 bytes (by means of the DATALEN type).
+
+   A list with two data elements:
+
+   /----+----+----+---+----+----+---+----+----\
+   | OT | DT | DL | D | DT | DL | D | CT | ST |  "(foo bar)"
+   \----+----+----+---+----+----+---+----+----/
+
+   In the above example both DL fields have a value of 3.
+   A list of a list with one data element:
+
+   /----+----+----+----+---+----+----+----\
+   | OT | OT | DT | DL | D | CT | CT | ST |  "((foo))"
+   \----+----+----+----+---+----+----+----/
+
+   A list with one element followed by another list:
+
+   /----+----+----+---+----+----+----+---+----+----+----\
+   | OT | DT | DL | D | OT | DT | DL | D | CT | CT | ST |  "(foo (bar))"
+   \----+----+----+---+----+----+----+---+----+----+----/
+
+ */
+
 typedef unsigned short DATALEN;
 
 struct gcry_sexp
@@ -41,11 +90,11 @@ struct gcry_sexp
 
 #define ST_STOP  0
 #define ST_DATA  1  /* datalen follows */
-#define ST_HINT  2  /* datalen follows */
+/*#define ST_HINT  2   datalen follows (currently not used) */
 #define ST_OPEN  3
 #define ST_CLOSE 4
 
-/* the atoi macros assume that the buffer has only valid digits */
+/* The atoi macros assume that the buffer has only valid digits.  */
 #define atoi_1(p)   (*(p) - '0' )
 #define xtoi_1(p)   (*(p) <= '9'? (*(p)- '0'): \
                      *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
@@ -53,15 +102,15 @@ struct gcry_sexp
 
 #define TOKEN_SPECIALS  "-./_:*+="
 
-static gcry_error_t
-vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
-            const char *buffer, size_t length, int argflag,
-            void **arg_list, va_list arg_ptr);
+static gcry_err_code_t
+do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+                const char *buffer, size_t length, int argflag,
+                void **arg_list, va_list arg_ptr);
 
-static gcry_error_t
-sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
-           const char *buffer, size_t length, int argflag,
-           void **arg_list, ...);
+static gcry_err_code_t
+do_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+               const char *buffer, size_t length, int argflag,
+               void **arg_list, ...);
 
 /* Return true if P points to a byte containing a whitespace according
    to the S-expressions definition. */
@@ -122,7 +171,7 @@ dump_string (const byte *p, size_t n, int delim )
 
 
 void
-gcry_sexp_dump (const gcry_sexp_t a)
+_gcry_sexp_dump (const gcry_sexp_t a)
 {
   const byte *p;
   int indent = 0;
@@ -166,9 +215,10 @@ gcry_sexp_dump (const gcry_sexp_t a)
     }
 }
 
-/****************
- * Pass list through except when it is an empty list - in that case
- * return NULL and release the passed list.
+
+/* Pass list through except when it is an empty list - in that case
+ * return NULL and release the passed list.  This is used to make sure
+ * that no forbidden empty lists are created.
  */
 static gcry_sexp_t
 normalize ( gcry_sexp_t list )
@@ -181,13 +231,13 @@ normalize ( gcry_sexp_t list )
   if ( *p == ST_STOP )
     {
       /* this is "" */
-      gcry_sexp_release ( list );
+      sexp_release ( list );
       return NULL;
     }
   if ( *p == ST_OPEN && p[1] == ST_CLOSE )
     {
       /* this is "()" */
-      gcry_sexp_release ( list );
+      sexp_release ( list );
       return NULL;
     }
 
@@ -209,23 +259,23 @@ normalize ( gcry_sexp_t list )
 
    This function returns 0 and and the pointer to the new object in
    RETSEXP or an error code in which case RETSEXP is set to NULL.  */
-gcry_error_t
-gcry_sexp_create (gcry_sexp_t *retsexp, void *buffer, size_t length,
+gcry_err_code_t
+_gcry_sexp_create (gcry_sexp_t *retsexp, void *buffer, size_t length,
                   int autodetect, void (*freefnc)(void*) )
 {
-  gcry_error_t errcode;
+  gcry_err_code_t errcode;
   gcry_sexp_t se;
 
   if (!retsexp)
-    return gcry_error (GPG_ERR_INV_ARG);
+    return GPG_ERR_INV_ARG;
   *retsexp = NULL;
   if (autodetect < 0 || autodetect > 1 || !buffer)
-    return gcry_error (GPG_ERR_INV_ARG);
+    return GPG_ERR_INV_ARG;
 
   if (!length && !autodetect)
     { /* What a brave caller to assume that there is really a canonical
          encoded S-expression in buffer */
-      length = gcry_sexp_canon_len (buffer, 0, NULL, &errcode);
+      length = _gcry_sexp_canon_len (buffer, 0, NULL, &errcode);
       if (!length)
         return errcode;
     }
@@ -234,7 +284,7 @@ gcry_sexp_create (gcry_sexp_t *retsexp, void *buffer, size_t length,
       length = strlen ((char *)buffer);
     }
 
-  errcode = sexp_sscan (&se, NULL, buffer, length, 0, NULL);
+  errcode = do_sexp_sscan (&se, NULL, buffer, length, 0, NULL);
   if (errcode)
     return errcode;
 
@@ -248,15 +298,15 @@ gcry_sexp_create (gcry_sexp_t *retsexp, void *buffer, size_t length,
          GCRYSEXP object and use the BUFFER directly.  */
       freefnc (buffer);
     }
-  return gcry_error (GPG_ERR_NO_ERROR);
+  return 0;
 }
 
 /* Same as gcry_sexp_create but don't transfer ownership */
-gcry_error_t
-gcry_sexp_new (gcry_sexp_t *retsexp, const void *buffer, size_t length,
+gcry_err_code_t
+_gcry_sexp_new (gcry_sexp_t *retsexp, const void *buffer, size_t length,
                int autodetect)
 {
-  return gcry_sexp_create (retsexp, (void *)buffer, length, autodetect, NULL);
+  return _gcry_sexp_create (retsexp, (void *)buffer, length, autodetect, NULL);
 }
 
 
@@ -264,11 +314,11 @@ gcry_sexp_new (gcry_sexp_t *retsexp, const void *buffer, size_t length,
  * Release resource of the given SEXP object.
  */
 void
-gcry_sexp_release( gcry_sexp_t sexp )
+_gcry_sexp_release( gcry_sexp_t sexp )
 {
   if (sexp)
     {
-      if (gcry_is_secure (sexp))
+      if (_gcry_is_secure (sexp))
         {
           /* Extra paranoid wiping. */
           const byte *p = sexp->d;
@@ -297,7 +347,7 @@ gcry_sexp_release( gcry_sexp_t sexp )
             }
           wipememory (sexp->d, p - sexp->d);
         }
-      gcry_free ( sexp );
+      xfree ( sexp );
     }
 }
 
@@ -308,7 +358,7 @@ gcry_sexp_release( gcry_sexp_t sexp )
  * element straight into the new pair.
  */
 gcry_sexp_t
-gcry_sexp_cons( const gcry_sexp_t a, const gcry_sexp_t b )
+_gcry_sexp_cons( const gcry_sexp_t a, const gcry_sexp_t b )
 {
   (void)a;
   (void)b;
@@ -325,7 +375,7 @@ gcry_sexp_cons( const gcry_sexp_t a, const gcry_sexp_t b )
  * with a NULL.
  */
 gcry_sexp_t
-gcry_sexp_alist( const gcry_sexp_t *array )
+_gcry_sexp_alist( const gcry_sexp_t *array )
 {
   (void)array;
 
@@ -339,7 +389,7 @@ gcry_sexp_alist( const gcry_sexp_t *array )
  * Make a list from all items, the end of list is indicated by a NULL
  */
 gcry_sexp_t
-gcry_sexp_vlist( const gcry_sexp_t a, ... )
+_gcry_sexp_vlist( const gcry_sexp_t a, ... )
 {
   (void)a;
   /* NYI: Implementation should be quite easy with our new data
@@ -354,7 +404,7 @@ gcry_sexp_vlist( const gcry_sexp_t a, ... )
  * Returns: a new ist (which maybe a)
  */
 gcry_sexp_t
-gcry_sexp_append( const gcry_sexp_t a, const gcry_sexp_t n )
+_gcry_sexp_append( const gcry_sexp_t a, const gcry_sexp_t n )
 {
   (void)a;
   (void)n;
@@ -365,7 +415,7 @@ 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 )
+_gcry_sexp_prepend( const gcry_sexp_t a, const gcry_sexp_t n )
 {
   (void)a;
   (void)n;
@@ -382,7 +432,7 @@ gcry_sexp_prepend( const gcry_sexp_t a, const gcry_sexp_t n )
  * Returns: A new list with this sublist or NULL if not found.
  */
 gcry_sexp_t
-gcry_sexp_find_token( const gcry_sexp_t list, const char *tok, size_t toklen )
+_gcry_sexp_find_token( const gcry_sexp_t list, const char *tok, size_t toklen )
 {
   const byte *p;
   DATALEN n;
@@ -433,7 +483,7 @@ gcry_sexp_find_token( const gcry_sexp_t list, const char *tok, size_t toklen )
                }
               n = p - head;
 
-              newlist = gcry_malloc ( sizeof *newlist + n );
+              newlist = xtrymalloc ( sizeof *newlist + n );
               if (!newlist)
                 {
                   /* No way to return an error code, so we can only
@@ -462,41 +512,45 @@ gcry_sexp_find_token( const gcry_sexp_t list, const char *tok, size_t toklen )
  * Return the length of the given list
  */
 int
-gcry_sexp_length( const gcry_sexp_t list )
+_gcry_sexp_length (const gcry_sexp_t list)
 {
-    const byte *p;
-    DATALEN n;
-    int type;
-    int length = 0;
-    int level = 0;
-
-    if ( !list )
-       return 0;
-
-    p = list->d;
-    while ( (type=*p) != ST_STOP ) {
-       p++;
-       if ( type == ST_DATA ) {
-           memcpy ( &n, p, sizeof n );
-           p += sizeof n + n;
-           if ( level == 1 )
-               length++;
+  const byte *p;
+  DATALEN n;
+  int type;
+  int length = 0;
+  int level = 0;
+
+  if (!list)
+    return 0;
+
+  p = list->d;
+  while ((type=*p) != ST_STOP)
+    {
+      p++;
+      if (type == ST_DATA)
+        {
+          memcpy (&n, p, sizeof n);
+          p += sizeof n + n;
+          if (level == 1)
+            length++;
        }
-       else if ( type == ST_OPEN ) {
-           if ( level == 1 )
-               length++;
-           level++;
+      else if (type == ST_OPEN)
+        {
+          if (level == 1)
+            length++;
+          level++;
        }
-       else if ( type == ST_CLOSE ) {
-           level--;
+      else if (type == ST_CLOSE)
+        {
+          level--;
        }
     }
-    return length;
+  return length;
 }
 
 
 /* Return the internal lengths offset of LIST.  That is the size of
-   the buffer from the first ST_OPEN, which is retruned at R_OFF, to
+   the buffer from the first ST_OPEN, which is returned at R_OFF, to
    the corresponding ST_CLOSE inclusive.  */
 static size_t
 get_internal_buffer (const gcry_sexp_t list, size_t *r_off)
@@ -537,100 +591,116 @@ get_internal_buffer (const gcry_sexp_t list, size_t *r_off)
 
 
 
-/* Extract the CAR of the given list.  May return NULL for bad lists
-   or memory failure.  */
+/* Extract the n-th element of the given LIST.  Returns NULL for
+   no-such-element, a corrupt list, or memory failure.  */
 gcry_sexp_t
-gcry_sexp_nth( const gcry_sexp_t list, int number )
+_gcry_sexp_nth (const gcry_sexp_t list, int number)
 {
-    const byte *p;
-    DATALEN n;
-    gcry_sexp_t newlist;
-    byte *d;
-    int level = 0;
-
-    if ( !list || list->d[0] != ST_OPEN )
-       return NULL;
-    p = list->d;
-
-    while ( number > 0 ) {
-       p++;
-       if ( *p == ST_DATA ) {
-           memcpy ( &n, ++p, sizeof n );
-           p += sizeof n + n;
-           p--;
-           if ( !level )
-               number--;
+  const byte *p;
+  DATALEN n;
+  gcry_sexp_t newlist;
+  byte *d;
+  int level = 0;
+
+  if (!list || list->d[0] != ST_OPEN)
+    return NULL;
+  p = list->d;
+
+  while (number > 0)
+    {
+      p++;
+      if (*p == ST_DATA)
+        {
+          memcpy (&n, ++p, sizeof n);
+          p += sizeof n + n;
+          p--;
+          if (!level)
+            number--;
        }
-       else if ( *p == ST_OPEN ) {
-           level++;
+      else if (*p == ST_OPEN)
+        {
+          level++;
        }
-       else if ( *p == ST_CLOSE ) {
-           level--;
-           if ( !level )
-               number--;
+      else if (*p == ST_CLOSE)
+        {
+          level--;
+          if ( !level )
+            number--;
        }
-       else if ( *p == ST_STOP ) {
-           return NULL;
+      else if (*p == ST_STOP)
+        {
+          return NULL;
        }
     }
-    p++;
+  p++;
 
-    if ( *p == ST_DATA ) {
-       memcpy ( &n, p, sizeof n ); p += sizeof n;
-       newlist = gcry_malloc ( sizeof *newlist + n + 1 );
-        if (!newlist)
-          return NULL;
-       d = newlist->d;
-       memcpy ( d, p, n ); d += n;
-       *d++ = ST_STOP;
+  if (*p == ST_DATA)
+    {
+      memcpy (&n, p+1, sizeof n);
+      newlist = xtrymalloc (sizeof *newlist + 1 + 1 + sizeof n + n + 1);
+      if (!newlist)
+        return NULL;
+      d = newlist->d;
+      *d++ = ST_OPEN;
+      memcpy (d, p, 1 + sizeof n + n);
+      d += 1 + sizeof n + n;
+      *d++ = ST_CLOSE;
+      *d = ST_STOP;
     }
-    else if ( *p == ST_OPEN ) {
-       const byte *head = p;
-
-       level = 1;
-       do {
-           p++;
-           if ( *p == ST_DATA ) {
-               memcpy ( &n, ++p, sizeof n );
-               p += sizeof n + n;
-               p--;
-           }
-           else if ( *p == ST_OPEN ) {
-               level++;
-           }
-           else if ( *p == ST_CLOSE ) {
-               level--;
-           }
-           else if ( *p == ST_STOP ) {
-               BUG ();
-           }
-       } while ( level );
-       n = p + 1 - head;
+  else if (*p == ST_OPEN)
+    {
+      const byte *head = p;
 
-       newlist = gcry_malloc ( sizeof *newlist + n );
-        if (!newlist)
-          return NULL;
-       d = newlist->d;
-       memcpy ( d, head, n ); d += n;
-       *d++ = ST_STOP;
+      level = 1;
+      do {
+        p++;
+        if (*p == ST_DATA)
+          {
+            memcpy (&n, ++p, sizeof n);
+            p += sizeof n + n;
+            p--;
+          }
+        else if (*p == ST_OPEN)
+          {
+            level++;
+          }
+        else if (*p == ST_CLOSE)
+          {
+            level--;
+          }
+        else if (*p == ST_STOP)
+          {
+            BUG ();
+          }
+      } while (level);
+      n = p + 1 - head;
+
+      newlist = xtrymalloc (sizeof *newlist + n);
+      if (!newlist)
+        return NULL;
+      d = newlist->d;
+      memcpy (d, head, n);
+      d += n;
+      *d++ = ST_STOP;
     }
-    else
-       newlist = NULL;
+  else
+    newlist = NULL;
 
-    return normalize (newlist);
+  return normalize (newlist);
 }
 
+
 gcry_sexp_t
-gcry_sexp_car( const gcry_sexp_t list )
+_gcry_sexp_car (const gcry_sexp_t list)
 {
-    return gcry_sexp_nth ( list, 0 );
+  return _gcry_sexp_nth (list, 0);
 }
 
 
 /* Helper to get data from the car.  The returned value is valid as
    long as the list is not modified. */
 static const char *
-sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen)
+do_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen)
 {
   const byte *p;
   DATALEN n;
@@ -647,9 +717,9 @@ sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen)
     return NULL;     /* Not a list but N > 0 requested. */
 
   /* Skip over N elements. */
-  while ( number > 0 )
+  while (number > 0)
     {
-      if ( *p == ST_DATA )
+      if (*p == ST_DATA)
         {
           memcpy ( &n, ++p, sizeof n );
           p += sizeof n + n;
@@ -657,17 +727,17 @@ sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen)
           if ( !level )
             number--;
        }
-      else if ( *p == ST_OPEN )
+      else if (*p == ST_OPEN)
         {
           level++;
        }
-      else if ( *p == ST_CLOSE )
+      else if (*p == ST_CLOSE)
         {
           level--;
           if ( !level )
             number--;
        }
-      else if ( *p == ST_STOP )
+      else if (*p == ST_STOP)
         {
           return NULL;
        }
@@ -675,7 +745,7 @@ sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen)
     }
 
   /* If this is data, return it.  */
-  if ( *p == ST_DATA )
+  if (*p == ST_DATA)
     {
       memcpy ( &n, ++p, sizeof n );
       *datalen = n;
@@ -689,25 +759,49 @@ sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen)
 /* Get data from the car.  The returned value is valid as long as the
    list is not modified.  */
 const char *
-gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen )
+_gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen )
 {
-  return sexp_nth_data (list, number, datalen);
+  return do_sexp_nth_data (list, number, datalen);
+}
+
+
+/* Get the nth element of a list which needs to be a simple object.
+   The returned value is a malloced buffer and needs to be freed by
+   the caller.  This is basically the same as gcry_sexp_nth_data but
+   with an allocated result. */
+void *
+_gcry_sexp_nth_buffer (const gcry_sexp_t list, int number, size_t *rlength)
+{
+  const char *s;
+  size_t n;
+  char *buf;
+
+  *rlength = 0;
+  s = do_sexp_nth_data (list, number, &n);
+  if (!s || !n)
+    return NULL;
+  buf = xtrymalloc (n);
+  if (!buf)
+    return NULL;
+  memcpy (buf, s, n);
+  *rlength = n;
+  return buf;
 }
 
 
 /* Get a string from the car.  The returned value is a malloced string
    and needs to be freed by the caller.  */
 char *
-gcry_sexp_nth_string (const gcry_sexp_t list, int number)
+_gcry_sexp_nth_string (const gcry_sexp_t list, int number)
 {
   const char *s;
   size_t n;
   char *buf;
 
-  s = sexp_nth_data (list, number, &n);
+  s = do_sexp_nth_data (list, number, &n);
   if (!s || n < 1 || (n+1) < 1)
     return NULL;
-  buf = gcry_malloc (n+1);
+  buf = xtrymalloc (n+1);
   if (!buf)
     return NULL;
   memcpy (buf, s, n);
@@ -715,25 +809,44 @@ gcry_sexp_nth_string (const gcry_sexp_t list, int number)
   return buf;
 }
 
+
 /*
  * Get a MPI from the car
  */
 gcry_mpi_t
-gcry_sexp_nth_mpi( gcry_sexp_t list, int number, int mpifmt )
+_gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt)
 {
-  const char *s;
   size_t n;
   gcry_mpi_t a;
 
-  if ( !mpifmt )
-    mpifmt = GCRYMPI_FMT_STD;
+  if (mpifmt == GCRYMPI_FMT_OPAQUE)
+    {
+      char *p;
 
-  s = sexp_nth_data (list, number, &n);
-  if (!s)
-    return NULL;
+      p = _gcry_sexp_nth_buffer (list, number, &n);
+      if (!p)
+        return NULL;
 
-  if ( gcry_mpi_scan ( &a, mpifmt, s, n, NULL ) )
-    return NULL;
+      a = _gcry_is_secure (list)? _gcry_mpi_snew (0) : _gcry_mpi_new (0);
+      if (a)
+        mpi_set_opaque (a, p, n*8);
+      else
+        xfree (p);
+    }
+  else
+    {
+      const char *s;
+
+      if (!mpifmt)
+        mpifmt = GCRYMPI_FMT_STD;
+
+      s = do_sexp_nth_data (list, number, &n);
+      if (!s)
+        return NULL;
+
+      if (_gcry_mpi_scan (&a, mpifmt, s, n, NULL))
+        return NULL;
+    }
 
   return a;
 }
@@ -743,118 +856,121 @@ gcry_sexp_nth_mpi( gcry_sexp_t list, int number, int mpifmt )
  * Get the CDR
  */
 gcry_sexp_t
-gcry_sexp_cdr( const gcry_sexp_t list )
+_gcry_sexp_cdr(const gcry_sexp_t list)
 {
-    const byte *p;
-    const byte *head;
-    DATALEN n;
-    gcry_sexp_t newlist;
-    byte *d;
-    int level = 0;
-    int skip = 1;
-
-    if ( !list || list->d[0] != ST_OPEN )
-       return NULL;
-    p = list->d;
-
-    while ( skip > 0 ) {
-       p++;
-       if ( *p == ST_DATA ) {
-           memcpy ( &n, ++p, sizeof n );
-           p += sizeof n + n;
-           p--;
-           if ( !level )
-               skip--;
+  const byte *p;
+  const byte *head;
+  DATALEN n;
+  gcry_sexp_t newlist;
+  byte *d;
+  int level = 0;
+  int skip = 1;
+
+  if (!list || list->d[0] != ST_OPEN)
+    return NULL;
+  p = list->d;
+
+  while (skip > 0)
+    {
+      p++;
+      if (*p == ST_DATA)
+        {
+          memcpy ( &n, ++p, sizeof n );
+          p += sizeof n + n;
+          p--;
+          if ( !level )
+            skip--;
        }
-       else if ( *p == ST_OPEN ) {
-           level++;
+      else if (*p == ST_OPEN)
+        {
+          level++;
        }
-       else if ( *p == ST_CLOSE ) {
-           level--;
-           if ( !level )
-               skip--;
+      else if (*p == ST_CLOSE)
+        {
+          level--;
+          if ( !level )
+            skip--;
        }
-       else if ( *p == ST_STOP ) {
-           return NULL;
+      else if (*p == ST_STOP)
+        {
+          return NULL;
        }
     }
+  p++;
+
+  head = p;
+  level = 0;
+  do {
+    if (*p == ST_DATA)
+      {
+        memcpy ( &n, ++p, sizeof n );
+        p += sizeof n + n;
+        p--;
+      }
+    else if (*p == ST_OPEN)
+      {
+        level++;
+      }
+    else if (*p == ST_CLOSE)
+      {
+        level--;
+      }
+    else if (*p == ST_STOP)
+      {
+        return NULL;
+      }
     p++;
+  } while (level);
+  n = p - head;
 
-    head = p;
-    level = 0;
-    do {
-       if ( *p == ST_DATA ) {
-           memcpy ( &n, ++p, sizeof n );
-           p += sizeof n + n;
-           p--;
-       }
-       else if ( *p == ST_OPEN ) {
-           level++;
-       }
-       else if ( *p == ST_CLOSE ) {
-           level--;
-       }
-       else if ( *p == ST_STOP ) {
-           return NULL;
-       }
-       p++;
-    } while ( level );
-    n = p - head;
-
-    newlist = gcry_malloc ( sizeof *newlist + n + 2 );
-    if (!newlist)
-      return NULL;
-    d = newlist->d;
-    *d++ = ST_OPEN;
-    memcpy ( d, head, n ); d += n;
-    *d++ = ST_CLOSE;
-    *d++ = ST_STOP;
-
-    return normalize (newlist);
+  newlist = xtrymalloc (sizeof *newlist + n + 2);
+  if (!newlist)
+    return NULL;
+  d = newlist->d;
+  *d++ = ST_OPEN;
+  memcpy (d, head, n);
+  d += n;
+  *d++ = ST_CLOSE;
+  *d++ = ST_STOP;
+
+  return normalize (newlist);
 }
 
+
 gcry_sexp_t
-gcry_sexp_cadr ( const gcry_sexp_t list )
+_gcry_sexp_cadr ( const gcry_sexp_t list )
 {
-    gcry_sexp_t a, b;
+  gcry_sexp_t a, b;
 
-    a = gcry_sexp_cdr ( list );
-    b = gcry_sexp_car ( a );
-    gcry_sexp_release ( a );
-    return b;
+  a = _gcry_sexp_cdr (list);
+  b = _gcry_sexp_car (a);
+  sexp_release (a);
+  return b;
 }
 
 
-
-static int
-hextobyte( const byte *s )
+static GPG_ERR_INLINE int
+hextonibble (int s)
 {
-    int c=0;
-
-    if( *s >= '0' && *s <= '9' )
-       c = 16 * (*s - '0');
-    else if( *s >= 'A' && *s <= 'F' )
-       c = 16 * (10 + *s - 'A');
-    else if( *s >= 'a' && *s <= 'f' ) {
-       c = 16 * (10 + *s - 'a');
-    }
-    s++;
-    if( *s >= '0' && *s <= '9' )
-       c += *s - '0';
-    else if( *s >= 'A' && *s <= 'F' )
-       c += 10 + *s - 'A';
-    else if( *s >= 'a' && *s <= 'f' ) {
-       c += 10 + *s - 'a';
-    }
-    return c;
+  if (s >= '0' && s <= '9')
+    return s - '0';
+  else if (s >= 'A' && s <= 'F')
+    return 10 + s - 'A';
+  else if (s >= 'a' && s <= 'f')
+    return 10 + s - 'a';
+  else
+    return 0;
 }
 
-struct make_space_ctx {
-    gcry_sexp_t sexp;
-    size_t allocated;
-    byte *pos;
+
+struct make_space_ctx
+{
+  gcry_sexp_t sexp;
+  size_t allocated;
+  byte *pos;
 };
 
+
 static gpg_err_code_t
 make_space ( struct make_space_ctx *c, size_t n )
 {
@@ -869,7 +985,7 @@ make_space ( struct make_space_ctx *c, size_t n )
       newsize = c->allocated + 2*(n+sizeof(DATALEN)+1);
       if (newsize <= c->allocated)
         return GPG_ERR_TOO_LARGE;
-      newsexp = gcry_realloc ( c->sexp, sizeof *newsexp + newsize - 1);
+      newsexp = xtryrealloc ( c->sexp, sizeof *newsexp + newsize - 1);
       if (!newsexp)
         return gpg_err_code_from_errno (errno);
       c->allocated = newsize;
@@ -976,10 +1092,10 @@ unquote_string (const char *string, size_t length, unsigned char *buf)
  * common operation gcry_sexp_cdr_mpi() will always return a secure MPI
  * regardless whether it is needed or not.
  */
-static gcry_error_t
-vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
-            const char *buffer, size_t length, int argflag,
-            void **arg_list, va_list arg_ptr)
+static gpg_err_code_t
+do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+                const char *buffer, size_t length, int argflag,
+                void **arg_list, va_list arg_ptr)
 {
   gcry_err_code_t err = 0;
   static const char tokenchars[] =
@@ -1044,10 +1160,10 @@ vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
      the provided one.  However, we add space for one extra datalen so
      that the code which does the ST_CLOSE can use MAKE_SPACE */
   c.allocated = length + sizeof(DATALEN);
-  if (buffer && length && gcry_is_secure (buffer))
-    c.sexp = gcry_malloc_secure (sizeof *c.sexp + c.allocated - 1);
+  if (buffer && length && _gcry_is_secure (buffer))
+    c.sexp = xtrymalloc_secure (sizeof *c.sexp + c.allocated - 1);
   else
-    c.sexp = gcry_malloc (sizeof *c.sexp + c.allocated - 1);
+    c.sexp = xtrymalloc (sizeof *c.sexp + c.allocated - 1);
   if (!c.sexp)
     {
       err = gpg_err_code_from_errno (errno);
@@ -1180,10 +1296,19 @@ vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
              STORE_LEN (c.pos, datalen);
              for (hexfmt++; hexfmt < p; hexfmt++)
                {
+                  int tmpc;
+
                  if (whitespacep (hexfmt))
                    continue;
-                 *c.pos++ = hextobyte ((const unsigned char*)hexfmt);
-                 hexfmt++;
+                 tmpc = hextonibble (*(const unsigned char*)hexfmt);
+                  for (hexfmt++; hexfmt < p && whitespacep (hexfmt); hexfmt++)
+                   ;
+                  if (hexfmt < p)
+                    {
+                      tmpc *= 16;
+                      tmpc += hextonibble (*(const unsigned char*)hexfmt);
+                    }
+                  *c.pos++ = tmpc;
                }
              hexfmt = NULL;
            }
@@ -1258,25 +1383,25 @@ vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
 
              ARG_NEXT (m, gcry_mpi_t);
 
-              if (gcry_mpi_get_flag (m, GCRYMPI_FLAG_OPAQUE))
+              if (mpi_get_flag (m, GCRYMPI_FLAG_OPAQUE))
                 {
                   void *mp;
                   unsigned int nbits;
 
-                  mp = gcry_mpi_get_opaque (m, &nbits);
+                  mp = mpi_get_opaque (m, &nbits);
                   nm = (nbits+7)/8;
                   if (mp && nm)
                     {
                       MAKE_SPACE (nm);
-                      if (!gcry_is_secure (c.sexp->d)
-                          && gcry_mpi_get_flag (m, GCRYMPI_FLAG_SECURE))
+                      if (!_gcry_is_secure (c.sexp->d)
+                          && mpi_get_flag (m, GCRYMPI_FLAG_SECURE))
                         {
                           /* We have to switch to secure allocation.  */
                           gcry_sexp_t newsexp;
                           byte *newhead;
 
-                          newsexp = gcry_malloc_secure (sizeof *newsexp
-                                                        + c.allocated - 1);
+                          newsexp = xtrymalloc_secure (sizeof *newsexp
+                                                       + c.allocated - 1);
                           if (!newsexp)
                             {
                               err = gpg_err_code_from_errno (errno);
@@ -1285,7 +1410,7 @@ vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
                           newhead = newsexp->d;
                           memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
                           c.pos = newhead + (c.pos - c.sexp->d);
-                          gcry_free (c.sexp);
+                          xfree (c.sexp);
                           c.sexp = newsexp;
                         }
 
@@ -1297,19 +1422,19 @@ vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
                 }
               else
                 {
-                  if (gcry_mpi_print (mpifmt, NULL, 0, &nm, m))
+                  if (_gcry_mpi_print (mpifmt, NULL, 0, &nm, m))
                     BUG ();
 
                   MAKE_SPACE (nm);
-                  if (!gcry_is_secure (c.sexp->d)
-                      && gcry_mpi_get_flag ( m, GCRYMPI_FLAG_SECURE))
+                  if (!_gcry_is_secure (c.sexp->d)
+                      && mpi_get_flag ( m, GCRYMPI_FLAG_SECURE))
                     {
                       /* We have to switch to secure allocation.  */
                       gcry_sexp_t newsexp;
                       byte *newhead;
 
-                      newsexp = gcry_malloc_secure (sizeof *newsexp
-                                                    + c.allocated - 1);
+                      newsexp = xtrymalloc_secure (sizeof *newsexp
+                                                   + c.allocated - 1);
                       if (!newsexp)
                         {
                           err = gpg_err_code_from_errno (errno);
@@ -1318,13 +1443,13 @@ vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
                       newhead = newsexp->d;
                       memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
                       c.pos = newhead + (c.pos - c.sexp->d);
-                      gcry_free (c.sexp);
+                      xfree (c.sexp);
                       c.sexp = newsexp;
                     }
 
                   *c.pos++ = ST_DATA;
                   STORE_LEN (c.pos, nm);
-                  if (gcry_mpi_print (mpifmt, c.pos, nm, &nm, m))
+                  if (_gcry_mpi_print (mpifmt, c.pos, nm, &nm, m))
                     BUG ();
                   c.pos += nm;
                 }
@@ -1355,15 +1480,15 @@ vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
 
              MAKE_SPACE (alen);
              if (alen
-                  && !gcry_is_secure (c.sexp->d)
-                 && gcry_is_secure (astr))
+                  && !_gcry_is_secure (c.sexp->d)
+                 && _gcry_is_secure (astr))
               {
                  /* We have to switch to secure allocation.  */
                  gcry_sexp_t newsexp;
                  byte *newhead;
 
-                 newsexp = gcry_malloc_secure (sizeof *newsexp
-                                                + c.allocated - 1);
+                 newsexp = xtrymalloc_secure (sizeof *newsexp
+                                               + c.allocated - 1);
                   if (!newsexp)
                     {
                       err = gpg_err_code_from_errno (errno);
@@ -1372,7 +1497,7 @@ vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
                  newhead = newsexp->d;
                  memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
                  c.pos = newhead + (c.pos - c.sexp->d);
-                 gcry_free (c.sexp);
+                 xfree (c.sexp);
                  c.sexp = newsexp;
                }
 
@@ -1553,9 +1678,9 @@ vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
       if (c.sexp)
         {
           /* Extra paranoid wipe on error. */
-          if (gcry_is_secure (c.sexp))
+          if (_gcry_is_secure (c.sexp))
             wipememory (c.sexp, sizeof (struct gcry_sexp) + c.allocated - 1);
-          gcry_free (c.sexp);
+          xfree (c.sexp);
         }
       /* This might be expected by existing code...  */
       *retsexp = NULL;
@@ -1563,68 +1688,68 @@ vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
   else
     *retsexp = normalize (c.sexp);
 
-  return gcry_error (err);
+  return err;
 #undef MAKE_SPACE
 #undef STORE_LEN
 }
 
 
-static gcry_error_t
-sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
-           const char *buffer, size_t length, int argflag,
-           void **arg_list, ...)
+static gpg_err_code_t
+do_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+               const char *buffer, size_t length, int argflag,
+               void **arg_list, ...)
 {
-  gcry_error_t rc;
+  gcry_err_code_t rc;
   va_list arg_ptr;
 
   va_start (arg_ptr, arg_list);
-  rc = vsexp_sscan (retsexp, erroff, buffer, length, argflag,
-                   arg_list, arg_ptr);
+  rc = do_vsexp_sscan (retsexp, erroff, buffer, length, argflag,
+                       arg_list, arg_ptr);
   va_end (arg_ptr);
 
   return rc;
 }
 
 
-gcry_error_t
-gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, const char *format, ...)
+gpg_err_code_t
+_gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, const char *format, ...)
 {
-  gcry_error_t rc;
+  gcry_err_code_t rc;
   va_list arg_ptr;
 
   va_start (arg_ptr, format);
-  rc = vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
-                   NULL, arg_ptr);
+  rc = do_vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
+                       NULL, arg_ptr);
   va_end (arg_ptr);
 
   return rc;
 }
 
 
-gcry_error_t
+gcry_err_code_t
 _gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff,
                    const char *format, va_list arg_ptr)
 {
-  return vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
-                     NULL, arg_ptr);
+  return do_vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
+                         NULL, arg_ptr);
 }
 
 
 /* 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)
+gcry_err_code_t
+_gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
+                        const char *format, void **arg_list)
 {
-  return sexp_sscan (retsexp, erroff, format, strlen(format), 1, arg_list);
+  return do_sexp_sscan (retsexp, erroff, format, strlen(format), 1, arg_list);
 }
 
 
-gcry_error_t
-gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
-                const char *buffer, size_t length)
+gcry_err_code_t
+_gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
+                  const char *buffer, size_t length)
 {
-  return sexp_sscan (retsexp, erroff, buffer, length, 0, NULL);
+  return do_sexp_sscan (retsexp, erroff, buffer, length, 0, NULL);
 }
 
 \f
@@ -1642,6 +1767,12 @@ suitable_encoding (const unsigned char *buffer, size_t length)
   if (!length)
     return 1;
 
+  if (*buffer & 0x80)
+    return 0; /* If the MSB is set we assume that buffer represents a
+                 negative number.  */
+  if (!*buffer)
+    return 0; /* Starting with a zero is pretty much a binary string.  */
+
   for (s=buffer; length; s++, length--)
     {
       if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0))
@@ -1751,8 +1882,8 @@ convert_to_token (const unsigned char *src, size_t len, char *dest)
  * the required length is returned.
  */
 size_t
-gcry_sexp_sprint (const gcry_sexp_t list, int mode,
-                  void *buffer, size_t maxlength )
+_gcry_sexp_sprint (const gcry_sexp_t list, int mode,
+                   void *buffer, size_t maxlength )
 {
   static unsigned char empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP };
   const unsigned char *s;
@@ -1902,14 +2033,14 @@ gcry_sexp_sprint (const gcry_sexp_t list, int mode,
    data passed from outside. errorcode and erroff may both be passed as
    NULL.  */
 size_t
-gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
-                     size_t *erroff, gcry_error_t *errcode)
+_gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
+                      size_t *erroff, gcry_err_code_t *errcode)
 {
   const unsigned char *p;
   const unsigned char *disphint = NULL;
   unsigned int datalen = 0;
   size_t dummy_erroff;
-  gcry_error_t dummy_errcode;
+  gcry_err_code_t dummy_errcode;
   size_t count = 0;
   int level = 0;
 
@@ -1918,13 +2049,13 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
   if (!errcode)
     errcode = &dummy_errcode;
 
-  *errcode = gcry_error (GPG_ERR_NO_ERROR);
+  *errcode = GPG_ERR_NO_ERROR;
   *erroff = 0;
   if (!buffer)
     return 0;
   if (*buffer != '(')
     {
-      *errcode = gcry_error (GPG_ERR_SEXP_NOT_CANONICAL);
+      *errcode = GPG_ERR_SEXP_NOT_CANONICAL;
       return 0;
     }
 
@@ -1933,7 +2064,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
       if (length && count >= length)
         {
           *erroff = count;
-          *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG);
+          *errcode = GPG_ERR_SEXP_STRING_TOO_LONG;
           return 0;
         }
 
@@ -1944,7 +2075,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
               if (length && (count+datalen) >= length)
                 {
                   *erroff = count;
-                  *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG);
+                  *errcode = GPG_ERR_SEXP_STRING_TOO_LONG;
                   return 0;
                 }
               count += datalen;
@@ -1956,7 +2087,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
           else
             {
               *erroff = count;
-              *errcode = gcry_error (GPG_ERR_SEXP_INV_LEN_SPEC);
+              *errcode = GPG_ERR_SEXP_INV_LEN_SPEC;
               return 0;
            }
        }
@@ -1965,7 +2096,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
           if (disphint)
             {
               *erroff = count;
-              *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
+              *errcode = GPG_ERR_SEXP_UNMATCHED_DH;
               return 0;
            }
           level++;
@@ -1975,13 +2106,13 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
           if (!level)
             {
               *erroff = count;
-              *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_PAREN);
+              *errcode = GPG_ERR_SEXP_UNMATCHED_PAREN;
               return 0;
            }
           if (disphint)
             {
               *erroff = count;
-              *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
+              *errcode = GPG_ERR_SEXP_UNMATCHED_DH;
               return 0;
            }
           if (!--level)
@@ -1992,7 +2123,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
           if (disphint)
             {
               *erroff = count;
-              *errcode = gcry_error (GPG_ERR_SEXP_NESTED_DH);
+              *errcode = GPG_ERR_SEXP_NESTED_DH;
               return 0;
             }
           disphint = p;
@@ -2002,7 +2133,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
           if ( !disphint )
             {
               *erroff = count;
-              *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
+              *errcode = GPG_ERR_SEXP_UNMATCHED_DH;
               return 0;
            }
           disphint = NULL;
@@ -2012,7 +2143,7 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
           if (*p == '0')
             {
               *erroff = count;
-              *errcode = gcry_error (GPG_ERR_SEXP_ZERO_PREFIX);
+              *errcode = GPG_ERR_SEXP_ZERO_PREFIX;
               return 0;
            }
           datalen = atoi_1 (p);
@@ -2020,14 +2151,282 @@ gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
       else if (*p == '&' || *p == '\\')
         {
           *erroff = count;
-          *errcode = gcry_error (GPG_ERR_SEXP_UNEXPECTED_PUNC);
+          *errcode = GPG_ERR_SEXP_UNEXPECTED_PUNC;
           return 0;
        }
       else
         {
           *erroff = count;
-          *errcode = gcry_error (GPG_ERR_SEXP_BAD_CHARACTER);
+          *errcode = GPG_ERR_SEXP_BAD_CHARACTER;
           return 0;
        }
     }
 }
+
+
+/* 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 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 NULL on success.  On error an error code is
+ * returned and the passed MPIs are either unchanged or set to NULL.
+ */
+gpg_err_code_t
+_gcry_sexp_vextract_param (gcry_sexp_t sexp, const char *path,
+                           const char *list, va_list arg_ptr)
+{
+  gpg_err_code_t rc;
+  const char *s, *s2;
+  gcry_mpi_t *array[20];
+  char arrayisdesc[20];
+  int idx;
+  gcry_sexp_t l1;
+  int mode = '+'; /* Default to GCRYMPI_FMT_USG.  */
+  gcry_sexp_t freethis = NULL;
+
+  memset (arrayisdesc, 0, sizeof arrayisdesc);
+
+  /* First copy all the args into an array.  This is required so that
+     we are able to release already allocated MPIs if later an error
+     was found.  */
+  for (s=list, idx=0; *s && idx < DIM (array); s++)
+    {
+      if (*s == '&' || *s == '+' || *s == '-' || *s == '/' || *s == '?')
+        ;
+      else if (whitespacep (s))
+        ;
+      else
+        {
+          if (*s == '\'')
+            {
+              s++;
+              s2 = strchr (s, '\'');
+              if (!s2 || s2 == s)
+                {
+                  /* Closing quote not found or empty string.  */
+                  return GPG_ERR_SYNTAX;
+                }
+              s = s2;
+            }
+          array[idx] = va_arg (arg_ptr, gcry_mpi_t *);
+          if (!array[idx])
+            return GPG_ERR_MISSING_VALUE; /* NULL pointer given.  */
+          idx++;
+        }
+    }
+  if (*s)
+    return GPG_ERR_LIMIT_REACHED;  /* Too many list elements.  */
+  if (va_arg (arg_ptr, gcry_mpi_t *))
+    return GPG_ERR_INV_ARG;  /* Not enough list elemends.  */
+
+  /* Drill down.  */
+  while (path && *path)
+    {
+      size_t n;
+
+      s = strchr (path, '!');
+      if (s == path)
+        {
+          rc = GPG_ERR_NOT_FOUND;
+          goto cleanup;
+        }
+      n = s? s - path : 0;
+      l1 = _gcry_sexp_find_token (sexp, path, n);
+      if (!l1)
+        {
+          rc = GPG_ERR_NOT_FOUND;
+          goto cleanup;
+        }
+      sexp = l1; l1 = NULL;
+      sexp_release (freethis);
+      freethis = sexp;
+      if (n)
+        path += n + 1;
+      else
+        path = NULL;
+    }
+
+
+  /* Now extract all parameters.  */
+  for (s=list, idx=0; *s; s++)
+    {
+      if (*s == '&' || *s == '+' || *s == '-' || *s == '/')
+        mode = *s;
+      else if (whitespacep (s))
+        ;
+      else if (*s == '?')
+        ; /* Only used via lookahead.  */
+      else
+        {
+          if (*s == '\'')
+            {
+              /* Find closing quote, find token, set S to closing quote.  */
+              s++;
+              s2 = strchr (s, '\'');
+              if (!s2 || s2 == s)
+                {
+                  /* Closing quote not found or empty string.  */
+                  rc = GPG_ERR_SYNTAX;
+                  goto cleanup;
+                }
+              l1 = _gcry_sexp_find_token (sexp, s, s2 - s);
+              s = s2;
+            }
+          else
+            l1 = _gcry_sexp_find_token (sexp, s, 1);
+
+          if (!l1 && s[1] == '?')
+            {
+              /* Optional element not found.  */
+              if (mode == '&')
+                {
+                  gcry_buffer_t *spec = (gcry_buffer_t*)array[idx];
+                  if (!spec->data)
+                    {
+                      spec->size = 0;
+                      spec->off = 0;
+                    }
+                  spec->len = 0;
+                }
+              else
+                *array[idx] = NULL;
+            }
+          else if (!l1)
+            {
+              rc = GPG_ERR_NO_OBJ;  /* List element not found.  */
+              goto cleanup;
+            }
+           else
+            {
+              if (mode == '&')
+                {
+                  gcry_buffer_t *spec = (gcry_buffer_t*)array[idx];
+
+                  if (spec->data)
+                    {
+                      const char *pbuf;
+                      size_t nbuf;
+
+                      pbuf = _gcry_sexp_nth_data (l1, 1, &nbuf);
+                      if (!pbuf || !nbuf)
+                        {
+                          rc = GPG_ERR_INV_OBJ;
+                          goto cleanup;
+                        }
+                      if (spec->off + nbuf > spec->size)
+                        {
+                          rc = GPG_ERR_BUFFER_TOO_SHORT;
+                          goto cleanup;
+                        }
+                      memcpy ((char*)spec->data + spec->off, pbuf, nbuf);
+                      spec->len = nbuf;
+                      arrayisdesc[idx] = 1;
+                    }
+                  else
+                    {
+                      spec->data = _gcry_sexp_nth_buffer (l1, 1, &spec->size);
+                      if (!spec->data)
+                        {
+                          rc = GPG_ERR_INV_OBJ; /* Or out of core.  */
+                          goto cleanup;
+                        }
+                      spec->len = spec->size;
+                      spec->off = 0;
+                      arrayisdesc[idx] = 2;
+                    }
+                }
+              else if (mode == '/')
+                *array[idx] = _gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_OPAQUE);
+              else if (mode == '-')
+                *array[idx] = _gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_STD);
+              else
+                *array[idx] = _gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
+              sexp_release (l1); l1 = NULL;
+              if (!*array[idx])
+                {
+                  rc = GPG_ERR_INV_OBJ;  /* Conversion failed.  */
+                  goto cleanup;
+                }
+            }
+          idx++;
+        }
+    }
+
+  sexp_release (freethis);
+  return 0;
+
+ cleanup:
+  sexp_release (freethis);
+  sexp_release (l1);
+  while (idx--)
+    {
+      if (!arrayisdesc[idx])
+        {
+          _gcry_mpi_release (*array[idx]);
+          *array[idx] = NULL;
+        }
+      else if (!arrayisdesc[idx] == 1)
+        {
+          /* Caller provided buffer.  */
+          gcry_buffer_t *spec = (gcry_buffer_t*)array[idx];
+          spec->len = 0;
+        }
+      else
+        {
+          /* We might have allocated a buffer.  */
+          gcry_buffer_t *spec = (gcry_buffer_t*)array[idx];
+          xfree (spec->data);
+          spec->data = NULL;
+          spec->size = spec->off = spec->len = 0;
+        }
+     }
+  return rc;
+}
+
+gpg_error_t
+_gcry_sexp_extract_param (gcry_sexp_t sexp, const char *path,
+                          const char *list, ...)
+{
+  gcry_err_code_t rc;
+  va_list arg_ptr;
+
+  va_start (arg_ptr, list);
+  rc = _gcry_sexp_vextract_param (sexp, path, list, arg_ptr);
+  va_end (arg_ptr);
+  return gpg_error (rc);
+}
index 401851e..3199521 100644 (file)
@@ -18,7 +18,7 @@
 
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION @LIBGCRYPT_LT_CURRENT@,@LIBGCRYPT_LT_AGE@,@LIBGCRYPT_LT_REVISION@,@BUILD_REVISION@
+ FILEVERSION @BUILD_FILEVERSION@
  PRODUCTVERSION @BUILD_FILEVERSION@
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
@@ -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 © 2011 Free Software Foundation, Inc.\0"
+            VALUE "LegalCopyright", "Copyright © 2012 Free Software Foundation, Inc.\0"
             VALUE "LegalTrademarks", "\0"
             VALUE "OriginalFilename", "libgcrypt.dll\0"
             VALUE "PrivateBuild", "\0"
index 2fccb01..2989498 100644 (file)
@@ -1,5 +1,6 @@
 /* visibility.c - Wrapper for all public functions.
  * Copyright (C) 2007, 2008, 2011  Free Software Foundation, Inc.
+ * Copyright (C) 2013  g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
@@ -23,8 +24,8 @@
 #define _GCRY_INCLUDED_BY_VISIBILITY_C
 #include "g10lib.h"
 #include "cipher-proto.h"
-
-
+#include "context.h"
+#include "mpi.h"
 
 const char *
 gcry_strerror (gcry_error_t err)
@@ -75,7 +76,7 @@ gcry_control (enum gcry_ctl_cmds cmd, ...)
   va_list arg_ptr;
 
   va_start (arg_ptr, cmd);
-  err = _gcry_vcontrol (cmd, arg_ptr);
+  err = gpg_error (_gcry_vcontrol (cmd, arg_ptr));
   va_end(arg_ptr);
   return err;
 }
@@ -85,7 +86,7 @@ gcry_sexp_new (gcry_sexp_t *retsexp,
                const void *buffer, size_t length,
                int autodetect)
 {
-  return _gcry_sexp_new (retsexp, buffer, length, autodetect);
+  return gpg_error (_gcry_sexp_new (retsexp, buffer, length, autodetect));
 }
 
 gcry_error_t
@@ -93,35 +94,35 @@ gcry_sexp_create (gcry_sexp_t *retsexp,
                   void *buffer, size_t length,
                   int autodetect, void (*freefnc) (void *))
 {
-  return _gcry_sexp_create (retsexp, buffer, length,
-                            autodetect, freefnc);
+  return gpg_error (_gcry_sexp_create (retsexp, buffer, length,
+                                       autodetect, freefnc));
 }
 
 gcry_error_t
 gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
                  const char *buffer, size_t length)
 {
-  return _gcry_sexp_sscan (retsexp, erroff, buffer, length);
+  return gpg_error (_gcry_sexp_sscan (retsexp, erroff, buffer, length));
 }
 
 gcry_error_t
 gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff,
                  const char *format, ...)
 {
-  gcry_error_t err;
+  gcry_err_code_t rc;
   va_list arg_ptr;
 
   va_start (arg_ptr, format);
-  err = _gcry_sexp_vbuild (retsexp, erroff, format, arg_ptr);
+  rc = _gcry_sexp_vbuild (retsexp, erroff, format, arg_ptr);
   va_end (arg_ptr);
-  return err;
+  return gpg_error (rc);
 }
 
 gcry_error_t
 gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
                        const char *format, void **arg_list)
 {
-  return _gcry_sexp_build_array (retsexp, erroff, format, arg_list);
+  return gpg_error (_gcry_sexp_build_array (retsexp, erroff, format, arg_list));
 }
 
 void
@@ -134,7 +135,13 @@ size_t
 gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
                      size_t *erroff, gcry_error_t *errcode)
 {
-  return _gcry_sexp_canon_len (buffer, length, erroff, errcode);
+  size_t n;
+  gpg_err_code_t rc;
+
+  n = _gcry_sexp_canon_len (buffer, length, erroff, &rc);
+  if (errcode)
+    *errcode = gpg_error (rc);
+  return n;
 }
 
 size_t
@@ -225,6 +232,12 @@ gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen)
   return _gcry_sexp_nth_data (list, number, datalen);
 }
 
+void *
+gcry_sexp_nth_buffer (const gcry_sexp_t list, int number, size_t *rlength)
+{
+  return _gcry_sexp_nth_buffer (list, number, rlength);
+}
+
 char *
 gcry_sexp_nth_string (gcry_sexp_t list, int number)
 {
@@ -237,6 +250,21 @@ gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt)
   return _gcry_sexp_nth_mpi (list, number, mpifmt);
 }
 
+gpg_error_t
+gcry_sexp_extract_param (gcry_sexp_t sexp, const char *path,
+                         const char *list, ...)
+{
+  gcry_err_code_t rc;
+  va_list arg_ptr;
+
+  va_start (arg_ptr, list);
+  rc = _gcry_sexp_vextract_param (sexp, path, list, arg_ptr);
+  va_end (arg_ptr);
+  return gpg_error (rc);
+}
+
+
+\f
 gcry_mpi_t
 gcry_mpi_new (unsigned int nbits)
 {
@@ -261,6 +289,12 @@ gcry_mpi_copy (const gcry_mpi_t a)
   return _gcry_mpi_copy (a);
 }
 
+void
+gcry_mpi_snatch (gcry_mpi_t w, const gcry_mpi_t u)
+{
+  return _gcry_mpi_snatch (w, u);
+}
+
 gcry_mpi_t
 gcry_mpi_set (gcry_mpi_t w, const gcry_mpi_t u)
 {
@@ -273,6 +307,12 @@ gcry_mpi_set_ui (gcry_mpi_t w, unsigned long u)
   return _gcry_mpi_set_ui (w, u);
 }
 
+gcry_error_t
+gcry_mpi_get_ui (gcry_mpi_t w, unsigned long *u)
+{
+  return gpg_error (_gcry_mpi_get_ui (w, u));
+}
+
 void
 gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b)
 {
@@ -280,6 +320,24 @@ gcry_mpi_swap (gcry_mpi_t a, gcry_mpi_t b)
 }
 
 int
+gcry_mpi_is_neg (gcry_mpi_t a)
+{
+  return _gcry_mpi_is_neg (a);
+}
+
+void
+gcry_mpi_neg (gcry_mpi_t w, gcry_mpi_t u)
+{
+  _gcry_mpi_neg (w, u);
+}
+
+void
+gcry_mpi_abs (gcry_mpi_t w)
+{
+  _gcry_mpi_abs (w);
+}
+
+int
 gcry_mpi_cmp (const gcry_mpi_t u, const gcry_mpi_t v)
 {
   return _gcry_mpi_cmp (u, v);
@@ -296,7 +354,7 @@ gcry_mpi_scan (gcry_mpi_t *ret_mpi, enum gcry_mpi_format format,
                const void *buffer, size_t buflen,
                size_t *nscanned)
 {
-  return _gcry_mpi_scan (ret_mpi, format, buffer, buflen, nscanned);
+  return gpg_error (_gcry_mpi_scan (ret_mpi, format, buffer, buflen, nscanned));
 }
 
 gcry_error_t
@@ -305,7 +363,7 @@ gcry_mpi_print (enum gcry_mpi_format format,
                 size_t *nwritten,
                 const gcry_mpi_t a)
 {
-  return _gcry_mpi_print (format, buffer, buflen, nwritten, a);
+  return gpg_error (_gcry_mpi_print (format, buffer, buflen, nwritten, a));
 }
 
 gcry_error_t
@@ -313,13 +371,13 @@ gcry_mpi_aprint (enum gcry_mpi_format format,
                  unsigned char **buffer, size_t *nwritten,
                  const gcry_mpi_t a)
 {
-  return _gcry_mpi_aprint (format, buffer, nwritten, a);
+  return gpg_error (_gcry_mpi_aprint (format, buffer, nwritten, a));
 }
 
 void
 gcry_mpi_dump (const gcry_mpi_t a)
 {
-  _gcry_mpi_dump (a);
+  _gcry_log_printmpi (NULL, a);
 }
 
 void
@@ -414,6 +472,114 @@ gcry_mpi_invm (gcry_mpi_t x, gcry_mpi_t a, gcry_mpi_t m)
   return _gcry_mpi_invm (x, a, m);
 }
 
+gcry_mpi_point_t
+gcry_mpi_point_new (unsigned int nbits)
+{
+  return _gcry_mpi_point_new (nbits);
+}
+
+void
+gcry_mpi_point_release (gcry_mpi_point_t point)
+{
+  _gcry_mpi_point_release (point);
+}
+
+void
+gcry_mpi_point_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+                    gcry_mpi_point_t point)
+{
+  _gcry_mpi_point_get (x, y, z, point);
+}
+
+void
+gcry_mpi_point_snatch_get (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t z,
+                           gcry_mpi_point_t point)
+{
+  _gcry_mpi_point_snatch_get (x, y, z, 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)
+{
+  return _gcry_mpi_point_set (point, x, y, 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)
+{
+  return _gcry_mpi_point_snatch_set (point, x, y, z);
+}
+
+gpg_error_t
+gcry_mpi_ec_new (gcry_ctx_t *r_ctx,
+                 gcry_sexp_t keyparam, const char *curvename)
+{
+  return gpg_error (_gcry_mpi_ec_new (r_ctx, keyparam, curvename));
+}
+
+gcry_mpi_t
+gcry_mpi_ec_get_mpi (const char *name, gcry_ctx_t ctx, int copy)
+{
+  return _gcry_mpi_ec_get_mpi (name, ctx, copy);
+}
+
+gcry_mpi_point_t
+gcry_mpi_ec_get_point (const char *name, gcry_ctx_t ctx, int copy)
+{
+  return _gcry_mpi_ec_get_point (name, ctx, copy);
+}
+
+gpg_error_t
+gcry_mpi_ec_set_mpi (const char *name, gcry_mpi_t newvalue, gcry_ctx_t ctx)
+{
+  return gpg_error (_gcry_mpi_ec_set_mpi (name, newvalue, ctx));
+}
+
+gpg_error_t
+gcry_mpi_ec_set_point (const char *name, gcry_mpi_point_t newvalue,
+                        gcry_ctx_t ctx)
+{
+  return gpg_error (_gcry_mpi_ec_set_point (name, newvalue, ctx));
+}
+
+int
+gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_point_t point,
+                        gcry_ctx_t ctx)
+{
+  return _gcry_mpi_ec_get_affine (x, y, point,
+                                  _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC));
+}
+
+void
+gcry_mpi_ec_dup (gcry_mpi_point_t w, gcry_mpi_point_t u, gcry_ctx_t ctx)
+{
+  _gcry_mpi_ec_dup_point (w, u, _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC));
+}
+
+void
+gcry_mpi_ec_add (gcry_mpi_point_t w,
+                 gcry_mpi_point_t u, gcry_mpi_point_t v, gcry_ctx_t ctx)
+{
+  _gcry_mpi_ec_add_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)
+{
+  _gcry_mpi_ec_mul_point (w, n, u,
+                          _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC));
+}
+
+int
+gcry_mpi_ec_curve_point (gcry_mpi_point_t point, gcry_ctx_t ctx)
+{
+  return _gcry_mpi_ec_curve_point
+    (point, _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC));
+}
 
 unsigned int
 gcry_mpi_get_nbits (gcry_mpi_t a)
@@ -469,6 +635,12 @@ gcry_mpi_set_opaque (gcry_mpi_t a, void *p, unsigned int nbits)
   return _gcry_mpi_set_opaque (a, p, nbits);
 }
 
+gcry_mpi_t
+gcry_mpi_set_opaque_copy (gcry_mpi_t a, const void *p, unsigned int nbits)
+{
+  return _gcry_mpi_set_opaque_copy (a, p, nbits);
+}
+
 void *
 gcry_mpi_get_opaque (gcry_mpi_t a, unsigned int *nbits)
 {
@@ -493,6 +665,20 @@ gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag)
   return _gcry_mpi_get_flag (a, flag);
 }
 
+gcry_mpi_t
+_gcry_mpi_get_const (int no)
+{
+  switch (no)
+    {
+    case 1: return _gcry_mpi_const (MPI_C_ONE);
+    case 2: return _gcry_mpi_const (MPI_C_TWO);
+    case 3: return _gcry_mpi_const (MPI_C_THREE);
+    case 4: return _gcry_mpi_const (MPI_C_FOUR);
+    case 8: return _gcry_mpi_const (MPI_C_EIGHT);
+    default: log_bug("unsupported GCRYMPI_CONST_ macro used\n");
+    }
+}
+
 gcry_error_t
 gcry_cipher_open (gcry_cipher_hd_t *handle,
                   int algo, int mode, unsigned int flags)
@@ -503,7 +689,7 @@ gcry_cipher_open (gcry_cipher_hd_t *handle,
       return gpg_error (fips_not_operational ());
     }
 
-  return _gcry_cipher_open (handle, algo, mode, flags);
+  return gpg_error (_gcry_cipher_open (handle, algo, mode, flags));
 }
 
 void
@@ -518,7 +704,7 @@ gcry_cipher_setkey (gcry_cipher_hd_t hd, const void *key, size_t keylen)
   if (!fips_is_operational ())
     return gpg_error (fips_not_operational ());
 
-  return _gcry_cipher_setkey (hd, key, keylen);
+  return gcry_error (_gcry_cipher_setkey (hd, key, keylen));
 }
 
 gcry_error_t
@@ -527,7 +713,7 @@ gcry_cipher_setiv (gcry_cipher_hd_t hd, const void *iv, size_t ivlen)
   if (!fips_is_operational ())
     return gpg_error (fips_not_operational ());
 
-  return _gcry_cipher_setiv (hd, iv, ivlen);
+  return gcry_error (_gcry_cipher_setiv (hd, iv, ivlen));
 }
 
 gpg_error_t
@@ -536,7 +722,34 @@ gcry_cipher_setctr (gcry_cipher_hd_t hd, const void *ctr, size_t ctrlen)
   if (!fips_is_operational ())
     return gpg_error (fips_not_operational ());
 
-  return _gcry_cipher_setctr (hd, ctr, ctrlen);
+  return gcry_error (_gcry_cipher_setctr (hd, ctr, ctrlen));
+}
+
+gcry_error_t
+gcry_cipher_authenticate (gcry_cipher_hd_t hd, const void *abuf, size_t abuflen)
+{
+  if (!fips_is_operational ())
+    return gpg_error (fips_not_operational ());
+
+  return gpg_error (_gcry_cipher_authenticate (hd, abuf, abuflen));
+}
+
+gcry_error_t
+gcry_cipher_gettag (gcry_cipher_hd_t hd, void *outtag, size_t taglen)
+{
+  if (!fips_is_operational ())
+    return gpg_error (fips_not_operational ());
+
+  return gpg_error (_gcry_cipher_gettag (hd, outtag, taglen));
+}
+
+gcry_error_t
+gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag, size_t taglen)
+{
+  if (!fips_is_operational ())
+    return gpg_error (fips_not_operational ());
+
+  return gpg_error (_gcry_cipher_checktag (hd, intag, taglen));
 }
 
 
@@ -546,13 +759,13 @@ gcry_cipher_ctl (gcry_cipher_hd_t h, int cmd, void *buffer, size_t buflen)
   if (!fips_is_operational ())
     return gpg_error (fips_not_operational ());
 
-  return _gcry_cipher_ctl (h, cmd, buffer, buflen);
+  return gpg_error (_gcry_cipher_ctl (h, cmd, buffer, buflen));
 }
 
 gcry_error_t
 gcry_cipher_info (gcry_cipher_hd_t h, int what, void *buffer, size_t *nbytes)
 {
-  return _gcry_cipher_info (h, what, buffer, nbytes);
+  return gpg_error (_gcry_cipher_info (h, what, buffer, nbytes));
 }
 
 gcry_error_t
@@ -561,7 +774,7 @@ gcry_cipher_algo_info (int algo, int what, void *buffer, size_t *nbytes)
   if (!fips_is_operational ())
     return gpg_error (fips_not_operational ());
 
-  return _gcry_cipher_algo_info (algo, what, buffer, nbytes);
+  return gpg_error (_gcry_cipher_algo_info (algo, what, buffer, nbytes));
 }
 
 const char *
@@ -595,7 +808,7 @@ gcry_cipher_encrypt (gcry_cipher_hd_t h,
       return gpg_error (fips_not_operational ());
     }
 
-  return _gcry_cipher_encrypt (h, out, outsize, in, inlen);
+  return gpg_error (_gcry_cipher_encrypt (h, out, outsize, in, inlen));
 }
 
 gcry_error_t
@@ -606,7 +819,7 @@ gcry_cipher_decrypt (gcry_cipher_hd_t h,
   if (!fips_is_operational ())
     return gpg_error (fips_not_operational ());
 
-  return _gcry_cipher_decrypt (h, out, outsize, in, inlen);
+  return gpg_error (_gcry_cipher_decrypt (h, out, outsize, in, inlen));
 }
 
 size_t
@@ -622,9 +835,109 @@ gcry_cipher_get_algo_blklen (int algo)
 }
 
 gcry_error_t
-gcry_cipher_list (int *list, int *list_length)
+gcry_mac_algo_info (int algo, int what, void *buffer, size_t *nbytes)
+{
+  if (!fips_is_operational ())
+    return gpg_error (fips_not_operational ());
+
+  return gpg_error (_gcry_mac_algo_info (algo, what, buffer, nbytes));
+}
+
+const char *
+gcry_mac_algo_name (int algorithm)
+{
+  return _gcry_mac_algo_name (algorithm);
+}
+
+int
+gcry_mac_map_name (const char *string)
+{
+  return _gcry_mac_map_name (string);
+}
+
+unsigned int
+gcry_mac_get_algo_maclen (int algo)
 {
-  return _gcry_cipher_list (list, list_length);
+  return _gcry_mac_get_algo_maclen (algo);
+}
+
+unsigned int
+gcry_mac_get_algo_keylen (int algo)
+{
+  return _gcry_mac_get_algo_keylen (algo);
+}
+
+gcry_error_t
+gcry_mac_open (gcry_mac_hd_t *handle, int algo, unsigned int flags,
+              gcry_ctx_t ctx)
+{
+  if (!fips_is_operational ())
+    {
+      *handle = NULL;
+      return gpg_error (fips_not_operational ());
+    }
+
+  return gpg_error (_gcry_mac_open (handle, algo, flags, ctx));
+}
+
+void
+gcry_mac_close (gcry_mac_hd_t hd)
+{
+  _gcry_mac_close (hd);
+}
+
+gcry_error_t
+gcry_mac_setkey (gcry_mac_hd_t hd, const void *key, size_t keylen)
+{
+  if (!fips_is_operational ())
+    return gpg_error (fips_not_operational ());
+
+  return gpg_error (_gcry_mac_setkey (hd, key, keylen));
+}
+
+gcry_error_t
+gcry_mac_setiv (gcry_mac_hd_t hd, const void *iv, size_t ivlen)
+{
+  if (!fips_is_operational ())
+    return gpg_error (fips_not_operational ());
+
+  return gpg_error (_gcry_mac_setiv (hd, iv, ivlen));
+}
+
+gcry_error_t
+gcry_mac_write (gcry_mac_hd_t hd, const void *buf, size_t buflen)
+{
+  if (!fips_is_operational ())
+    return gpg_error (fips_not_operational ());
+
+  return gpg_error (_gcry_mac_write (hd, buf, buflen));
+}
+
+gcry_error_t
+gcry_mac_read (gcry_mac_hd_t hd, void *outbuf, size_t *outlen)
+{
+  if (!fips_is_operational ())
+    return gpg_error (fips_not_operational ());
+
+  return gpg_error (_gcry_mac_read (hd, outbuf, outlen));
+}
+
+gcry_error_t
+gcry_mac_verify (gcry_mac_hd_t hd, const void *buf, size_t buflen)
+{
+  if (!fips_is_operational ())
+    return gpg_error (fips_not_operational ());
+
+  return gpg_error (_gcry_mac_verify (hd, buf, buflen));
+}
+
+gcry_error_t
+gcry_mac_ctl (gcry_mac_hd_t h, int cmd, void *buffer, size_t buflen)
+{
+  if (!fips_is_operational ())
+    return gpg_error (fips_not_operational ());
+
+  return gpg_error (_gcry_mac_ctl (h, cmd, buffer, buflen));
 }
 
 gcry_error_t
@@ -635,7 +948,7 @@ gcry_pk_encrypt (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t pkey)
       *result = NULL;
       return gpg_error (fips_not_operational ());
     }
-  return _gcry_pk_encrypt (result, data, pkey);
+  return gpg_error (_gcry_pk_encrypt (result, data, pkey));
 }
 
 gcry_error_t
@@ -646,7 +959,7 @@ gcry_pk_decrypt (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey)
       *result = NULL;
       return gpg_error (fips_not_operational ());
     }
-  return _gcry_pk_decrypt (result, data, skey);
+  return gpg_error (_gcry_pk_decrypt (result, data, skey));
 }
 
 gcry_error_t
@@ -657,7 +970,7 @@ gcry_pk_sign (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t skey)
       *result = NULL;
       return gpg_error (fips_not_operational ());
     }
-  return _gcry_pk_sign (result, data, skey);
+  return gpg_error (_gcry_pk_sign (result, data, skey));
 }
 
 gcry_error_t
@@ -665,7 +978,7 @@ gcry_pk_verify (gcry_sexp_t sigval, gcry_sexp_t data, gcry_sexp_t pkey)
 {
   if (!fips_is_operational ())
     return gpg_error (fips_not_operational ());
-  return _gcry_pk_verify (sigval, data, pkey);
+  return gpg_error (_gcry_pk_verify (sigval, data, pkey));
 }
 
 gcry_error_t
@@ -673,7 +986,7 @@ gcry_pk_testkey (gcry_sexp_t key)
 {
   if (!fips_is_operational ())
     return gpg_error (fips_not_operational ());
-  return _gcry_pk_testkey (key);
+  return gpg_error (_gcry_pk_testkey (key));
 }
 
 gcry_error_t
@@ -684,13 +997,13 @@ gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
       *r_key = NULL;
       return gpg_error (fips_not_operational ());
     }
-  return _gcry_pk_genkey (r_key, s_parms);
+  return gpg_error (_gcry_pk_genkey (r_key, s_parms));
 }
 
 gcry_error_t
 gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
 {
-  return _gcry_pk_ctl (cmd, buffer, buflen);
+  return gpg_error (_gcry_pk_ctl (cmd, buffer, buflen));
 }
 
 gcry_error_t
@@ -699,7 +1012,7 @@ gcry_pk_algo_info (int algo, int what, void *buffer, size_t *nbytes)
   if (!fips_is_operational ())
     return gpg_error (fips_not_operational ());
 
-  return _gcry_pk_algo_info (algo, what, buffer, nbytes);
+  return gpg_error (_gcry_pk_algo_info (algo, what, buffer, nbytes));
 }
 
 const char *
@@ -760,9 +1073,14 @@ gcry_pk_get_param (int algo, const char *name)
 }
 
 gcry_error_t
-gcry_pk_list (int *list, int *list_length)
+gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp, int mode, gcry_ctx_t ctx)
 {
-  return _gcry_pk_list (list, list_length);
+  if (!fips_is_operational ())
+    {
+      *r_sexp = NULL;
+      return gpg_error (fips_not_operational ());
+    }
+  return gpg_error (_gcry_pubkey_get_sexp (r_sexp, mode, ctx));
 }
 
 gcry_error_t
@@ -774,7 +1092,7 @@ gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
       return gpg_error (fips_not_operational ());
     }
 
-  return _gcry_md_open (h, algo, flags);
+  return gpg_error (_gcry_md_open (h, algo, flags));
 }
 
 void
@@ -788,7 +1106,7 @@ gcry_md_enable (gcry_md_hd_t hd, int algo)
 {
   if (!fips_is_operational ())
     return gpg_error (fips_not_operational ());
-  return _gcry_md_enable (hd, algo);
+  return gpg_error (_gcry_md_enable (hd, algo));
 }
 
 gcry_error_t
@@ -799,7 +1117,7 @@ gcry_md_copy (gcry_md_hd_t *bhd, gcry_md_hd_t ahd)
       *bhd = NULL;
       return gpg_error (fips_not_operational ());
     }
-  return _gcry_md_copy (bhd, ahd);
+  return gpg_error (_gcry_md_copy (bhd, ahd));
 }
 
 void
@@ -813,7 +1131,7 @@ gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
 {
   if (!fips_is_operational ())
     return gpg_error (fips_not_operational ());
-  return _gcry_md_ctl (hd, cmd, buffer, buflen);
+  return gpg_error (_gcry_md_ctl (hd, cmd, buffer, buflen));
 }
 
 void
@@ -845,6 +1163,18 @@ gcry_md_hash_buffer (int algo, void *digest,
   _gcry_md_hash_buffer (algo, digest, buffer, length);
 }
 
+gpg_error_t
+gcry_md_hash_buffers (int algo, unsigned int flags, void *digest,
+                      const gcry_buffer_t *iov, int iovcnt)
+{
+  if (!fips_is_operational ())
+    {
+      (void)fips_not_operational ();
+      fips_signal_error ("called in non-operational state");
+    }
+  return gpg_error (_gcry_md_hash_buffers (algo, flags, digest, iov, iovcnt));
+}
+
 int
 gcry_md_get_algo (gcry_md_hd_t hd)
 {
@@ -887,13 +1217,13 @@ gcry_md_info (gcry_md_hd_t h, int what, void *buffer, size_t *nbytes)
   if (!fips_is_operational ())
     return gpg_error (fips_not_operational ());
 
-  return _gcry_md_info (h, what, buffer, nbytes);
+  return gpg_error (_gcry_md_info (h, what, buffer, nbytes));
 }
 
 gcry_error_t
 gcry_md_algo_info (int algo, int what, void *buffer, size_t *nbytes)
 {
-  return _gcry_md_algo_info (algo, what, buffer, nbytes);
+  return gpg_error (_gcry_md_algo_info (algo, what, buffer, nbytes));
 }
 
 const char *
@@ -913,7 +1243,7 @@ gcry_md_setkey (gcry_md_hd_t hd, const void *key, size_t keylen)
 {
   if (!fips_is_operational ())
     return gpg_error (fips_not_operational ());
-  return _gcry_md_setkey (hd, key, keylen);
+  return gpg_error (_gcry_md_setkey (hd, key, keylen));
 }
 
 void
@@ -922,294 +1252,6 @@ gcry_md_debug (gcry_md_hd_t hd, const char *suffix)
   _gcry_md_debug (hd, suffix);
 }
 
-gcry_error_t
-gcry_md_list (int *list, int *list_length)
-{
-  return _gcry_md_list (list, list_length);
-}
-
-gcry_error_t
-gcry_ac_data_new (gcry_ac_data_t *data)
-{
-  return _gcry_ac_data_new (data);
-}
-
-void
-gcry_ac_data_destroy (gcry_ac_data_t data)
-{
-  _gcry_ac_data_destroy (data);
-}
-
-gcry_error_t
-gcry_ac_data_copy (gcry_ac_data_t *data_cp, gcry_ac_data_t data)
-{
-  return _gcry_ac_data_copy (data_cp, data);
-}
-
-unsigned int
-gcry_ac_data_length (gcry_ac_data_t data)
-{
-  return _gcry_ac_data_length (data);
-}
-
-void
-gcry_ac_data_clear (gcry_ac_data_t data)
-{
-  _gcry_ac_data_clear (data);
-}
-
-gcry_error_t
-gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
-                  const char *name, gcry_mpi_t mpi)
-{
-  return _gcry_ac_data_set (data, flags, name, mpi);
-}
-
-gcry_error_t
-gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
-                       const char *name, gcry_mpi_t *mpi)
-{
-  return _gcry_ac_data_get_name (data, flags, name, mpi);
-}
-
-gcry_error_t
-gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
-                        unsigned int idx, const char **name, gcry_mpi_t *mpi)
-{
-  return _gcry_ac_data_get_index (data, flags, idx, name, mpi);
-}
-
-gcry_error_t
-gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
-                      const char **identifiers)
-{
-  return _gcry_ac_data_to_sexp (data, sexp, identifiers);
-}
-
-gcry_error_t
-gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp,
-                        const char **identifiers)
-{
-  return _gcry_ac_data_from_sexp (data, sexp, identifiers);
-}
-
-void
-gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
-                 gcry_ac_io_type_t type, ...)
-{
-  va_list arg_ptr;
-
-  va_start (arg_ptr, type);
-  _gcry_ac_io_init_va (ac_io, mode, type, arg_ptr);
-  va_end (arg_ptr);
-}
-
-void
-gcry_ac_io_init_va (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
-                    gcry_ac_io_type_t type, va_list ap)
-{
-  _gcry_ac_io_init_va (ac_io, mode, type, ap);
-}
-
-gcry_error_t
-gcry_ac_open (gcry_ac_handle_t *handle,
-              gcry_ac_id_t algorithm, unsigned int flags)
-{
-  return _gcry_ac_open (handle, algorithm, flags);
-}
-
-void
-gcry_ac_close (gcry_ac_handle_t handle)
-{
-  _gcry_ac_close (handle);
-}
-
-gcry_error_t
-gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
-                  gcry_ac_key_type_t type, gcry_ac_data_t data)
-{
-  return _gcry_ac_key_init (key, handle, type, data);
-}
-
-gcry_error_t
-gcry_ac_key_pair_generate (gcry_ac_handle_t handle,
-                           unsigned int nbits, void *spec,
-                           gcry_ac_key_pair_t *key_pair,
-                           gcry_mpi_t **miscdata)
-{
-  return _gcry_ac_key_pair_generate ( handle, nbits, spec, key_pair, miscdata);
-}
-
-gcry_ac_key_t
-gcry_ac_key_pair_extract (gcry_ac_key_pair_t keypair, gcry_ac_key_type_t which)
-{
-  return _gcry_ac_key_pair_extract (keypair, which);
-}
-
-gcry_ac_data_t
-gcry_ac_key_data_get (gcry_ac_key_t key)
-{
-  return _gcry_ac_key_data_get (key);
-}
-
-gcry_error_t
-gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
-{
-  return _gcry_ac_key_test (handle, key);
-}
-
-gcry_error_t
-gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
-                       gcry_ac_key_t key, unsigned int *nbits)
-{
-  return _gcry_ac_key_get_nbits (handle, key, nbits);
-}
-
-gcry_error_t
-gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key,
-                      unsigned char *key_grip)
-{
-  return _gcry_ac_key_get_grip (handle, key, key_grip);
-}
-
-void
-gcry_ac_key_destroy (gcry_ac_key_t key)
-{
-  _gcry_ac_key_destroy (key);
-}
-
-void
-gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
-{
-  _gcry_ac_key_pair_destroy (key_pair);
-}
-
-gcry_error_t
-gcry_ac_data_encode (gcry_ac_em_t method, unsigned int flags, void *options,
-                     gcry_ac_io_t *io_read, gcry_ac_io_t *io_write)
-{
-  return _gcry_ac_data_encode (method, flags, options, io_read, io_write);
-}
-
-gcry_error_t
-gcry_ac_data_decode (gcry_ac_em_t method, unsigned int flags, void *options,
-                     gcry_ac_io_t *io_read, gcry_ac_io_t *io_write)
-{
-  return _gcry_ac_data_decode (method, flags, options, io_read,  io_write);
-}
-
-gcry_error_t
-gcry_ac_data_encrypt (gcry_ac_handle_t handle,
-                      unsigned int flags,
-                      gcry_ac_key_t key,
-                      gcry_mpi_t data_plain,
-                      gcry_ac_data_t *data_encrypted)
-{
-  return _gcry_ac_data_encrypt (handle, flags, key,
-                                data_plain, data_encrypted);
-}
-
-gcry_error_t
-gcry_ac_data_decrypt (gcry_ac_handle_t handle,
-                      unsigned int flags,
-                      gcry_ac_key_t key,
-                      gcry_mpi_t *data_plain,
-                      gcry_ac_data_t data_encrypted)
-{
-  return _gcry_ac_data_decrypt (handle, flags, key,
-                                data_plain, data_encrypted);
-}
-
-gcry_error_t
-gcry_ac_data_sign (gcry_ac_handle_t handle,
-                   gcry_ac_key_t key,
-                   gcry_mpi_t data,
-                   gcry_ac_data_t *data_signature)
-{
-  return _gcry_ac_data_sign (handle, key, data, data_signature);
-}
-
-gcry_error_t
-gcry_ac_data_verify (gcry_ac_handle_t handle,
-                     gcry_ac_key_t key,
-                     gcry_mpi_t data,
-                     gcry_ac_data_t data_signature)
-{
-  return _gcry_ac_data_verify (handle, key, data, data_signature);
-}
-
-gcry_error_t
-gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
-                             gcry_ac_scheme_t scheme,
-                             unsigned int flags, void *opts,
-                             gcry_ac_key_t key,
-                             gcry_ac_io_t *io_message,
-                             gcry_ac_io_t *io_cipher)
-{
-  return _gcry_ac_data_encrypt_scheme (handle, scheme, flags, opts, key,
-                                       io_message, io_cipher);
-}
-
-gcry_error_t
-gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
-                             gcry_ac_scheme_t scheme,
-                             unsigned int flags, void *opts,
-                             gcry_ac_key_t key,
-                             gcry_ac_io_t *io_cipher,
-                             gcry_ac_io_t *io_message)
-{
-  return _gcry_ac_data_decrypt_scheme (handle, scheme, flags, opts, key,
-                                       io_cipher, io_message);
-}
-
-gcry_error_t
-gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
-                          gcry_ac_scheme_t scheme,
-                          unsigned int flags, void *opts,
-                          gcry_ac_key_t key,
-                          gcry_ac_io_t *io_message,
-                          gcry_ac_io_t *io_signature)
-{
-  return _gcry_ac_data_sign_scheme (handle, scheme, flags, opts, key,
-                                    io_message, io_signature);
-}
-
-gcry_error_t
-gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
-                            gcry_ac_scheme_t scheme,
-                            unsigned int flags, void *opts,
-                            gcry_ac_key_t key,
-                            gcry_ac_io_t *io_message,
-                            gcry_ac_io_t *io_signature)
-{
-  return _gcry_ac_data_verify_scheme (handle, scheme, flags, opts, key,
-                                      io_message, io_signature);
-}
-
-gcry_error_t
-gcry_ac_id_to_name (gcry_ac_id_t algorithm, const char **name)
-{
-  /* This function is deprecated.  We implement it in terms of the
-     suggested replacement.  */
-  const char *tmp = _gcry_pk_algo_name (algorithm);
-  if (!*tmp)
-    return gcry_error (GPG_ERR_PUBKEY_ALGO);
-  *name = tmp;
-  return 0;
-}
-
-gcry_error_t
-gcry_ac_name_to_id (const char *name, gcry_ac_id_t *algorithm)
-{
-  /* This function is deprecated.  We implement it in terms of the
-     suggested replacement.  */
-  int algo = _gcry_pk_map_name (name);
-  if (!algo)
-    return gcry_error (GPG_ERR_PUBKEY_ALGO);
-  *algorithm = algo;
-  return 0;
-}
-
 gpg_error_t
 gcry_kdf_derive (const void *passphrase, size_t passphraselen,
                  int algo, int hashalgo,
@@ -1217,8 +1259,9 @@ gcry_kdf_derive (const void *passphrase, size_t passphraselen,
                  unsigned long iterations,
                  size_t keysize, void *keybuffer)
 {
-  return _gcry_kdf_derive (passphrase, passphraselen, algo, hashalgo,
-                           salt, saltlen, iterations, keysize, keybuffer);
+  return gpg_error (_gcry_kdf_derive (passphrase, passphraselen, algo, hashalgo,
+                                      salt, saltlen, iterations,
+                                      keysize, keybuffer));
 }
 
 void
@@ -1238,7 +1281,7 @@ gcry_random_add_bytes (const void *buffer, size_t length, int quality)
 {
   if (!fips_is_operational ())
     return gpg_error (fips_not_operational ());
-  return _gcry_random_add_bytes (buffer, length, quality);
+  return gpg_error (_gcry_random_add_bytes (buffer, length, quality));
 }
 
 void *
@@ -1296,8 +1339,9 @@ gcry_prime_generate (gcry_mpi_t *prime,
                      gcry_random_level_t random_level,
                      unsigned int flags)
 {
-  return _gcry_prime_generate (prime, prime_bits, factor_bits, factors,
-                               cb_func, cb_arg, random_level, flags);
+  return gpg_error (_gcry_prime_generate (prime, prime_bits, factor_bits,
+                                          factors, cb_func, cb_arg,
+                                          random_level, flags));
 }
 
 gcry_error_t
@@ -1305,7 +1349,7 @@ gcry_prime_group_generator (gcry_mpi_t *r_g,
                             gcry_mpi_t prime, gcry_mpi_t *factors,
                             gcry_mpi_t start_g)
 {
-  return _gcry_prime_group_generator (r_g, prime, factors, start_g);
+  return gpg_error (_gcry_prime_group_generator (r_g, prime, factors, start_g));
 }
 
 void
@@ -1317,7 +1361,49 @@ gcry_prime_release_factors (gcry_mpi_t *factors)
 gcry_error_t
 gcry_prime_check (gcry_mpi_t x, unsigned int flags)
 {
-  return _gcry_prime_check (x, flags);
+  return gpg_error (_gcry_prime_check (x, flags));
+}
+
+void
+gcry_ctx_release (gcry_ctx_t ctx)
+{
+  _gcry_ctx_release (ctx);
+}
+
+void
+gcry_log_debug (const char *fmt, ...)
+{
+  va_list arg_ptr ;
+
+  va_start( arg_ptr, fmt ) ;
+  _gcry_logv (GCRY_LOG_DEBUG, fmt, arg_ptr);
+  va_end (arg_ptr);
+}
+
+void
+gcry_log_debughex (const char *text, const void *buffer, size_t length)
+{
+  _gcry_log_printhex (text, buffer, length);
+}
+
+void
+gcry_log_debugmpi (const char *text, gcry_mpi_t mpi)
+{
+  _gcry_log_printmpi (text, mpi);
+}
+
+void
+gcry_log_debugpnt (const char *text, mpi_point_t point, gcry_ctx_t ctx)
+{
+  mpi_ec_t ec = ctx? _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC) : NULL;
+
+  _gcry_mpi_point_log (text, point, ec);
+}
+
+void
+gcry_log_debugsxp (const char *text, gcry_sexp_t sexp)
+{
+  _gcry_log_printsxp (text, sexp);
 }
 
 void
@@ -1444,43 +1530,3 @@ gcry_is_secure (const void *a)
 {
   return _gcry_is_secure (a);
 }
-
-
-gcry_error_t
-gcry_cipher_register (gcry_cipher_spec_t *cipher, int *algorithm_id,
-                      gcry_module_t *module)
-{
-  return _gcry_cipher_register (cipher, NULL, algorithm_id, module);
-}
-
-void
-gcry_cipher_unregister (gcry_module_t module)
-{
-  _gcry_cipher_unregister (module);
-}
-
-gcry_error_t
-gcry_pk_register (gcry_pk_spec_t *pubkey, unsigned int *algorithm_id,
-                  gcry_module_t *module)
-{
-  return _gcry_pk_register (pubkey, NULL, algorithm_id, module);
-}
-
-void
-gcry_pk_unregister (gcry_module_t module)
-{
-  _gcry_pk_unregister (module);
-}
-
-gcry_error_t
-gcry_md_register (gcry_md_spec_t *digest, unsigned int *algorithm_id,
-                  gcry_module_t *module)
-{
-  return _gcry_md_register (digest, NULL, algorithm_id, module);
-}
-
-void
-gcry_md_unregister (gcry_module_t module)
-{
-  _gcry_md_unregister (module);
-}
index 3c1e8aa..4127a43 100644 (file)
 
 /* Redefine all public symbols with an underscore unless we already
    use the underscore prefixed version internally.  */
-#define gcry_check_version          _gcry_check_version
-#define gcry_control                _gcry_control
-
-#define gcry_set_allocation_handler _gcry_set_allocation_handler
-#define gcry_set_fatalerror_handler _gcry_set_fatalerror_handler
-#define gcry_set_gettext_handler    _gcry_set_gettext_handler
-#define gcry_set_log_handler        _gcry_set_log_handler
-#define gcry_set_outofcore_handler  _gcry_set_outofcore_handler
-#define gcry_set_progress_handler   _gcry_set_progress_handler
-#define gcry_err_code_from_errno    _gcry_err_code_from_errno
-#define gcry_err_code_to_errno      _gcry_err_code_to_errno
-#define gcry_err_make_from_errno    _gcry_err_make_from_errno
-#define gcry_error_from_errno       _gcry_error_from_errno
-#define gcry_strerror               _gcry_strerror
-#define gcry_strsource              _gcry_strsource
-
-#define gcry_free                   _gcry_free
-#define gcry_malloc                 _gcry_malloc
-#define gcry_malloc_secure          _gcry_malloc_secure
-#define gcry_calloc                 _gcry_calloc
-#define gcry_calloc_secure          _gcry_calloc_secure
-#define gcry_realloc                _gcry_realloc
-#define gcry_strdup                 _gcry_strdup
-#define gcry_is_secure              _gcry_is_secure
-#define gcry_xcalloc                _gcry_xcalloc
-#define gcry_xcalloc_secure         _gcry_xcalloc_secure
-#define gcry_xmalloc                _gcry_xmalloc
-#define gcry_xmalloc_secure         _gcry_xmalloc_secure
-#define gcry_xrealloc               _gcry_xrealloc
-#define gcry_xstrdup                _gcry_xstrdup
-
-#define gcry_md_algo_info           _gcry_md_algo_info
-#define gcry_md_algo_name           _gcry_md_algo_name
-#define gcry_md_close               _gcry_md_close
-#define gcry_md_copy                _gcry_md_copy
-#define gcry_md_ctl                 _gcry_md_ctl
-#define gcry_md_enable              _gcry_md_enable
-#define gcry_md_get                 _gcry_md_get
-#define gcry_md_get_algo            _gcry_md_get_algo
-#define gcry_md_get_algo_dlen       _gcry_md_get_algo_dlen
-#define gcry_md_hash_buffer         _gcry_md_hash_buffer
-#define gcry_md_info                _gcry_md_info
-#define gcry_md_is_enabled          _gcry_md_is_enabled
-#define gcry_md_is_secure           _gcry_md_is_secure
-#define gcry_md_list                _gcry_md_list
-#define gcry_md_map_name            _gcry_md_map_name
-#define gcry_md_open                _gcry_md_open
-#define gcry_md_read                _gcry_md_read
-/* gcry_md_register and _gcry_md_register differ.  */
-#define gcry_md_unregister          _gcry_md_unregister
-#define gcry_md_reset               _gcry_md_reset
-#define gcry_md_setkey              _gcry_md_setkey
-#define gcry_md_write               _gcry_md_write
-#define gcry_md_debug               _gcry_md_debug
-
-#define gcry_cipher_algo_info       _gcry_cipher_algo_info
-#define gcry_cipher_algo_name       _gcry_cipher_algo_name
-#define gcry_cipher_close           _gcry_cipher_close
-#define gcry_cipher_setkey          _gcry_cipher_setkey
-#define gcry_cipher_setiv           _gcry_cipher_setiv
-#define gcry_cipher_setctr          _gcry_cipher_setctr
-#define gcry_cipher_ctl             _gcry_cipher_ctl
-#define gcry_cipher_decrypt         _gcry_cipher_decrypt
-#define gcry_cipher_encrypt         _gcry_cipher_encrypt
-#define gcry_cipher_get_algo_blklen _gcry_cipher_get_algo_blklen
-#define gcry_cipher_get_algo_keylen _gcry_cipher_get_algo_keylen
-#define gcry_cipher_info            _gcry_cipher_info
-#define gcry_cipher_list            _gcry_cipher_list
-#define gcry_cipher_map_name        _gcry_cipher_map_name
-#define gcry_cipher_mode_from_oid   _gcry_cipher_mode_from_oid
-#define gcry_cipher_open            _gcry_cipher_open
-/* gcry_cipher_register and  _gcry_cipher_register differ.  */
-#define gcry_cipher_unregister      _gcry_cipher_unregister
-
-#define gcry_pk_algo_info           _gcry_pk_algo_info
-#define gcry_pk_algo_name           _gcry_pk_algo_name
-#define gcry_pk_ctl                 _gcry_pk_ctl
-#define gcry_pk_decrypt             _gcry_pk_decrypt
-#define gcry_pk_encrypt             _gcry_pk_encrypt
-#define gcry_pk_genkey              _gcry_pk_genkey
-#define gcry_pk_get_keygrip         _gcry_pk_get_keygrip
-#define gcry_pk_get_curve           _gcry_pk_get_curve
-#define gcry_pk_get_param           _gcry_pk_get_param
-#define gcry_pk_get_nbits           _gcry_pk_get_nbits
-#define gcry_pk_list                _gcry_pk_list
-#define gcry_pk_map_name            _gcry_pk_map_name
-/* gcry_pk_register and _gcry_pk_register differ.  */
-#define gcry_pk_unregister          _gcry_pk_unregister
-#define gcry_pk_sign                _gcry_pk_sign
-#define gcry_pk_testkey             _gcry_pk_testkey
-#define gcry_pk_verify              _gcry_pk_verify
-
-#define gcry_ac_data_new            _gcry_ac_data_new
-#define gcry_ac_data_destroy        _gcry_ac_data_destroy
-#define gcry_ac_data_copy           _gcry_ac_data_copy
-#define gcry_ac_data_length         _gcry_ac_data_length
-#define gcry_ac_data_clear          _gcry_ac_data_clear
-#define gcry_ac_data_set            _gcry_ac_data_set
-#define gcry_ac_data_get_name       _gcry_ac_data_get_name
-#define gcry_ac_data_get_index      _gcry_ac_data_get_index
-#define gcry_ac_open                _gcry_ac_open
-#define gcry_ac_close               _gcry_ac_close
-#define gcry_ac_key_init            _gcry_ac_key_init
-#define gcry_ac_key_pair_generate   _gcry_ac_key_pair_generate
-#define gcry_ac_key_pair_extract    _gcry_ac_key_pair_extract
-#define gcry_ac_key_data_get        _gcry_ac_key_data_get
-#define gcry_ac_key_test            _gcry_ac_key_test
-#define gcry_ac_key_get_nbits       _gcry_ac_key_get_nbits
-#define gcry_ac_key_get_grip        _gcry_ac_key_get_grip
-#define gcry_ac_key_destroy         _gcry_ac_key_destroy
-#define gcry_ac_key_pair_destroy    _gcry_ac_key_pair_destroy
-#define gcry_ac_data_encrypt        _gcry_ac_data_encrypt
-#define gcry_ac_data_decrypt        _gcry_ac_data_decrypt
-#define gcry_ac_data_sign           _gcry_ac_data_sign
-#define gcry_ac_data_verify         _gcry_ac_data_verify
-#define gcry_ac_id_to_name          _gcry_ac_id_to_name
-#define gcry_ac_name_to_id          _gcry_ac_name_to_id
-#define gcry_ac_data_encode         _gcry_ac_data_encode
-#define gcry_ac_data_decode         _gcry_ac_data_decode
-#define gcry_ac_mpi_to_os           _gcry_ac_mpi_to_os
-#define gcry_ac_mpi_to_os_alloc     _gcry_ac_mpi_to_os_alloc
-#define gcry_ac_os_to_mpi           _gcry_ac_os_to_mpi
-#define gcry_ac_data_encrypt_scheme _gcry_ac_data_encrypt_scheme
-#define gcry_ac_data_decrypt_scheme _gcry_ac_data_decrypt_scheme
-#define gcry_ac_data_sign_scheme    _gcry_ac_data_sign_scheme
-#define gcry_ac_data_verify_scheme  _gcry_ac_data_verify_scheme
-#define gcry_ac_data_to_sexp        _gcry_ac_data_to_sexp
-#define gcry_ac_data_from_sexp      _gcry_ac_data_from_sexp
-#define gcry_ac_io_init             _gcry_ac_io_init
-#define gcry_ac_io_init_va          _gcry_ac_io_init_va
-
-#define gcry_kdf_derive             _gcry_kdf_derive
-
-#define gcry_prime_check            _gcry_prime_check
-#define gcry_prime_generate         _gcry_prime_generate
-#define gcry_prime_group_generator  _gcry_prime_group_generator
-#define gcry_prime_release_factors  _gcry_prime_release_factors
-
-#define gcry_random_add_bytes       _gcry_random_add_bytes
-#define gcry_random_bytes           _gcry_random_bytes
-#define gcry_random_bytes_secure    _gcry_random_bytes_secure
-#define gcry_randomize              _gcry_randomize
-#define gcry_create_nonce           _gcry_create_nonce
-
-#define gcry_sexp_alist             _gcry_sexp_alist
-#define gcry_sexp_append            _gcry_sexp_append
-#define gcry_sexp_build             _gcry_sexp_build
-#define gcry_sexp_build_array       _gcry_sexp_build_array
-#define gcry_sexp_cadr              _gcry_sexp_cadr
-#define gcry_sexp_canon_len         _gcry_sexp_canon_len
-#define gcry_sexp_car               _gcry_sexp_car
-#define gcry_sexp_cdr               _gcry_sexp_cdr
-#define gcry_sexp_cons              _gcry_sexp_cons
-#define gcry_sexp_create            _gcry_sexp_create
-#define gcry_sexp_dump              _gcry_sexp_dump
-#define gcry_sexp_find_token        _gcry_sexp_find_token
-#define gcry_sexp_length            _gcry_sexp_length
-#define gcry_sexp_new               _gcry_sexp_new
-#define gcry_sexp_nth               _gcry_sexp_nth
-#define gcry_sexp_nth_data          _gcry_sexp_nth_data
-#define gcry_sexp_nth_mpi           _gcry_sexp_nth_mpi
-#define gcry_sexp_prepend           _gcry_sexp_prepend
-#define gcry_sexp_release           _gcry_sexp_release
-#define gcry_sexp_sprint            _gcry_sexp_sprint
-#define gcry_sexp_sscan             _gcry_sexp_sscan
-#define gcry_sexp_vlist             _gcry_sexp_vlist
-#define gcry_sexp_nth_string        _gcry_sexp_nth_string
-
-#define gcry_mpi_add                _gcry_mpi_add
-#define gcry_mpi_add_ui             _gcry_mpi_add_ui
-#define gcry_mpi_addm               _gcry_mpi_addm
-#define gcry_mpi_aprint             _gcry_mpi_aprint
-#define gcry_mpi_clear_bit          _gcry_mpi_clear_bit
-#define gcry_mpi_clear_flag         _gcry_mpi_clear_flag
-#define gcry_mpi_clear_highbit      _gcry_mpi_clear_highbit
-#define gcry_mpi_cmp                _gcry_mpi_cmp
-#define gcry_mpi_cmp_ui             _gcry_mpi_cmp_ui
-#define gcry_mpi_copy               _gcry_mpi_copy
-#define gcry_mpi_div                _gcry_mpi_div
-#define gcry_mpi_dump               _gcry_mpi_dump
-#define gcry_mpi_gcd                _gcry_mpi_gcd
-#define gcry_mpi_get_flag           _gcry_mpi_get_flag
-#define gcry_mpi_get_nbits          _gcry_mpi_get_nbits
-#define gcry_mpi_get_opaque         _gcry_mpi_get_opaque
-#define gcry_mpi_invm               _gcry_mpi_invm
-#define gcry_mpi_mod                _gcry_mpi_mod
-#define gcry_mpi_mul                _gcry_mpi_mul
-#define gcry_mpi_mul_2exp           _gcry_mpi_mul_2exp
-#define gcry_mpi_mul_ui             _gcry_mpi_mul_ui
-#define gcry_mpi_mulm               _gcry_mpi_mulm
-#define gcry_mpi_new                _gcry_mpi_new
-#define gcry_mpi_powm               _gcry_mpi_powm
-#define gcry_mpi_print              _gcry_mpi_print
-#define gcry_mpi_randomize          _gcry_mpi_randomize
-#define gcry_mpi_release            _gcry_mpi_release
-#define gcry_mpi_rshift             _gcry_mpi_rshift
-#define gcry_mpi_lshift             _gcry_mpi_lshift
-#define gcry_mpi_scan               _gcry_mpi_scan
-#define gcry_mpi_set                _gcry_mpi_set
-#define gcry_mpi_set_bit            _gcry_mpi_set_bit
-#define gcry_mpi_set_flag           _gcry_mpi_set_flag
-#define gcry_mpi_set_highbit        _gcry_mpi_set_highbit
-#define gcry_mpi_set_opaque         _gcry_mpi_set_opaque
-#define gcry_mpi_set_ui             _gcry_mpi_set_ui
-#define gcry_mpi_snew               _gcry_mpi_snew
-#define gcry_mpi_sub                _gcry_mpi_sub
-#define gcry_mpi_sub_ui             _gcry_mpi_sub_ui
-#define gcry_mpi_subm               _gcry_mpi_subm
-#define gcry_mpi_swap               _gcry_mpi_swap
-#define gcry_mpi_test_bit           _gcry_mpi_test_bit
 
 
 /* Include the main header here so that public symbols are mapped to
   /* We need to redeclare the deprecated functions without the
      deprecated attribute.  */
 # define GCRYPT_NO_DEPRECATED
-# include "gcrypt.h"
-/* The algorithm IDs. */
-  gcry_error_t gcry_ac_data_new (gcry_ac_data_t *data);
-  void gcry_ac_data_destroy (gcry_ac_data_t data);
-  gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *data_cp,
-                                  gcry_ac_data_t data);
-  unsigned int gcry_ac_data_length (gcry_ac_data_t data);
-  void gcry_ac_data_clear (gcry_ac_data_t data);
-  gcry_error_t gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
-                                 const char *name, gcry_mpi_t mpi);
-  gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
-                                      const char *name, gcry_mpi_t *mpi);
-  gcry_error_t gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
-                                       unsigned int idx,
-                                       const char **name, gcry_mpi_t *mpi);
-  gcry_error_t gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
-                                   const char **identifiers);
-  gcry_error_t gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp,
-                                     const char **identifiers);
-  void gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
-                      gcry_ac_io_type_t type, ...);
-  void gcry_ac_io_init_va (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
-                         gcry_ac_io_type_t type, va_list ap);
-  gcry_error_t gcry_ac_open (gcry_ac_handle_t *handle,
-                             gcry_ac_id_t algorithm, unsigned int flags);
-  void gcry_ac_close (gcry_ac_handle_t handle);
-  gcry_error_t gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
-                                 gcry_ac_key_type_t type, gcry_ac_data_t data);
-  gcry_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t handle,
-                                          unsigned int nbits, void *spec,
-                                          gcry_ac_key_pair_t *key_pair,
-                                          gcry_mpi_t **misc_data);
-  gcry_ac_key_t gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair,
-                                          gcry_ac_key_type_t which);
-  gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t key);
-  gcry_error_t gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key);
-  gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
-                                      gcry_ac_key_t key, unsigned int *nbits);
-  gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key,
-                                     unsigned char *key_grip);
-  void gcry_ac_key_destroy (gcry_ac_key_t key);
-  void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair);
-  gcry_error_t gcry_ac_data_encode (gcry_ac_em_t method,
-                                  unsigned int flags, void *options,
-                                  gcry_ac_io_t *io_read,
-                                  gcry_ac_io_t *io_write);
-  gcry_error_t gcry_ac_data_decode (gcry_ac_em_t method,
-                                  unsigned int flags, void *options,
-                                  gcry_ac_io_t *io_read,
-                                  gcry_ac_io_t *io_write);
-  gcry_error_t gcry_ac_data_encrypt (gcry_ac_handle_t handle,
-                                     unsigned int flags,
-                                     gcry_ac_key_t key,
-                                     gcry_mpi_t data_plain,
-                                     gcry_ac_data_t *data_encrypted);
-  gcry_error_t gcry_ac_data_decrypt (gcry_ac_handle_t handle,
-                                     unsigned int flags,
-                                     gcry_ac_key_t key,
-                                     gcry_mpi_t *data_plain,
-                                     gcry_ac_data_t data_encrypted);
-  gcry_error_t gcry_ac_data_sign (gcry_ac_handle_t handle,
-                                  gcry_ac_key_t key,
-                                  gcry_mpi_t data,
-                                  gcry_ac_data_t *data_signature);
-  gcry_error_t gcry_ac_data_verify (gcry_ac_handle_t handle,
-                                    gcry_ac_key_t key,
-                                    gcry_mpi_t data,
-                                    gcry_ac_data_t data_signature);
-  gcry_error_t gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
-                                          gcry_ac_scheme_t scheme,
-                                          unsigned int flags, void *opts,
-                                          gcry_ac_key_t key,
-                                          gcry_ac_io_t *io_message,
-                                          gcry_ac_io_t *io_cipher);
-  gcry_error_t gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
-                                          gcry_ac_scheme_t scheme,
-                                          unsigned int flags, void *opts,
-                                          gcry_ac_key_t key,
-                                          gcry_ac_io_t *io_cipher,
-                                          gcry_ac_io_t *io_message);
-  gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
-                                       gcry_ac_scheme_t scheme,
-                                       unsigned int flags, void *opts,
-                                       gcry_ac_key_t key,
-                                       gcry_ac_io_t *io_message,
-                                       gcry_ac_io_t *io_signature);
-  gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
-                                         gcry_ac_scheme_t scheme,
-                                         unsigned int flags, void *opts,
-                                         gcry_ac_key_t key,
-                                         gcry_ac_io_t *io_message,
-                                         gcry_ac_io_t *io_signature);
-  gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t algorithm, const char **name);
-  gcry_error_t gcry_ac_name_to_id (const char *name, gcry_ac_id_t *algorithm);
+# include "gcrypt-int.h"
+  /* None in this version.  */
 #else
-# include "gcrypt.h"
+# include "gcrypt-int.h"
 #endif
 
 /* Prototypes of functions exported but not ready for use.  */
 gcry_err_code_t gcry_md_get (gcry_md_hd_t hd, int algo,
                              unsigned char *buffer, int buflen);
-void gcry_ac_mpi_to_os (gcry_mpi_t mpi, unsigned char *os, size_t os_n);
-gcry_error_t gcry_ac_mpi_to_os_alloc (gcry_mpi_t mpi, unsigned char **os,
-                                       size_t *os_n);
-void gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n);
-
 
 
 /* Our use of the ELF visibility feature works by passing
@@ -357,451 +50,454 @@ void gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n);
 
 #ifdef _GCRY_INCLUDED_BY_VISIBILITY_C
 
-/* A macro to flag a function as visible.  Note that we take the
-   definition from the mapped name.  */
+/* A macro to flag a function as visible.  */
 #ifdef GCRY_USE_VISIBILITY
-# define MARK_VISIBLE(name) \
-    extern __typeof__ (_##name) name __attribute__ ((visibility("default")));
 # define MARK_VISIBLEX(name) \
     extern __typeof__ (name) name __attribute__ ((visibility("default")));
 #else
-# define MARK_VISIBLE(name) /* */
 # define MARK_VISIBLEX(name) /* */
 #endif
 
 
-/* First undef all redefined symbols so that we set the attribute on
-   the correct version name.  */
-#undef gcry_check_version
-#undef gcry_control
-
-#undef gcry_set_allocation_handler
-#undef gcry_set_fatalerror_handler
-#undef gcry_set_gettext_handler
-#undef gcry_set_log_handler
-#undef gcry_set_outofcore_handler
-#undef gcry_set_progress_handler
-#undef gcry_err_code_from_errno
-#undef gcry_err_code_to_errno
-#undef gcry_err_make_from_errno
-#undef gcry_error_from_errno
-#undef gcry_strerror
-#undef gcry_strsource
-
-#undef gcry_free
-#undef gcry_malloc
-#undef gcry_malloc_secure
-#undef gcry_calloc
-#undef gcry_calloc_secure
-#undef gcry_realloc
-#undef gcry_strdup
-#undef gcry_is_secure
-#undef gcry_xcalloc
-#undef gcry_xcalloc_secure
-#undef gcry_xmalloc
-#undef gcry_xmalloc_secure
-#undef gcry_xrealloc
-#undef gcry_xstrdup
-
-#undef gcry_md_algo_info
-#undef gcry_md_algo_name
-#undef gcry_md_close
-#undef gcry_md_copy
-#undef gcry_md_ctl
-#undef gcry_md_enable
-#undef gcry_md_get
-#undef gcry_md_get_algo
-#undef gcry_md_get_algo_dlen
-#undef gcry_md_hash_buffer
-#undef gcry_md_info
-#undef gcry_md_is_enabled
-#undef gcry_md_is_secure
-#undef gcry_md_list
-#undef gcry_md_map_name
-#undef gcry_md_open
-#undef gcry_md_read
-/* gcry_md_register is not anymore a macro.  */
-#undef gcry_md_unregister
-#undef gcry_md_reset
-#undef gcry_md_setkey
-#undef gcry_md_write
-#undef gcry_md_debug
-
-#undef gcry_cipher_algo_info
-#undef gcry_cipher_algo_name
-#undef gcry_cipher_close
-#undef gcry_cipher_setkey
-#undef gcry_cipher_setiv
-#undef gcry_cipher_setctr
-#undef gcry_cipher_ctl
-#undef gcry_cipher_decrypt
-#undef gcry_cipher_encrypt
-#undef gcry_cipher_get_algo_blklen
-#undef gcry_cipher_get_algo_keylen
-#undef gcry_cipher_info
-#undef gcry_cipher_list
-#undef gcry_cipher_map_name
-#undef gcry_cipher_mode_from_oid
-#undef gcry_cipher_open
-/* gcry_cipher_register is not anymore a macro.  */
-#undef gcry_cipher_unregister
-
-#undef gcry_pk_algo_info
-#undef gcry_pk_algo_name
-#undef gcry_pk_ctl
-#undef gcry_pk_decrypt
-#undef gcry_pk_encrypt
-#undef gcry_pk_genkey
-#undef gcry_pk_get_keygrip
-#undef gcry_pk_get_curve
-#undef gcry_pk_get_param
-#undef gcry_pk_get_nbits
-#undef gcry_pk_list
-#undef gcry_pk_map_name
-/* gcry_pk_register is not anymore a macro.  */
-#undef gcry_pk_unregister
-#undef gcry_pk_sign
-#undef gcry_pk_testkey
-#undef gcry_pk_verify
-
-#undef gcry_ac_data_new
-#undef gcry_ac_data_destroy
-#undef gcry_ac_data_copy
-#undef gcry_ac_data_length
-#undef gcry_ac_data_clear
-#undef gcry_ac_data_set
-#undef gcry_ac_data_get_name
-#undef gcry_ac_data_get_index
-#undef gcry_ac_open
-#undef gcry_ac_close
-#undef gcry_ac_key_init
-#undef gcry_ac_key_pair_generate
-#undef gcry_ac_key_pair_extract
-#undef gcry_ac_key_data_get
-#undef gcry_ac_key_test
-#undef gcry_ac_key_get_nbits
-#undef gcry_ac_key_get_grip
-#undef gcry_ac_key_destroy
-#undef gcry_ac_key_pair_destroy
-#undef gcry_ac_data_encrypt
-#undef gcry_ac_data_decrypt
-#undef gcry_ac_data_sign
-#undef gcry_ac_data_verify
-#undef gcry_ac_id_to_name
-#undef gcry_ac_name_to_id
-#undef gcry_ac_data_encode
-#undef gcry_ac_data_decode
-#undef gcry_ac_mpi_to_os
-#undef gcry_ac_mpi_to_os_alloc
-#undef gcry_ac_os_to_mpi
-#undef gcry_ac_data_encrypt_scheme
-#undef gcry_ac_data_decrypt_scheme
-#undef gcry_ac_data_sign_scheme
-#undef gcry_ac_data_verify_scheme
-#undef gcry_ac_data_to_sexp
-#undef gcry_ac_data_from_sexp
-#undef gcry_ac_io_init
-#undef gcry_ac_io_init_va
-
-#undef gcry_kdf_derive
-
-#undef gcry_prime_check
-#undef gcry_prime_generate
-#undef gcry_prime_group_generator
-#undef gcry_prime_release_factors
-
-#undef gcry_random_add_bytes
-#undef gcry_random_bytes
-#undef gcry_random_bytes_secure
-#undef gcry_randomize
-#undef gcry_create_nonce
-
-#undef gcry_sexp_alist
-#undef gcry_sexp_append
-#undef gcry_sexp_build
-#undef gcry_sexp_build_array
-#undef gcry_sexp_cadr
-#undef gcry_sexp_canon_len
-#undef gcry_sexp_car
-#undef gcry_sexp_cdr
-#undef gcry_sexp_cons
-#undef gcry_sexp_create
-#undef gcry_sexp_dump
-#undef gcry_sexp_find_token
-#undef gcry_sexp_length
-#undef gcry_sexp_new
-#undef gcry_sexp_nth
-#undef gcry_sexp_nth_data
-#undef gcry_sexp_nth_mpi
-#undef gcry_sexp_prepend
-#undef gcry_sexp_release
-#undef gcry_sexp_sprint
-#undef gcry_sexp_sscan
-#undef gcry_sexp_vlist
-#undef gcry_sexp_nth_string
-
-#undef gcry_mpi_add
-#undef gcry_mpi_add_ui
-#undef gcry_mpi_addm
-#undef gcry_mpi_aprint
-#undef gcry_mpi_clear_bit
-#undef gcry_mpi_clear_flag
-#undef gcry_mpi_clear_highbit
-#undef gcry_mpi_cmp
-#undef gcry_mpi_cmp_ui
-#undef gcry_mpi_copy
-#undef gcry_mpi_div
-#undef gcry_mpi_dump
-#undef gcry_mpi_gcd
-#undef gcry_mpi_get_flag
-#undef gcry_mpi_get_nbits
-#undef gcry_mpi_get_opaque
-#undef gcry_mpi_invm
-#undef gcry_mpi_mod
-#undef gcry_mpi_mul
-#undef gcry_mpi_mul_2exp
-#undef gcry_mpi_mul_ui
-#undef gcry_mpi_mulm
-#undef gcry_mpi_new
-#undef gcry_mpi_powm
-#undef gcry_mpi_print
-#undef gcry_mpi_randomize
-#undef gcry_mpi_release
-#undef gcry_mpi_rshift
-#undef gcry_mpi_lshift
-#undef gcry_mpi_scan
-#undef gcry_mpi_set
-#undef gcry_mpi_set_bit
-#undef gcry_mpi_set_flag
-#undef gcry_mpi_set_highbit
-#undef gcry_mpi_set_opaque
-#undef gcry_mpi_set_ui
-#undef gcry_mpi_snew
-#undef gcry_mpi_sub
-#undef gcry_mpi_sub_ui
-#undef gcry_mpi_subm
-#undef gcry_mpi_swap
-#undef gcry_mpi_test_bit
-
-
 /* Now mark all symbols.  */
 
-MARK_VISIBLE (gcry_check_version)
-MARK_VISIBLE (gcry_control)
-
-MARK_VISIBLE (gcry_set_allocation_handler)
-MARK_VISIBLE (gcry_set_fatalerror_handler)
-MARK_VISIBLE (gcry_set_gettext_handler)
-MARK_VISIBLE (gcry_set_log_handler)
-MARK_VISIBLE (gcry_set_outofcore_handler)
-MARK_VISIBLE (gcry_set_progress_handler)
-MARK_VISIBLE (gcry_err_code_from_errno)
-MARK_VISIBLE (gcry_err_code_to_errno)
-MARK_VISIBLE (gcry_err_make_from_errno)
-MARK_VISIBLE (gcry_error_from_errno)
-MARK_VISIBLE (gcry_strerror)
-MARK_VISIBLE (gcry_strsource)
-
-MARK_VISIBLE (gcry_free)
-MARK_VISIBLE (gcry_malloc)
-MARK_VISIBLE (gcry_malloc_secure)
-MARK_VISIBLE (gcry_calloc)
-MARK_VISIBLE (gcry_calloc_secure)
-MARK_VISIBLE (gcry_realloc)
-MARK_VISIBLE (gcry_strdup)
-MARK_VISIBLE (gcry_is_secure)
-MARK_VISIBLE (gcry_xcalloc)
-MARK_VISIBLE (gcry_xcalloc_secure)
-MARK_VISIBLE (gcry_xmalloc)
-MARK_VISIBLE (gcry_xmalloc_secure)
-MARK_VISIBLE (gcry_xrealloc)
-MARK_VISIBLE (gcry_xstrdup)
-
-MARK_VISIBLE (gcry_md_algo_info)
-MARK_VISIBLE (gcry_md_algo_name)
-MARK_VISIBLE (gcry_md_close)
-MARK_VISIBLE (gcry_md_copy)
-MARK_VISIBLE (gcry_md_ctl)
-MARK_VISIBLE (gcry_md_enable)
-MARK_VISIBLE (gcry_md_get)
-MARK_VISIBLE (gcry_md_get_algo)
-MARK_VISIBLE (gcry_md_get_algo_dlen)
-MARK_VISIBLE (gcry_md_hash_buffer)
-MARK_VISIBLE (gcry_md_info)
-MARK_VISIBLE (gcry_md_is_enabled)
-MARK_VISIBLE (gcry_md_is_secure)
-MARK_VISIBLE (gcry_md_list)
-MARK_VISIBLE (gcry_md_map_name)
-MARK_VISIBLE (gcry_md_open)
-MARK_VISIBLE (gcry_md_read)
-MARK_VISIBLEX(gcry_md_register)
-MARK_VISIBLE (gcry_md_reset)
-MARK_VISIBLE (gcry_md_setkey)
-MARK_VISIBLE (gcry_md_unregister)
-MARK_VISIBLE (gcry_md_write)
-MARK_VISIBLE (gcry_md_debug)
-
-MARK_VISIBLE (gcry_cipher_algo_info)
-MARK_VISIBLE (gcry_cipher_algo_name)
-MARK_VISIBLE (gcry_cipher_close)
-MARK_VISIBLE (gcry_cipher_setkey)
-MARK_VISIBLE (gcry_cipher_setiv)
-MARK_VISIBLE (gcry_cipher_setctr)
-MARK_VISIBLE (gcry_cipher_ctl)
-MARK_VISIBLE (gcry_cipher_decrypt)
-MARK_VISIBLE (gcry_cipher_encrypt)
-MARK_VISIBLE (gcry_cipher_get_algo_blklen)
-MARK_VISIBLE (gcry_cipher_get_algo_keylen)
-MARK_VISIBLE (gcry_cipher_info)
-MARK_VISIBLE (gcry_cipher_list)
-MARK_VISIBLE (gcry_cipher_map_name)
-MARK_VISIBLE (gcry_cipher_mode_from_oid)
-MARK_VISIBLE (gcry_cipher_open)
-MARK_VISIBLEX(gcry_cipher_register)
-MARK_VISIBLE (gcry_cipher_unregister)
-
-MARK_VISIBLE (gcry_pk_algo_info)
-MARK_VISIBLE (gcry_pk_algo_name)
-MARK_VISIBLE (gcry_pk_ctl)
-MARK_VISIBLE (gcry_pk_decrypt)
-MARK_VISIBLE (gcry_pk_encrypt)
-MARK_VISIBLE (gcry_pk_genkey)
-MARK_VISIBLE (gcry_pk_get_keygrip)
-MARK_VISIBLE (gcry_pk_get_curve)
-MARK_VISIBLE (gcry_pk_get_param)
-MARK_VISIBLE (gcry_pk_get_nbits)
-MARK_VISIBLE (gcry_pk_list)
-MARK_VISIBLE (gcry_pk_map_name)
-MARK_VISIBLEX(gcry_pk_register)
-MARK_VISIBLE (gcry_pk_sign)
-MARK_VISIBLE (gcry_pk_testkey)
-MARK_VISIBLE (gcry_pk_unregister)
-MARK_VISIBLE (gcry_pk_verify)
-
-MARK_VISIBLE (gcry_ac_data_new)
-MARK_VISIBLE (gcry_ac_data_destroy)
-MARK_VISIBLE (gcry_ac_data_copy)
-MARK_VISIBLE (gcry_ac_data_length)
-MARK_VISIBLE (gcry_ac_data_clear)
-MARK_VISIBLE (gcry_ac_data_set)
-MARK_VISIBLE (gcry_ac_data_get_name)
-MARK_VISIBLE (gcry_ac_data_get_index)
-MARK_VISIBLE (gcry_ac_open)
-MARK_VISIBLE (gcry_ac_close)
-MARK_VISIBLE (gcry_ac_key_init)
-MARK_VISIBLE (gcry_ac_key_pair_generate)
-MARK_VISIBLE (gcry_ac_key_pair_extract)
-MARK_VISIBLE (gcry_ac_key_data_get)
-MARK_VISIBLE (gcry_ac_key_test)
-MARK_VISIBLE (gcry_ac_key_get_nbits)
-MARK_VISIBLE (gcry_ac_key_get_grip)
-MARK_VISIBLE (gcry_ac_key_destroy)
-MARK_VISIBLE (gcry_ac_key_pair_destroy)
-MARK_VISIBLE (gcry_ac_data_encrypt)
-MARK_VISIBLE (gcry_ac_data_decrypt)
-MARK_VISIBLE (gcry_ac_data_sign)
-MARK_VISIBLE (gcry_ac_data_verify)
-MARK_VISIBLE (gcry_ac_id_to_name)
-MARK_VISIBLE (gcry_ac_name_to_id)
-/* MARK_VISIBLE (gcry_ac_list) Not defined although it is in
-        libgcrypt.vers. */
-MARK_VISIBLE (gcry_ac_data_encode)
-MARK_VISIBLE (gcry_ac_data_decode)
-MARK_VISIBLE (gcry_ac_mpi_to_os)
-MARK_VISIBLE (gcry_ac_mpi_to_os_alloc)
-MARK_VISIBLE (gcry_ac_os_to_mpi)
-MARK_VISIBLE (gcry_ac_data_encrypt_scheme)
-MARK_VISIBLE (gcry_ac_data_decrypt_scheme)
-MARK_VISIBLE (gcry_ac_data_sign_scheme)
-MARK_VISIBLE (gcry_ac_data_verify_scheme)
-MARK_VISIBLE (gcry_ac_data_to_sexp)
-MARK_VISIBLE (gcry_ac_data_from_sexp)
-MARK_VISIBLE (gcry_ac_io_init)
-MARK_VISIBLE (gcry_ac_io_init_va)
-
-MARK_VISIBLE (gcry_kdf_derive)
-
-MARK_VISIBLE (gcry_prime_check)
-MARK_VISIBLE (gcry_prime_generate)
-MARK_VISIBLE (gcry_prime_group_generator)
-MARK_VISIBLE (gcry_prime_release_factors)
-
-MARK_VISIBLE (gcry_random_add_bytes)
-MARK_VISIBLE (gcry_random_bytes)
-MARK_VISIBLE (gcry_random_bytes_secure)
-MARK_VISIBLE (gcry_randomize)
-MARK_VISIBLE (gcry_create_nonce)
-
-MARK_VISIBLE (gcry_sexp_alist)
-MARK_VISIBLE (gcry_sexp_append)
-MARK_VISIBLE (gcry_sexp_build)
-MARK_VISIBLE (gcry_sexp_build_array)
-MARK_VISIBLE (gcry_sexp_cadr)
-MARK_VISIBLE (gcry_sexp_canon_len)
-MARK_VISIBLE (gcry_sexp_car)
-MARK_VISIBLE (gcry_sexp_cdr)
-MARK_VISIBLE (gcry_sexp_cons)
-MARK_VISIBLE (gcry_sexp_create)
-MARK_VISIBLE (gcry_sexp_dump)
-MARK_VISIBLE (gcry_sexp_find_token)
-MARK_VISIBLE (gcry_sexp_length)
-MARK_VISIBLE (gcry_sexp_new)
-MARK_VISIBLE (gcry_sexp_nth)
-MARK_VISIBLE (gcry_sexp_nth_data)
-MARK_VISIBLE (gcry_sexp_nth_mpi)
-MARK_VISIBLE (gcry_sexp_prepend)
-MARK_VISIBLE (gcry_sexp_release)
-MARK_VISIBLE (gcry_sexp_sprint)
-MARK_VISIBLE (gcry_sexp_sscan)
-MARK_VISIBLE (gcry_sexp_vlist)
-MARK_VISIBLE (gcry_sexp_nth_string)
-
-MARK_VISIBLE (gcry_mpi_add)
-MARK_VISIBLE (gcry_mpi_add_ui)
-MARK_VISIBLE (gcry_mpi_addm)
-MARK_VISIBLE (gcry_mpi_aprint)
-MARK_VISIBLE (gcry_mpi_clear_bit)
-MARK_VISIBLE (gcry_mpi_clear_flag)
-MARK_VISIBLE (gcry_mpi_clear_highbit)
-MARK_VISIBLE (gcry_mpi_cmp)
-MARK_VISIBLE (gcry_mpi_cmp_ui)
-MARK_VISIBLE (gcry_mpi_copy)
-MARK_VISIBLE (gcry_mpi_div)
-MARK_VISIBLE (gcry_mpi_dump)
-MARK_VISIBLE (gcry_mpi_gcd)
-MARK_VISIBLE (gcry_mpi_get_flag)
-MARK_VISIBLE (gcry_mpi_get_nbits)
-MARK_VISIBLE (gcry_mpi_get_opaque)
-MARK_VISIBLE (gcry_mpi_invm)
-MARK_VISIBLE (gcry_mpi_mod)
-MARK_VISIBLE (gcry_mpi_mul)
-MARK_VISIBLE (gcry_mpi_mul_2exp)
-MARK_VISIBLE (gcry_mpi_mul_ui)
-MARK_VISIBLE (gcry_mpi_mulm)
-MARK_VISIBLE (gcry_mpi_new)
-MARK_VISIBLE (gcry_mpi_powm)
-MARK_VISIBLE (gcry_mpi_print)
-MARK_VISIBLE (gcry_mpi_randomize)
-MARK_VISIBLE (gcry_mpi_release)
-MARK_VISIBLE (gcry_mpi_rshift)
-MARK_VISIBLE (gcry_mpi_lshift)
-MARK_VISIBLE (gcry_mpi_scan)
-MARK_VISIBLE (gcry_mpi_set)
-MARK_VISIBLE (gcry_mpi_set_bit)
-MARK_VISIBLE (gcry_mpi_set_flag)
-MARK_VISIBLE (gcry_mpi_set_highbit)
-MARK_VISIBLE (gcry_mpi_set_opaque)
-MARK_VISIBLE (gcry_mpi_set_ui)
-MARK_VISIBLE (gcry_mpi_snew)
-MARK_VISIBLE (gcry_mpi_sub)
-MARK_VISIBLE (gcry_mpi_sub_ui)
-MARK_VISIBLE (gcry_mpi_subm)
-MARK_VISIBLE (gcry_mpi_swap)
-MARK_VISIBLE (gcry_mpi_test_bit)
-
-
-
-#undef MARK_VISIBLE
-#endif /*_GCRY_INCLUDED_BY_VISIBILITY_C*/
+MARK_VISIBLEX (gcry_check_version)
+MARK_VISIBLEX (gcry_control)
+
+MARK_VISIBLEX (gcry_set_allocation_handler)
+MARK_VISIBLEX (gcry_set_fatalerror_handler)
+MARK_VISIBLEX (gcry_set_gettext_handler)
+MARK_VISIBLEX (gcry_set_log_handler)
+MARK_VISIBLEX (gcry_set_outofcore_handler)
+MARK_VISIBLEX (gcry_set_progress_handler)
+
+MARK_VISIBLEX (gcry_err_code_from_errno)
+MARK_VISIBLEX (gcry_err_code_to_errno)
+MARK_VISIBLEX (gcry_err_make_from_errno)
+MARK_VISIBLEX (gcry_error_from_errno)
+MARK_VISIBLEX (gcry_strerror)
+MARK_VISIBLEX (gcry_strsource)
+
+MARK_VISIBLEX (gcry_malloc)
+MARK_VISIBLEX (gcry_malloc_secure)
+MARK_VISIBLEX (gcry_calloc)
+MARK_VISIBLEX (gcry_calloc_secure)
+MARK_VISIBLEX (gcry_realloc)
+MARK_VISIBLEX (gcry_strdup)
+MARK_VISIBLEX (gcry_is_secure)
+MARK_VISIBLEX (gcry_xcalloc)
+MARK_VISIBLEX (gcry_xcalloc_secure)
+MARK_VISIBLEX (gcry_xmalloc)
+MARK_VISIBLEX (gcry_xmalloc_secure)
+MARK_VISIBLEX (gcry_xrealloc)
+MARK_VISIBLEX (gcry_xstrdup)
+MARK_VISIBLEX (gcry_free)
+
+MARK_VISIBLEX (gcry_md_algo_info)
+MARK_VISIBLEX (gcry_md_algo_name)
+MARK_VISIBLEX (gcry_md_close)
+MARK_VISIBLEX (gcry_md_copy)
+MARK_VISIBLEX (gcry_md_ctl)
+MARK_VISIBLEX (gcry_md_enable)
+MARK_VISIBLEX (gcry_md_get)
+MARK_VISIBLEX (gcry_md_get_algo)
+MARK_VISIBLEX (gcry_md_get_algo_dlen)
+MARK_VISIBLEX (gcry_md_hash_buffer)
+MARK_VISIBLEX (gcry_md_hash_buffers)
+MARK_VISIBLEX (gcry_md_info)
+MARK_VISIBLEX (gcry_md_is_enabled)
+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_reset)
+MARK_VISIBLEX (gcry_md_setkey)
+MARK_VISIBLEX (gcry_md_write)
+MARK_VISIBLEX (gcry_md_debug)
+
+MARK_VISIBLEX (gcry_cipher_algo_info)
+MARK_VISIBLEX (gcry_cipher_algo_name)
+MARK_VISIBLEX (gcry_cipher_close)
+MARK_VISIBLEX (gcry_cipher_setkey)
+MARK_VISIBLEX (gcry_cipher_setiv)
+MARK_VISIBLEX (gcry_cipher_setctr)
+MARK_VISIBLEX (gcry_cipher_authenticate)
+MARK_VISIBLEX (gcry_cipher_checktag)
+MARK_VISIBLEX (gcry_cipher_gettag)
+MARK_VISIBLEX (gcry_cipher_ctl)
+MARK_VISIBLEX (gcry_cipher_decrypt)
+MARK_VISIBLEX (gcry_cipher_encrypt)
+MARK_VISIBLEX (gcry_cipher_get_algo_blklen)
+MARK_VISIBLEX (gcry_cipher_get_algo_keylen)
+MARK_VISIBLEX (gcry_cipher_info)
+MARK_VISIBLEX (gcry_cipher_map_name)
+MARK_VISIBLEX (gcry_cipher_mode_from_oid)
+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_maclen)
+MARK_VISIBLEX (gcry_mac_get_algo_keylen)
+MARK_VISIBLEX (gcry_mac_open)
+MARK_VISIBLEX (gcry_mac_close)
+MARK_VISIBLEX (gcry_mac_setkey)
+MARK_VISIBLEX (gcry_mac_setiv)
+MARK_VISIBLEX (gcry_mac_write)
+MARK_VISIBLEX (gcry_mac_read)
+MARK_VISIBLEX (gcry_mac_verify)
+MARK_VISIBLEX (gcry_mac_ctl)
+
+MARK_VISIBLEX (gcry_pk_algo_info)
+MARK_VISIBLEX (gcry_pk_algo_name)
+MARK_VISIBLEX (gcry_pk_ctl)
+MARK_VISIBLEX (gcry_pk_decrypt)
+MARK_VISIBLEX (gcry_pk_encrypt)
+MARK_VISIBLEX (gcry_pk_genkey)
+MARK_VISIBLEX (gcry_pk_get_keygrip)
+MARK_VISIBLEX (gcry_pk_get_curve)
+MARK_VISIBLEX (gcry_pk_get_param)
+MARK_VISIBLEX (gcry_pk_get_nbits)
+MARK_VISIBLEX (gcry_pk_map_name)
+MARK_VISIBLEX (gcry_pk_sign)
+MARK_VISIBLEX (gcry_pk_testkey)
+MARK_VISIBLEX (gcry_pk_verify)
+MARK_VISIBLEX (gcry_pubkey_get_sexp)
+
+MARK_VISIBLEX (gcry_kdf_derive)
+
+MARK_VISIBLEX (gcry_prime_check)
+MARK_VISIBLEX (gcry_prime_generate)
+MARK_VISIBLEX (gcry_prime_group_generator)
+MARK_VISIBLEX (gcry_prime_release_factors)
+
+MARK_VISIBLEX (gcry_random_add_bytes)
+MARK_VISIBLEX (gcry_random_bytes)
+MARK_VISIBLEX (gcry_random_bytes_secure)
+MARK_VISIBLEX (gcry_randomize)
+MARK_VISIBLEX (gcry_create_nonce)
+
+MARK_VISIBLEX (gcry_sexp_alist)
+MARK_VISIBLEX (gcry_sexp_append)
+MARK_VISIBLEX (gcry_sexp_build)
+MARK_VISIBLEX (gcry_sexp_build_array)
+MARK_VISIBLEX (gcry_sexp_cadr)
+MARK_VISIBLEX (gcry_sexp_canon_len)
+MARK_VISIBLEX (gcry_sexp_car)
+MARK_VISIBLEX (gcry_sexp_cdr)
+MARK_VISIBLEX (gcry_sexp_cons)
+MARK_VISIBLEX (gcry_sexp_create)
+MARK_VISIBLEX (gcry_sexp_dump)
+MARK_VISIBLEX (gcry_sexp_find_token)
+MARK_VISIBLEX (gcry_sexp_length)
+MARK_VISIBLEX (gcry_sexp_new)
+MARK_VISIBLEX (gcry_sexp_nth)
+MARK_VISIBLEX (gcry_sexp_nth_buffer)
+MARK_VISIBLEX (gcry_sexp_nth_data)
+MARK_VISIBLEX (gcry_sexp_nth_mpi)
+MARK_VISIBLEX (gcry_sexp_nth_string)
+MARK_VISIBLEX (gcry_sexp_prepend)
+MARK_VISIBLEX (gcry_sexp_release)
+MARK_VISIBLEX (gcry_sexp_sprint)
+MARK_VISIBLEX (gcry_sexp_sscan)
+MARK_VISIBLEX (gcry_sexp_vlist)
+MARK_VISIBLEX (gcry_sexp_extract_param)
+
+MARK_VISIBLEX (gcry_mpi_abs)
+MARK_VISIBLEX (gcry_mpi_add)
+MARK_VISIBLEX (gcry_mpi_add_ui)
+MARK_VISIBLEX (gcry_mpi_addm)
+MARK_VISIBLEX (gcry_mpi_aprint)
+MARK_VISIBLEX (gcry_mpi_clear_bit)
+MARK_VISIBLEX (gcry_mpi_clear_flag)
+MARK_VISIBLEX (gcry_mpi_clear_highbit)
+MARK_VISIBLEX (gcry_mpi_cmp)
+MARK_VISIBLEX (gcry_mpi_cmp_ui)
+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_curve_point)
+MARK_VISIBLEX (gcry_mpi_ec_dup)
+MARK_VISIBLEX (gcry_mpi_ec_get_affine)
+MARK_VISIBLEX (gcry_mpi_ec_mul)
+MARK_VISIBLEX (gcry_mpi_ec_new)
+MARK_VISIBLEX (gcry_mpi_ec_get_mpi)
+MARK_VISIBLEX (gcry_mpi_ec_get_point)
+MARK_VISIBLEX (gcry_mpi_ec_set_mpi)
+MARK_VISIBLEX (gcry_mpi_ec_set_point)
+MARK_VISIBLEX (gcry_mpi_gcd)
+MARK_VISIBLEX (gcry_mpi_get_flag)
+MARK_VISIBLEX (gcry_mpi_get_nbits)
+MARK_VISIBLEX (gcry_mpi_get_opaque)
+MARK_VISIBLEX (gcry_mpi_is_neg)
+MARK_VISIBLEX (gcry_mpi_invm)
+MARK_VISIBLEX (gcry_mpi_mod)
+MARK_VISIBLEX (gcry_mpi_mul)
+MARK_VISIBLEX (gcry_mpi_mul_2exp)
+MARK_VISIBLEX (gcry_mpi_mul_ui)
+MARK_VISIBLEX (gcry_mpi_mulm)
+MARK_VISIBLEX (gcry_mpi_neg)
+MARK_VISIBLEX (gcry_mpi_new)
+MARK_VISIBLEX (gcry_mpi_point_get)
+MARK_VISIBLEX (gcry_mpi_point_new)
+MARK_VISIBLEX (gcry_mpi_point_release)
+MARK_VISIBLEX (gcry_mpi_point_set)
+MARK_VISIBLEX (gcry_mpi_point_snatch_get)
+MARK_VISIBLEX (gcry_mpi_point_snatch_set)
+MARK_VISIBLEX (gcry_mpi_powm)
+MARK_VISIBLEX (gcry_mpi_print)
+MARK_VISIBLEX (gcry_mpi_randomize)
+MARK_VISIBLEX (gcry_mpi_release)
+MARK_VISIBLEX (gcry_mpi_rshift)
+MARK_VISIBLEX (gcry_mpi_lshift)
+MARK_VISIBLEX (gcry_mpi_scan)
+MARK_VISIBLEX (gcry_mpi_snatch)
+MARK_VISIBLEX (gcry_mpi_set)
+MARK_VISIBLEX (gcry_mpi_set_bit)
+MARK_VISIBLEX (gcry_mpi_set_flag)
+MARK_VISIBLEX (gcry_mpi_set_highbit)
+MARK_VISIBLEX (gcry_mpi_set_opaque)
+MARK_VISIBLEX (gcry_mpi_set_opaque_copy)
+MARK_VISIBLEX (gcry_mpi_set_ui)
+MARK_VISIBLEX (gcry_mpi_snew)
+MARK_VISIBLEX (gcry_mpi_sub)
+MARK_VISIBLEX (gcry_mpi_sub_ui)
+MARK_VISIBLEX (gcry_mpi_subm)
+MARK_VISIBLEX (gcry_mpi_swap)
+MARK_VISIBLEX (gcry_mpi_test_bit)
+
+MARK_VISIBLEX (gcry_ctx_release)
+
+MARK_VISIBLEX (gcry_log_debug)
+MARK_VISIBLEX (gcry_log_debughex)
+MARK_VISIBLEX (gcry_log_debugmpi)
+MARK_VISIBLEX (gcry_log_debugpnt)
+MARK_VISIBLEX (gcry_log_debugsxp)
+
+/* Functions used to implement macros.  */
+MARK_VISIBLEX (_gcry_mpi_get_const)
+
+
+#undef MARK_VISIBLEX
+
+#else /*!_GCRY_INCLUDED_BY_VISIBILITY_C*/
+
+/* To avoid accidental use of the public functions inside Libgcrypt,
+   we redefine them to catch such errors.  The usual difference
+   between a public and an internal version is that the internal
+   version use gpg_err_code_t and the public version gpg_error_t.  */
+
+#define gcry_check_version          _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_control                _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_set_allocation_handler _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_set_fatalerror_handler _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_set_gettext_handler    _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_set_log_handler        _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_set_outofcore_handler  _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_set_progress_handler   _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_err_code_from_errno    _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_err_code_to_errno      _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_err_make_from_errno    _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_error_from_errno       _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_strerror               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_strsource              _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_malloc                 _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_malloc_secure          _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_calloc                 _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_calloc_secure          _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_realloc                _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_strdup                 _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_xcalloc                _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_xcalloc_secure         _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_xmalloc                _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_xmalloc_secure         _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_xrealloc               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_xstrdup                _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_free                   _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_is_secure              _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_cipher_open            _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_close           _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_setkey          _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_setiv           _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_setctr          _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_algo_info       _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_algo_name       _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_authenticate    _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_checktag        _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_gettag          _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_ctl             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_decrypt         _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_encrypt         _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_get_algo_blklen _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_get_algo_keylen _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_info            _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_map_name        _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_cipher_mode_from_oid   _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_pk_algo_info           _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_algo_name           _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_ctl                 _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_decrypt             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_encrypt             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_genkey              _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_get_keygrip         _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_get_curve           _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_get_param           _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_get_nbits           _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_map_name            _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_sign                _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_testkey             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pk_verify              _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_pubkey_get_sexp        _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_md_algo_info           _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_algo_name           _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_close               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_copy                _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_ctl                 _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_enable              _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_get                 _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_get_algo            _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_get_algo_dlen       _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_hash_buffer         _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_hash_buffers        _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_info                _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_is_enabled          _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_is_secure           _gcry_USE_THE_UNDERSCORED_FUNCTION
+#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_reset               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_setkey              _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_write               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_md_debug               _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#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_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
+#define gcry_mac_close              _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_setkey             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_setiv              _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_write              _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_read               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_verify             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mac_ctl                _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_kdf_derive             _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_prime_check            _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_prime_generate         _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_prime_group_generator  _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_prime_release_factors  _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_random_add_bytes       _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_random_bytes           _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_random_bytes_secure    _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_randomize              _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_create_nonce           _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_ctx_release            _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_sexp_alist             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_append            _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_build             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_build_array       _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_cadr              _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_canon_len         _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_car               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_cdr               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_cons              _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_create            _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_dump              _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_find_token        _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_length            _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_new               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_nth               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_nth_buffer        _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_nth_data          _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_nth_mpi           _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_nth_string        _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_prepend           _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_release           _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_sprint            _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_sscan             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_vlist             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_sexp_extract_param     _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_mpi_add                _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_add_ui             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_addm               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_aprint             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_clear_bit          _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_clear_flag         _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_clear_highbit      _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_cmp                _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_cmp_ui             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_copy               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_div                _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_dump               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_gcd                _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_get_flag           _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_get_nbits          _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_get_opaque         _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_invm               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_mod                _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_mul                _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_mul_2exp           _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_mul_ui             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_mulm               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_new                _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_point_get          _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_point_new          _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_point_release      _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_point_set          _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_point_snatch_get   _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_point_snatch_set   _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_powm               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_print              _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_randomize          _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_release            _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_rshift             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_lshift             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_scan               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_set                _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_set_bit            _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_set_flag           _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_set_highbit        _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_set_opaque         _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_set_ui             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_snatch             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_snew               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_sub                _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_sub_ui             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_subm               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_swap               _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_test_bit           _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+#define gcry_mpi_abs                _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_ec_add             _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_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
+#define gcry_mpi_ec_mul             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_ec_new             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_ec_set_mpi         _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_ec_set_point       _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_is_neg             _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_neg                _gcry_USE_THE_UNDERSCORED_FUNCTION
+#define gcry_mpi_set_opaque_copy    _gcry_USE_THE_UNDERSCORED_FUNCTION
+
+
+#endif /*!_GCRY_INCLUDED_BY_VISIBILITY_C*/
 
 #endif /*GCRY_VISIBILITY_H*/
similarity index 97%
rename from tests/ChangeLog
rename to tests/ChangeLog-2011
index 09da582..a9fb1ca 100644 (file)
@@ -1,3 +1,23 @@
+2011-12-01  Werner Koch  <wk@g10code.com>
+
+       NB: ChangeLog files are no longer manually maintained.  Starting
+       on December 1st, 2011 we put change information only in the GIT
+       commit log, and generate a top-level ChangeLog file from logs at
+       "make dist".  See doc/HACKING for details.
+
+2011-11-11  Jim Meyering  <meyering@redhat.com>
+
+       tests: avoid write-beyond-end-of-heap buffer
+       * basic.c (check_bulk_cipher_modes): Allocate one more byte in
+       each of the two test buffers.  Otherwise, running
+       "env -i MALLOC_CHECK_=3 ./basic" would abort.
+
+2011-09-15  Werner Koch  <wk@g10code.com>
+
+       * register.c: Remove.
+
+       * ac-data.c, ac-schemes.c, ac.c: Remove.
+
 2011-06-13  Werner Koch  <wk@g10code.com>
 
        * basic.c (check_pubkey_sign): Run PKCS1 tests only for RSA.
  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.
+
+Local Variables:
+buffer-read-only: t
+End:
index 689a3db..9645471 100644 (file)
 
 ## Process this file with automake to produce Makefile.in
 
-TESTS = version t-mpi-bit prime register ac ac-schemes ac-data basic \
-        mpitests tsexp keygen pubkey hmac keygrip fips186-dsa aeswrap \
-       curves t-kdf pkcs1v2
+tests_bin = \
+        version mpitests tsexp 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
 
+tests_bin_last = benchmark bench-slope
 
-# random.c uses fork() thus a test for W32 does not make any sense.
-if !HAVE_W32_SYSTEM
-TESTS += random
-endif
+tests_sh =
 
-# The last test to run.
-TESTS += benchmark
+tests_sh_last = hashtest-256g
+
+TESTS = $(tests_bin) $(tests_sh) $(tests_bin_last) $(tests_sh_last)
+
+# Force sequential run of some tests.
+bench-slope.log:    benchmark.log
+hashtest-256g.log:  bench-slope.log
+
+
+TESTS_ENVIRONMENT = GCRYPT_IN_REGRESSION_TEST=1
 
 
 # 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_LDFLAGS = -no-install
 
-LDADD = ../src/libgcrypt.la $(DL_LIBS) ../compat/libcompat.la $(GPG_ERROR_LIBS)
+default_ldadd = \
+       ../src/libgcrypt.la $(DL_LIBS) \
+        ../compat/libcompat.la $(GPG_ERROR_LIBS)
 
 EXTRA_PROGRAMS = testapi pkbench
-noinst_PROGRAMS = $(TESTS) fipsdrv rsacvt
+noinst_PROGRAMS = $(tests_bin) $(tests_bin_last) fipsdrv rsacvt genhashdata
+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
+            pkcs1v2-oaep.h pkcs1v2-pss.h pkcs1v2-v15c.h pkcs1v2-v15s.h \
+            t-ed25519.inp stopwatch.h hashtest-256g.in
+
+LDADD = $(default_ldadd) $(LIBTHREAD)
+t_lock_LDADD = $(default_ldadd) $(LIBMULTITHREAD)
index 7eaba29..66fdfe1 100644 (file)
@@ -1,9 +1,9 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11.6 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009  Free Software Foundation,
-# Inc.
+# 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 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; \
+    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;; \
+    esac; \
+    test $$am__dry = yes; \
+  }
 pkgdatadir = $(datadir)/@PACKAGE@
 pkgincludedir = $(includedir)/@PACKAGE@
 pkglibdir = $(libdir)/@PACKAGE@
@@ -52,200 +70,212 @@ PRE_UNINSTALL = :
 POST_UNINSTALL = :
 build_triplet = @build@
 host_triplet = @host@
-TESTS = version$(EXEEXT) t-mpi-bit$(EXEEXT) prime$(EXEEXT) \
-       register$(EXEEXT) ac$(EXEEXT) ac-schemes$(EXEEXT) \
-       ac-data$(EXEEXT) basic$(EXEEXT) mpitests$(EXEEXT) \
-       tsexp$(EXEEXT) keygen$(EXEEXT) pubkey$(EXEEXT) hmac$(EXEEXT) \
-       keygrip$(EXEEXT) fips186-dsa$(EXEEXT) aeswrap$(EXEEXT) \
-       curves$(EXEEXT) t-kdf$(EXEEXT) pkcs1v2$(EXEEXT) \
-       $(am__EXEEXT_1) benchmark$(EXEEXT)
-
-# random.c uses fork() thus a test for W32 does not make any sense.
-@HAVE_W32_SYSTEM_FALSE@am__append_1 = random
+TESTS = $(am__EXEEXT_1) $(am__EXEEXT_3) $(am__EXEEXT_2) \
+       $(tests_sh_last)
 EXTRA_PROGRAMS = testapi$(EXEEXT) pkbench$(EXEEXT)
-noinst_PROGRAMS = $(am__EXEEXT_2) fipsdrv$(EXEEXT) rsacvt$(EXEEXT)
+noinst_PROGRAMS = $(am__EXEEXT_1) $(am__EXEEXT_2) fipsdrv$(EXEEXT) \
+       rsacvt$(EXEEXT) genhashdata$(EXEEXT)
 subdir = tests
-DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
-       ChangeLog
+DIST_COMMON = README $(noinst_HEADERS) $(srcdir)/Makefile.am \
+       $(srcdir)/Makefile.in $(srcdir)/hashtest-256g.in
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
 am__aclocal_m4_deps = $(top_srcdir)/m4/gpg-error.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/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/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \
        $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \
-       $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
+       $(top_srcdir)/m4/threadlib.m4 $(top_srcdir)/acinclude.m4 \
+       $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+mkinstalldirs = $(install_sh) -d
 CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
+CONFIG_CLEAN_FILES = hashtest-256g
 CONFIG_CLEAN_VPATH_FILES =
-@HAVE_W32_SYSTEM_FALSE@am__EXEEXT_1 = random$(EXEEXT)
-am__EXEEXT_2 = version$(EXEEXT) t-mpi-bit$(EXEEXT) prime$(EXEEXT) \
-       register$(EXEEXT) ac$(EXEEXT) ac-schemes$(EXEEXT) \
-       ac-data$(EXEEXT) basic$(EXEEXT) mpitests$(EXEEXT) \
-       tsexp$(EXEEXT) keygen$(EXEEXT) pubkey$(EXEEXT) hmac$(EXEEXT) \
-       keygrip$(EXEEXT) fips186-dsa$(EXEEXT) aeswrap$(EXEEXT) \
-       curves$(EXEEXT) t-kdf$(EXEEXT) pkcs1v2$(EXEEXT) \
-       $(am__EXEEXT_1) benchmark$(EXEEXT)
+am__EXEEXT_1 = version$(EXEEXT) mpitests$(EXEEXT) tsexp$(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)
+am__EXEEXT_2 = benchmark$(EXEEXT) bench-slope$(EXEEXT)
 PROGRAMS = $(noinst_PROGRAMS)
-ac_SOURCES = ac.c
-ac_OBJECTS = ac.$(OBJEXT)
-ac_LDADD = $(LDADD)
-am__DEPENDENCIES_1 =
-ac_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
-ac_data_SOURCES = ac-data.c
-ac_data_OBJECTS = ac-data.$(OBJEXT)
-ac_data_LDADD = $(LDADD)
-ac_data_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
-ac_schemes_SOURCES = ac-schemes.c
-ac_schemes_OBJECTS = ac-schemes.$(OBJEXT)
-ac_schemes_LDADD = $(LDADD)
-ac_schemes_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
 aeswrap_SOURCES = aeswrap.c
 aeswrap_OBJECTS = aeswrap.$(OBJEXT)
 aeswrap_LDADD = $(LDADD)
-aeswrap_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
+am__DEPENDENCIES_1 =
+am__DEPENDENCIES_2 = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
        ../compat/libcompat.la $(am__DEPENDENCIES_1)
+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
 basic_SOURCES = basic.c
 basic_OBJECTS = basic.$(OBJEXT)
 basic_LDADD = $(LDADD)
-basic_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+basic_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
+bench_slope_SOURCES = bench-slope.c
+bench_slope_OBJECTS = bench-slope.$(OBJEXT)
+bench_slope_LDADD = $(LDADD)
+bench_slope_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 benchmark_SOURCES = benchmark.c
 benchmark_OBJECTS = benchmark.$(OBJEXT)
 benchmark_LDADD = $(LDADD)
-benchmark_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+benchmark_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 curves_SOURCES = curves.c
 curves_OBJECTS = curves.$(OBJEXT)
 curves_LDADD = $(LDADD)
-curves_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+curves_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
+dsa_rfc6979_SOURCES = dsa-rfc6979.c
+dsa_rfc6979_OBJECTS = dsa-rfc6979.$(OBJEXT)
+dsa_rfc6979_LDADD = $(LDADD)
+dsa_rfc6979_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 fips186_dsa_SOURCES = fips186-dsa.c
 fips186_dsa_OBJECTS = fips186-dsa.$(OBJEXT)
 fips186_dsa_LDADD = $(LDADD)
-fips186_dsa_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+fips186_dsa_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 fipsdrv_SOURCES = fipsdrv.c
 fipsdrv_OBJECTS = fipsdrv.$(OBJEXT)
 fipsdrv_LDADD = $(LDADD)
-fipsdrv_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+fipsdrv_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
+genhashdata_SOURCES = genhashdata.c
+genhashdata_OBJECTS = genhashdata.$(OBJEXT)
+genhashdata_LDADD = $(LDADD)
+genhashdata_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
+hashtest_SOURCES = hashtest.c
+hashtest_OBJECTS = hashtest.$(OBJEXT)
+hashtest_LDADD = $(LDADD)
+hashtest_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 hmac_SOURCES = hmac.c
 hmac_OBJECTS = hmac.$(OBJEXT)
 hmac_LDADD = $(LDADD)
-hmac_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+hmac_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 keygen_SOURCES = keygen.c
 keygen_OBJECTS = keygen.$(OBJEXT)
 keygen_LDADD = $(LDADD)
-keygen_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+keygen_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 keygrip_SOURCES = keygrip.c
 keygrip_OBJECTS = keygrip.$(OBJEXT)
 keygrip_LDADD = $(LDADD)
-keygrip_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+keygrip_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 mpitests_SOURCES = mpitests.c
 mpitests_OBJECTS = mpitests.$(OBJEXT)
 mpitests_LDADD = $(LDADD)
-mpitests_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+mpitests_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 pkbench_SOURCES = pkbench.c
 pkbench_OBJECTS = pkbench.$(OBJEXT)
 pkbench_LDADD = $(LDADD)
-pkbench_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+pkbench_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 pkcs1v2_SOURCES = pkcs1v2.c
 pkcs1v2_OBJECTS = pkcs1v2.$(OBJEXT)
 pkcs1v2_LDADD = $(LDADD)
-pkcs1v2_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+pkcs1v2_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 prime_SOURCES = prime.c
 prime_OBJECTS = prime.$(OBJEXT)
 prime_LDADD = $(LDADD)
-prime_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+prime_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 pubkey_SOURCES = pubkey.c
 pubkey_OBJECTS = pubkey.$(OBJEXT)
 pubkey_LDADD = $(LDADD)
-pubkey_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+pubkey_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 random_SOURCES = random.c
 random_OBJECTS = random.$(OBJEXT)
 random_LDADD = $(LDADD)
-random_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
-register_SOURCES = register.c
-register_OBJECTS = register.$(OBJEXT)
-register_LDADD = $(LDADD)
-register_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+random_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 rsacvt_SOURCES = rsacvt.c
 rsacvt_OBJECTS = rsacvt.$(OBJEXT)
 rsacvt_LDADD = $(LDADD)
-rsacvt_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+rsacvt_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
+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_ed25519_SOURCES = t-ed25519.c
+t_ed25519_OBJECTS = t-ed25519.$(OBJEXT)
+t_ed25519_LDADD = $(LDADD)
+t_ed25519_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 t_kdf_SOURCES = t-kdf.c
 t_kdf_OBJECTS = t-kdf.$(OBJEXT)
 t_kdf_LDADD = $(LDADD)
-t_kdf_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+t_kdf_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
+t_lock_SOURCES = t-lock.c
+t_lock_OBJECTS = t-lock.$(OBJEXT)
+t_lock_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 t_mpi_bit_SOURCES = t-mpi-bit.c
 t_mpi_bit_OBJECTS = t-mpi-bit.$(OBJEXT)
 t_mpi_bit_LDADD = $(LDADD)
-t_mpi_bit_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+t_mpi_bit_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
+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)
 testapi_SOURCES = testapi.c
 testapi_OBJECTS = testapi.$(OBJEXT)
 testapi_LDADD = $(LDADD)
-testapi_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+testapi_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 tsexp_SOURCES = tsexp.c
 tsexp_OBJECTS = tsexp.$(OBJEXT)
 tsexp_LDADD = $(LDADD)
-tsexp_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+tsexp_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 version_SOURCES = version.c
 version_OBJECTS = version.$(OBJEXT)
 version_LDADD = $(LDADD)
-version_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) \
-       ../compat/libcompat.la $(am__DEPENDENCIES_1)
+version_DEPENDENCIES = $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1)
 DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
-depcomp = $(SHELL) $(top_srcdir)/depcomp
+depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp
 am__depfiles_maybe = depfiles
 am__mv = mv -f
 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
        $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-       --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
-       $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
+       $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
+       $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
+       $(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 = @
 CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
-       --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
-       $(LDFLAGS) -o $@
-SOURCES = ac.c ac-data.c ac-schemes.c aeswrap.c basic.c benchmark.c \
-       curves.c fips186-dsa.c fipsdrv.c hmac.c keygen.c keygrip.c \
-       mpitests.c pkbench.c pkcs1v2.c prime.c pubkey.c random.c \
-       register.c rsacvt.c t-kdf.c t-mpi-bit.c testapi.c tsexp.c \
+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   " $@;
+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
+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
-DIST_SOURCES = ac.c ac-data.c ac-schemes.c aeswrap.c basic.c \
-       benchmark.c curves.c fips186-dsa.c fipsdrv.c hmac.c keygen.c \
-       keygrip.c mpitests.c pkbench.c pkcs1v2.c prime.c pubkey.c \
-       random.c register.c rsacvt.c t-kdf.c t-mpi-bit.c testapi.c \
-       tsexp.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)
 ETAGS = etags
 CTAGS = ctags
 am__tty_colors = \
 red=; grn=; lgn=; blu=; std=
+am__EXEEXT_3 =
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 AMTAR = @AMTAR@
+AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
 AR = @AR@
 AS = @AS@
 AUTOCONF = @AUTOCONF@
@@ -260,6 +290,7 @@ CCAS = @CCAS@
 CCASDEPMODE = @CCASDEPMODE@
 CCASFLAGS = @CCASFLAGS@
 CCDEPMODE = @CCDEPMODE@
+CC_FOR_BUILD = @CC_FOR_BUILD@
 CFLAGS = @CFLAGS@
 CPP = @CPP@
 CPPFLAGS = @CPPFLAGS@
@@ -279,6 +310,8 @@ FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@
 FGREP = @FGREP@
 GCRYPT_CIPHERS = @GCRYPT_CIPHERS@
 GCRYPT_DIGESTS = @GCRYPT_DIGESTS@
+GCRYPT_HWF_MODULES = @GCRYPT_HWF_MODULES@
+GCRYPT_KDFS = @GCRYPT_KDFS@
 GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@
 GCRYPT_RANDOM = @GCRYPT_RANDOM@
 GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@
@@ -304,14 +337,19 @@ 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@
 MKDIR_P = @MKDIR_P@
 MPI_SFLAGS = @MPI_SFLAGS@
 NM = @NM@
@@ -334,16 +372,19 @@ PTH_CONFIG = @PTH_CONFIG@
 PTH_LIBS = @PTH_LIBS@
 RANLIB = @RANLIB@
 RC = @RC@
+RUN_LARGE_DATA_TESTS = @RUN_LARGE_DATA_TESTS@
 SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
 SYS_SOCKET_H = @SYS_SOCKET_H@
 VERSION = @VERSION@
+VERSION_NUMBER = @VERSION_NUMBER@
 abs_builddir = @abs_builddir@
 abs_srcdir = @abs_srcdir@
 abs_top_builddir = @abs_top_builddir@
 abs_top_srcdir = @abs_top_srcdir@
+ac_ct_AR = @ac_ct_AR@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 am__include = @am__include@
@@ -379,7 +420,6 @@ libdir = @libdir@
 libexecdir = @libexecdir@
 localedir = @localedir@
 localstatedir = @localstatedir@
-lt_ECHO = @lt_ECHO@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 oldincludedir = @oldincludedir@
@@ -395,15 +435,33 @@ target_alias = @target_alias@
 top_build_prefix = @top_build_prefix@
 top_builddir = @top_builddir@
 top_srcdir = @top_srcdir@
+tests_bin = \
+        version mpitests tsexp 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
+
+tests_bin_last = benchmark bench-slope
+tests_sh = 
+tests_sh_last = hashtest-256g
+TESTS_ENVIRONMENT = GCRYPT_IN_REGRESSION_TEST=1
 
 # 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)
-LDADD = ../src/libgcrypt.la $(DL_LIBS) ../compat/libcompat.la $(GPG_ERROR_LIBS)
+AM_LDFLAGS = -no-install
+default_ldadd = \
+       ../src/libgcrypt.la $(DL_LIBS) \
+        ../compat/libcompat.la $(GPG_ERROR_LIBS)
+
+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
+            pkcs1v2-oaep.h pkcs1v2-pss.h pkcs1v2-v15c.h pkcs1v2-v15s.h \
+            t-ed25519.inp stopwatch.h hashtest-256g.in
 
+LDADD = $(default_ldadd) $(LIBTHREAD)
+t_lock_LDADD = $(default_ldadd) $(LIBMULTITHREAD)
 all: all-am
 
 .SUFFIXES:
@@ -438,6 +496,8 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
 $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 $(am__aclocal_m4_deps):
+hashtest-256g: $(top_builddir)/config.status $(srcdir)/hashtest-256g.in
+       cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
 
 clean-noinstPROGRAMS:
        @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
@@ -447,81 +507,93 @@ clean-noinstPROGRAMS:
        list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
        echo " rm -f" $$list; \
        rm -f $$list
-ac$(EXEEXT): $(ac_OBJECTS) $(ac_DEPENDENCIES) 
-       @rm -f ac$(EXEEXT)
-       $(LINK) $(ac_OBJECTS) $(ac_LDADD) $(LIBS)
-ac-data$(EXEEXT): $(ac_data_OBJECTS) $(ac_data_DEPENDENCIES) 
-       @rm -f ac-data$(EXEEXT)
-       $(LINK) $(ac_data_OBJECTS) $(ac_data_LDADD) $(LIBS)
-ac-schemes$(EXEEXT): $(ac_schemes_OBJECTS) $(ac_schemes_DEPENDENCIES) 
-       @rm -f ac-schemes$(EXEEXT)
-       $(LINK) $(ac_schemes_OBJECTS) $(ac_schemes_LDADD) $(LIBS)
-aeswrap$(EXEEXT): $(aeswrap_OBJECTS) $(aeswrap_DEPENDENCIES) 
+aeswrap$(EXEEXT): $(aeswrap_OBJECTS) $(aeswrap_DEPENDENCIES) $(EXTRA_aeswrap_DEPENDENCIES) 
        @rm -f aeswrap$(EXEEXT)
-       $(LINK) $(aeswrap_OBJECTS) $(aeswrap_LDADD) $(LIBS)
-basic$(EXEEXT): $(basic_OBJECTS) $(basic_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK) $(aeswrap_OBJECTS) $(aeswrap_LDADD) $(LIBS)
+basic$(EXEEXT): $(basic_OBJECTS) $(basic_DEPENDENCIES) $(EXTRA_basic_DEPENDENCIES) 
        @rm -f basic$(EXEEXT)
-       $(LINK) $(basic_OBJECTS) $(basic_LDADD) $(LIBS)
-benchmark$(EXEEXT): $(benchmark_OBJECTS) $(benchmark_DEPENDENCIES) 
+       $(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)
-       $(LINK) $(benchmark_OBJECTS) $(benchmark_LDADD) $(LIBS)
-curves$(EXEEXT): $(curves_OBJECTS) $(curves_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK) $(benchmark_OBJECTS) $(benchmark_LDADD) $(LIBS)
+curves$(EXEEXT): $(curves_OBJECTS) $(curves_DEPENDENCIES) $(EXTRA_curves_DEPENDENCIES) 
        @rm -f curves$(EXEEXT)
-       $(LINK) $(curves_OBJECTS) $(curves_LDADD) $(LIBS)
-fips186-dsa$(EXEEXT): $(fips186_dsa_OBJECTS) $(fips186_dsa_DEPENDENCIES) 
+       $(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)
-       $(LINK) $(fips186_dsa_OBJECTS) $(fips186_dsa_LDADD) $(LIBS)
-fipsdrv$(EXEEXT): $(fipsdrv_OBJECTS) $(fipsdrv_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK) $(fips186_dsa_OBJECTS) $(fips186_dsa_LDADD) $(LIBS)
+fipsdrv$(EXEEXT): $(fipsdrv_OBJECTS) $(fipsdrv_DEPENDENCIES) $(EXTRA_fipsdrv_DEPENDENCIES) 
        @rm -f fipsdrv$(EXEEXT)
-       $(LINK) $(fipsdrv_OBJECTS) $(fipsdrv_LDADD) $(LIBS)
-hmac$(EXEEXT): $(hmac_OBJECTS) $(hmac_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK) $(fipsdrv_OBJECTS) $(fipsdrv_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)
-       $(LINK) $(hmac_OBJECTS) $(hmac_LDADD) $(LIBS)
-keygen$(EXEEXT): $(keygen_OBJECTS) $(keygen_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK) $(hmac_OBJECTS) $(hmac_LDADD) $(LIBS)
+keygen$(EXEEXT): $(keygen_OBJECTS) $(keygen_DEPENDENCIES) $(EXTRA_keygen_DEPENDENCIES) 
        @rm -f keygen$(EXEEXT)
-       $(LINK) $(keygen_OBJECTS) $(keygen_LDADD) $(LIBS)
-keygrip$(EXEEXT): $(keygrip_OBJECTS) $(keygrip_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK) $(keygen_OBJECTS) $(keygen_LDADD) $(LIBS)
+keygrip$(EXEEXT): $(keygrip_OBJECTS) $(keygrip_DEPENDENCIES) $(EXTRA_keygrip_DEPENDENCIES) 
        @rm -f keygrip$(EXEEXT)
-       $(LINK) $(keygrip_OBJECTS) $(keygrip_LDADD) $(LIBS)
-mpitests$(EXEEXT): $(mpitests_OBJECTS) $(mpitests_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK) $(keygrip_OBJECTS) $(keygrip_LDADD) $(LIBS)
+mpitests$(EXEEXT): $(mpitests_OBJECTS) $(mpitests_DEPENDENCIES) $(EXTRA_mpitests_DEPENDENCIES) 
        @rm -f mpitests$(EXEEXT)
-       $(LINK) $(mpitests_OBJECTS) $(mpitests_LDADD) $(LIBS)
-pkbench$(EXEEXT): $(pkbench_OBJECTS) $(pkbench_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK) $(mpitests_OBJECTS) $(mpitests_LDADD) $(LIBS)
+pkbench$(EXEEXT): $(pkbench_OBJECTS) $(pkbench_DEPENDENCIES) $(EXTRA_pkbench_DEPENDENCIES) 
        @rm -f pkbench$(EXEEXT)
-       $(LINK) $(pkbench_OBJECTS) $(pkbench_LDADD) $(LIBS)
-pkcs1v2$(EXEEXT): $(pkcs1v2_OBJECTS) $(pkcs1v2_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK) $(pkbench_OBJECTS) $(pkbench_LDADD) $(LIBS)
+pkcs1v2$(EXEEXT): $(pkcs1v2_OBJECTS) $(pkcs1v2_DEPENDENCIES) $(EXTRA_pkcs1v2_DEPENDENCIES) 
        @rm -f pkcs1v2$(EXEEXT)
-       $(LINK) $(pkcs1v2_OBJECTS) $(pkcs1v2_LDADD) $(LIBS)
-prime$(EXEEXT): $(prime_OBJECTS) $(prime_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK) $(pkcs1v2_OBJECTS) $(pkcs1v2_LDADD) $(LIBS)
+prime$(EXEEXT): $(prime_OBJECTS) $(prime_DEPENDENCIES) $(EXTRA_prime_DEPENDENCIES) 
        @rm -f prime$(EXEEXT)
-       $(LINK) $(prime_OBJECTS) $(prime_LDADD) $(LIBS)
-pubkey$(EXEEXT): $(pubkey_OBJECTS) $(pubkey_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK) $(prime_OBJECTS) $(prime_LDADD) $(LIBS)
+pubkey$(EXEEXT): $(pubkey_OBJECTS) $(pubkey_DEPENDENCIES) $(EXTRA_pubkey_DEPENDENCIES) 
        @rm -f pubkey$(EXEEXT)
-       $(LINK) $(pubkey_OBJECTS) $(pubkey_LDADD) $(LIBS)
-random$(EXEEXT): $(random_OBJECTS) $(random_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK) $(pubkey_OBJECTS) $(pubkey_LDADD) $(LIBS)
+random$(EXEEXT): $(random_OBJECTS) $(random_DEPENDENCIES) $(EXTRA_random_DEPENDENCIES) 
        @rm -f random$(EXEEXT)
-       $(LINK) $(random_OBJECTS) $(random_LDADD) $(LIBS)
-register$(EXEEXT): $(register_OBJECTS) $(register_DEPENDENCIES) 
-       @rm -f register$(EXEEXT)
-       $(LINK) $(register_OBJECTS) $(register_LDADD) $(LIBS)
-rsacvt$(EXEEXT): $(rsacvt_OBJECTS) $(rsacvt_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK) $(random_OBJECTS) $(random_LDADD) $(LIBS)
+rsacvt$(EXEEXT): $(rsacvt_OBJECTS) $(rsacvt_DEPENDENCIES) $(EXTRA_rsacvt_DEPENDENCIES) 
        @rm -f rsacvt$(EXEEXT)
-       $(LINK) $(rsacvt_OBJECTS) $(rsacvt_LDADD) $(LIBS)
-t-kdf$(EXEEXT): $(t_kdf_OBJECTS) $(t_kdf_DEPENDENCIES) 
+       $(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-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)
-       $(LINK) $(t_kdf_OBJECTS) $(t_kdf_LDADD) $(LIBS)
-t-mpi-bit$(EXEEXT): $(t_mpi_bit_OBJECTS) $(t_mpi_bit_DEPENDENCIES) 
+       $(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)
+t-mpi-bit$(EXEEXT): $(t_mpi_bit_OBJECTS) $(t_mpi_bit_DEPENDENCIES) $(EXTRA_t_mpi_bit_DEPENDENCIES) 
        @rm -f t-mpi-bit$(EXEEXT)
-       $(LINK) $(t_mpi_bit_OBJECTS) $(t_mpi_bit_LDADD) $(LIBS)
-testapi$(EXEEXT): $(testapi_OBJECTS) $(testapi_DEPENDENCIES) 
+       $(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)
+testapi$(EXEEXT): $(testapi_OBJECTS) $(testapi_DEPENDENCIES) $(EXTRA_testapi_DEPENDENCIES) 
        @rm -f testapi$(EXEEXT)
-       $(LINK) $(testapi_OBJECTS) $(testapi_LDADD) $(LIBS)
-tsexp$(EXEEXT): $(tsexp_OBJECTS) $(tsexp_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK) $(testapi_OBJECTS) $(testapi_LDADD) $(LIBS)
+tsexp$(EXEEXT): $(tsexp_OBJECTS) $(tsexp_DEPENDENCIES) $(EXTRA_tsexp_DEPENDENCIES) 
        @rm -f tsexp$(EXEEXT)
-       $(LINK) $(tsexp_OBJECTS) $(tsexp_LDADD) $(LIBS)
-version$(EXEEXT): $(version_OBJECTS) $(version_DEPENDENCIES) 
+       $(AM_V_CCLD)$(LINK) $(tsexp_OBJECTS) $(tsexp_LDADD) $(LIBS)
+version$(EXEEXT): $(version_OBJECTS) $(version_DEPENDENCIES) $(EXTRA_version_DEPENDENCIES) 
        @rm -f version$(EXEEXT)
-       $(LINK) $(version_OBJECTS) $(version_LDADD) $(LIBS)
+       $(AM_V_CCLD)$(LINK) $(version_OBJECTS) $(version_LDADD) $(LIBS)
 
 mostlyclean-compile:
        -rm -f *.$(OBJEXT)
@@ -529,15 +601,16 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ac-data.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ac-schemes.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ac.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aeswrap.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basic.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bench-slope.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/benchmark.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/curves.Po@am__quote@
+@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)/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@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keygen.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keygrip.Po@am__quote@
@@ -547,34 +620,37 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prime.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pubkey.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/register.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-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)/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:
-@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@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@  $(COMPILE) -c $<
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
 
 .c.obj:
-@am__fastdepCC_TRUE@   $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@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@  $(COMPILE) -c `$(CYGPATH_W) '$<'`
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
 
 .c.lo:
-@am__fastdepCC_TRUE@   $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@   $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@am__fastdepCC_TRUE@   $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@   $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LTCOMPILE) -c -o $@ $<
+@am__fastdepCC_FALSE@  $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
 
 mostlyclean-libtool:
        -rm -f *.lo
@@ -715,14 +791,15 @@ check-TESTS: $(TESTS)
          fi; \
          dashes=`echo "$$dashes" | sed s/./=/g`; \
          if test "$$failed" -eq 0; then \
-           echo "$$grn$$dashes"; \
+           col="$$grn"; \
          else \
-           echo "$$red$$dashes"; \
+           col="$$red"; \
          fi; \
-         echo "$$banner"; \
-         test -z "$$skipped" || echo "$$skipped"; \
-         test -z "$$report" || echo "$$report"; \
-         echo "$$dashes$$std"; \
+         echo "$${col}$$dashes$${std}"; \
+         echo "$${col}$$banner$${std}"; \
+         test -z "$$skipped" || echo "$${col}$$skipped$${std}"; \
+         test -z "$$report" || echo "$${col}$$report$${std}"; \
+         echo "$${col}$$dashes$${std}"; \
          test "$$failed" -eq 0; \
        else :; fi
 
@@ -759,7 +836,7 @@ distdir: $(DISTFILES)
 check-am: all-am
        $(MAKE) $(AM_MAKEFLAGS) check-TESTS
 check: check-am
-all-am: Makefile $(PROGRAMS)
+all-am: Makefile $(PROGRAMS) $(HEADERS)
 installdirs:
 install: install-am
 install-exec: install-exec-am
@@ -771,10 +848,15 @@ install-am: all-am
 
 installcheck: installcheck-am
 install-strip:
-       $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
-         install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
-         `test -z '$(STRIP)' || \
-           echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+       if test -z '$(STRIP)'; then \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+             install; \
+       else \
+         $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+           install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+           "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
+       fi
 mostlyclean-generic:
 
 clean-generic:
@@ -874,6 +956,10 @@ uninstall-am:
        tags uninstall uninstall-am
 
 
+# Force sequential run of some tests.
+bench-slope.log:    benchmark.log
+hashtest-256g.log:  bench-slope.log
+
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
diff --git a/tests/ac-data.c b/tests/ac-data.c
deleted file mode 100644 (file)
index 56fedbc..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-/* ac-data.c - Public key encryption/decryption tests
- *     Copyright (C) 2005 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
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdlib.h>
-#include <stdio.h>
-#include <assert.h>
-
-#define assert_err(err) \
-  do \
-    if (err) \
-      { \
-        fprintf (stderr, "Error occurred at line %i: %s\n", \
-                 __LINE__, gcry_strerror (err)); \
-        exit (1); \
-      } \
-  while (0)
-
-#include "../src/gcrypt.h"
-
-static int verbose;
-
-static void
-die (const char *format, ...)
-{
-  va_list arg_ptr ;
-
-  va_start( arg_ptr, format ) ;
-  vfprintf (stderr, format, arg_ptr );
-  va_end(arg_ptr);
-  exit (1);
-}
-
-static void
-check_sexp_conversion (gcry_ac_data_t data, const char **identifiers)
-{
-  gcry_ac_data_t data2;
-  gcry_error_t err;
-  gcry_sexp_t sexp;
-  unsigned int i;
-  const char *label1, *label2;
-  gcry_mpi_t mpi1, mpi2;
-  size_t length1, length2;
-
-  err = gcry_ac_data_to_sexp (data, &sexp, identifiers);
-  assert_err (err);
-  if (verbose)
-    gcry_sexp_dump (sexp);
-  err = gcry_ac_data_from_sexp (&data2, sexp, identifiers);
-  assert_err (err);
-
-  length1 = gcry_ac_data_length (data);
-  length2 = gcry_ac_data_length (data2);
-  assert (length1 == length2);
-
-  for (i = 0; i < length1; i++)
-    {
-      err = gcry_ac_data_get_index (data, 0, i, &label1, &mpi1);
-      assert_err (err);
-      err = gcry_ac_data_get_index (data2, 0, i, &label2, &mpi2);
-      assert_err (err);
-      if (verbose)
-        {
-          fprintf (stderr, "Label1=`%s'\n", label1);
-          fprintf (stderr, "Label2=`%s'\n", label2);
-        }
-      assert (! strcmp (label1, label2));
-      assert (! gcry_mpi_cmp (mpi1, mpi2));
-    }
-
-  gcry_ac_data_destroy (data2);
-  gcry_sexp_release (sexp);
-}
-
-void
-check_run (void)
-{
-  const char *identifiers[] = { "foo",
-                               "bar",
-                               "baz",
-                               "hello",
-                               "somemoretexthere",
-                               "blahblahblah",
-                               NULL };
-  const char *identifiers_null[] = { NULL };
-  gcry_ac_data_t data;
-  gcry_error_t err;
-  const char *label0;
-  const char *label1;
-  gcry_mpi_t mpi0;
-  gcry_mpi_t mpi1;
-  gcry_mpi_t mpi2;
-
-  /* Initialize values.  */
-
-  label0 = "thisisreallylonglabelbutsincethereisnolimitationonthelengthoflabelsitshouldworkjustfine";
-  mpi0 = gcry_mpi_new (0);
-  assert (mpi0);
-  gcry_mpi_set_ui (mpi0, 123456);
-
-  err = gcry_ac_data_new (&data);
-  assert_err (err);
-
-  check_sexp_conversion (data, identifiers);
-  check_sexp_conversion (data, identifiers_null);
-  check_sexp_conversion (data, NULL);
-
-  err = gcry_ac_data_set (data, 0, label0, mpi0);
-  assert_err (err);
-  err = gcry_ac_data_get_index (data, 0, 0, &label1, &mpi1);
-  assert_err (err);
-  assert (label0 == label1);
-  assert (mpi0 == mpi1);
-  check_sexp_conversion (data, identifiers);
-  check_sexp_conversion (data, identifiers_null);
-  check_sexp_conversion (data, NULL);
-
-  if (verbose)
-    printf ("data-set-test-0 succeeded\n");
-
-  gcry_ac_data_clear (data);
-
-  err = gcry_ac_data_set (data, GCRY_AC_FLAG_COPY, label0, mpi0);
-  assert_err (err);
-
-  err = gcry_ac_data_set (data, GCRY_AC_FLAG_COPY, "foo", mpi0);
-  assert_err (err);
-  err = gcry_ac_data_set (data, GCRY_AC_FLAG_COPY, "foo", mpi0);
-  assert_err (err);
-  err = gcry_ac_data_set (data, GCRY_AC_FLAG_COPY, "bar", mpi0);
-  assert_err (err);
-  err = gcry_ac_data_set (data, GCRY_AC_FLAG_COPY, "blah1", mpi0);
-  assert_err (err);
-  check_sexp_conversion (data, identifiers);
-  check_sexp_conversion (data, identifiers_null);
-  check_sexp_conversion (data, NULL);
-
-  err = gcry_ac_data_get_name (data, 0, label0, &mpi1);
-  assert_err (err);
-  assert (mpi0 != mpi1);
-  err = gcry_ac_data_get_name (data, GCRY_AC_FLAG_COPY, label0, &mpi2);
-  assert_err (err);
-  assert (mpi0 != mpi1);
-  assert (mpi1 != mpi2);
-  err = gcry_ac_data_get_index (data, 0, 0, &label1, &mpi1);
-  assert_err (err);
-  gcry_mpi_release (mpi0);
-  gcry_mpi_release (mpi2);
-
-  if (verbose)
-    printf ("data-set-test-1 succeeded\n");
-
-  gcry_ac_data_clear (data);
-  assert (! gcry_ac_data_length (data));
-  check_sexp_conversion (data, identifiers);
-  check_sexp_conversion (data, identifiers_null);
-  check_sexp_conversion (data, NULL);
-
-  if (verbose)
-    printf ("data-set-test-2 succeeded\n");
-
-  gcry_ac_data_destroy (data);
-
-
-}
-
-int
-main (int argc, char **argv)
-{
-  int debug = 0;
-  int i = 1;
-
-  if (argc > 1 && !strcmp (argv[1], "--verbose"))
-    verbose = 1;
-  else if (argc > 1 && !strcmp (argv[1], "--debug"))
-    verbose = debug = 1;
-
-  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
-  if (!gcry_check_version (GCRYPT_VERSION))
-    die ("version mismatch\n");
-  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
-  if (debug)
-    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
-
-  for (; i > 0; i--)
-    check_run ();
-
-  return 0;
-}
diff --git a/tests/ac-schemes.c b/tests/ac-schemes.c
deleted file mode 100644 (file)
index 58180c0..0000000
+++ /dev/null
@@ -1,347 +0,0 @@
-/* ac-schemes.c - Tests for ES/SSA
-   Copyright (C) 2003, 2005 Free Software Foundation, Inc.
-
-   This file is part of Libgcrypt.
-
-   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.  */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-#include <errno.h>
-
-#include "../src/gcrypt.h"
-
-static unsigned int verbose;
-
-static void
-die (const char *format, ...)
-{
-  va_list arg_ptr ;
-
-  va_start( arg_ptr, format ) ;
-  vfprintf (stderr, format, arg_ptr );
-  va_end(arg_ptr);
-  exit (1);
-}
-
-typedef struct scheme_spec
-{
-  unsigned int idx;
-  gcry_ac_scheme_t scheme;
-  unsigned int flags;
-  const char *m;
-  size_t m_n;
-} scheme_spec_t;
-
-#define SCHEME_SPEC_FLAG_GET_OPTS (1 << 0)
-
-#define FILL(idx, scheme, flags, m) \
-    { idx, GCRY_AC_##scheme, flags, m, sizeof (m) }
-
-scheme_spec_t es_specs[] =
-  {
-    FILL (0, ES_PKCS_V1_5, 0, "foobar"),
-    FILL (1, ES_PKCS_V1_5, 0, "")
-  };
-
-scheme_spec_t ssa_specs[] =
-  {
-    FILL (0, SSA_PKCS_V1_5, SCHEME_SPEC_FLAG_GET_OPTS, "foobar")
-  };
-
-#undef FILL
-
-gcry_err_code_t
-scheme_get_opts (scheme_spec_t specs, void **opts)
-{
-  gcry_err_code_t err = GPG_ERR_NO_ERROR;
-  void *opts_new = NULL;
-
-  switch (specs.scheme)
-    {
-    case GCRY_AC_SSA_PKCS_V1_5:
-      {
-       gcry_ac_ssa_pkcs_v1_5_t *opts_pkcs_v1_5 = NULL;
-
-       opts_new = gcry_malloc (sizeof (gcry_ac_ssa_pkcs_v1_5_t));
-       if (! opts_new)
-         err = gpg_err_code_from_errno (ENOMEM);
-       else
-         {
-           opts_pkcs_v1_5 = (gcry_ac_ssa_pkcs_v1_5_t *) opts_new;
-
-           switch (specs.idx)
-             {
-             case 0:
-               opts_pkcs_v1_5->md = GCRY_MD_SHA1;
-               break;
-             case 1:
-               opts_pkcs_v1_5->md = GCRY_MD_MD5;
-               break;
-             }
-         }
-      }
-    case GCRY_AC_ES_PKCS_V1_5:
-      break;
-    }
-
-  if (! err)
-    *opts = opts_new;
-
-  return err;
-}
-
-gcry_error_t
-es_check (gcry_ac_handle_t handle, scheme_spec_t spec,
-         gcry_ac_key_t key_public, gcry_ac_key_t key_secret)
-{
-  gcry_error_t err = GPG_ERR_NO_ERROR;
-  char *c = NULL;
-  char *m2 = NULL;
-  size_t c_n = 0;
-  size_t m2_n = 0;
-  void *opts = NULL;
-  gcry_ac_io_t io_m;
-  gcry_ac_io_t io_c;
-  gcry_ac_io_t io_m2;
-
-  if (spec.flags & SCHEME_SPEC_FLAG_GET_OPTS)
-    err = scheme_get_opts (spec, &opts);
-  if (! err)
-    {
-      c = NULL;
-      m2 = NULL;
-
-      gcry_ac_io_init (&io_m, GCRY_AC_IO_READABLE,
-                      GCRY_AC_IO_STRING, spec.m, spec.m_n);
-      gcry_ac_io_init (&io_c, GCRY_AC_IO_WRITABLE,
-                      GCRY_AC_IO_STRING, &c, &c_n);
-
-      err = gcry_ac_data_encrypt_scheme (handle, GCRY_AC_ES_PKCS_V1_5, 0, opts, key_public,
-                                        &io_m, &io_c);
-      if (! err)
-       {
-         gcry_ac_io_init (&io_c, GCRY_AC_IO_READABLE,
-                          GCRY_AC_IO_STRING, c, c_n);
-         gcry_ac_io_init (&io_m2, GCRY_AC_IO_WRITABLE,
-                          GCRY_AC_IO_STRING, &m2, &m2_n);
-
-         err = gcry_ac_data_decrypt_scheme (handle, GCRY_AC_ES_PKCS_V1_5, 0,
-                                            opts, key_secret, &io_c, &io_m2);
-       }
-      if (! err)
-       assert ((spec.m_n == m2_n) && (! strncmp (spec.m, m2, spec.m_n)));
-
-      if (c)
-       gcry_free (c);
-      if (m2)
-       gcry_free (m2);
-    }
-
-  if (opts)
-    gcry_free (opts);
-
-  return err;
-}
-
-gcry_error_t
-ssa_check (gcry_ac_handle_t handle, scheme_spec_t spec,
-          gcry_ac_key_t key_public, gcry_ac_key_t key_secret)
-{
-  gcry_error_t err = GPG_ERR_NO_ERROR;
-  unsigned char *s = NULL;
-  size_t s_n = 0;
-  void *opts = NULL;
-  gcry_ac_io_t io_m;
-  gcry_ac_io_t io_s;
-
-  if (spec.flags & SCHEME_SPEC_FLAG_GET_OPTS)
-    err = scheme_get_opts (spec, &opts);
-  if (! err)
-    {
-      gcry_ac_io_init (&io_m, GCRY_AC_IO_READABLE,
-                      GCRY_AC_IO_STRING, spec.m, spec.m_n);
-      gcry_ac_io_init (&io_s, GCRY_AC_IO_WRITABLE,
-                      GCRY_AC_IO_STRING, &s, &s_n);
-
-      err = gcry_ac_data_sign_scheme (handle, GCRY_AC_SSA_PKCS_V1_5, 0, opts, key_secret,
-                                     &io_m, &io_s);
-      if (! err)
-       {
-         gcry_ac_io_init (&io_m, GCRY_AC_IO_READABLE,
-                          GCRY_AC_IO_STRING, spec.m, spec.m_n);
-         gcry_ac_io_init (&io_s, GCRY_AC_IO_READABLE,
-                          GCRY_AC_IO_STRING, s, s_n);
-         err = gcry_ac_data_verify_scheme (handle, GCRY_AC_SSA_PKCS_V1_5, 0, opts, key_public,
-                                           &io_m, &io_s);
-       }
-      assert (! err);
-
-      if (s)
-       gcry_free (s);
-    }
-
-  if (opts)
-    gcry_free (opts);
-
-  return err;
-}
-
-void
-es_checks (gcry_ac_handle_t handle, gcry_ac_key_t key_public, gcry_ac_key_t key_secret)
-{
-  gcry_error_t err = GPG_ERR_NO_ERROR;
-  unsigned int i = 0;
-
-  for (i = 0; (i < (sizeof (es_specs) / sizeof (*es_specs))) && (! err); i++)
-    err = es_check (handle, es_specs[i], key_public, key_secret);
-
-  assert (! err);
-}
-
-void
-ssa_checks (gcry_ac_handle_t handle, gcry_ac_key_t key_public, gcry_ac_key_t key_secret)
-{
-  gcry_error_t err = GPG_ERR_NO_ERROR;
-  unsigned int i = 0;
-
-  for (i = 0; (i < (sizeof (ssa_specs) / sizeof (*ssa_specs))) && (! err); i++)
-    err = ssa_check (handle, ssa_specs[i], key_public, key_secret);
-
-  assert (! err);
-}
-
-#define KEY_TYPE_PUBLIC (1 << 0)
-#define KEY_TYPE_SECRET (1 << 1)
-
-typedef struct key_spec
-{
-  const char *name;
-  unsigned int flags;
-  const char *mpi_string;
-} key_spec_t;
-
-key_spec_t key_specs[] =
-  {
-    { "n", KEY_TYPE_PUBLIC | KEY_TYPE_SECRET,
-      "e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
-      "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
-      "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
-      "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251" },
-    { "e", KEY_TYPE_PUBLIC | KEY_TYPE_SECRET,
-      "010001" },
-    { "d", KEY_TYPE_SECRET,
-      "046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
-      "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
-      "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
-      "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781" },
-    { "p", KEY_TYPE_SECRET,
-      "00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
-      "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1" },
-    { "q", KEY_TYPE_SECRET,
-      "00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
-      "35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361" },
-    { "u", KEY_TYPE_SECRET,
-      "304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
-      "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b" },
-    { NULL },
-  };
-
-gcry_error_t
-key_init (gcry_ac_key_type_t type, gcry_ac_key_t *key)
-{
-  gcry_error_t err = GPG_ERR_NO_ERROR;
-  gcry_ac_data_t key_data = NULL;
-  gcry_ac_key_t key_new = NULL;
-  gcry_mpi_t mpi = NULL;
-  unsigned int i = 0;
-
-  err = gcry_ac_data_new (&key_data);
-  for (i = 0; key_specs[i].name && (! err); i++)
-    {
-      if (((type == GCRY_AC_KEY_PUBLIC) && (key_specs[i].flags & KEY_TYPE_PUBLIC))
-         || ((type == GCRY_AC_KEY_SECRET) && (key_specs[i].flags & KEY_TYPE_SECRET)))
-       {
-         err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_HEX, key_specs[i].mpi_string, 0, NULL);
-         if (! err)
-           {
-             gcry_ac_data_set (key_data, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
-                               key_specs[i].name, mpi);
-             gcry_mpi_release (mpi);
-           }
-       }
-    }
-  if (! err)
-    err = gcry_ac_key_init (&key_new, NULL, type, key_data);
-
-  if (key_data)
-    gcry_ac_data_destroy (key_data);
-
-  if (! err)
-    *key = key_new;
-
-  return err;
-}
-
-static void
-check_run (void)
-{
-  gcry_ac_handle_t handle = NULL;
-  gcry_error_t err = GPG_ERR_NO_ERROR;
-  gcry_ac_key_t key_public = NULL, key_secret = NULL;
-
-  err = key_init (GCRY_AC_KEY_PUBLIC, &key_public);
-  if (! err)
-    err = key_init (GCRY_AC_KEY_SECRET, &key_secret);
-
-  if (! err)
-    err = gcry_ac_open (&handle, GCRY_AC_RSA, 0);
-  if (! err)
-    {
-      es_checks (handle, key_public, key_secret);
-      ssa_checks (handle, key_public, key_secret);
-    }
-
-  assert (! err);
-}
-
-int
-main (int argc, char **argv)
-{
-  unsigned int debug = 0;
-
-  if ((argc > 1) && (! strcmp (argv[1], "--verbose")))
-    verbose = 1;
-  else if ((argc > 1) && (! strcmp (argv[1], "--debug")))
-    verbose = debug = 1;
-
-  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
-  if (! gcry_check_version (GCRYPT_VERSION))
-    die ("version mismatch\n");
-  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
-  if (debug)
-    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
-
-  check_run ();
-
-  return 0;
-}
diff --git a/tests/ac.c b/tests/ac.c
deleted file mode 100644 (file)
index 8b2d252..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/* pubkey.c - Public key encryption/decryption tests
- *     Copyright (C) 2003, 2005 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
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "../src/gcrypt.h"
-
-static int verbose;
-
-static void
-die (const char *format, ...)
-{
-  va_list arg_ptr ;
-
-  va_start( arg_ptr, format ) ;
-  vfprintf (stderr, format, arg_ptr );
-  va_end(arg_ptr);
-  exit (1);
-}
-
-void
-key_copy (gcry_ac_handle_t handle,
-         gcry_ac_key_type_t type,
-         gcry_ac_key_t *key_cp, gcry_ac_key_t key)
-{
-  gcry_error_t err = 0;
-
-  err = gcry_ac_key_init (key_cp, handle, type,
-                         gcry_ac_key_data_get (key));
-
-  assert (! err);
-}
-
-void
-check_one (gcry_mpi_t x)
-{
-  gcry_ac_handle_t handle;
-  gcry_ac_key_pair_t key_pair;
-  gcry_ac_key_t key_sec, key_sec_cp, key_pub, key_pub_cp;
-  gcry_error_t err = 0;
-  gcry_mpi_t x2;
-  gcry_ac_data_t data, data2;
-  gcry_ac_key_spec_rsa_t rsa_spec;
-
-  rsa_spec.e = gcry_mpi_new (0);
-  gcry_mpi_set_ui (rsa_spec.e, 1);
-
-  err = gcry_ac_open (&handle, GCRY_AC_RSA, 0);
-  assert (! err);
-
-  err = gcry_ac_key_pair_generate (handle, 1024, &rsa_spec, &key_pair, NULL);
-  assert (! err);
-
-  key_sec = gcry_ac_key_pair_extract (key_pair, GCRY_AC_KEY_SECRET);
-  key_copy (handle, GCRY_AC_KEY_SECRET, &key_sec_cp, key_sec);
-
-  key_pub = gcry_ac_key_pair_extract (key_pair, GCRY_AC_KEY_PUBLIC);
-  key_copy (handle, GCRY_AC_KEY_PUBLIC, &key_pub_cp, key_pub);
-
-  err = gcry_ac_data_encrypt (handle, GCRY_AC_FLAG_NO_BLINDING, key_pub_cp, x, &data);
-  assert (! err);
-
-  err = gcry_ac_data_decrypt (handle, GCRY_AC_FLAG_NO_BLINDING, key_sec_cp, &x2, data);
-  assert (! err);
-
-  assert (! gcry_mpi_cmp (x, x2));
-
-  gcry_ac_data_destroy (data);
-
-  err = gcry_ac_data_sign (handle, key_sec, x, &data);
-  assert (! err);
-  err = gcry_ac_data_copy (&data2, data);
-  assert (! err);
-  gcry_ac_data_destroy (data);
-  err = gcry_ac_data_copy (&data, data2);
-  assert (! err);
-  gcry_ac_data_destroy (data2);
-
-  err = gcry_ac_data_verify (handle, key_pub, x, data);
-  assert (! err);
-
-  gcry_ac_data_destroy (data);
-
-  err = gcry_ac_data_sign (handle, key_sec, x, &data);
-  assert (! err);
-  {
-    const char *label;
-    gcry_mpi_t y;
-
-    err = gcry_ac_data_get_index (data, 0, 0, &label, &y);
-    assert (! err);
-    gcry_mpi_add_ui (y, y, 1);
-
-    err = gcry_ac_data_verify (handle, key_pub, x, data);
-    assert (gcry_err_code (err) == GPG_ERR_BAD_SIGNATURE);
-  }
-
-  gcry_ac_close (handle);
-}
-
-void
-check_run (void)
-{
-  /*const char *s = "All Hail Discordia."; -- not used */
-  unsigned int a = 0x4223;
-  gcry_mpi_t x;
-
-  x = gcry_mpi_new (0);
-  gcry_mpi_set_ui (x, a);
-  check_one (x);
-  gcry_mpi_release (x);
-}
-
-int
-main (int argc, char **argv)
-{
-  int debug = 0;
-  int i = 1;
-
-  if (argc > 1 && !strcmp (argv[1], "--verbose"))
-    verbose = 1;
-  else if (argc > 1 && !strcmp (argv[1], "--debug"))
-    verbose = debug = 1;
-
-  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
-  if (!gcry_check_version (GCRYPT_VERSION))
-    die ("version mismatch\n");
-  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
-  if (debug)
-    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
-  /* No valuable keys are create, so we can speed up our RNG. */
-  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
-
-  for (; i > 0; i--)
-    check_run ();
-
-  return 0;
-}
index bb52fc9..16b576d 100644 (file)
@@ -26,7 +26,7 @@
 #include <string.h>
 #include <stdarg.h>
 
-#include "../src/gcrypt.h"
+#include "../src/gcrypt-int.h"
 
 static int verbose;
 static int error_count;
index cdc3462..86be89d 100644 (file)
@@ -1,6 +1,7 @@
 /* basic.c  -  basic regression tests
  * Copyright (C) 2001, 2002, 2003, 2005, 2008,
  *               2009 Free Software Foundation, Inc.
+ * Copyright (C) 2013 g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
@@ -25,8 +26,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
+#include <assert.h>
 
-#include "../src/gcrypt.h"
+#include "../src/gcrypt-int.h"
 
 #ifndef DIM
 # define DIM(v)                     (sizeof(v)/sizeof((v)[0]))
@@ -98,6 +100,24 @@ die (const char *format, ...)
   exit (1);
 }
 
+
+static void
+show_sexp (const char *prefix, gcry_sexp_t a)
+{
+  char *buf;
+  size_t size;
+
+  if (prefix)
+    fputs (prefix, stderr);
+  size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+  buf = gcry_xmalloc (size);
+
+  gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
+  fprintf (stderr, "%.*s", (int)size, buf);
+  gcry_free (buf);
+}
+
+
 #define MAX_DATA_LEN 100
 
 void
@@ -119,7 +139,7 @@ progress_handler (void *cb_data, const char *what, int printchar,
 static void
 check_cbc_mac_cipher (void)
 {
-  struct tv
+  static const struct tv
   {
     int algo;
     char key[MAX_DATA_LEN];
@@ -244,10 +264,10 @@ check_cbc_mac_cipher (void)
 static void
 check_aes128_cbc_cts_cipher (void)
 {
-  char key[128 / 8] = "chicken teriyaki";
-  unsigned char plaintext[] =
+  static const char key[128 / 8] = "chicken teriyaki";
+  static const unsigned char plaintext[] =
     "I would like the General Gau's Chicken, please, and wonton soup.";
-  struct tv
+  static const struct tv
   {
     unsigned char out[MAX_DATA_LEN];
     int inlen;
@@ -358,7 +378,7 @@ check_aes128_cbc_cts_cipher (void)
 static void
 check_ctr_cipher (void)
 {
-  struct tv
+  static const struct tv
   {
     int algo;
     char key[MAX_DATA_LEN];
@@ -714,7 +734,7 @@ check_ctr_cipher (void)
 static void
 check_cfb_cipher (void)
 {
-  struct tv
+  static const struct tv
   {
     int algo;
     char key[MAX_DATA_LEN];
@@ -885,7 +905,7 @@ check_cfb_cipher (void)
 static void
 check_ofb_cipher (void)
 {
-  struct tv
+  static const struct tv
   {
     int algo;
     char key[MAX_DATA_LEN];
@@ -1117,224 +1137,2182 @@ check_ofb_cipher (void)
     fprintf (stderr, "  Completed OFB checks.\n");
 }
 
-
-/* Check that our bulk encryption fucntions work properly.  */
 static void
-check_bulk_cipher_modes (void)
+_check_gcm_cipher (unsigned int step)
 {
-  struct
+  struct tv
   {
     int algo;
-    int mode;
-    const char *key;
-    int  keylen;
-    const char *iv;
+    char key[MAX_DATA_LEN];
+    char iv[MAX_DATA_LEN];
     int ivlen;
-    char t1_hash[20];
-  } tv[] = {
-    { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CFB,
-      "abcdefghijklmnop", 16,
-      "1234567890123456", 16,
-/*[0]*/
-      { 0x53, 0xda, 0x27, 0x3c, 0x78, 0x3d, 0x54, 0x66, 0x19, 0x63,
-        0xd7, 0xe6, 0x20, 0x10, 0xcd, 0xc0, 0x5a, 0x0b, 0x06, 0xcc }
-    },
-    { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB,
-      "abcdefghijklmnopABCDEFG", 24,
-      "1234567890123456", 16,
-/*[1]*/
-      { 0xc7, 0xb1, 0xd0, 0x09, 0x95, 0x04, 0x34, 0x61, 0x2b, 0xd9,
-        0xcb, 0xb3, 0xc7, 0xcb, 0xef, 0xea, 0x16, 0x19, 0x9b, 0x3e }
-    },
-    { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB,
-      "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
-      "1234567890123456", 16,
-/*[2]*/
-      { 0x31, 0xe1, 0x1f, 0x63, 0x65, 0x47, 0x8c, 0x3f, 0x53, 0xdb,
-        0xd9, 0x4d, 0x91, 0x1d, 0x02, 0x9c, 0x05, 0x25, 0x58, 0x29 }
-    },
-    { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC,
-      "abcdefghijklmnop", 16,
-      "1234567890123456", 16,
-/*[3]*/
-      { 0xdc, 0x0c, 0xc2, 0xd9, 0x6b, 0x47, 0xf9, 0xeb, 0x06, 0xb4,
-        0x2f, 0x6e, 0xec, 0x72, 0xbf, 0x55, 0x26, 0x7f, 0xa9, 0x97 }
-    },
-    { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC,
-      "abcdefghijklmnopABCDEFG", 24,
-      "1234567890123456", 16,
-/*[4]*/
-      { 0x2b, 0x90, 0x9b, 0xe6, 0x40, 0xab, 0x6e, 0xc2, 0xc5, 0xb1,
-        0x87, 0xf5, 0x43, 0x84, 0x7b, 0x04, 0x06, 0x47, 0xd1, 0x8f }
-    },
-    { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC,
-      "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
-      "1234567890123456", 16,
-/*[5]*/
-      { 0xaa, 0xa8, 0xdf, 0x03, 0xb0, 0xba, 0xc4, 0xe3, 0xc1, 0x02,
-        0x38, 0x31, 0x8d, 0x86, 0xcb, 0x49, 0x6d, 0xad, 0xae, 0x01 }
-    },
-    { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_OFB,
-      "abcdefghijklmnop", 16,
-      "1234567890123456", 16,
-/*[6]*/
-      { 0x65, 0xfe, 0xde, 0x48, 0xd0, 0xa1, 0xa6, 0xf9, 0x24, 0x6b,
-        0x52, 0x5f, 0x21, 0x8a, 0x6f, 0xc7, 0x70, 0x3b, 0xd8, 0x4a }
-    },
-    { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB,
-      "abcdefghijklmnopABCDEFG", 24,
-      "1234567890123456", 16,
-/*[7]*/
-      { 0x59, 0x5b, 0x02, 0xa2, 0x88, 0xc0, 0xbe, 0x94, 0x43, 0xaa,
-        0x39, 0xf6, 0xbd, 0xcc, 0x83, 0x99, 0xee, 0x00, 0xa1, 0x91 }
-    },
-    { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB,
-      "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
-      "1234567890123456", 16,
-/*[8]*/
-      { 0x38, 0x8c, 0xe1, 0xe2, 0xbe, 0x67, 0x60, 0xe8, 0xeb, 0xce,
-        0xd0, 0xc6, 0xaa, 0xd6, 0xf6, 0x26, 0x15, 0x56, 0xd0, 0x2b }
-    },
-    { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CTR,
-      "abcdefghijklmnop", 16,
-      "1234567890123456", 16,
-/*[9]*/
-      { 0x9a, 0x48, 0x94, 0xd6, 0x50, 0x46, 0x81, 0xdb, 0x68, 0x34,
-        0x3b, 0xc5, 0x9e, 0x66, 0x94, 0x81, 0x98, 0xa0, 0xf9, 0xff }
-    },
-    { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CTR,
-      "abcdefghijklmnopABCDEFG", 24,
-      "1234567890123456", 16,
-/*[10]*/
-      { 0x2c, 0x2c, 0xd3, 0x75, 0x81, 0x2a, 0x59, 0x07, 0xeb, 0x08,
-        0xce, 0x28, 0x4c, 0x0c, 0x6a, 0xa8, 0x8f, 0xa3, 0x98, 0x7e }
-    },
-    { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR,
-      "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
-      "1234567890123456", 16,
-/*[11]*/
-      { 0x64, 0xce, 0x73, 0x03, 0xc7, 0x89, 0x99, 0x1f, 0xf1, 0xce,
-        0xfe, 0xfb, 0xb9, 0x42, 0x30, 0xdf, 0xbb, 0x68, 0x6f, 0xd3 }
-    },
-    { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB,
-      "abcdefghijklmnop", 16,
-      "1234567890123456", 16,
-/*[12]*/
-      { 0x51, 0xae, 0xf5, 0xac, 0x22, 0xa0, 0xba, 0x11, 0xc5, 0xaa,
-        0xb4, 0x70, 0x99, 0xce, 0x18, 0x08, 0x12, 0x9b, 0xb1, 0xc5 }
-    },
-    { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB,
-      "abcdefghijklmnopABCDEFG", 24,
-      "1234567890123456", 16,
-/*[13]*/
-      { 0x57, 0x91, 0xea, 0x48, 0xd8, 0xbf, 0x9e, 0xc1, 0xae, 0x33,
-        0xb3, 0xfd, 0xf7, 0x7a, 0xeb, 0x30, 0xb1, 0x62, 0x0d, 0x82 }
-    },
-    { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB,
-      "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
-      "1234567890123456", 16,
-/*[14]*/
-      { 0x2d, 0x71, 0x54, 0xb9, 0xc5, 0x28, 0x76, 0xff, 0x76, 0xb5,
-        0x99, 0x37, 0x99, 0x9d, 0xf7, 0x10, 0x6d, 0x86, 0x4f, 0x3f }
-    }
-  };
-  gcry_cipher_hd_t hde = NULL;
-  gcry_cipher_hd_t hdd = NULL;
-  unsigned char *buffer_base, *outbuf_base; /* Allocated buffers.  */
-  unsigned char *buffer, *outbuf;           /* Aligned buffers.  */
-  size_t buflen;
-  unsigned char hash[20];
-  int i, j, keylen, blklen;
+    unsigned char aad[MAX_DATA_LEN];
+    int aadlen;
+    unsigned char plaintext[MAX_DATA_LEN];
+    int inlen;
+    char out[MAX_DATA_LEN];
+    char tag[MAX_DATA_LEN];
+  } tv[] =
+    {
+      /* http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-revised-spec.pdf */
+      { 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\x45\x5a" },
+      { 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",
+        "\xab\x6e\x47\xd4\x2c\xec\x13\xbd\xf5\x3a\x67\xb2\x12\x57\xbd\xdf" },
+      { GCRY_CIPHER_AES,
+        "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+        "\xca\xfe\xba\xbe\xfa\xce\xdb\xad\xde\xca\xf8\x88", 12,
+        "", 0,
+        "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+        "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+        "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+        "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39\x1a\xaf\xd2\x55",
+        64,
+        "\x42\x83\x1e\xc2\x21\x77\x74\x24\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
+        "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
+        "\x21\xd5\x14\xb2\x54\x66\x93\x1c\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
+        "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97\x3d\x58\xe0\x91\x47\x3f\x59\x85",
+        "\x4d\x5c\x2a\xf3\x27\xcd\x64\xa6\x2c\xf3\x5a\xbd\x2b\xa6\xfa\xb4" },
+      { GCRY_CIPHER_AES,
+        "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+        "\xca\xfe\xba\xbe\xfa\xce\xdb\xad\xde\xca\xf8\x88", 12,
+        "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+        "\xab\xad\xda\xd2", 20,
+        "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+        "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+        "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+        "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39",
+        60,
+        "\x42\x83\x1e\xc2\x21\x77\x74\x24\x4b\x72\x21\xb7\x84\xd0\xd4\x9c"
+        "\xe3\xaa\x21\x2f\x2c\x02\xa4\xe0\x35\xc1\x7e\x23\x29\xac\xa1\x2e"
+        "\x21\xd5\x14\xb2\x54\x66\x93\x1c\x7d\x8f\x6a\x5a\xac\x84\xaa\x05"
+        "\x1b\xa3\x0b\x39\x6a\x0a\xac\x97\x3d\x58\xe0\x91\x47\x3f\x59\x85",
+        "\x5b\xc9\x4f\xbc\x32\x21\xa5\xdb\x94\xfa\xe9\x5a\xe7\x12\x1a\x47" },
+      { GCRY_CIPHER_AES,
+        "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+        "\xca\xfe\xba\xbe\xfa\xce\xdb\xad", 8,
+        "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+        "\xab\xad\xda\xd2", 20,
+        "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+        "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+        "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+        "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39",
+        60,
+        "\x61\x35\x3b\x4c\x28\x06\x93\x4a\x77\x7f\xf5\x1f\xa2\x2a\x47\x55"
+        "\x69\x9b\x2a\x71\x4f\xcd\xc6\xf8\x37\x66\xe5\xf9\x7b\x6c\x74\x23"
+        "\x73\x80\x69\x00\xe4\x9f\x24\xb2\x2b\x09\x75\x44\xd4\x89\x6b\x42"
+        "\x49\x89\xb5\xe1\xeb\xac\x0f\x07\xc2\x3f\x45\x98",
+        "\x36\x12\xd2\xe7\x9e\x3b\x07\x85\x56\x1b\xe1\x4a\xac\xa2\xfc\xcb" },
+      { GCRY_CIPHER_AES,
+        "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+        "\x93\x13\x22\x5d\xf8\x84\x06\xe5\x55\x90\x9c\x5a\xff\x52\x69\xaa"
+        "\x6a\x7a\x95\x38\x53\x4f\x7d\xa1\xe4\xc3\x03\xd2\xa3\x18\xa7\x28"
+        "\xc3\xc0\xc9\x51\x56\x80\x95\x39\xfc\xf0\xe2\x42\x9a\x6b\x52\x54"
+        "\x16\xae\xdb\xf5\xa0\xde\x6a\x57\xa6\x37\xb3\x9b", 60,
+        "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+        "\xab\xad\xda\xd2", 20,
+        "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+        "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+        "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+        "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39",
+        60,
+        "\x8c\xe2\x49\x98\x62\x56\x15\xb6\x03\xa0\x33\xac\xa1\x3f\xb8\x94"
+        "\xbe\x91\x12\xa5\xc3\xa2\x11\xa8\xba\x26\x2a\x3c\xca\x7e\x2c\xa7"
+        "\x01\xe4\xa9\xa4\xfb\xa4\x3c\x90\xcc\xdc\xb2\x81\xd4\x8c\x7c\x6f"
+        "\xd6\x28\x75\xd2\xac\xa4\x17\x03\x4c\x34\xae\xe5",
+        "\x61\x9c\xc5\xae\xff\xfe\x0b\xfa\x46\x2a\xf4\x3c\x16\x99\xd0\x50" },
+      { GCRY_CIPHER_AES192,
+        "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+        "\xfe\xff\xe9\x92\x86\x65\x73\x1c",
+        "\x93\x13\x22\x5d\xf8\x84\x06\xe5\x55\x90\x9c\x5a\xff\x52\x69\xaa"
+        "\x6a\x7a\x95\x38\x53\x4f\x7d\xa1\xe4\xc3\x03\xd2\xa3\x18\xa7\x28"
+        "\xc3\xc0\xc9\x51\x56\x80\x95\x39\xfc\xf0\xe2\x42\x9a\x6b\x52\x54"
+        "\x16\xae\xdb\xf5\xa0\xde\x6a\x57\xa6\x37\xb3\x9b", 60,
+        "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+        "\xab\xad\xda\xd2", 20,
+        "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+        "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+        "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+        "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39",
+        60,
+        "\xd2\x7e\x88\x68\x1c\xe3\x24\x3c\x48\x30\x16\x5a\x8f\xdc\xf9\xff"
+        "\x1d\xe9\xa1\xd8\xe6\xb4\x47\xef\x6e\xf7\xb7\x98\x28\x66\x6e\x45"
+        "\x81\xe7\x90\x12\xaf\x34\xdd\xd9\xe2\xf0\x37\x58\x9b\x29\x2d\xb3"
+        "\xe6\x7c\x03\x67\x45\xfa\x22\xe7\xe9\xb7\x37\x3b",
+        "\xdc\xf5\x66\xff\x29\x1c\x25\xbb\xb8\x56\x8f\xc3\xd3\x76\xa6\xd9" },
+      { GCRY_CIPHER_AES256,
+        "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08"
+        "\xfe\xff\xe9\x92\x86\x65\x73\x1c\x6d\x6a\x8f\x94\x67\x30\x83\x08",
+        "\x93\x13\x22\x5d\xf8\x84\x06\xe5\x55\x90\x9c\x5a\xff\x52\x69\xaa"
+        "\x6a\x7a\x95\x38\x53\x4f\x7d\xa1\xe4\xc3\x03\xd2\xa3\x18\xa7\x28"
+        "\xc3\xc0\xc9\x51\x56\x80\x95\x39\xfc\xf0\xe2\x42\x9a\x6b\x52\x54"
+        "\x16\xae\xdb\xf5\xa0\xde\x6a\x57\xa6\x37\xb3\x9b", 60,
+        "\xfe\xed\xfa\xce\xde\xad\xbe\xef\xfe\xed\xfa\xce\xde\xad\xbe\xef"
+        "\xab\xad\xda\xd2", 20,
+        "\xd9\x31\x32\x25\xf8\x84\x06\xe5\xa5\x59\x09\xc5\xaf\xf5\x26\x9a"
+        "\x86\xa7\xa9\x53\x15\x34\xf7\xda\x2e\x4c\x30\x3d\x8a\x31\x8a\x72"
+        "\x1c\x3c\x0c\x95\x95\x68\x09\x53\x2f\xcf\x0e\x24\x49\xa6\xb5\x25"
+        "\xb1\x6a\xed\xf5\xaa\x0d\xe6\x57\xba\x63\x7b\x39",
+        60,
+        "\x5a\x8d\xef\x2f\x0c\x9e\x53\xf1\xf7\x5d\x78\x53\x65\x9e\x2a\x20"
+        "\xee\xb2\xb2\x2a\xaf\xde\x64\x19\xa0\x58\xab\x4f\x6f\x74\x6b\xf4"
+        "\x0f\xc0\xc3\xb7\x80\xf2\x44\x45\x2d\xa3\xeb\xf1\xc5\xd8\x2c\xde"
+        "\xa2\x41\x89\x97\x20\x0e\xf8\x2e\x44\xae\x7e\x3f",
+        "\xa4\x4a\x82\x66\xee\x1c\x8e\xb0\xc8\xb5\xd4\xcf\x5a\xe9\xf1\x9a" }
+    };
+
+  gcry_cipher_hd_t hde, hdd;
+  unsigned char out[MAX_DATA_LEN];
+  unsigned char tag[GCRY_GCM_BLOCK_LEN];
+  int i, keylen;
   gcry_error_t err = 0;
+  size_t pos, poslen;
+  int byteNum;
 
   if (verbose)
-    fprintf (stderr, "Starting bulk cipher checks.\n");
-
-  buflen = 16*100;  /* We check a 1600 byte buffer.  */
-  buffer_base = gcry_xmalloc (buflen+15);
-  buffer = buffer_base + (16 - ((size_t)buffer_base & 0x0f));
-  outbuf_base = gcry_xmalloc (buflen+15);
-  outbuf = outbuf_base + (16 - ((size_t)outbuf_base & 0x0f));
-
+    fprintf (stderr, "  Starting GCM checks.\n");
 
-  for (i = 0; i < DIM (tv); i++)
+  for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
     {
       if (verbose)
-        fprintf (stderr, "    checking bulk encryption for %s [%i], mode %d\n",
-                gcry_cipher_algo_name (tv[i].algo),
-                tv[i].algo, tv[i].mode);
-      err = gcry_cipher_open (&hde, tv[i].algo, tv[i].mode, 0);
+        fprintf (stderr, "    checking GCM 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_GCM, 0);
       if (!err)
-        err = gcry_cipher_open (&hdd, tv[i].algo, tv[i].mode, 0);
+        err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_GCM, 0);
       if (err)
         {
-          fail ("gcry_cipher_open failed: %s\n", gpg_strerror (err));
-          goto leave;
+          fail ("aes-gcm, gcry_cipher_open failed: %s\n", gpg_strerror (err));
+          return;
         }
 
       keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
       if (!keylen)
         {
-          fail ("gcry_cipher_get_algo_keylen failed\n");
-          goto leave;
+          fail ("aes-gcm, gcry_cipher_get_algo_keylen failed\n");
+          return;
         }
 
-      err = gcry_cipher_setkey (hde, tv[i].key, tv[i].keylen);
+      err = gcry_cipher_setkey (hde, tv[i].key, keylen);
       if (!err)
-        err = gcry_cipher_setkey (hdd, tv[i].key, tv[i].keylen);
+        err = gcry_cipher_setkey (hdd, tv[i].key, keylen);
       if (err)
         {
-          fail ("gcry_cipher_setkey failed: %s\n", gpg_strerror (err));
-          goto leave;
-        }
-
-      blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
-      if (!blklen)
-        {
-          fail ("gcry_cipher_get_algo_blklen failed\n");
-          goto leave;
+          fail ("aes-gcm, 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);
+        err = gcry_cipher_setiv (hdd, tv[i].iv, tv[i].ivlen);
       if (err)
         {
-          fail ("gcry_cipher_setiv failed: %s\n", gpg_strerror (err));
-          goto leave;
+          fail ("aes-gcm, gcry_cipher_setiv failed: %s\n",
+                gpg_strerror (err));
+          gcry_cipher_close (hde);
+          gcry_cipher_close (hdd);
+          return;
         }
 
-      /* Fill the buffer with our test pattern.  */
-      for (j=0; j < buflen; j++)
-        buffer[j] = ((j & 0xff) ^ ((j >> 8) & 0xff));
+      for (pos = 0; pos < tv[i].aadlen; pos += step)
+        {
+          poslen = (pos + step < tv[i].aadlen) ? step : tv[i].aadlen - pos;
 
-      err = gcry_cipher_encrypt (hde, outbuf, buflen, buffer, buflen);
-      if (err)
+          err = gcry_cipher_authenticate(hde, tv[i].aad + pos, poslen);
+          if (err)
+            {
+              fail ("aes-gcm, 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 ("aes-gcm, 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)
         {
-          fail ("gcry_cipher_encrypt (algo %d, mode %d) failed: %s\n",
-                tv[i].algo, tv[i].mode, gpg_strerror (err));
-          goto leave;
+          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 ("aes-gcm, gcry_cipher_encrypt (%d) (%d:%d) failed: %s\n",
+                    i, pos, step, gpg_strerror (err));
+              gcry_cipher_close (hde);
+              gcry_cipher_close (hdd);
+              return;
+            }
         }
 
-      gcry_md_hash_buffer (GCRY_MD_SHA1, hash, outbuf, buflen);
-#if 0
-      printf ("/*[%d]*/\n", i);
-      fputs ("      {", stdout);
-      for (j=0; j < 20; j++)
-        printf (" 0x%02x%c%s", hash[j], j==19? ' ':',', j == 9? "\n       ":"");
-      puts ("}");
-#endif
+      if (memcmp (tv[i].out, out, tv[i].inlen))
+        fail ("aes-gcm, encrypt mismatch entry %d (step %d)\n", i, step);
 
-      if (memcmp (hash, tv[i].t1_hash, 20))
-        fail ("encrypt mismatch (algo %d, mode %d)\n",
-              tv[i].algo, tv[i].mode);
+      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, outbuf, buflen, NULL, 0);
+          err = gcry_cipher_decrypt (hdd, out + pos, poslen, NULL, 0);
+          if (err)
+            {
+              fail ("aes-gcm, 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 ("aes-gcm, decrypt mismatch entry %d (step %d)\n", i, step);
+
+      err = gcry_cipher_gettag (hde, out, GCRY_GCM_BLOCK_LEN);
       if (err)
         {
-          fail ("gcry_cipher_decrypt (algo %d, mode %d) failed: %s\n",
-                tv[i].algo, tv[i].mode, gpg_strerror (err));
-          goto leave;
+          fail ("aes-gcm, 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, GCRY_GCM_BLOCK_LEN))
+        fail ("aes-gcm, encrypt tag mismatch entry %d\n", i);
+
+
+      err = gcry_cipher_checktag (hdd, out, GCRY_GCM_BLOCK_LEN);
+      if (err)
+        {
+          fail ("aes-gcm, 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 ("aes-gcm, 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 ("aes-gcm, 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 ("aes-gcm, 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 ("aes-gcm, 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 ("aes-gcm, 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 ("aes-gcm, encrypt mismatch entry %d, (byte-buf)\n", i);
+
+      err = gcry_cipher_gettag (hde, tag, GCRY_GCM_BLOCK_LEN);
+      if (err)
+        {
+          fail ("aes-gcm, 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, GCRY_GCM_BLOCK_LEN))
+        fail ("aes-gcm, 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 ("aes-gcm, 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 ("aes-gcm, decrypt mismatch entry %d\n", i);
+
+      err = gcry_cipher_checktag (hdd, tag, GCRY_GCM_BLOCK_LEN);
+      if (err)
+        {
+          fail ("aes-gcm, 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 GCM checks.\n");
+}
+
+
+static void
+check_gcm_cipher (void)
+{
+  /* Large buffers, no splitting. */
+  _check_gcm_cipher(0xffffffff);
+  /* Split input to one byte buffers. */
+  _check_gcm_cipher(1);
+  /* Split input to 7 byte buffers. */
+  _check_gcm_cipher(7);
+  /* Split input to 16 byte buffers. */
+  _check_gcm_cipher(16);
+}
+
+
+static void
+check_ccm_cipher (void)
+{
+#ifdef HAVE_U64_TYPEDEF
+  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",
+          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",
+          34,
+          "\x7B\x75\x39\x9A\xC0\x83\x1D\xD2\xF0\xBB\xD7\x58\x79\xA2\xFD\x8F\x6C\xAE\x6B\x6C\xD9\xB7\xDB\x24\xC1\x7B\x44\x33\xF4\x34\x96\x3F\x34\xB4"},
+      { GCRY_CIPHER_AES, /* Packet Vector #9 */
+          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+          13, "\x00\x00\x00\x0B\x0A\x09\x08\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",
+          35,
+          "\x82\x53\x1A\x60\xCC\x24\x94\x5A\x4B\x82\x79\x18\x1A\xB5\xC8\x4D\xF2\x1C\xE7\xF9\xB7\x3F\x42\xE1\x97\xEA\x9C\x07\xE5\x6B\x5E\xB1\x7E\x5F\x4E"},
+      { GCRY_CIPHER_AES, /* Packet Vector #10 */
+          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+          13, "\x00\x00\x00\x0C\x0B\x0A\x09\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",
+          29,
+          "\x07\x34\x25\x94\x15\x77\x85\x15\x2B\x07\x40\x98\x33\x0A\xBB\x14\x1B\x94\x7B\x56\x6A\xA9\x40\x6B\x4D\x99\x99\x88\xDD"},
+      { GCRY_CIPHER_AES, /* Packet Vector #11 */
+          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+          13, "\x00\x00\x00\x0D\x0C\x0B\x0A\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",
+          30,
+          "\x67\x6B\xB2\x03\x80\xB0\xE3\x01\xE8\xAB\x79\x59\x0A\x39\x6D\xA7\x8B\x83\x49\x34\xF5\x3A\xA2\xE9\x10\x7A\x8B\x6C\x02\x2C"},
+      { GCRY_CIPHER_AES, /* Packet Vector #12 */
+          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+          13, "\x00\x00\x00\x0E\x0D\x0C\x0B\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",
+          31,
+          "\xC0\xFF\xA0\xD6\xF0\x5B\xDB\x67\xF2\x4D\x43\xA4\x33\x8D\x2A\xA4\xBE\xD7\xB2\x0E\x43\xCD\x1A\xA3\x16\x62\xE7\xAD\x65\xD6\xDB"},
+      { GCRY_CIPHER_AES, /* Packet Vector #13 */
+          16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+          13, "\x00\x41\x2B\x4E\xA9\xCD\xBE\x3C\x96\x96\x76\x6C\xFA",
+          8, "\x0B\xE1\xA8\x8B\xAC\xE0\x18\xB1",
+          23,
+          "\x08\xE8\xCF\x97\xD8\x20\xEA\x25\x84\x60\xE9\x6A\xD9\xCF\x52\x89\x05\x4D\x89\x5C\xEA\xC4\x7C",
+          31,
+          "\x4C\xB9\x7F\x86\xA2\xA4\x68\x9A\x87\x79\x47\xAB\x80\x91\xEF\x53\x86\xA6\xFF\xBD\xD0\x80\xF8\xE7\x8C\xF7\xCB\x0C\xDD\xD7\xB3"},
+      { GCRY_CIPHER_AES, /* Packet Vector #14 */
+          16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+          13, "\x00\x33\x56\x8E\xF7\xB2\x63\x3C\x96\x96\x76\x6C\xFA",
+          8, "\x63\x01\x8F\x76\xDC\x8A\x1B\xCB",
+          24,
+          "\x90\x20\xEA\x6F\x91\xBD\xD8\x5A\xFA\x00\x39\xBA\x4B\xAF\xF9\xBF\xB7\x9C\x70\x28\x94\x9C\xD0\xEC",
+          32,
+          "\x4C\xCB\x1E\x7C\xA9\x81\xBE\xFA\xA0\x72\x6C\x55\xD3\x78\x06\x12\x98\xC8\x5C\x92\x81\x4A\xBC\x33\xC5\x2E\xE8\x1D\x7D\x77\xC0\x8A"},
+      { GCRY_CIPHER_AES, /* Packet Vector #15 */
+          16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+          13, "\x00\x10\x3F\xE4\x13\x36\x71\x3C\x96\x96\x76\x6C\xFA",
+          8, "\xAA\x6C\xFA\x36\xCA\xE8\x6B\x40",
+          25,
+          "\xB9\x16\xE0\xEA\xCC\x1C\x00\xD7\xDC\xEC\x68\xEC\x0B\x3B\xBB\x1A\x02\xDE\x8A\x2D\x1A\xA3\x46\x13\x2E",
+          33,
+          "\xB1\xD2\x3A\x22\x20\xDD\xC0\xAC\x90\x0D\x9A\xA0\x3C\x61\xFC\xF4\xA5\x59\xA4\x41\x77\x67\x08\x97\x08\xA7\x76\x79\x6E\xDB\x72\x35\x06"},
+      { GCRY_CIPHER_AES, /* Packet Vector #16 */
+          16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+          13, "\x00\x76\x4C\x63\xB8\x05\x8E\x3C\x96\x96\x76\x6C\xFA",
+          12, "\xD0\xD0\x73\x5C\x53\x1E\x1B\xEC\xF0\x49\xC2\x44",
+          19,
+          "\x12\xDA\xAC\x56\x30\xEF\xA5\x39\x6F\x77\x0C\xE1\xA6\x6B\x21\xF7\xB2\x10\x1C",
+          27,
+          "\x14\xD2\x53\xC3\x96\x7B\x70\x60\x9B\x7C\xBB\x7C\x49\x91\x60\x28\x32\x45\x26\x9A\x6F\x49\x97\x5B\xCA\xDE\xAF"},
+      { GCRY_CIPHER_AES, /* Packet Vector #17 */
+          16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+          13, "\x00\xF8\xB6\x78\x09\x4E\x3B\x3C\x96\x96\x76\x6C\xFA",
+          12, "\x77\xB6\x0F\x01\x1C\x03\xE1\x52\x58\x99\xBC\xAE",
+          20,
+          "\xE8\x8B\x6A\x46\xC7\x8D\x63\xE5\x2E\xB8\xC5\x46\xEF\xB5\xDE\x6F\x75\xE9\xCC\x0D",
+          28,
+          "\x55\x45\xFF\x1A\x08\x5E\xE2\xEF\xBF\x52\xB2\xE0\x4B\xEE\x1E\x23\x36\xC7\x3E\x3F\x76\x2C\x0C\x77\x44\xFE\x7E\x3C"},
+      { GCRY_CIPHER_AES, /* Packet Vector #18 */
+          16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+          13, "\x00\xD5\x60\x91\x2D\x3F\x70\x3C\x96\x96\x76\x6C\xFA",
+          12, "\xCD\x90\x44\xD2\xB7\x1F\xDB\x81\x20\xEA\x60\xC0",
+          21,
+          "\x64\x35\xAC\xBA\xFB\x11\xA8\x2E\x2F\x07\x1D\x7C\xA4\xA5\xEB\xD9\x3A\x80\x3B\xA8\x7F",
+          29,
+          "\x00\x97\x69\xEC\xAB\xDF\x48\x62\x55\x94\xC5\x92\x51\xE6\x03\x57\x22\x67\x5E\x04\xC8\x47\x09\x9E\x5A\xE0\x70\x45\x51"},
+      { GCRY_CIPHER_AES, /* Packet Vector #19 */
+          16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+          13, "\x00\x42\xFF\xF8\xF1\x95\x1C\x3C\x96\x96\x76\x6C\xFA",
+          8, "\xD8\x5B\xC7\xE6\x9F\x94\x4F\xB8",
+          23,
+          "\x8A\x19\xB9\x50\xBC\xF7\x1A\x01\x8E\x5E\x67\x01\xC9\x17\x87\x65\x98\x09\xD6\x7D\xBE\xDD\x18",
+          33,
+          "\xBC\x21\x8D\xAA\x94\x74\x27\xB6\xDB\x38\x6A\x99\xAC\x1A\xEF\x23\xAD\xE0\xB5\x29\x39\xCB\x6A\x63\x7C\xF9\xBE\xC2\x40\x88\x97\xC6\xBA"},
+      { GCRY_CIPHER_AES, /* Packet Vector #20 */
+          16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+          13, "\x00\x92\x0F\x40\xE5\x6C\xDC\x3C\x96\x96\x76\x6C\xFA",
+          8, "\x74\xA0\xEB\xC9\x06\x9F\x5B\x37",
+          24,
+          "\x17\x61\x43\x3C\x37\xC5\xA3\x5F\xC1\xF3\x9F\x40\x63\x02\xEB\x90\x7C\x61\x63\xBE\x38\xC9\x84\x37",
+          34,
+          "\x58\x10\xE6\xFD\x25\x87\x40\x22\xE8\x03\x61\xA4\x78\xE3\xE9\xCF\x48\x4A\xB0\x4F\x44\x7E\xFF\xF6\xF0\xA4\x77\xCC\x2F\xC9\xBF\x54\x89\x44"},
+      { GCRY_CIPHER_AES, /* Packet Vector #21 */
+          16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+          13, "\x00\x27\xCA\x0C\x71\x20\xBC\x3C\x96\x96\x76\x6C\xFA",
+          8, "\x44\xA3\xAA\x3A\xAE\x64\x75\xCA",
+          25,
+          "\xA4\x34\xA8\xE5\x85\x00\xC6\xE4\x15\x30\x53\x88\x62\xD6\x86\xEA\x9E\x81\x30\x1B\x5A\xE4\x22\x6B\xFA",
+          35,
+          "\xF2\xBE\xED\x7B\xC5\x09\x8E\x83\xFE\xB5\xB3\x16\x08\xF8\xE2\x9C\x38\x81\x9A\x89\xC8\xE7\x76\xF1\x54\x4D\x41\x51\xA4\xED\x3A\x8B\x87\xB9\xCE"},
+      { GCRY_CIPHER_AES, /* Packet Vector #22 */
+          16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+          13, "\x00\x5B\x8C\xCB\xCD\x9A\xF8\x3C\x96\x96\x76\x6C\xFA",
+          12, "\xEC\x46\xBB\x63\xB0\x25\x20\xC3\x3C\x49\xFD\x70",
+          19,
+          "\xB9\x6B\x49\xE2\x1D\x62\x17\x41\x63\x28\x75\xDB\x7F\x6C\x92\x43\xD2\xD7\xC2",
+          29,
+          "\x31\xD7\x50\xA0\x9D\xA3\xED\x7F\xDD\xD4\x9A\x20\x32\xAA\xBF\x17\xEC\x8E\xBF\x7D\x22\xC8\x08\x8C\x66\x6B\xE5\xC1\x97"},
+      { GCRY_CIPHER_AES, /* Packet Vector #23 */
+          16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+          13, "\x00\x3E\xBE\x94\x04\x4B\x9A\x3C\x96\x96\x76\x6C\xFA",
+          12, "\x47\xA6\x5A\xC7\x8B\x3D\x59\x42\x27\xE8\x5E\x71",
+          20,
+          "\xE2\xFC\xFB\xB8\x80\x44\x2C\x73\x1B\xF9\x51\x67\xC8\xFF\xD7\x89\x5E\x33\x70\x76",
+          30,
+          "\xE8\x82\xF1\xDB\xD3\x8C\xE3\xED\xA7\xC2\x3F\x04\xDD\x65\x07\x1E\xB4\x13\x42\xAC\xDF\x7E\x00\xDC\xCE\xC7\xAE\x52\x98\x7D"},
+      { GCRY_CIPHER_AES, /* Packet Vector #24 */
+          16, "\xD7\x82\x8D\x13\xB2\xB0\xBD\xC3\x25\xA7\x62\x36\xDF\x93\xCC\x6B",
+          13, "\x00\x8D\x49\x3B\x30\xAE\x8B\x3C\x96\x96\x76\x6C\xFA",
+          12, "\x6E\x37\xA6\xEF\x54\x6D\x95\x5D\x34\xAB\x60\x59",
+          21,
+          "\xAB\xF2\x1C\x0B\x02\xFE\xB8\x8F\x85\x6D\xF4\xA3\x73\x81\xBC\xE3\xCC\x12\x85\x17\xD4",
+          31,
+          "\xF3\x29\x05\xB8\x8A\x64\x1B\x04\xB9\xC9\xFF\xB5\x8C\xC3\x90\x90\x0F\x3D\xA1\x2A\xB1\x6D\xCE\x9E\x82\xEF\xA1\x6D\xA6\x20\x59"},
+      /* RFC 5528 */
+      { GCRY_CIPHER_CAMELLIA128, /* 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,
+          "\xBA\x73\x71\x85\xE7\x19\x31\x04\x92\xF3\x8A\x5F\x12\x51\xDA\x55\xFA\xFB\xC9\x49\x84\x8A\x0D\xFC\xAE\xCE\x74\x6B\x3D\xB9\xAD"},
+      { GCRY_CIPHER_CAMELLIA128, /* 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,
+          "\x5D\x25\x64\xBF\x8E\xAF\xE1\xD9\x95\x26\xEC\x01\x6D\x1B\xF0\x42\x4C\xFB\xD2\xCD\x62\x84\x8F\x33\x60\xB2\x29\x5D\xF2\x42\x83\xE8"},
+      { GCRY_CIPHER_CAMELLIA128, /* 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,
+          "\x81\xF6\x63\xD6\xC7\x78\x78\x17\xF9\x20\x36\x08\xB9\x82\xAD\x15\xDC\x2B\xBD\x87\xD7\x56\xF7\x92\x04\xF5\x51\xD6\x68\x2F\x23\xAA\x46"},
+      { GCRY_CIPHER_CAMELLIA128, /* 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,
+          "\xCA\xEF\x1E\x82\x72\x11\xB0\x8F\x7B\xD9\x0F\x08\xC7\x72\x88\xC0\x70\xA4\xA0\x8B\x3A\x93\x3A\x63\xE4\x97\xA0"},
+      { GCRY_CIPHER_CAMELLIA128, /* 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,
+          "\x2A\xD3\xBA\xD9\x4F\xC5\x2E\x92\xBE\x43\x8E\x82\x7C\x10\x23\xB9\x6A\x8A\x77\x25\x8F\xA1\x7B\xA7\xF3\x31\xDB\x09"},
+      { GCRY_CIPHER_CAMELLIA128, /* 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,
+          "\xFE\xA5\x48\x0B\xA5\x3F\xA8\xD3\xC3\x44\x22\xAA\xCE\x4D\xE6\x7F\xFA\x3B\xB7\x3B\xAB\xAB\x36\xA1\xEE\x4F\xE0\xFE\x28"},
+      { GCRY_CIPHER_CAMELLIA128, /* 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,
+          "\x54\x53\x20\x26\xE5\x4C\x11\x9A\x8D\x36\xD9\xEC\x6E\x1E\xD9\x74\x16\xC8\x70\x8C\x4B\x5C\x2C\xAC\xAF\xA3\xBC\xCF\x7A\x4E\xBF\x95\x73"},
+      { GCRY_CIPHER_CAMELLIA128, /* 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",
+          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",
+          34,
+          "\x8A\xD1\x9B\x00\x1A\x87\xD1\x48\xF4\xD9\x2B\xEF\x34\x52\x5C\xCC\xE3\xA6\x3C\x65\x12\xA6\xF5\x75\x73\x88\xE4\x91\x3E\xF1\x47\x01\xF4\x41"},
+      { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #9 */
+          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+          13, "\x00\x00\x00\x0B\x0A\x09\x08\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",
+          35,
+          "\x5D\xB0\x8D\x62\x40\x7E\x6E\x31\xD6\x0F\x9C\xA2\xC6\x04\x74\x21\x9A\xC0\xBE\x50\xC0\xD4\xA5\x77\x87\x94\xD6\xE2\x30\xCD\x25\xC9\xFE\xBF\x87"},
+      { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #10 */
+          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+          13, "\x00\x00\x00\x0C\x0B\x0A\x09\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",
+          29,
+          "\xDB\x11\x8C\xCE\xC1\xB8\x76\x1C\x87\x7C\xD8\x96\x3A\x67\xD6\xF3\xBB\xBC\x5C\xD0\x92\x99\xEB\x11\xF3\x12\xF2\x32\x37"},
+      { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #11 */
+          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+          13, "\x00\x00\x00\x0D\x0C\x0B\x0A\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",
+          30,
+          "\x7C\xC8\x3D\x8D\xC4\x91\x03\x52\x5B\x48\x3D\xC5\xCA\x7E\xA9\xAB\x81\x2B\x70\x56\x07\x9D\xAF\xFA\xDA\x16\xCC\xCF\x2C\x4E"},
+      { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #12 */
+          16, "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF",
+          13, "\x00\x00\x00\x0E\x0D\x0C\x0B\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",
+          31,
+          "\x2C\xD3\x5B\x88\x20\xD2\x3E\x7A\xA3\x51\xB0\xE9\x2F\xC7\x93\x67\x23\x8B\x2C\xC7\x48\xCB\xB9\x4C\x29\x47\x79\x3D\x64\xAF\x75"},
+      { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #13 */
+          16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+          13, "\x00\xA9\x70\x11\x0E\x19\x27\xB1\x60\xB6\xA3\x1C\x1C",
+          8, "\x6B\x7F\x46\x45\x07\xFA\xE4\x96",
+          23,
+          "\xC6\xB5\xF3\xE6\xCA\x23\x11\xAE\xF7\x47\x2B\x20\x3E\x73\x5E\xA5\x61\xAD\xB1\x7D\x56\xC5\xA3",
+          31,
+          "\xA4\x35\xD7\x27\x34\x8D\xDD\x22\x90\x7F\x7E\xB8\xF5\xFD\xBB\x4D\x93\x9D\xA6\x52\x4D\xB4\xF6\x45\x58\xC0\x2D\x25\xB1\x27\xEE"},
+      { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #14 */
+          16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+          13, "\x00\x83\xCD\x8C\xE0\xCB\x42\xB1\x60\xB6\xA3\x1C\x1C",
+          8, "\x98\x66\x05\xB4\x3D\xF1\x5D\xE7",
+          24,
+          "\x01\xF6\xCE\x67\x64\xC5\x74\x48\x3B\xB0\x2E\x6B\xBF\x1E\x0A\xBD\x26\xA2\x25\x72\xB4\xD8\x0E\xE7",
+          32,
+          "\x8A\xE0\x52\x50\x8F\xBE\xCA\x93\x2E\x34\x6F\x05\xE0\xDC\x0D\xFB\xCF\x93\x9E\xAF\xFA\x3E\x58\x7C\x86\x7D\x6E\x1C\x48\x70\x38\x06"},
+      { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #15 */
+          16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+          13, "\x00\x5F\x54\x95\x0B\x18\xF2\xB1\x60\xB6\xA3\x1C\x1C",
+          8, "\x48\xF2\xE7\xE1\xA7\x67\x1A\x51",
+          25,
+          "\xCD\xF1\xD8\x40\x6F\xC2\xE9\x01\x49\x53\x89\x70\x05\xFB\xFB\x8B\xA5\x72\x76\xF9\x24\x04\x60\x8E\x08",
+          33,
+          "\x08\xB6\x7E\xE2\x1C\x8B\xF2\x6E\x47\x3E\x40\x85\x99\xE9\xC0\x83\x6D\x6A\xF0\xBB\x18\xDF\x55\x46\x6C\xA8\x08\x78\xA7\x90\x47\x6D\xE5"},
+      { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #16 */
+          16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+          13, "\x00\xEC\x60\x08\x63\x31\x9A\xB1\x60\xB6\xA3\x1C\x1C",
+          12, "\xDE\x97\xDF\x3B\x8C\xBD\x6D\x8E\x50\x30\xDA\x4C",
+          19,
+          "\xB0\x05\xDC\xFA\x0B\x59\x18\x14\x26\xA9\x61\x68\x5A\x99\x3D\x8C\x43\x18\x5B",
+          27,
+          "\x63\xB7\x8B\x49\x67\xB1\x9E\xDB\xB7\x33\xCD\x11\x14\xF6\x4E\xB2\x26\x08\x93\x68\xC3\x54\x82\x8D\x95\x0C\xC5"},
+      { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #17 */
+          16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+          13, "\x00\x60\xCF\xF1\xA3\x1E\xA1\xB1\x60\xB6\xA3\x1C\x1C",
+          12, "\xA5\xEE\x93\xE4\x57\xDF\x05\x46\x6E\x78\x2D\xCF",
+          20,
+          "\x2E\x20\x21\x12\x98\x10\x5F\x12\x9D\x5E\xD9\x5B\x93\xF7\x2D\x30\xB2\xFA\xCC\xD7",
+          28,
+          "\x0B\xC6\xBB\xE2\xA8\xB9\x09\xF4\x62\x9E\xE6\xDC\x14\x8D\xA4\x44\x10\xE1\x8A\xF4\x31\x47\x38\x32\x76\xF6\x6A\x9F"},
+      { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #18 */
+          16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+          13, "\x00\x0F\x85\xCD\x99\x5C\x97\xB1\x60\xB6\xA3\x1C\x1C",
+          12, "\x24\xAA\x1B\xF9\xA5\xCD\x87\x61\x82\xA2\x50\x74",
+          21,
+          "\x26\x45\x94\x1E\x75\x63\x2D\x34\x91\xAF\x0F\xC0\xC9\x87\x6C\x3B\xE4\xAA\x74\x68\xC9",
+          29,
+          "\x22\x2A\xD6\x32\xFA\x31\xD6\xAF\x97\x0C\x34\x5F\x7E\x77\xCA\x3B\xD0\xDC\x25\xB3\x40\xA1\xA3\xD3\x1F\x8D\x4B\x44\xB7"},
+      { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #19 */
+          16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+          13, "\x00\xC2\x9B\x2C\xAA\xC4\xCD\xB1\x60\xB6\xA3\x1C\x1C",
+          8, "\x69\x19\x46\xB9\xCA\x07\xBE\x87",
+          23,
+          "\x07\x01\x35\xA6\x43\x7C\x9D\xB1\x20\xCD\x61\xD8\xF6\xC3\x9C\x3E\xA1\x25\xFD\x95\xA0\xD2\x3D",
+          33,
+          "\x05\xB8\xE1\xB9\xC4\x9C\xFD\x56\xCF\x13\x0A\xA6\x25\x1D\xC2\xEC\xC0\x6C\xCC\x50\x8F\xE6\x97\xA0\x06\x6D\x57\xC8\x4B\xEC\x18\x27\x68"},
+      { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #20 */
+          16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+          13, "\x00\x2C\x6B\x75\x95\xEE\x62\xB1\x60\xB6\xA3\x1C\x1C",
+          8, "\xD0\xC5\x4E\xCB\x84\x62\x7D\xC4",
+          24,
+          "\xC8\xC0\x88\x0E\x6C\x63\x6E\x20\x09\x3D\xD6\x59\x42\x17\xD2\xE1\x88\x77\xDB\x26\x4E\x71\xA5\xCC",
+          34,
+          "\x54\xCE\xB9\x68\xDE\xE2\x36\x11\x57\x5E\xC0\x03\xDF\xAA\x1C\xD4\x88\x49\xBD\xF5\xAE\x2E\xDB\x6B\x7F\xA7\x75\xB1\x50\xED\x43\x83\xC5\xA9"},
+      { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #21 */
+          16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+          13, "\x00\xC5\x3C\xD4\xC2\xAA\x24\xB1\x60\xB6\xA3\x1C\x1C",
+          8, "\xE2\x85\xE0\xE4\x80\x8C\xDA\x3D",
+          25,
+          "\xF7\x5D\xAA\x07\x10\xC4\xE6\x42\x97\x79\x4D\xC2\xB7\xD2\xA2\x07\x57\xB1\xAA\x4E\x44\x80\x02\xFF\xAB",
+          35,
+          "\xB1\x40\x45\x46\xBF\x66\x72\x10\xCA\x28\xE3\x09\xB3\x9B\xD6\xCA\x7E\x9F\xC8\x28\x5F\xE6\x98\xD4\x3C\xD2\x0A\x02\xE0\xBD\xCA\xED\x20\x10\xD3"},
+      { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #22 */
+          16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+          13, "\x00\xBE\xE9\x26\x7F\xBA\xDC\xB1\x60\xB6\xA3\x1C\x1C",
+          12, "\x6C\xAE\xF9\x94\x11\x41\x57\x0D\x7C\x81\x34\x05",
+          19,
+          "\xC2\x38\x82\x2F\xAC\x5F\x98\xFF\x92\x94\x05\xB0\xAD\x12\x7A\x4E\x41\x85\x4E",
+          29,
+          "\x94\xC8\x95\x9C\x11\x56\x9A\x29\x78\x31\xA7\x21\x00\x58\x57\xAB\x61\xB8\x7A\x2D\xEA\x09\x36\xB6\xEB\x5F\x62\x5F\x5D"},
+      { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #23 */
+          16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+          13, "\x00\xDF\xA8\xB1\x24\x50\x07\xB1\x60\xB6\xA3\x1C\x1C",
+          12, "\x36\xA5\x2C\xF1\x6B\x19\xA2\x03\x7A\xB7\x01\x1E",
+          20,
+          "\x4D\xBF\x3E\x77\x4A\xD2\x45\xE5\xD5\x89\x1F\x9D\x1C\x32\xA0\xAE\x02\x2C\x85\xD7",
+          30,
+          "\x58\x69\xE3\xAA\xD2\x44\x7C\x74\xE0\xFC\x05\xF9\xA4\xEA\x74\x57\x7F\x4D\xE8\xCA\x89\x24\x76\x42\x96\xAD\x04\x11\x9C\xE7"},
+      { GCRY_CIPHER_CAMELLIA128, /* Packet Vector #24 */
+          16, "\xD7\x5C\x27\x78\x07\x8C\xA9\x3D\x97\x1F\x96\xFD\xE7\x20\xF4\xCD",
+          13, "\x00\x3B\x8F\xD8\xD3\xA9\x37\xB1\x60\xB6\xA3\x1C\x1C",
+          12, "\xA4\xD4\x99\xF7\x84\x19\x72\x8C\x19\x17\x8B\x0C",
+          21,
+          "\x9D\xC9\xED\xAE\x2F\xF5\xDF\x86\x36\xE8\xC6\xDE\x0E\xED\x55\xF7\x86\x7E\x33\x33\x7D",
+          31,
+          "\x4B\x19\x81\x56\x39\x3B\x0F\x77\x96\x08\x6A\xAF\xB4\x54\xF8\xC3\xF0\x34\xCC\xA9\x66\x94\x5F\x1F\xCE\xA7\xE1\x1B\xEE\x6A\x2F"}
+    };
+  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;
+
+  if (verbose)
+    fprintf (stderr, "  Starting CCM checks.\n");
+
+  for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+    {
+      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;
+            }
+
+          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
+#endif /*HAVE_U64_TYPEDEF*/
+}
+
+
+static void
+check_stream_cipher (void)
+{
+  static const struct tv
+  {
+    const char *name;
+    int algo;
+    int keylen;
+    int ivlen;
+    const char *key;
+    const char *iv;
+    struct data
+    {
+      int inlen;
+      const char *plaintext;
+      const char *out;
+    } data[MAX_DATA_LEN];
+  } tv[] = {
+#ifdef USE_SALSA20
+    {
+      "Salsa20 128 bit, test 1",
+      GCRY_CIPHER_SALSA20, 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",
+          "\x4D\xFA\x5E\x48\x1D\xA2\x3E\xA0"
+        }
+      }
+    },
+    {
+      "Salsa20 128 bit, test 2",
+      GCRY_CIPHER_SALSA20, 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",
+          "\xB6\x6C\x1E\x44\x46\xDD\x95\x57"
+        }
+      }
+    },
+    {
+      "Salsa20 128 bit, test 3",
+      GCRY_CIPHER_SALSA20, 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",
+          "\x05\xE1\xE7\xBE\xB6\x97\xD9\x99"
+        }
+      }
+    },
+    {
+      "Salsa20 256 bit, test 1",
+      GCRY_CIPHER_SALSA20, 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",
+          "\xE3\xBE\x8F\xDD\x8B\xEC\xA2\xE3"
+        }
+      }
+    },
+    {
+      "Salsa20 256 bit, test 2",
+      GCRY_CIPHER_SALSA20, 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",
+          "\x2A\xBA\x3D\xC4\x5B\x49\x47\x00"
+        }
+      }
+    },
+    {
+      "Salsa20 256 bit, ecrypt verified, set 6, vector 0",
+      GCRY_CIPHER_SALSA20, 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",
+          "\xF5\xFA\xD5\x3F\x79\xF9\xDF\x58"
+        },
+        { 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",
+          "\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*/
+  };
+
+  gcry_cipher_hd_t hde, hdd;
+  unsigned char out[MAX_DATA_LEN];
+  int i, j;
+  gcry_error_t err = 0;
+
+
+  if (verbose)
+    fprintf (stderr, "  Starting stream cipher checks.\n");
+
+  for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+    {
+      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);
+
+      if (gcry_cipher_get_algo_blklen(tv[i].algo) != 1)
+        {
+          fail ("stream, gcry_cipher_get_algo_blklen: bad block length\n");
+          continue;
+        }
+
+      err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_STREAM, 0);
+      if (!err)
+        err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_STREAM, 0);
+      if (err)
+        {
+          fail ("stream, gcry_cipher_open for stream mode failed: %s\n",
+                gpg_strerror (err));
+          continue;
+        }
+
+      /* Now loop over all the data samples.  */
+      for (j = 0; tv[i].data[j].inlen; j++)
+        {
+          err = gcry_cipher_setkey (hde, tv[i].key, tv[i].keylen);
+          if (!err)
+            err = gcry_cipher_setkey (hdd, tv[i].key, tv[i].keylen);
+          if (err)
+            {
+              fail ("stream, gcry_cipher_setkey failed: %s\n",
+                    gpg_strerror (err));
+              goto next;
+            }
+
+          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 ("stream, gcry_cipher_setiv failed: %s\n",
+                    gpg_strerror (err));
+              goto next;
+            }
+
+          err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN,
+                                     tv[i].data[j].plaintext,
+                                     tv[i].data[j].inlen);
+          if (err)
+            {
+              fail ("stream, gcry_cipher_encrypt (%d, %d) failed: %s\n",
+                    i, j, gpg_strerror (err));
+              goto next;
+            }
+
+          if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen))
+            {
+              fail ("stream, encrypt mismatch entry %d:%d\n", i, j);
+              mismatch (tv[i].data[j].out, tv[i].data[j].inlen,
+                        out, tv[i].data[j].inlen);
+            }
+
+          err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0);
+          if (err)
+            {
+              fail ("stream, gcry_cipher_decrypt (%d, %d) failed: %s\n",
+                    i, j, gpg_strerror (err));
+              goto next;
+            }
+
+          if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen))
+            fail ("stream, decrypt mismatch entry %d:%d\n", i, j);
+        }
+
+
+      /* This time we encrypt and decrypt one byte at a time */
+      for (j = 0; tv[i].data[j].inlen; j++)
+        {
+          int byteNum;
+
+          err = gcry_cipher_setkey (hde, tv[i].key, tv[i].keylen);
+          if (!err)
+            err = gcry_cipher_setkey (hdd, tv[i].key, tv[i].keylen);
+          if (err)
+            {
+              fail ("stream, gcry_cipher_setkey failed: %s\n",
+                    gpg_strerror (err));
+              goto next;
+            }
+
+          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 ("stream, gcry_cipher_setiv failed: %s\n",
+                    gpg_strerror (err));
+              goto next;
+            }
+
+          for (byteNum = 0; byteNum < tv[i].data[j].inlen; ++byteNum)
+            {
+              err = gcry_cipher_encrypt (hde, out+byteNum, 1,
+                                         (tv[i].data[j].plaintext) + byteNum,
+                                         1);
+              if (err)
+                {
+                  fail ("stream, gcry_cipher_encrypt (%d, %d) failed: %s\n",
+                        i, j, gpg_strerror (err));
+                  goto next;
+                }
+            }
+
+          if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen))
+            fail ("stream, encrypt mismatch entry %d:%d (byte-wise)\n", i, j);
+
+          for (byteNum = 0; byteNum < tv[i].data[j].inlen; ++byteNum)
+            {
+              err = gcry_cipher_decrypt (hdd, out+byteNum, 1, NULL, 0);
+              if (err)
+                {
+                  fail ("stream, gcry_cipher_decrypt (%d, %d) failed: %s\n",
+                        i, j, gpg_strerror (err));
+                  goto next;
+                }
+            }
+
+          if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen))
+            fail ("stream, decrypt mismatch entry %d:%d (byte-wise)\n", i, j);
+        }
+
+    next:
+      gcry_cipher_close (hde);
+      gcry_cipher_close (hdd);
+    }
+  if (verbose)
+    fprintf (stderr, "  Completed stream cipher checks.\n");
+}
+
+
+static void
+check_stream_cipher_large_block (void)
+{
+  static const struct tv
+  {
+    const char *name;
+    int algo;
+    int keylen;
+    int ivlen;
+    const char *key;
+    const char *iv;
+    struct data
+    {
+      int offset, length;
+      const char *result;
+    } data[MAX_DATA_LEN];
+  } tv[] = {
+#ifdef USE_SALSA20
+    {
+      "Salsa20 256 bit, ecrypt verified, set 6, vector 0",
+      GCRY_CIPHER_SALSA20, 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",
+      {
+        { 0, 64,
+          "\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"
+        },
+        { 65472, 64,
+         "\xB7\x0C\x50\x13\x9C\x63\x33\x2E\xF6\xE7\x7A\xC5\x43\x38\xA4\x07"
+         "\x9B\x82\xBE\xC9\xF9\xA4\x03\xDF\xEA\x82\x1B\x83\xF7\x86\x07\x91"
+         "\x65\x0E\xF1\xB2\x48\x9D\x05\x90\xB1\xDE\x77\x2E\xED\xA4\xE3\xBC"
+         "\xD6\x0F\xA7\xCE\x9C\xD6\x23\xD9\xD2\xFD\x57\x58\xB8\x65\x3E\x70"
+        },
+        { 65536, 64,
+         "\x81\x58\x2C\x65\xD7\x56\x2B\x80\xAE\xC2\xF1\xA6\x73\xA9\xD0\x1C"
+         "\x9F\x89\x2A\x23\xD4\x91\x9F\x6A\xB4\x7B\x91\x54\xE0\x8E\x69\x9B"
+         "\x41\x17\xD7\xC6\x66\x47\x7B\x60\xF8\x39\x14\x81\x68\x2F\x5D\x95"
+         "\xD9\x66\x23\xDB\xC4\x89\xD8\x8D\xAA\x69\x56\xB9\xF0\x64\x6B\x6E"
+        },
+        { 131008, 64,
+         "\xA1\x3F\xFA\x12\x08\xF8\xBF\x50\x90\x08\x86\xFA\xAB\x40\xFD\x10"
+         "\xE8\xCA\xA3\x06\xE6\x3D\xF3\x95\x36\xA1\x56\x4F\xB7\x60\xB2\x42"
+         "\xA9\xD6\xA4\x62\x8C\xDC\x87\x87\x62\x83\x4E\x27\xA5\x41\xDA\x2A"
+         "\x5E\x3B\x34\x45\x98\x9C\x76\xF6\x11\xE0\xFE\xC6\xD9\x1A\xCA\xCC"
+        }
+      }
+    },
+    {
+      "Salsa20 256 bit, ecrypt verified, set 6, vector 1",
+      GCRY_CIPHER_SALSA20, 32, 8,
+      "\x05\x58\xAB\xFE\x51\xA4\xF7\x4A\x9D\xF0\x43\x96\xE9\x3C\x8F\xE2"
+      "\x35\x88\xDB\x2E\x81\xD4\x27\x7A\xCD\x20\x73\xC6\x19\x6C\xBF\x12",
+      "\x16\x7D\xE4\x4B\xB2\x19\x80\xE7",
+      {
+        { 0, 64,
+          "\x39\x44\xF6\xDC\x9F\x85\xB1\x28\x08\x38\x79\xFD\xF1\x90\xF7\xDE"
+          "\xE4\x05\x3A\x07\xBC\x09\x89\x6D\x51\xD0\x69\x0B\xD4\xDA\x4A\xC1"
+          "\x06\x2F\x1E\x47\xD3\xD0\x71\x6F\x80\xA9\xB4\xD8\x5E\x6D\x60\x85"
+          "\xEE\x06\x94\x76\x01\xC8\x5F\x1A\x27\xA2\xF7\x6E\x45\xA6\xAA\x87"
+        },
+        { 65472, 64,
+          "\x36\xE0\x3B\x4B\x54\xB0\xB2\xE0\x4D\x06\x9E\x69\x00\x82\xC8\xC5"
+          "\x92\xDF\x56\xE6\x33\xF5\xD8\xC7\x68\x2A\x02\xA6\x5E\xCD\x13\x71"
+          "\x8C\xA4\x35\x2A\xAC\xCB\x0D\xA2\x0E\xD6\xBB\xBA\x62\xE1\x77\xF2"
+          "\x10\xE3\x56\x0E\x63\xBB\x82\x2C\x41\x58\xCA\xA8\x06\xA8\x8C\x82"
+        },
+        { 65536, 64,
+          "\x1B\x77\x9E\x7A\x91\x7C\x8C\x26\x03\x9F\xFB\x23\xCF\x0E\xF8\xE0"
+          "\x8A\x1A\x13\xB4\x3A\xCD\xD9\x40\x2C\xF5\xDF\x38\x50\x10\x98\xDF"
+          "\xC9\x45\xA6\xCC\x69\xA6\xA1\x73\x67\xBC\x03\x43\x1A\x86\xB3\xED"
+          "\x04\xB0\x24\x5B\x56\x37\x9B\xF9\x97\xE2\x58\x00\xAD\x83\x7D\x7D"
+        },
+        { 131008, 64,
+          "\x7E\xC6\xDA\xE8\x1A\x10\x5E\x67\x17\x2A\x0B\x8C\x4B\xBE\x7D\x06"
+          "\xA7\xA8\x75\x9F\x91\x4F\xBE\xB1\xAF\x62\xC8\xA5\x52\xEF\x4A\x4F"
+          "\x56\x96\x7E\xA2\x9C\x74\x71\xF4\x6F\x3B\x07\xF7\xA3\x74\x6E\x95"
+          "\x3D\x31\x58\x21\xB8\x5B\x6E\x8C\xB4\x01\x22\xB9\x66\x35\x31\x3C"
+        }
+      }
+    },
+    {
+      "Salsa20 256 bit, ecrypt verified, set 6, vector 2",
+      GCRY_CIPHER_SALSA20, 32, 8,
+      "\x0A\x5D\xB0\x03\x56\xA9\xFC\x4F\xA2\xF5\x48\x9B\xEE\x41\x94\xE7"
+      "\x3A\x8D\xE0\x33\x86\xD9\x2C\x7F\xD2\x25\x78\xCB\x1E\x71\xC4\x17",
+      "\x1F\x86\xED\x54\xBB\x22\x89\xF0",
+      {
+        { 0, 64,
+          "\x3F\xE8\x5D\x5B\xB1\x96\x0A\x82\x48\x0B\x5E\x6F\x4E\x96\x5A\x44"
+          "\x60\xD7\xA5\x45\x01\x66\x4F\x7D\x60\xB5\x4B\x06\x10\x0A\x37\xFF"
+          "\xDC\xF6\xBD\xE5\xCE\x3F\x48\x86\xBA\x77\xDD\x5B\x44\xE9\x56\x44"
+          "\xE4\x0A\x8A\xC6\x58\x01\x15\x5D\xB9\x0F\x02\x52\x2B\x64\x40\x23"
+        },
+        { 65472, 64,
+          "\xC8\xD6\xE5\x4C\x29\xCA\x20\x40\x18\xA8\x30\xE2\x66\xCE\xEE\x0D"
+          "\x03\x7D\xC4\x7E\x92\x19\x47\x30\x2A\xCE\x40\xD1\xB9\x96\xA6\xD8"
+          "\x0B\x59\x86\x77\xF3\x35\x2F\x1D\xAA\x6D\x98\x88\xF8\x91\xAD\x95"
+          "\xA1\xC3\x2F\xFE\xB7\x1B\xB8\x61\xE8\xB0\x70\x58\x51\x51\x71\xC9"
+        },
+        { 65536, 64,
+          "\xB7\x9F\xD7\x76\x54\x2B\x46\x20\xEF\xCB\x88\x44\x95\x99\xF2\x34"
+          "\x03\xE7\x4A\x6E\x91\xCA\xCC\x50\xA0\x5A\x8F\x8F\x3C\x0D\xEA\x8B"
+          "\x00\xE1\xA5\xE6\x08\x1F\x55\x26\xAE\x97\x5B\x3B\xC0\x45\x0F\x1A"
+          "\x0C\x8B\x66\xF8\x08\xF1\x90\x4B\x97\x13\x61\x13\x7C\x93\x15\x6F"
+        },
+        { 131008, 64,
+          "\x79\x98\x20\x4F\xED\x70\xCE\x8E\x0D\x02\x7B\x20\x66\x35\xC0\x8C"
+          "\x8B\xC4\x43\x62\x26\x08\x97\x0E\x40\xE3\xAE\xDF\x3C\xE7\x90\xAE"
+          "\xED\xF8\x9F\x92\x26\x71\xB4\x53\x78\xE2\xCD\x03\xF6\xF6\x23\x56"
+          "\x52\x9C\x41\x58\xB7\xFF\x41\xEE\x85\x4B\x12\x35\x37\x39\x88\xC8"
+        }
+      }
+    },
+    {
+      "Salsa20 256 bit, ecrypt verified, set 6, vector 3",
+      GCRY_CIPHER_SALSA20, 32, 8,
+      "\x0F\x62\xB5\x08\x5B\xAE\x01\x54\xA7\xFA\x4D\xA0\xF3\x46\x99\xEC"
+      "\x3F\x92\xE5\x38\x8B\xDE\x31\x84\xD7\x2A\x7D\xD0\x23\x76\xC9\x1C",
+      "\x28\x8F\xF6\x5D\xC4\x2B\x92\xF9",
+      {
+        { 0, 64,
+          "\x5E\x5E\x71\xF9\x01\x99\x34\x03\x04\xAB\xB2\x2A\x37\xB6\x62\x5B"
+          "\xF8\x83\xFB\x89\xCE\x3B\x21\xF5\x4A\x10\xB8\x10\x66\xEF\x87\xDA"
+          "\x30\xB7\x76\x99\xAA\x73\x79\xDA\x59\x5C\x77\xDD\x59\x54\x2D\xA2"
+          "\x08\xE5\x95\x4F\x89\xE4\x0E\xB7\xAA\x80\xA8\x4A\x61\x76\x66\x3F"
+        },
+        { 65472, 64,
+          "\x2D\xA2\x17\x4B\xD1\x50\xA1\xDF\xEC\x17\x96\xE9\x21\xE9\xD6\xE2"
+          "\x4E\xCF\x02\x09\xBC\xBE\xA4\xF9\x83\x70\xFC\xE6\x29\x05\x6F\x64"
+          "\x91\x72\x83\x43\x6E\x2D\x3F\x45\x55\x62\x25\x30\x7D\x5C\xC5\xA5"
+          "\x65\x32\x5D\x89\x93\xB3\x7F\x16\x54\x19\x5C\x24\x0B\xF7\x5B\x16"
+        },
+        { 65536, 64,
+          "\xAB\xF3\x9A\x21\x0E\xEE\x89\x59\x8B\x71\x33\x37\x70\x56\xC2\xFE"
+          "\xF4\x2D\xA7\x31\x32\x75\x63\xFB\x67\xC7\xBE\xDB\x27\xF3\x8C\x7C"
+          "\x5A\x3F\xC2\x18\x3A\x4C\x6B\x27\x7F\x90\x11\x52\x47\x2C\x6B\x2A"
+          "\xBC\xF5\xE3\x4C\xBE\x31\x5E\x81\xFD\x3D\x18\x0B\x5D\x66\xCB\x6C"
+        },
+        { 131008, 64,
+          "\x1B\xA8\x9D\xBD\x3F\x98\x83\x97\x28\xF5\x67\x91\xD5\xB7\xCE\x23"
+          "\x50\x36\xDE\x84\x3C\xCC\xAB\x03\x90\xB8\xB5\x86\x2F\x1E\x45\x96"
+          "\xAE\x8A\x16\xFB\x23\xDA\x99\x7F\x37\x1F\x4E\x0A\xAC\xC2\x6D\xB8"
+          "\xEB\x31\x4E\xD4\x70\xB1\xAF\x6B\x9F\x8D\x69\xDD\x79\xA9\xD7\x50"
+        }
+      }
+    },
+    {
+      "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",
+      {
+        { 0, 64,
+          "\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"
+        },
+        { 65472, 64,
+          "\x8F\xBC\x9F\xE8\x69\x1B\xD4\xF0\x82\xB4\x7F\x54\x05\xED\xFB\xC1"
+          "\x6F\x4D\x5A\x12\xDD\xCB\x2D\x75\x4E\x8A\x99\x98\xD0\xB2\x19\x55"
+          "\x7D\xFE\x29\x84\xF4\xA1\xD2\xDD\xA7\x6B\x95\x96\x92\x8C\xCE\x05"
+          "\x56\xF5\x00\x66\xCD\x59\x9E\x44\xEF\x5C\x14\xB2\x26\x68\x3A\xEF"
+        },
+        { 65536, 64,
+          "\xBC\xBD\x01\xDD\x28\x96\x1C\xC7\xAD\x30\x47\x38\x6C\xBC\xC6\x7C"
+          "\x10\x8D\x6A\xF1\x11\x67\xE4\x0D\x7A\xE1\xB2\xFC\x45\x18\xA8\x67"
+          "\xEF\xE4\x02\x65\x1D\x1D\x88\x51\xC4\xFD\x23\x30\xC5\x97\xB3\x6A"
+          "\x46\xD5\x68\x9E\x00\xFC\x96\xFE\xCF\x9C\xE3\xE2\x21\x1D\x44\xBE"
+        },
+        { 131008, 64,
+          "\x91\x66\xF3\x1C\xD8\x5B\x5B\xB1\x8F\xC6\x14\xE5\x4E\x4A\xD6\x7F"
+          "\xB8\x65\x8E\x3B\xF9\xFB\x19\xB7\xA8\x2F\x0F\xE7\xDC\x90\x2D\xF5"
+          "\x63\xC6\xAC\x4F\x44\x67\x48\xC4\xBC\x3E\x14\x05\xE1\x24\x82\x0D"
+          "\xC4\x09\x41\x99\x8F\x44\xA8\x10\xE7\x22\x78\x7F\xCD\x47\x78\x4C"
+        }
+      }
+    },
+    {
+      "Salsa20/12 256 bit, ecrypt verified, set 6, vector 1",
+      GCRY_CIPHER_SALSA20R12, 32, 8,
+      "\x05\x58\xAB\xFE\x51\xA4\xF7\x4A\x9D\xF0\x43\x96\xE9\x3C\x8F\xE2"
+      "\x35\x88\xDB\x2E\x81\xD4\x27\x7A\xCD\x20\x73\xC6\x19\x6C\xBF\x12",
+      "\x16\x7D\xE4\x4B\xB2\x19\x80\xE7",
+      {
+        { 0, 64,
+          "\xC0\x75\x60\xB3\xE7\x76\xB4\x71\xC5\xE2\x93\x14\x26\xCA\xF1\xED"
+          "\x3A\xE4\xB8\x67\x08\x76\x82\xCA\x9D\xFD\xC2\xBA\xE8\x93\x50\xBD"
+          "\x84\x82\x1C\xAE\xFF\x85\xAA\xC4\x9D\x74\x35\xA7\xD9\x88\x93\x52"
+          "\xF5\x27\x9E\x36\x12\x3F\x41\x72\x8A\x14\xEF\x26\x9F\xCB\x94\x4B"
+        },
+        { 65472, 64,
+          "\xEE\xD1\xBB\x58\xF9\x0C\x89\xE0\x5C\xC6\x8B\x2D\xB6\x05\x58\x49"
+          "\xB3\xD2\xB1\x87\xB7\xF0\x2F\x9A\x24\xCE\x34\x2A\xF0\xFC\x47\xA3"
+          "\x74\xBD\x75\x90\xFB\xF4\xFD\x9E\xE5\x9B\x1A\x38\x1E\xBF\xD2\x29"
+          "\xAD\x2A\x29\x01\xB3\xFB\x61\x08\x12\x90\x0B\x92\x30\xE6\x22\xE9"
+        },
+        { 65536, 64,
+          "\x70\xF0\x49\x3A\x1B\x62\x53\xCC\x5E\xD3\x45\x0A\x31\xCF\x37\x7D"
+          "\x83\x4B\xAD\x20\x72\x30\x29\x27\xCC\xD8\x30\x10\x4B\xD3\x05\xFF"
+          "\x59\xD2\x94\x17\xB2\x32\x88\x4E\xC9\x59\x19\x4D\x60\x47\xC3\xDD"
+          "\x66\x56\xC4\x7E\x32\x00\x64\xEB\x01\x44\xF7\x34\x1B\xC3\xD6\x97"
+        },
+        { 131008, 64,
+          "\xD2\xCC\xF7\xC1\xAF\x2A\xB4\x66\xE6\x27\xDB\x44\x08\x40\x96\x9A"
+          "\xBD\xAB\x68\xD8\x86\xAE\x6A\x38\xA1\x3F\xEE\x17\x50\xCA\x97\xB5"
+          "\xD3\x31\x5B\x84\x08\x47\x28\x86\x2F\xBC\xC7\xD4\xA9\x7C\x75\xC8"
+          "\x65\x5F\xF9\xD6\xBB\xC2\x61\x88\x63\x6F\x3E\xDF\xE1\x5C\x7D\x30"
+        }
+      }
+    },
+    {
+      "Salsa20/12 256 bit, ecrypt verified, set 6, vector 2",
+      GCRY_CIPHER_SALSA20R12, 32, 8,
+      "\x0A\x5D\xB0\x03\x56\xA9\xFC\x4F\xA2\xF5\x48\x9B\xEE\x41\x94\xE7"
+      "\x3A\x8D\xE0\x33\x86\xD9\x2C\x7F\xD2\x25\x78\xCB\x1E\x71\xC4\x17",
+      "\x1F\x86\xED\x54\xBB\x22\x89\xF0",
+      {
+        { 0, 64,
+          "\x51\x22\x52\x91\x01\x90\xD1\x54\xD1\x4D\x0B\x92\x32\xB8\x84\x31"
+          "\x8C\xCB\x43\x81\x9B\xD5\x42\x19\x32\xC0\x3A\x13\xF0\x7B\x40\x10"
+          "\x83\xD7\x89\x72\x5A\xA9\xDA\x0B\x41\xCB\x62\x24\x94\x5E\xDC\xB0"
+          "\xFB\x6F\xD7\xC2\x34\x22\x35\xC9\x70\xF6\x4E\x10\x1C\x25\x68\x64"
+        },
+        { 65472, 64,
+          "\x97\x96\x74\x55\x84\x0A\x4A\xE5\xC1\xCA\xCE\x49\x15\x19\x13\x8A"
+          "\xA3\x5E\x5F\x02\x40\x7D\x4A\x1F\xE5\x08\x6D\x35\xF3\x55\x1E\xF4"
+          "\x77\xD9\x28\x9D\x17\x23\x79\x7C\x1A\x49\xEC\x26\x62\x9A\xFA\xDC"
+          "\x56\xA0\x38\xA3\x8C\x75\x88\x1B\x62\x17\xFD\x74\x67\x25\x59\x09"
+        },
+        { 65536, 64,
+          "\x1B\xF8\x2E\x3D\x5C\x54\xDA\xAB\xCF\x84\x15\xF8\xA2\xA1\xA2\x2E"
+          "\x86\x88\x06\x33\x4F\xF3\x11\x36\x04\x74\x1C\x1D\xF2\xB9\x84\x0F"
+          "\x87\xDE\xEF\xB0\x07\x23\xA8\xA1\xB2\x4A\x4D\xA1\x7E\xCD\xAD\x00"
+          "\x01\xF9\x79\xDD\xAE\x2D\xF0\xC5\xE1\xE5\x32\xC4\x8F\x8E\x0D\x34"
+        },
+        { 131008, 64,
+          "\x06\xD8\x4F\x6A\x71\x34\x84\x20\x32\x9F\xCD\x0C\x41\x75\x9A\xD1"
+          "\x8F\x99\x57\xA3\x8F\x22\x89\x3B\xA5\x58\xC5\x05\x11\x97\x28\x5C"
+          "\x6B\xE2\xFD\x6C\x96\xA5\xC6\x62\xAF\xD3\x11\x78\xE7\x0F\x96\x0A"
+          "\xAB\x3F\x47\x96\x23\xA4\x44\xB6\x81\x91\xE4\xC5\x28\x46\x93\x88"
+        }
+      }
+    },
+    {
+      "Salsa20/12 256 bit, ecrypt verified, set 6, vector 3",
+      GCRY_CIPHER_SALSA20R12, 32, 8,
+      "\x0F\x62\xB5\x08\x5B\xAE\x01\x54\xA7\xFA\x4D\xA0\xF3\x46\x99\xEC"
+      "\x3F\x92\xE5\x38\x8B\xDE\x31\x84\xD7\x2A\x7D\xD0\x23\x76\xC9\x1C",
+      "\x28\x8F\xF6\x5D\xC4\x2B\x92\xF9",
+      {
+        { 0, 64,
+          "\x99\xDB\x33\xAD\x11\xCE\x0C\xCB\x3B\xFD\xBF\x8D\x0C\x18\x16\x04"
+          "\x52\xD0\x14\xCD\xE9\x89\xB4\xC4\x11\xA5\x59\xFF\x7C\x20\xA1\x69"
+          "\xE6\xDC\x99\x09\xD8\x16\xBE\xCE\xDC\x40\x63\xCE\x07\xCE\xA8\x28"
+          "\xF4\x4B\xF9\xB6\xC9\xA0\xA0\xB2\x00\xE1\xB5\x2A\xF4\x18\x59\xC5"
+        },
+        { 65472, 64,
+          "\x2F\xF2\x02\x64\xEE\xAF\x47\xAB\x7D\x57\xC3\x62\x24\x53\x54\x51"
+          "\x73\x5A\xC8\x36\xD3\x2D\xD2\x8A\xE6\x36\x45\xCE\x95\x2F\x7F\xDB"
+          "\xE6\x68\x9C\x69\x59\x77\xB1\xC7\x6E\x60\xDD\x5B\x27\xAC\xA4\x76"
+          "\xD2\x62\x0F\xDC\x93\x13\xE8\x48\x9B\xA5\x6A\x70\xC9\xF4\xC3\xA8"
+        },
+        { 65536, 64,
+          "\xEB\x30\xCD\xA7\x27\xC0\xF8\xB7\xE4\x5D\x5E\xF3\x0D\xB7\xCB\xE0"
+          "\x21\xF2\x29\x1E\x5F\x56\x93\x8D\x56\xF6\x87\xB7\x37\xC3\xB4\x27"
+          "\x54\x5C\x56\xA6\xD3\xA0\xBF\x2B\x2F\x47\xB4\x84\x93\xFA\xE4\x5E"
+          "\xD5\x0C\x2E\x9B\xBE\x49\xFD\x92\xD6\x7C\x76\x49\x05\x5F\x06\xFD"
+        },
+        { 131008, 64,
+          "\x0E\xBF\x6C\xC3\xCB\xCB\xE7\x4E\x6E\xE8\x07\x47\x1B\x49\x2A\x67"
+          "\x39\xA5\x2F\x57\x11\x31\xA2\x50\xBC\xDF\xA0\x76\xA2\x65\x90\xD7"
+          "\xED\xE6\x75\x1C\x03\x26\xA0\x2C\xB1\x1C\x58\x77\x35\x52\x80\x4F"
+          "\xD8\x68\x67\x15\x35\x5C\x5A\x5C\xC5\x91\x96\x3A\x75\xE9\x94\xB4"
+        }
+      }
+    }
+#endif /*USE_SALSA20*/
+  };
+
+
+  char zeroes[512];
+  gcry_cipher_hd_t hde;
+  unsigned char *buffer;
+  unsigned char *p;
+  size_t buffersize;
+  unsigned int n;
+  int i, j;
+  gcry_error_t err = 0;
+
+  if (verbose)
+    fprintf (stderr, "  Starting large block stream cipher checks.\n");
+
+  memset (zeroes, 0, 512);
+
+  buffersize = 128 * 1024;
+  buffer = gcry_xmalloc (buffersize+1024);
+  memset (buffer+buffersize, 0x5a, 1024);
+
+  for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++)
+    {
+      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);
+
+      err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_STREAM, 0);
+      if (err)
+        {
+          fail ("large stream, gcry_cipher_open for stream mode failed: %s\n",
+                gpg_strerror (err));
+          continue;
+        }
+
+      err = gcry_cipher_setkey (hde, tv[i].key, tv[i].keylen);
+      if (err)
+        {
+          fail ("large stream, gcry_cipher_setkey failed: %s\n",
+                gpg_strerror (err));
+          goto next;
+        }
+
+      err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen);
+      if (err)
+        {
+          fail ("large stream, gcry_cipher_setiv failed: %s\n",
+                gpg_strerror (err));
+          goto next;
+        }
+
+      for (j=0, p=buffer; j < buffersize/512; j++, p += 512)
+        {
+          err = gcry_cipher_encrypt (hde, p, 512, zeroes, 512);
+          if (err)
+            {
+              fail ("large stream, "
+                    "gcry_cipher_encrypt (%d) block %d failed: %s\n",
+                    i, j, gpg_strerror (err));
+              goto next;
+            }
+        }
+      for (j=0, p=buffer+buffersize; j < 1024; j++, p++)
+        if (*p != 0x5a)
+          die ("large stream, buffer corrupted at j=%d\n", j);
+
+      /* Now loop over all the data samples.  */
+      for (j = 0; tv[i].data[j].length; j++)
+        {
+          assert (tv[i].data[j].offset + tv[i].data[j].length <= buffersize);
+
+          if (memcmp (tv[i].data[j].result,
+                      buffer + tv[i].data[j].offset, tv[i].data[j].length))
+            {
+              fail ("large stream, encrypt mismatch entry %d:%d\n", i, j);
+              mismatch (tv[i].data[j].result, tv[i].data[j].length,
+                        buffer + tv[i].data[j].offset, tv[i].data[j].length);
+            }
+        }
+
+      /*
+       *  Let's do the same thing again but using changing block sizes.
+       */
+      err = gcry_cipher_setkey (hde, tv[i].key, tv[i].keylen);
+      if (err)
+        {
+          fail ("large stream, gcry_cipher_setkey failed: %s\n",
+                gpg_strerror (err));
+          goto next;
+        }
+
+      err = gcry_cipher_setiv (hde, tv[i].iv, tv[i].ivlen);
+      if (err)
+        {
+          fail ("large stream, gcry_cipher_setiv failed: %s\n",
+                gpg_strerror (err));
+          goto next;
+        }
+
+      for (n=0, p=buffer, j = 0; n < buffersize; n += j, p += j)
+        {
+          switch (j)
+            {
+            case   0: j =   1;  break;
+            case   1: j =  64; break;
+            case  64: j=  384; break;
+            case 384: j =  63; break;
+            case  63: j = 512; break;
+            case 512: j =  32; break;
+            case  32: j = 503; break;
+            default:  j = 509; break;
+            }
+          if ( n + j >= buffersize )
+            j = buffersize - n;
+          assert (j <= 512);
+          err = gcry_cipher_encrypt (hde, p, j, zeroes, j);
+          if (err)
+            {
+              fail ("large stream, "
+                    "gcry_cipher_encrypt (%d) offset %u failed: %s\n",
+                    i, n, gpg_strerror (err));
+              goto next;
+            }
+        }
+      for (j=0, p=buffer+buffersize; j < 1024; j++, p++)
+        if (*p != 0x5a)
+          die ("large stream, buffer corrupted at j=%d (line %d)\n",
+               j, __LINE__);
+
+      /* Now loop over all the data samples.  */
+      for (j = 0; tv[i].data[j].length; j++)
+        {
+          assert (tv[i].data[j].offset + tv[i].data[j].length <= buffersize);
+
+          if (memcmp (tv[i].data[j].result,
+                      buffer + tv[i].data[j].offset, tv[i].data[j].length))
+            {
+              fail ("large stream var, encrypt mismatch entry %d:%d\n", i, j);
+              mismatch (tv[i].data[j].result, tv[i].data[j].length,
+                        buffer + tv[i].data[j].offset, tv[i].data[j].length);
+            }
+        }
+
+    next:
+      gcry_cipher_close (hde);
+    }
+
+  gcry_free (buffer);
+  if (verbose)
+    fprintf (stderr, "  Completed large block stream cipher checks.\n");
+}
+
+
+
+/* Check that our bulk encryption fucntions work properly.  */
+static void
+check_bulk_cipher_modes (void)
+{
+  static const struct
+  {
+    int algo;
+    int mode;
+    const char *key;
+    int  keylen;
+    const char *iv;
+    int ivlen;
+    char t1_hash[20];
+  } tv[] = {
+    { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CFB,
+      "abcdefghijklmnop", 16,
+      "1234567890123456", 16,
+/*[0]*/
+      { 0x53, 0xda, 0x27, 0x3c, 0x78, 0x3d, 0x54, 0x66, 0x19, 0x63,
+        0xd7, 0xe6, 0x20, 0x10, 0xcd, 0xc0, 0x5a, 0x0b, 0x06, 0xcc }
+    },
+    { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB,
+      "abcdefghijklmnopABCDEFG", 24,
+      "1234567890123456", 16,
+/*[1]*/
+      { 0xc7, 0xb1, 0xd0, 0x09, 0x95, 0x04, 0x34, 0x61, 0x2b, 0xd9,
+        0xcb, 0xb3, 0xc7, 0xcb, 0xef, 0xea, 0x16, 0x19, 0x9b, 0x3e }
+    },
+    { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB,
+      "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
+      "1234567890123456", 16,
+/*[2]*/
+      { 0x31, 0xe1, 0x1f, 0x63, 0x65, 0x47, 0x8c, 0x3f, 0x53, 0xdb,
+        0xd9, 0x4d, 0x91, 0x1d, 0x02, 0x9c, 0x05, 0x25, 0x58, 0x29 }
+    },
+    { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC,
+      "abcdefghijklmnop", 16,
+      "1234567890123456", 16,
+/*[3]*/
+      { 0xdc, 0x0c, 0xc2, 0xd9, 0x6b, 0x47, 0xf9, 0xeb, 0x06, 0xb4,
+        0x2f, 0x6e, 0xec, 0x72, 0xbf, 0x55, 0x26, 0x7f, 0xa9, 0x97 }
+    },
+    { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC,
+      "abcdefghijklmnopABCDEFG", 24,
+      "1234567890123456", 16,
+/*[4]*/
+      { 0x2b, 0x90, 0x9b, 0xe6, 0x40, 0xab, 0x6e, 0xc2, 0xc5, 0xb1,
+        0x87, 0xf5, 0x43, 0x84, 0x7b, 0x04, 0x06, 0x47, 0xd1, 0x8f }
+    },
+    { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC,
+      "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
+      "1234567890123456", 16,
+/*[5]*/
+      { 0xaa, 0xa8, 0xdf, 0x03, 0xb0, 0xba, 0xc4, 0xe3, 0xc1, 0x02,
+        0x38, 0x31, 0x8d, 0x86, 0xcb, 0x49, 0x6d, 0xad, 0xae, 0x01 }
+    },
+    { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_OFB,
+      "abcdefghijklmnop", 16,
+      "1234567890123456", 16,
+/*[6]*/
+      { 0x65, 0xfe, 0xde, 0x48, 0xd0, 0xa1, 0xa6, 0xf9, 0x24, 0x6b,
+        0x52, 0x5f, 0x21, 0x8a, 0x6f, 0xc7, 0x70, 0x3b, 0xd8, 0x4a }
+    },
+    { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB,
+      "abcdefghijklmnopABCDEFG", 24,
+      "1234567890123456", 16,
+/*[7]*/
+      { 0x59, 0x5b, 0x02, 0xa2, 0x88, 0xc0, 0xbe, 0x94, 0x43, 0xaa,
+        0x39, 0xf6, 0xbd, 0xcc, 0x83, 0x99, 0xee, 0x00, 0xa1, 0x91 }
+    },
+    { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB,
+      "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
+      "1234567890123456", 16,
+/*[8]*/
+      { 0x38, 0x8c, 0xe1, 0xe2, 0xbe, 0x67, 0x60, 0xe8, 0xeb, 0xce,
+        0xd0, 0xc6, 0xaa, 0xd6, 0xf6, 0x26, 0x15, 0x56, 0xd0, 0x2b }
+    },
+    { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CTR,
+      "abcdefghijklmnop", 16,
+      "1234567890123456", 16,
+/*[9]*/
+      { 0x9a, 0x48, 0x94, 0xd6, 0x50, 0x46, 0x81, 0xdb, 0x68, 0x34,
+        0x3b, 0xc5, 0x9e, 0x66, 0x94, 0x81, 0x98, 0xa0, 0xf9, 0xff }
+    },
+    { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CTR,
+      "abcdefghijklmnopABCDEFG", 24,
+      "1234567890123456", 16,
+/*[10]*/
+      { 0x2c, 0x2c, 0xd3, 0x75, 0x81, 0x2a, 0x59, 0x07, 0xeb, 0x08,
+        0xce, 0x28, 0x4c, 0x0c, 0x6a, 0xa8, 0x8f, 0xa3, 0x98, 0x7e }
+    },
+    { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CTR,
+      "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
+      "1234567890123456", 16,
+/*[11]*/
+      { 0x64, 0xce, 0x73, 0x03, 0xc7, 0x89, 0x99, 0x1f, 0xf1, 0xce,
+        0xfe, 0xfb, 0xb9, 0x42, 0x30, 0xdf, 0xbb, 0x68, 0x6f, 0xd3 }
+    },
+    { GCRY_CIPHER_AES, GCRY_CIPHER_MODE_ECB,
+      "abcdefghijklmnop", 16,
+      "1234567890123456", 16,
+/*[12]*/
+      { 0x51, 0xae, 0xf5, 0xac, 0x22, 0xa0, 0xba, 0x11, 0xc5, 0xaa,
+        0xb4, 0x70, 0x99, 0xce, 0x18, 0x08, 0x12, 0x9b, 0xb1, 0xc5 }
+    },
+    { GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB,
+      "abcdefghijklmnopABCDEFG", 24,
+      "1234567890123456", 16,
+/*[13]*/
+      { 0x57, 0x91, 0xea, 0x48, 0xd8, 0xbf, 0x9e, 0xc1, 0xae, 0x33,
+        0xb3, 0xfd, 0xf7, 0x7a, 0xeb, 0x30, 0xb1, 0x62, 0x0d, 0x82 }
+    },
+    { GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB,
+      "abcdefghijklmnopABCDEFGHIJKLMNOP", 32,
+      "1234567890123456", 16,
+/*[14]*/
+      { 0x2d, 0x71, 0x54, 0xb9, 0xc5, 0x28, 0x76, 0xff, 0x76, 0xb5,
+        0x99, 0x37, 0x99, 0x9d, 0xf7, 0x10, 0x6d, 0x86, 0x4f, 0x3f }
+    }
+  };
+  gcry_cipher_hd_t hde = NULL;
+  gcry_cipher_hd_t hdd = NULL;
+  unsigned char *buffer_base, *outbuf_base; /* Allocated buffers.  */
+  unsigned char *buffer, *outbuf;           /* Aligned buffers.  */
+  size_t buflen;
+  unsigned char hash[20];
+  int i, j, keylen, blklen;
+  gcry_error_t err = 0;
+
+  if (verbose)
+    fprintf (stderr, "Starting bulk cipher checks.\n");
+
+  buflen = 16*100;  /* We check a 1600 byte buffer.  */
+  buffer_base = gcry_xmalloc (buflen+16);
+  buffer = buffer_base + (16 - ((size_t)buffer_base & 0x0f));
+  outbuf_base = gcry_xmalloc (buflen+16);
+  outbuf = outbuf_base + (16 - ((size_t)outbuf_base & 0x0f));
+
+
+  for (i = 0; i < DIM (tv); i++)
+    {
+      if (verbose)
+        fprintf (stderr, "    checking bulk encryption for %s [%i], mode %d\n",
+                gcry_cipher_algo_name (tv[i].algo),
+                tv[i].algo, tv[i].mode);
+      err = gcry_cipher_open (&hde, tv[i].algo, tv[i].mode, 0);
+      if (!err)
+        err = gcry_cipher_open (&hdd, tv[i].algo, tv[i].mode, 0);
+      if (err)
+        {
+          fail ("gcry_cipher_open failed: %s\n", gpg_strerror (err));
+          goto leave;
+        }
+
+      keylen = gcry_cipher_get_algo_keylen(tv[i].algo);
+      if (!keylen)
+        {
+          fail ("gcry_cipher_get_algo_keylen failed\n");
+          goto leave;
+        }
+
+      err = gcry_cipher_setkey (hde, tv[i].key, tv[i].keylen);
+      if (!err)
+        err = gcry_cipher_setkey (hdd, tv[i].key, tv[i].keylen);
+      if (err)
+        {
+          fail ("gcry_cipher_setkey failed: %s\n", gpg_strerror (err));
+          goto leave;
+        }
+
+      blklen = gcry_cipher_get_algo_blklen(tv[i].algo);
+      if (!blklen)
+        {
+          fail ("gcry_cipher_get_algo_blklen failed\n");
+          goto leave;
+        }
+
+      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 ("gcry_cipher_setiv failed: %s\n", gpg_strerror (err));
+          goto leave;
+        }
+
+      /* Fill the buffer with our test pattern.  */
+      for (j=0; j < buflen; j++)
+        buffer[j] = ((j & 0xff) ^ ((j >> 8) & 0xff));
+
+      err = gcry_cipher_encrypt (hde, outbuf, buflen, buffer, buflen);
+      if (err)
+        {
+          fail ("gcry_cipher_encrypt (algo %d, mode %d) failed: %s\n",
+                tv[i].algo, tv[i].mode, gpg_strerror (err));
+          goto leave;
+        }
+
+      gcry_md_hash_buffer (GCRY_MD_SHA1, hash, outbuf, buflen);
+#if 0
+      printf ("/*[%d]*/\n", i);
+      fputs ("      {", stdout);
+      for (j=0; j < 20; j++)
+        printf (" 0x%02x%c%s", hash[j], j==19? ' ':',', j == 9? "\n       ":"");
+      puts ("}");
+#endif
+
+      if (memcmp (hash, tv[i].t1_hash, 20))
+        fail ("encrypt mismatch (algo %d, mode %d)\n",
+              tv[i].algo, tv[i].mode);
+
+      err = gcry_cipher_decrypt (hdd, outbuf, buflen, NULL, 0);
+      if (err)
+        {
+          fail ("gcry_cipher_decrypt (algo %d, mode %d) failed: %s\n",
+                tv[i].algo, tv[i].mode, gpg_strerror (err));
+          goto leave;
         }
 
       if (memcmp (buffer, outbuf, buflen))
@@ -1355,110 +3333,194 @@ check_bulk_cipher_modes (void)
 }
 
 
-
-static void
-check_one_cipher (int algo, int mode, int flags)
+/* 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
+   success.  */
+static int
+check_one_cipher_core (int algo, int mode, int flags,
+                       const char *key, size_t nkey,
+                       const unsigned char *plain, size_t nplain,
+                       int bufshift, int pass)
 {
   gcry_cipher_hd_t hd;
-  char key[32];
-  unsigned char plain[16], in[16], out[16];
+  unsigned char in_buffer[1040+1], out_buffer[1040+1];
+  unsigned char *in, *out;
   int keylen;
   gcry_error_t err = 0;
 
-  memcpy (key, "0123456789abcdef.,;/[]{}-=ABCDEF", 32);
-  memcpy (plain, "foobar42FOOBAR17", 16);
+  assert (nkey == 32);
+  assert (nplain == 1040);
+  assert (sizeof(in_buffer) == nplain + 1);
+  assert (sizeof(out_buffer) == sizeof(in_buffer));
+
+  if (!bufshift)
+    {
+      in = in_buffer;
+      out = out_buffer;
+    }
+  else if (bufshift == 1)
+    {
+      in = in_buffer+1;
+      out = out_buffer;
+    }
+  else if (bufshift == 2)
+    {
+      in = in_buffer+1;
+      out = out_buffer+1;
+    }
+  else
+    {
+      in = in_buffer;
+      out = out_buffer+1;
+    }
 
   keylen = gcry_cipher_get_algo_keylen (algo);
   if (!keylen)
     {
-      fail ("algo %d, mode %d, gcry_cipher_get_algo_keylen failed\n",
-           algo, mode);
-      return;
+      fail ("pass %d, algo %d, mode %d, gcry_cipher_get_algo_keylen failed\n",
+           pass, algo, mode);
+      return -1;
     }
 
   if (keylen < 40 / 8 || keylen > 32)
     {
-      fail ("algo %d, mode %d, keylength problem (%d)\n", algo, mode, keylen);
-      return;
+      fail ("pass %d, algo %d, mode %d, keylength problem (%d)\n", pass, algo, mode, keylen);
+      return -1;
     }
 
   err = gcry_cipher_open (&hd, algo, mode, flags);
   if (err)
     {
-      fail ("algo %d, mode %d, gcry_cipher_open failed: %s\n",
-           algo, mode, gpg_strerror (err));
-      return;
+      fail ("pass %d, algo %d, mode %d, gcry_cipher_open failed: %s\n",
+           pass, algo, mode, gpg_strerror (err));
+      return -1;
     }
 
   err = gcry_cipher_setkey (hd, key, keylen);
   if (err)
     {
-      fail ("algo %d, mode %d, gcry_cipher_setkey failed: %s\n",
-           algo, mode, gpg_strerror (err));
+      fail ("pass %d, algo %d, mode %d, gcry_cipher_setkey failed: %s\n",
+           pass, algo, mode, gpg_strerror (err));
       gcry_cipher_close (hd);
-      return;
+      return -1;
     }
 
-  err = gcry_cipher_encrypt (hd, out, 16, plain, 16);
+  err = gcry_cipher_encrypt (hd, out, nplain, plain, nplain);
   if (err)
     {
-      fail ("algo %d, mode %d, gcry_cipher_encrypt failed: %s\n",
-           algo, mode, gpg_strerror (err));
+      fail ("pass %d, algo %d, mode %d, gcry_cipher_encrypt failed: %s\n",
+           pass, algo, mode, gpg_strerror (err));
       gcry_cipher_close (hd);
-      return;
+      return -1;
     }
 
   gcry_cipher_reset (hd);
 
-  err = gcry_cipher_decrypt (hd, in, 16, out, 16);
+  err = gcry_cipher_decrypt (hd, in, nplain, out, nplain);
   if (err)
     {
-      fail ("algo %d, mode %d, gcry_cipher_decrypt failed: %s\n",
-           algo, mode, gpg_strerror (err));
+      fail ("pass %d, algo %d, mode %d, gcry_cipher_decrypt failed: %s\n",
+           pass, algo, mode, gpg_strerror (err));
       gcry_cipher_close (hd);
-      return;
+      return -1;
     }
 
-  if (memcmp (plain, in, 16))
-    fail ("algo %d, mode %d, encrypt-decrypt mismatch\n", algo, mode);
+  if (memcmp (plain, in, nplain))
+    fail ("pass %d, algo %d, mode %d, encrypt-decrypt mismatch\n",
+          pass, algo, mode);
 
   /* Again, using in-place encryption.  */
   gcry_cipher_reset (hd);
 
-  memcpy (out, plain, 16);
-  err = gcry_cipher_encrypt (hd, out, 16, NULL, 0);
+  memcpy (out, plain, nplain);
+  err = gcry_cipher_encrypt (hd, out, nplain, NULL, 0);
   if (err)
     {
-      fail ("algo %d, mode %d, in-place, gcry_cipher_encrypt failed: %s\n",
-           algo, mode, gpg_strerror (err));
+      fail ("pass %d, algo %d, mode %d, in-place, gcry_cipher_encrypt failed:"
+            " %s\n",
+           pass, algo, mode, gpg_strerror (err));
       gcry_cipher_close (hd);
-      return;
+      return -1;
     }
 
   gcry_cipher_reset (hd);
 
-  err = gcry_cipher_decrypt (hd, out, 16, NULL, 0);
+  err = gcry_cipher_decrypt (hd, out, nplain, NULL, 0);
   if (err)
     {
-      fail ("algo %d, mode %d, in-place, gcry_cipher_decrypt failed: %s\n",
-           algo, mode, gpg_strerror (err));
+      fail ("pass %d, algo %d, mode %d, in-place, gcry_cipher_decrypt failed:"
+            " %s\n",
+           pass, algo, mode, gpg_strerror (err));
       gcry_cipher_close (hd);
-      return;
+      return -1;
     }
 
-  if (memcmp (plain, out, 16))
-    fail ("algo %d, mode %d, in-place, encrypt-decrypt mismatch\n",algo, mode);
+  if (memcmp (plain, out, nplain))
+    fail ("pass %d, algo %d, mode %d, in-place, encrypt-decrypt mismatch\n",
+          pass, algo, mode);
 
 
   gcry_cipher_close (hd);
 
+  return 0;
+}
+
+
+
+static void
+check_one_cipher (int algo, int mode, int flags)
+{
+  char key[32+1];
+  unsigned char plain[1040+1];
+  int bufshift, i;
+
+  for (bufshift=0; bufshift < 4; bufshift++)
+    {
+      /* Pass 0: Standard test.  */
+      memcpy (key, "0123456789abcdef.,;/[]{}-=ABCDEF", 32);
+      memcpy (plain, "foobar42FOOBAR17", 16);
+      for (i = 16; i < 1040; i += 16)
+        {
+          memcpy (&plain[i], &plain[i-16], 16);
+          if (!++plain[i+7])
+            plain[i+6]++;
+          if (!++plain[i+15])
+            plain[i+14]++;
+        }
+
+      if (check_one_cipher_core (algo, mode, flags, key, 32, plain, 1040,
+                                 bufshift, 0+10*bufshift))
+        return;
+
+      /* Pass 1: Key not aligned.  */
+      memmove (key+1, key, 32);
+      if (check_one_cipher_core (algo, mode, flags, key+1, 32, plain, 1040,
+                                 bufshift, 1+10*bufshift))
+        return;
+
+      /* Pass 2: Key not aligned and data not aligned.  */
+      memmove (plain+1, plain, 1040);
+      if (check_one_cipher_core (algo, mode, flags, key+1, 32, plain+1, 1040,
+                                 bufshift, 2+10*bufshift))
+        return;
+
+      /* Pass 3: Key aligned and data not aligned.  */
+      memmove (key, key+1, 32);
+      if (check_one_cipher_core (algo, mode, flags, key, 32, plain+1, 1040,
+                                 bufshift, 3+10*bufshift))
+        return;
+    }
+
+  return;
 }
 
 
+
 static void
 check_ciphers (void)
 {
-  static int algos[] = {
+  static const int algos[] = {
 #if USE_BLOWFISH
     GCRY_CIPHER_BLOWFISH,
 #endif
@@ -1494,12 +3556,22 @@ check_ciphers (void)
     GCRY_CIPHER_CAMELLIA192,
     GCRY_CIPHER_CAMELLIA256,
 #endif
+#if USE_IDEA
+    GCRY_CIPHER_IDEA,
+#endif
+#if USE_GOST28147
+    GCRY_CIPHER_GOST28147,
+#endif
     0
   };
-  static int algos2[] = {
+  static const int algos2[] = {
 #if USE_ARCFOUR
     GCRY_CIPHER_ARCFOUR,
 #endif
+#if USE_SALSA20
+    GCRY_CIPHER_SALSA20,
+    GCRY_CIPHER_SALSA20R12,
+#endif
     0
   };
   int i;
@@ -1526,6 +3598,8 @@ 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_GCM_BLOCK_LEN)
+        check_one_cipher (algos[i], GCRY_CIPHER_MODE_GCM, 0);
     }
 
   for (i = 0; algos2[i]; i++)
@@ -1538,7 +3612,7 @@ check_ciphers (void)
           continue;
         }
       if (verbose)
-       fprintf (stderr, "  checking `%s'\n",
+       fprintf (stderr, "  checking %s\n",
                 gcry_cipher_algo_name (algos2[i]));
 
       check_one_cipher (algos2[i], GCRY_CIPHER_MODE_STREAM, 0);
@@ -1563,6 +3637,10 @@ check_cipher_modes(void)
   check_ctr_cipher ();
   check_cfb_cipher ();
   check_ofb_cipher ();
+  check_ccm_cipher ();
+  check_gcm_cipher ();
+  check_stream_cipher ();
+  check_stream_cipher_large_block ();
 
   if (verbose)
     fprintf (stderr, "Completed Cipher Mode checks.\n");
@@ -1631,9 +3709,75 @@ check_one_md (int algo, const char *data, int len, const char *expect)
 
 
 static void
+check_one_md_multi (int algo, const char *data, int len, const char *expect)
+{
+  gpg_error_t err;
+  gcry_buffer_t iov[3];
+  int iovcnt;
+  char digest[64];
+  int mdlen;
+  int i;
+
+  mdlen = gcry_md_get_algo_dlen (algo);
+  if (mdlen < 1 || mdlen > 64)
+    {
+      fail ("check_one_md_multi: algo %d, gcry_md_get_algo_dlen failed: %d\n",
+            algo, mdlen);
+      return;
+    }
+
+  if (*data == '!' && !data[1])
+    return;  /* We can't do that here.  */
+
+  memset (iov, 0, sizeof iov);
+
+  iov[0].data = (void*)data;
+  if (len)
+    {
+      iov[0].len = 1;
+      len--;
+      data++;
+    }
+  iovcnt = 1;
+  if (len >= 4)
+    {
+      iov[iovcnt].data = (void*)data;
+      iov[iovcnt].len = 4;
+      iovcnt++;
+      data += 4;
+      len  -= 4;
+    }
+  iov[iovcnt].data = (void*)data;
+  iov[iovcnt].len = len;
+  iovcnt++;
+  assert (iovcnt <= DIM (iov));
+
+  err = gcry_md_hash_buffers (algo, 0, digest, iov, iovcnt);
+  if (err)
+    {
+      fail ("check_one_md_multi: algo %d, gcry_hash_buffers failed: %s\n",
+            algo, gpg_strerror (err));
+      return;
+    }
+  if (memcmp (digest, expect, mdlen))
+    {
+      printf ("computed: ");
+      for (i = 0; i < mdlen; i++)
+       printf ("%02x ", digest[i] & 0xFF);
+      printf ("\nexpected: ");
+      for (i = 0; i < mdlen; i++)
+       printf ("%02x ", expect[i] & 0xFF);
+      printf ("\n");
+
+      fail ("check_one_md_multi: algo %d, digest mismatch\n", algo);
+    }
+}
+
+
+static void
 check_digests (void)
 {
-  static struct algos
+  static const struct algos
   {
     int md;
     const char *data;
@@ -1851,13 +3995,62 @@ check_digests (void)
        "\x08\xEB\xA2\x66\x29\x12\x9D\x8F\xB7\xCB\x57\x21\x1B\x92\x81\xA6"
        "\x55\x17\xCC\x87\x9D\x7B\x96\x21\x42\xC6\x5F\x5A\x7A\xF0\x14\x67" },
       { GCRY_MD_WHIRLPOOL,
+        "!",
+        "\x0C\x99\x00\x5B\xEB\x57\xEF\xF5\x0A\x7C\xF0\x05\x56\x0D\xDF\x5D"
+        "\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_GOSTR3411_94,
+       "This is message, length=32 bytes",
+       "\xB1\xC4\x66\xD3\x75\x19\xB8\x2E\x83\x19\x81\x9F\xF3\x25\x95\xE0"
+       "\x47\xA2\x8C\xB6\xF8\x3E\xFF\x1C\x69\x16\xA8\x15\xA6\x37\xFF\xFA" },
+      { GCRY_MD_GOSTR3411_94,
+       "Suppose the original message has length = 50 bytes",
+       "\x47\x1A\xBA\x57\xA6\x0A\x77\x0D\x3A\x76\x13\x06\x35\xC1\xFB\xEA"
+       "\x4E\xF1\x4D\xE5\x1F\x78\xB4\xAE\x57\xDD\x89\x3B\x62\xF5\x52\x08" },
+      { GCRY_MD_GOSTR3411_94,
+       "",
+       "\xCE\x85\xB9\x9C\xC4\x67\x52\xFF\xFE\xE3\x5C\xAB\x9A\x7B\x02\x78"
+       "\xAB\xB4\xC2\xD2\x05\x5C\xFF\x68\x5A\xF4\x91\x2C\x49\x49\x0F\x8D" },
+      { GCRY_MD_GOSTR3411_94,
        "!",
-       "\x0C\x99\x00\x5B\xEB\x57\xEF\xF5\x0A\x7C\xF0\x05\x56\x0D\xDF\x5D"
-       "\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" },
-      {        0 },
+       "\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_STRIBOG512,
+        "012345678901234567890123456789012345678901234567890123456789012",
+        "\x1b\x54\xd0\x1a\x4a\xf5\xb9\xd5\xcc\x3d\x86\xd6\x8d\x28\x54\x62"
+        "\xb1\x9a\xbc\x24\x75\x22\x2f\x35\xc0\x85\x12\x2b\xe4\xba\x1f\xfa"
+        "\x00\xad\x30\xf8\x76\x7b\x3a\x82\x38\x4c\x65\x74\xf0\x24\xc3\x11"
+        "\xe2\xa4\x81\x33\x2b\x08\xef\x7f\x41\x79\x78\x91\xc1\x64\x6f\x48" },
+      { GCRY_MD_STRIBOG256,
+        "012345678901234567890123456789012345678901234567890123456789012",
+        "\x9d\x15\x1e\xef\xd8\x59\x0b\x89\xda\xa6\xba\x6c\xb7\x4a\xf9\x27"
+        "\x5d\xd0\x51\x02\x6b\xb1\x49\xa4\x52\xfd\x84\xe5\xe5\x7b\x55\x00" },
+      { GCRY_MD_STRIBOG512,
+        "\xd1\xe5\x20\xe2\xe5\xf2\xf0\xe8\x2c\x20\xd1\xf2\xf0\xe8\xe1\xee"
+        "\xe6\xe8\x20\xe2\xed\xf3\xf6\xe8\x2c\x20\xe2\xe5\xfe\xf2\xfa\x20"
+        "\xf1\x20\xec\xee\xf0\xff\x20\xf1\xf2\xf0\xe5\xeb\xe0\xec\xe8\x20"
+        "\xed\xe0\x20\xf5\xf0\xe0\xe1\xf0\xfb\xff\x20\xef\xeb\xfa\xea\xfb"
+        "\x20\xc8\xe3\xee\xf0\xe5\xe2\xfb",
+        "\x1e\x88\xe6\x22\x26\xbf\xca\x6f\x99\x94\xf1\xf2\xd5\x15\x69\xe0"
+        "\xda\xf8\x47\x5a\x3b\x0f\xe6\x1a\x53\x00\xee\xe4\x6d\x96\x13\x76"
+        "\x03\x5f\xe8\x35\x49\xad\xa2\xb8\x62\x0f\xcd\x7c\x49\x6c\xe5\xb3"
+        "\x3f\x0c\xb9\xdd\xdc\x2b\x64\x60\x14\x3b\x03\xda\xba\xc9\xfb\x28" },
+      { GCRY_MD_STRIBOG256,
+        "\xd1\xe5\x20\xe2\xe5\xf2\xf0\xe8\x2c\x20\xd1\xf2\xf0\xe8\xe1\xee"
+        "\xe6\xe8\x20\xe2\xed\xf3\xf6\xe8\x2c\x20\xe2\xe5\xfe\xf2\xfa\x20"
+        "\xf1\x20\xec\xee\xf0\xff\x20\xf1\xf2\xf0\xe5\xeb\xe0\xec\xe8\x20"
+        "\xed\xe0\x20\xf5\xf0\xe0\xe1\xf0\xfb\xff\x20\xef\xeb\xfa\xea\xfb"
+        "\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 }
     };
+  gcry_error_t err;
   int i;
 
   if (verbose)
@@ -1874,16 +4067,70 @@ check_digests (void)
           continue;
         }
       if (verbose)
-       fprintf (stderr, "  checking %s [%i] for length %zi\n",
+       fprintf (stderr, "  checking %s [%i] for length %d\n",
                 gcry_md_algo_name (algos[i].md),
                 algos[i].md,
                  !strcmp (algos[i].data, "!")?
-                 1000000 : strlen(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),
+                          algos[i].expect);
+    }
+
+  /* Check the Whirlpool bug emulation.  */
+  if (!gcry_md_test_algo (GCRY_MD_WHIRLPOOL) && !in_fips_mode)
+    {
+      static const char expect[] =
+        "\x35\x28\xd6\x4c\x56\x2c\x55\x2e\x3b\x91\x93\x95\x7b\xdd\xcc\x6e"
+        "\x6f\xb7\xbf\x76\x22\x9c\xc6\x23\xda\x3e\x09\x9b\x36\xe8\x6d\x76"
+        "\x2f\x94\x3b\x0c\x63\xa0\xba\xa3\x4d\x66\x71\xe6\x5d\x26\x67\x28"
+        "\x36\x1f\x0e\x1a\x40\xf0\xce\x83\x50\x90\x1f\xfa\x3f\xed\x6f\xfd";
+      gcry_md_hd_t hd;
+      int algo = GCRY_MD_WHIRLPOOL;
+      unsigned char *p;
+      int mdlen;
+
+      err = gcry_md_open (&hd, GCRY_MD_WHIRLPOOL, GCRY_MD_FLAG_BUGEMU1);
+      if (err)
+        {
+          fail ("algo %d, gcry_md_open failed: %s\n", algo, gpg_strerror (err));
+          goto leave;
+        }
+
+      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);
+          gcry_md_close (hd);
+          goto leave;
+        }
+
+      /* Hash 62 byes in chunks.  */
+      gcry_md_write (hd, "1234567890", 10);
+      gcry_md_write (hd, "1234567890123456789012345678901234567890123456789012",
+                     52);
+
+      p = gcry_md_read (hd, algo);
+
+      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);
+        }
+
+      gcry_md_close (hd);
     }
 
+ leave:
   if (verbose)
     fprintf (stderr, "Completed hash checks.\n");
 }
@@ -1947,7 +4194,7 @@ check_one_hmac (int algo, const char *data, int datalen,
 static void
 check_hmac (void)
 {
-  static struct algos
+  static const struct algos
   {
     int md;
     const char *data;
@@ -2245,10 +4492,10 @@ check_hmac (void)
         }
       if (verbose)
        fprintf (stderr,
-                 "  checking %s [%i] for %zi byte key and %zi byte data\n",
+                 "  checking %s [%i] for %d byte key and %d byte data\n",
                 gcry_md_algo_name (algos[i].md),
                 algos[i].md,
-                strlen(algos[i].key), strlen(algos[i].data));
+                (int)strlen(algos[i].key), (int)strlen(algos[i].data));
 
       check_one_hmac (algos[i].md, algos[i].data, strlen (algos[i].data),
                      algos[i].key, strlen(algos[i].key),
@@ -2257,11 +4504,613 @@ check_hmac (void)
 
   if (verbose)
     fprintf (stderr, "Completed hashed MAC checks.\n");
- }
+}
+
+
+static void
+check_one_mac (int algo, const char *data, int datalen,
+              const char *key, int keylen, const char *iv, int ivlen,
+              const char *expect, int test_buffering)
+{
+  gcry_mac_hd_t hd;
+  unsigned char *p;
+  unsigned int maclen;
+  size_t macoutlen;
+  int i;
+  gcry_error_t err = 0;
+
+  err = gcry_mac_open (&hd, algo, 0, NULL);
+  if (err)
+    {
+      fail ("algo %d, gcry_mac_open failed: %s\n", algo, gpg_strerror (err));
+      return;
+    }
+
+  maclen = gcry_mac_get_algo_maclen (algo);
+  if (maclen < 1 || maclen > 500)
+    {
+      fail ("algo %d, gcry_mac_get_algo_maclen failed: %d\n", algo, maclen);
+      return;
+    }
+
+  p = malloc(maclen);
+  if (!p)
+    {
+      fail ("algo %d, could not malloc %d bytes\n", algo, maclen);
+      return;
+    }
+
+  err = gcry_mac_setkey (hd, key, keylen);
+  if (err)
+    fail("algo %d, mac gcry_mac_setkey failed: %s\n", algo, gpg_strerror (err));
+  if (err)
+    goto out;
+
+  if (ivlen && iv)
+    {
+      err = gcry_mac_setiv (hd, iv, ivlen);
+      if (err)
+        fail("algo %d, mac gcry_mac_ivkey failed: %s\n", algo,
+             gpg_strerror (err));
+      if (err)
+        goto out;
+    }
+
+  if (test_buffering)
+    {
+      for (i = 0; i < datalen; i++)
+        {
+          err = gcry_mac_write (hd, &data[i], 1);
+          if (err)
+            fail("algo %d, mac gcry_mac_write [buf-offset: %d] failed: %s\n",
+                 algo, i, gpg_strerror (err));
+          if (err)
+            goto out;
+        }
+    }
+  else
+    {
+      err = gcry_mac_write (hd, data, datalen);
+      if (err)
+        fail("algo %d, mac gcry_mac_write failed: %s\n", algo, gpg_strerror (err));
+      if (err)
+        goto out;
+    }
+
+  err = gcry_mac_verify (hd, expect, maclen);
+  if (err)
+    fail("algo %d, mac gcry_mac_verify failed: %s\n", algo, gpg_strerror (err));
+  if (err)
+    goto out;
+
+  macoutlen = maclen;
+  err = gcry_mac_read (hd, p, &macoutlen);
+  if (err)
+    fail("algo %d, mac gcry_mac_read failed: %s\n", algo, gpg_strerror (err));
+  if (err)
+    goto out;
+
+  if (memcmp (p, expect, maclen))
+    {
+      printf ("computed: ");
+      for (i = 0; i < maclen; i++)
+       printf ("%02x ", p[i] & 0xFF);
+      printf ("\nexpected: ");
+      for (i = 0; i < maclen; i++)
+       printf ("%02x ", expect[i] & 0xFF);
+      printf ("\n");
+
+      fail ("algo %d, digest mismatch\n", algo);
+    }
+  if (err)
+    goto out;
+
+out:
+  free (p);
+  gcry_mac_close (hd);
+}
+
+static void
+check_mac (void)
+{
+  static const struct algos
+  {
+    int algo;
+    const char *data;
+    const char *key;
+    const char *expect;
+    const char *iv;
+  } algos[] =
+    {
+      { GCRY_MAC_HMAC_MD5, "what do ya want for nothing?", "Jefe",
+        "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38" },
+      { GCRY_MAC_HMAC_MD5,
+        "Hi There",
+        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b",
+        "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d" },
+      { GCRY_MAC_HMAC_MD5,
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd",
+        "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA",
+        "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6" },
+      { GCRY_MAC_HMAC_MD5,
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd",
+        "\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",
+        "\x69\x7e\xaf\x0a\xca\x3a\x3a\xea\x3a\x75\x16\x47\x46\xff\xaa\x79" },
+      { GCRY_MAC_HMAC_MD5, "Test With Truncation",
+        "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c",
+        "\x56\x46\x1e\xf2\x34\x2e\xdc\x00\xf9\xba\xb9\x95\x69\x0e\xfd\x4c" },
+      { GCRY_MAC_HMAC_MD5, "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",
+        "\x6b\x1a\xb7\xfe\x4b\xd7\xbf\x8f\x0b\x62\xe6\xce\x61\xb9\xd0\xcd" },
+      { GCRY_MAC_HMAC_MD5,
+        "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data",
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+        "\xaa\xaa\xaa\xaa\xaa",
+        "\x6f\x63\x0f\xad\x67\xcd\xa0\xee\x1f\xb1\xf5\x62\xdb\x3a\xa5\x3e", },
+      { GCRY_MAC_HMAC_SHA256, "what do ya want for nothing?", "Jefe",
+        "\x5b\xdc\xc1\x46\xbf\x60\x75\x4e\x6a\x04\x24\x26\x08\x95\x75\xc7\x5a"
+        "\x00\x3f\x08\x9d\x27\x39\x83\x9d\xec\x58\xb9\x64\xec\x38\x43" },
+      { GCRY_MAC_HMAC_SHA256,
+        "Hi There",
+        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+        "\x0b\x0b\x0b",
+        "\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1\x2b\x88"
+        "\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32\xcf\xf7" },
+      { GCRY_MAC_HMAC_SHA256,
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd",
+        "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
+        "\xAA\xAA\xAA\xAA",
+        "\x77\x3e\xa9\x1e\x36\x80\x0e\x46\x85\x4d\xb8\xeb\xd0\x91\x81\xa7"
+        "\x29\x59\x09\x8b\x3e\xf8\xc1\x22\xd9\x63\x55\x14\xce\xd5\x65\xfe" },
+      { GCRY_MAC_HMAC_SHA256,
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd",
+        "\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",
+        "\x82\x55\x8a\x38\x9a\x44\x3c\x0e\xa4\xcc\x81\x98\x99\xf2\x08"
+        "\x3a\x85\xf0\xfa\xa3\xe5\x78\xf8\x07\x7a\x2e\x3f\xf4\x67\x29\x66\x5b" },
+      { GCRY_MAC_HMAC_SHA256,
+        "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",
+        "\x60\xe4\x31\x59\x1e\xe0\xb6\x7f\x0d\x8a\x26\xaa\xcb\xf5\xb7\x7f"
+        "\x8e\x0b\xc6\x21\x37\x28\xc5\x14\x05\x46\x04\x0f\x0e\xe3\x7f\x54" },
+      { GCRY_MAC_HMAC_SHA256,
+        "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",
+        "\x9b\x09\xff\xa7\x1b\x94\x2f\xcb\x27\x63\x5f\xbc\xd5\xb0\xe9\x44"
+        "\xbf\xdc\x63\x64\x4f\x07\x13\x93\x8a\x7f\x51\x53\x5c\x3a\x35\xe2" },
+      { GCRY_MAC_HMAC_SHA224, "what do ya want for nothing?", "Jefe",
+        "\xa3\x0e\x01\x09\x8b\xc6\xdb\xbf\x45\x69\x0f\x3a\x7e\x9e\x6d\x0f"
+        "\x8b\xbe\xa2\xa3\x9e\x61\x48\x00\x8f\xd0\x5e\x44" },
+      { GCRY_MAC_HMAC_SHA224,
+        "Hi There",
+        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+        "\x0b\x0b\x0b",
+        "\x89\x6f\xb1\x12\x8a\xbb\xdf\x19\x68\x32\x10\x7c\xd4\x9d\xf3\x3f\x47"
+        "\xb4\xb1\x16\x99\x12\xba\x4f\x53\x68\x4b\x22" },
+      { GCRY_MAC_HMAC_SHA224,
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd",
+        "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
+        "\xAA\xAA\xAA\xAA",
+        "\x7f\xb3\xcb\x35\x88\xc6\xc1\xf6\xff\xa9\x69\x4d\x7d\x6a\xd2\x64"
+        "\x93\x65\xb0\xc1\xf6\x5d\x69\xd1\xec\x83\x33\xea" },
+      { GCRY_MAC_HMAC_SHA224,
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd",
+        "\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",
+        "\x6c\x11\x50\x68\x74\x01\x3c\xac\x6a\x2a\xbc\x1b\xb3\x82\x62"
+        "\x7c\xec\x6a\x90\xd8\x6e\xfc\x01\x2d\xe7\xaf\xec\x5a" },
+      { GCRY_MAC_HMAC_SHA224,
+        "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",
+        "\x95\xe9\xa0\xdb\x96\x20\x95\xad\xae\xbe\x9b\x2d\x6f\x0d\xbc\xe2"
+        "\xd4\x99\xf1\x12\xf2\xd2\xb7\x27\x3f\xa6\x87\x0e" },
+      { GCRY_MAC_HMAC_SHA224,
+        "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",
+        "\x3a\x85\x41\x66\xac\x5d\x9f\x02\x3f\x54\xd5\x17\xd0\xb3\x9d\xbd"
+        "\x94\x67\x70\xdb\x9c\x2b\x95\xc9\xf6\xf5\x65\xd1" },
+      { GCRY_MAC_HMAC_SHA384, "what do ya want for nothing?", "Jefe",
+        "\xaf\x45\xd2\xe3\x76\x48\x40\x31\x61\x7f\x78\xd2\xb5\x8a\x6b\x1b"
+        "\x9c\x7e\xf4\x64\xf5\xa0\x1b\x47\xe4\x2e\xc3\x73\x63\x22\x44\x5e"
+        "\x8e\x22\x40\xca\x5e\x69\xe2\xc7\x8b\x32\x39\xec\xfa\xb2\x16\x49" },
+      { GCRY_MAC_HMAC_SHA384,
+        "Hi There",
+        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+        "\x0b\x0b\x0b",
+        "\xaf\xd0\x39\x44\xd8\x48\x95\x62\x6b\x08\x25\xf4\xab\x46\x90\x7f\x15"
+        "\xf9\xda\xdb\xe4\x10\x1e\xc6\x82\xaa\x03\x4c\x7c\xeb\xc5\x9c\xfa\xea"
+        "\x9e\xa9\x07\x6e\xde\x7f\x4a\xf1\x52\xe8\xb2\xfa\x9c\xb6" },
+      { GCRY_MAC_HMAC_SHA384,
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd",
+        "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
+        "\xAA\xAA\xAA\xAA",
+        "\x88\x06\x26\x08\xd3\xe6\xad\x8a\x0a\xa2\xac\xe0\x14\xc8\xa8\x6f"
+        "\x0a\xa6\x35\xd9\x47\xac\x9f\xeb\xe8\x3e\xf4\xe5\x59\x66\x14\x4b"
+        "\x2a\x5a\xb3\x9d\xc1\x38\x14\xb9\x4e\x3a\xb6\xe1\x01\xa3\x4f\x27" },
+      { GCRY_MAC_HMAC_SHA384,
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd",
+        "\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",
+        "\x3e\x8a\x69\xb7\x78\x3c\x25\x85\x19\x33\xab\x62\x90\xaf\x6c\xa7"
+        "\x7a\x99\x81\x48\x08\x50\x00\x9c\xc5\x57\x7c\x6e\x1f\x57\x3b\x4e"
+        "\x68\x01\xdd\x23\xc4\xa7\xd6\x79\xcc\xf8\xa3\x86\xc6\x74\xcf\xfb" },
+      { GCRY_MAC_HMAC_SHA384,
+        "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",
+        "\x4e\xce\x08\x44\x85\x81\x3e\x90\x88\xd2\xc6\x3a\x04\x1b\xc5\xb4"
+        "\x4f\x9e\xf1\x01\x2a\x2b\x58\x8f\x3c\xd1\x1f\x05\x03\x3a\xc4\xc6"
+        "\x0c\x2e\xf6\xab\x40\x30\xfe\x82\x96\x24\x8d\xf1\x63\xf4\x49\x52" },
+      { GCRY_MAC_HMAC_SHA384,
+        "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",
+        "\x66\x17\x17\x8e\x94\x1f\x02\x0d\x35\x1e\x2f\x25\x4e\x8f\xd3\x2c"
+        "\x60\x24\x20\xfe\xb0\xb8\xfb\x9a\xdc\xce\xbb\x82\x46\x1e\x99\xc5"
+        "\xa6\x78\xcc\x31\xe7\x99\x17\x6d\x38\x60\xe6\x11\x0c\x46\x52\x3e" },
+      { GCRY_MAC_HMAC_SHA512, "what do ya want for nothing?", "Jefe",
+        "\x16\x4b\x7a\x7b\xfc\xf8\x19\xe2\xe3\x95\xfb\xe7\x3b\x56\xe0\xa3"
+        "\x87\xbd\x64\x22\x2e\x83\x1f\xd6\x10\x27\x0c\xd7\xea\x25\x05\x54"
+        "\x97\x58\xbf\x75\xc0\x5a\x99\x4a\x6d\x03\x4f\x65\xf8\xf0\xe6\xfd"
+        "\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b\x63\x6e\x07\x0a\x38\xbc\xe7\x37" },
+      { GCRY_MAC_HMAC_SHA512,
+        "Hi There",
+        "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+        "\x0b\x0b\x0b",
+        "\x87\xaa\x7c\xde\xa5\xef\x61\x9d\x4f\xf0\xb4\x24\x1a\x1d\x6c\xb0"
+        "\x23\x79\xf4\xe2\xce\x4e\xc2\x78\x7a\xd0\xb3\x05\x45\xe1\x7c\xde"
+        "\xda\xa8\x33\xb7\xd6\xb8\xa7\x02\x03\x8b\x27\x4e\xae\xa3\xf4\xe4"
+        "\xbe\x9d\x91\x4e\xeb\x61\xf1\x70\x2e\x69\x6c\x20\x3a\x12\x68\x54" },
+      { GCRY_MAC_HMAC_SHA512,
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+        "\xdd\xdd\xdd\xdd\xdd",
+        "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
+        "\xAA\xAA\xAA\xAA",
+        "\xfa\x73\xb0\x08\x9d\x56\xa2\x84\xef\xb0\xf0\x75\x6c\x89\x0b\xe9"
+        "\xb1\xb5\xdb\xdd\x8e\xe8\x1a\x36\x55\xf8\x3e\x33\xb2\x27\x9d\x39"
+        "\xbf\x3e\x84\x82\x79\xa7\x22\xc8\x06\xb4\x85\xa4\x7e\x67\xc8\x07"
+        "\xb9\x46\xa3\x37\xbe\xe8\x94\x26\x74\x27\x88\x59\xe1\x32\x92\xfb"  },
+      { GCRY_MAC_HMAC_SHA512,
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+        "\xcd\xcd\xcd\xcd\xcd",
+        "\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",
+        "\xb0\xba\x46\x56\x37\x45\x8c\x69\x90\xe5\xa8\xc5\xf6\x1d\x4a\xf7"
+        "\xe5\x76\xd9\x7f\xf9\x4b\x87\x2d\xe7\x6f\x80\x50\x36\x1e\xe3\xdb"
+        "\xa9\x1c\xa5\xc1\x1a\xa2\x5e\xb4\xd6\x79\x27\x5c\xc5\x78\x80\x63"
+        "\xa5\xf1\x97\x41\x12\x0c\x4f\x2d\xe2\xad\xeb\xeb\x10\xa2\x98\xdd" },
+      { GCRY_MAC_HMAC_SHA512,
+        "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",
+        "\x80\xb2\x42\x63\xc7\xc1\xa3\xeb\xb7\x14\x93\xc1\xdd\x7b\xe8\xb4"
+        "\x9b\x46\xd1\xf4\x1b\x4a\xee\xc1\x12\x1b\x01\x37\x83\xf8\xf3\x52"
+        "\x6b\x56\xd0\x37\xe0\x5f\x25\x98\xbd\x0f\xd2\x21\x5d\x6a\x1e\x52"
+        "\x95\xe6\x4f\x73\xf6\x3f\x0a\xec\x8b\x91\x5a\x98\x5d\x78\x65\x98" },
+      { GCRY_MAC_HMAC_SHA512,
+        "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",
+        "\xe3\x7b\x6a\x77\x5d\xc8\x7d\xba\xa4\xdf\xa9\xf9\x6e\x5e\x3f\xfd"
+        "\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" },
+      /* 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 */
+      { GCRY_MAC_CMAC_AES,
+        "",
+        "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+        "\xbb\x1d\x69\x29\xe9\x59\x37\x28\x7f\xa3\x7d\x12\x9b\x75\x67\x46" },
+      { GCRY_MAC_CMAC_AES,
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+        "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+        "\x07\x0a\x16\xb4\x6b\x4d\x41\x44\xf7\x9b\xdd\x9d\xd0\x4a\x28\x7c" },
+      { GCRY_MAC_CMAC_AES,
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+        "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+        "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11",
+        "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+        "\xdf\xa6\x67\x47\xde\x9a\xe6\x30\x30\xca\x32\x61\x14\x97\xc8\x27" },
+      { GCRY_MAC_CMAC_AES,
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+        "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+        "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+        "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+        "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+        "\x51\xf0\xbe\xbf\x7e\x3b\x9d\x92\xfc\x49\x74\x17\x79\x36\x3c\xfe" },
+      { GCRY_MAC_CMAC_AES,
+        "",
+        "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+        "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+        "\xd1\x7d\xdf\x46\xad\xaa\xcd\xe5\x31\xca\xc4\x83\xde\x7a\x93\x67" },
+      { GCRY_MAC_CMAC_AES,
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+        "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+        "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+        "\x9e\x99\xa7\xbf\x31\xe7\x10\x90\x06\x62\xf6\x5e\x61\x7c\x51\x84" },
+      { GCRY_MAC_CMAC_AES,
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+        "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+        "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11",
+        "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+        "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+        "\x8a\x1d\xe5\xbe\x2e\xb3\x1a\xad\x08\x9a\x82\xe6\xee\x90\x8b\x0e" },
+      { GCRY_MAC_CMAC_AES,
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+        "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+        "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+        "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+        "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5"
+        "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b",
+        "\xa1\xd5\xdf\x0e\xed\x79\x0f\x79\x4d\x77\x58\x96\x59\xf3\x9a\x11" },
+      { GCRY_MAC_CMAC_AES,
+        "",
+        "\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",
+        "\x02\x89\x62\xf6\x1b\x7b\xf8\x9e\xfc\x6b\x55\x1f\x46\x67\xd9\x83" },
+      { GCRY_MAC_CMAC_AES,
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+        "\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",
+        "\x28\xa7\x02\x3f\x45\x2e\x8f\x82\xbd\x4b\xf2\x8d\x8c\x37\xc3\x5c" },
+      { GCRY_MAC_CMAC_AES,
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+        "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+        "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11",
+        "\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",
+        "\xaa\xf3\xd8\xf1\xde\x56\x40\xc2\x32\xf5\xb1\x69\xb9\xc9\x11\xe6" },
+      { GCRY_MAC_CMAC_AES,
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+        "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+        "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+        "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+        "\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",
+        "\xe1\x99\x21\x90\x54\x9f\x6e\xd5\x69\x6a\x2c\x05\x6c\x31\x54\x10" },
+      { GCRY_MAC_CMAC_3DES,
+        "",
+        "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58"
+        "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5",
+        "\xb7\xa6\x88\xe1\x22\xff\xaf\x95" },
+      { GCRY_MAC_CMAC_3DES,
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96",
+        "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58"
+        "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5",
+        "\x8e\x8f\x29\x31\x36\x28\x37\x97" },
+      { GCRY_MAC_CMAC_3DES,
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+        "\xae\x2d\x8a\x57",
+        "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58"
+        "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5",
+        "\x74\x3d\xdb\xe0\xce\x2d\xc2\xed" },
+      { GCRY_MAC_CMAC_3DES,
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+        "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+        "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58"
+        "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5",
+        "\x33\xe6\xb1\x09\x24\x00\xea\xe5" },
+      { GCRY_MAC_CMAC_3DES,
+        "",
+        "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5\x8a\x3d\x10\xba\x80\x57\x0d\x38"
+        "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5",
+        "\xbd\x2e\xbf\x9a\x3b\xa0\x03\x61" },
+      { GCRY_MAC_CMAC_3DES,
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96",
+        "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5\x8a\x3d\x10\xba\x80\x57\x0d\x38"
+        "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5",
+        "\x4f\xf2\xab\x81\x3c\x53\xce\x83" },
+      { GCRY_MAC_CMAC_3DES,
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+        "\xae\x2d\x8a\x57",
+        "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5\x8a\x3d\x10\xba\x80\x57\x0d\x38"
+        "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5",
+        "\x62\xdd\x1b\x47\x19\x02\xbd\x4e" },
+      { GCRY_MAC_CMAC_3DES,
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+        "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51",
+        "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5\x8a\x3d\x10\xba\x80\x57\x0d\x38"
+        "\x4c\xf1\x51\x34\xa2\x85\x0d\xd5",
+        "\x31\xb1\xe4\x31\xda\xbc\x4e\xb8" },
+      /* CMAC Camellia test vectors from
+         http://tools.ietf.org/html/draft-kato-ipsec-camellia-cmac96and128-05 */
+      { GCRY_MAC_CMAC_CAMELLIA,
+        "",
+        "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+        "\xba\x92\x57\x82\xaa\xa1\xf5\xd9\xa0\x0f\x89\x64\x80\x94\xfc\x71" },
+      { GCRY_MAC_CMAC_CAMELLIA,
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a",
+        "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+        "\x6d\x96\x28\x54\xa3\xb9\xfd\xa5\x6d\x7d\x45\xa9\x5e\xe1\x79\x93" },
+      { GCRY_MAC_CMAC_CAMELLIA,
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+        "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+        "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11",
+        "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+        "\x5c\x18\xd1\x19\xcc\xd6\x76\x61\x44\xac\x18\x66\x13\x1d\x9f\x22" },
+      { GCRY_MAC_CMAC_CAMELLIA,
+        "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a"
+        "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51"
+        "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef"
+        "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
+        "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c",
+        "\xc2\x69\x9a\x6e\xba\x55\xce\x9d\x93\x9a\x8a\x4e\x19\x46\x6e\xe9" },
+      /* http://csrc.nist.gov/groups/STM/cavp/documents/mac/gcmtestvectors.zip */
+      { GCRY_MAC_GMAC_AES,
+        "",
+        "\x11\x75\x4c\xd7\x2a\xec\x30\x9b\xf5\x2f\x76\x87\x21\x2e\x89\x57",
+        "\x25\x03\x27\xc6\x74\xaa\xf4\x77\xae\xf2\x67\x57\x48\xcf\x69\x71",
+        "\x3c\x81\x9d\x9a\x9b\xed\x08\x76\x15\x03\x0b\x65" },
+      { GCRY_MAC_GMAC_AES,
+        "\x2b\x63\x26\x64\x29\x67\x4a\xb5\xe2\xea\xff\x63\x9c\x23\x14\x66"
+        "\x2f\x92\x57\x4b\x29\x8f\x57\x7a\xcf\x7d\x6f\x99\x1a\x87\x92\x1f"
+        "\xc2\x32\xea\xfc\xc7\xb1\x46\x48\x96\x63\x2d\x6c\x8a\xbe\x88\xc2"
+        "\xcc\xa4\x04\xdb\xf8\x7c\x20\x6a\x19\xd3\x73\xed\x99\x50\x17\x34"
+        "\x69\x13\x4d\x7c\x14\xc2\x84\x7d\xf2\x4a\x88\xc1\xc5\x3b\x4d\xe4"
+        "\x9d\xb3\x66\x39\x2b\x6d\xc6\x51\x27\x6e",
+        "\x0f\x3b\x17\xde\xae\x62\x13\x64\x55\x4a\xe5\x39\xdb\x09\xde\x11",
+        "\xff\xb0\xbb\x6d\xfc\x23\x58\x75\x4f\x17\x78\x48\x5b\x59\x65\x7f",
+        "\xa7\xf6\x07\x4c\xda\x56\x1c\xd2\xaa\x15\xba\x8c\x2f\xa6\x39\x42"
+        "\x59\x3e\x7c\xcf\x45\xc2\x9a\x57\xda\xd8\xa6\xe2\xea\x63\x54\xce"
+        "\x8a\xde\x39\xdd\xde\x4a\xc4\x5b\xbd\xc6\x63\xf0\xa5\x37\xc9\x48"
+        "\x18\x23\x5a\x73\xd8\xa0\x8b\xd8\x98\xab\xd0\x99\xe1\x5c\x08\x8c"
+        "\x6e\x21\x17\x5a\xf4\xe9\xa4\x99\x70\x12\x82\xed\x32\x81\x50\xa6"
+        "\xd9\x90\xe8\xec\x87\x85\xce\x26\x1b\xe1\xb8\x3f\xd8\x59\x1e\x57"
+        "\x76\x5f\x3d\xc1\x11\x3f\xd0\x2a\x40\xf5\x01\x6a\xd0\xd0\xed\xc4"
+        "\x92\x9a\x02\xe0\x17\xb2\xc5\xf4\x18\xd2\x96\xab\xd6\xc2\xea\x2e" },
+      { GCRY_MAC_GMAC_AES,
+        "\x61\x14\x60\x11\x90\xf6\xef\x5e\x59\x23\x5d\xc0\x42\x8c\x09\xe3"
+        "\x27\x0b\x19\xea",
+        "\x15\xa4\x14\x46\x6a\x7f\x90\xea\x32\xbf\xd7\xf6\xe5\x8b\xfa\x06"
+        "\xe9\x07\xfc\x41\x66\x89\xd9\x60\x39\x45\xd7\x94\x54\xd4\x23\x17",
+        "\x19\x6e\x0e\x01\x0f\x08\x56\xf9\x82\xb4\x08\x92\x41\xd6\x24\x84",
+        "\xab" },
+      { GCRY_MAC_GMAC_AES,
+        "\x8b\x5c\x12\x4b\xef\x6e\x2f\x0f\xe4\xd8\xc9\x5c\xd5\xfa\x4c\xf1",
+        "\x41\xc5\xda\x86\x67\xef\x72\x52\x20\xff\xe3\x9a\xe0\xac\x59\x0a"
+        "\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" },
+      { 0 },
+    };
+  int i;
+
+  if (verbose)
+    fprintf (stderr, "Starting MAC checks.\n");
+
+  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)
+        {
+          if (verbose)
+            fprintf (stderr, "  algorithm %d not available in fips mode\n",
+                    algos[i].algo);
+          continue;
+        }
+      if (verbose)
+       fprintf (stderr,
+                 "  checking %s [%i] for %d byte key and %d byte data\n",
+                gcry_mac_algo_name (algos[i].algo),
+                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,
+                    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,
+                    algos[i].expect, 1);
+    }
+
+  if (verbose)
+    fprintf (stderr, "Completed MAC checks.\n");
+}
 
 /* Check that the signature SIG matches the hash HASH. PKEY is the
-   public key used for the verification. BADHASH is a hasvalue which
-   should; result in a bad signature status. */
+   public key used for the verification. BADHASH is a hasvalue which
+   should result in a bad signature status. */
 static void
 verify_one_signature (gcry_sexp_t pkey, gcry_sexp_t hash,
                      gcry_sexp_t badhash, gcry_sexp_t sig)
@@ -2289,7 +5138,7 @@ check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
   static const char baddata[] =
     "(data\n (flags pkcs1)\n"
     " (hash sha1 #11223344556677889900AABBCCDDEEFF10203041#))\n";
-  static struct
+  static const struct
   {
     const char *data;
     int algo;
@@ -2348,8 +5197,6 @@ check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
       { NULL }
     };
 
-  (void)n;
-
   rc = gcry_sexp_sscan (&badhash, NULL, baddata, strlen (baddata));
   if (rc)
     die ("converting data failed: %s\n", gpg_strerror (rc));
@@ -2360,7 +5207,8 @@ check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
        continue;
 
       if (verbose)
-       fprintf (stderr, "  signature test %d\n", dataidx);
+       fprintf (stderr, "  test %d, signature test %d (%s)\n",
+                 n, dataidx, gcry_pk_algo_name (algo));
 
       rc = gcry_sexp_sscan (&hash, NULL, datas[dataidx].data,
                            strlen (datas[dataidx].data));
@@ -2383,13 +5231,129 @@ check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
   gcry_sexp_release (badhash);
 }
 
+
+/* Test the public key sign function using the private ket SKEY. PKEY
+   is used for verification.  This variant is only used for ECDSA.  */
+static void
+check_pubkey_sign_ecdsa (int n, gcry_sexp_t skey, gcry_sexp_t pkey)
+{
+  gcry_error_t rc;
+  gcry_sexp_t sig, badhash, hash;
+  unsigned int nbits;
+  int dataidx;
+  static const struct
+  {
+    unsigned int nbits;
+    const char *data;
+    int expected_rc;
+    const char *baddata;
+    int dummy;
+  } datas[] =
+    {
+      { 192,
+        "(data (flags raw)\n"
+        " (value #00112233445566778899AABBCCDDEEFF0001020304050607#))",
+        0,
+        "(data (flags raw)\n"
+        " (value #80112233445566778899AABBCCDDEEFF0001020304050607#))",
+        0
+      },
+      { 256,
+        "(data (flags raw)\n"
+        " (value #00112233445566778899AABBCCDDEEFF"
+        /* */    "000102030405060708090A0B0C0D0E0F#))",
+        0,
+        "(data (flags raw)\n"
+        " (value #80112233445566778899AABBCCDDEEFF"
+        /* */    "000102030405060708090A0B0C0D0E0F#))",
+        0
+      },
+      { 256,
+        "(data (flags raw)\n"
+        " (hash sha256 #00112233445566778899AABBCCDDEEFF"
+        /* */          "000102030405060708090A0B0C0D0E0F#))",
+        0,
+        "(data (flags raw)\n"
+        " (hash sha256 #80112233445566778899AABBCCDDEEFF"
+        /* */          "000102030405060708090A0B0C0D0E0F#))",
+        0
+      },
+      { 256,
+        "(data (flags gost)\n"
+        " (value #00112233445566778899AABBCCDDEEFF"
+        /* */    "000102030405060708090A0B0C0D0E0F#))",
+        0,
+        "(data (flags gost)\n"
+        " (value #80112233445566778899AABBCCDDEEFF"
+        /* */    "000102030405060708090A0B0C0D0E0F#))",
+        0
+      },
+      { 512,
+        "(data (flags gost)\n"
+        " (value #00112233445566778899AABBCCDDEEFF"
+        /* */    "000102030405060708090A0B0C0D0E0F"
+        /* */    "000102030405060708090A0B0C0D0E0F"
+        /* */    "000102030405060708090A0B0C0D0E0F#))",
+        0,
+        "(data (flags gost)\n"
+        " (value #80112233445566778899AABBCCDDEEFF"
+        /* */    "000102030405060708090A0B0C0D0E0F"
+        /* */    "000102030405060708090A0B0C0D0E0F"
+        /* */    "000102030405060708090A0B0C0D0E0F#))",
+        0
+      },
+      { 0, NULL }
+    };
+
+  nbits = gcry_pk_get_nbits (skey);
+
+  for (dataidx = 0; datas[dataidx].data; dataidx++)
+    {
+      if (datas[dataidx].nbits != nbits)
+       continue;
+
+      if (verbose)
+       fprintf (stderr, "  test %d, signature test %d (%u bit ecdsa)\n",
+                 n, dataidx, nbits);
+
+      rc = gcry_sexp_sscan (&hash, NULL, datas[dataidx].data,
+                           strlen (datas[dataidx].data));
+      if (rc)
+       die ("converting data failed: %s\n", gpg_strerror (rc));
+      rc = gcry_sexp_sscan (&badhash, NULL, datas[dataidx].baddata,
+                            strlen (datas[dataidx].baddata));
+      if (rc)
+        die ("converting data failed: %s\n", gpg_strerror (rc));
+
+      rc = gcry_pk_sign (&sig, hash, skey);
+      if (gcry_err_code (rc) != datas[dataidx].expected_rc)
+       fail ("gcry_pk_sign failed: %s\n", gpg_strerror (rc));
+
+      if (!rc && verbose > 1)
+        show_sexp ("ECDSA signature:\n", sig);
+
+      if (!rc)
+        verify_one_signature (pkey, hash, badhash, sig);
+
+      gcry_sexp_release (sig);
+      sig = NULL;
+      gcry_sexp_release (badhash);
+      badhash = NULL;
+      gcry_sexp_release (hash);
+      hash = NULL;
+    }
+}
+
+
 static void
 check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
 {
   gcry_error_t rc;
-  gcry_sexp_t plain, ciph, data;
+  gcry_sexp_t plain = NULL;
+  gcry_sexp_t ciph = NULL;
+  gcry_sexp_t data = NULL;
   int dataidx;
-  static struct
+  static const struct
   {
     int algo;    /* If not 0 run test only if ALGO matches.  */
     const char *data;
@@ -2397,6 +5361,7 @@ check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
     int unpadded;
     int encrypt_expected_rc;
     int decrypt_expected_rc;
+    int special;
   } datas[] =
     {
       {        GCRY_PK_RSA,
@@ -2480,14 +5445,14 @@ check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
        "(flags oaep)",
        1,
        0,
-       GPG_ERR_ENCODING_PROBLEM },
+       GPG_ERR_ENCODING_PROBLEM, 1 },
       { GCRY_PK_RSA,
         "(data\n (flags oaep)\n"
        " (value #11223344556677889900AA#))\n",
        "(flags pkcs1)",
        1,
        0,
-       GPG_ERR_ENCODING_PROBLEM },
+       GPG_ERR_ENCODING_PROBLEM, 1 },
       {        0,
         "(data\n (flags pss)\n"
        " (value #11223344556677889900AA#))\n",
@@ -2519,6 +5484,8 @@ check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
 
       if (!rc)
        {
+          int expect_mismatch = 0;
+
          /* Insert decoding hint to CIPH. */
          if (datas[dataidx].hint)
            {
@@ -2555,8 +5522,28 @@ check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
              ciph = list;
            }
          rc = gcry_pk_decrypt (&plain, ciph, skey);
-         if (gcry_err_code (rc) != datas[dataidx].decrypt_expected_rc)
-           fail ("gcry_pk_decrypt failed: %s\n", gpg_strerror (rc));
+          if (!rc && datas[dataidx].special == 1)
+            {
+              /* It may happen that OAEP formatted data which is
+                 decrypted as pkcs#1 data returns a valid pkcs#1
+                 frame.  However, the returned value will not be
+                 identical - thus we expect a mismatch and test further on
+                 whether this mismatch actually happened.  */
+              expect_mismatch = 1;
+            }
+         else if (gcry_err_code (rc) != datas[dataidx].decrypt_expected_rc)
+            {
+              if (verbose)
+                {
+                  show_sexp ("  data:\n", data);
+                  show_sexp ("  ciph:\n", ciph);
+                  show_sexp ("   key:\n", skey);
+                }
+              fail ("gcry_pk_decrypt failed: expected %d (%s), got %d (%s)\n",
+                    datas[dataidx].decrypt_expected_rc,
+                    gpg_strerror (datas[dataidx].decrypt_expected_rc),
+                    rc, gpg_strerror (rc));
+            }
 
          if (!rc && datas[dataidx].unpadded)
            {
@@ -2572,8 +5559,19 @@ check_pubkey_crypt (int n, gcry_sexp_t skey, gcry_sexp_t pkey, int algo)
                  s1 = gcry_sexp_nth_data (p1, 1, &n1);
                  s2 = gcry_sexp_nth_data (p2, 1, &n2);
                  if (n1 != n2 || memcmp (s1, s2, n1))
-                   fail ("gcry_pk_encrypt/gcry_pk_decrypt do not roundtrip\n");
+                    {
+                      if (expect_mismatch)
+                        expect_mismatch = 0;
+                      else
+                        fail ("gcry_pk_encrypt/gcry_pk_decrypt "
+                              "do not roundtrip\n");
+                    }
                }
+
+              if (expect_mismatch)
+                fail ("gcry_pk_encrypt/gcry_pk_decrypt "
+                      "expected mismatch did not happen\n");
+
              gcry_sexp_release (p1);
              gcry_sexp_release (p2);
            }
@@ -2611,7 +5609,12 @@ do_check_one_pubkey (int n, gcry_sexp_t skey, gcry_sexp_t pkey,
                     const unsigned char *grip, int algo, int flags)
 {
  if (flags & FLAG_SIGN)
-   check_pubkey_sign (n, skey, pkey, algo);
+   {
+     if (algo == GCRY_PK_ECDSA)
+       check_pubkey_sign_ecdsa (n, skey, pkey);
+     else
+       check_pubkey_sign (n, skey, pkey, algo);
+   }
  if (flags & FLAG_CRYPT)
    check_pubkey_crypt (n, skey, pkey, algo);
  if (grip && (flags & FLAG_GRIP))
@@ -2687,112 +5690,278 @@ check_one_pubkey_new (int n)
 static void
 check_pubkey (void)
 {
-  test_spec_pubkey_t pubkeys[] =
+  static const test_spec_pubkey_t pubkeys[] = {
+  {
+    GCRY_PK_RSA, FLAG_CRYPT | FLAG_SIGN,
     {
-      {
-       GCRY_PK_RSA, FLAG_CRYPT | FLAG_SIGN,
-
-       { "(private-key\n"
-         " (rsa\n"
-         "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
-         "      2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
-         "      ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
-         "      891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
-         "  (e #010001#)\n"
-         "  (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
-         "      7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
-         "      C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
-         "      C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
-         "  (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
-         "      fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
-         "  (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
-         "      35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)\n"
-         "  (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
-         "      ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)))\n",
-
-         "(public-key\n"
-         " (rsa\n"
-         "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
-         "      2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
-         "      ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
-         "      891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
-         "  (e #010001#)))\n",
-
-         "\x32\x10\x0c\x27\x17\x3e\xf6\xe9\xc4\xe9"
-         "\xa2\x5d\x3d\x69\xf8\x6d\x37\xa4\xf9\x39"}
-      },
-      {
-       GCRY_PK_DSA, FLAG_SIGN,
-
-       { "(private-key\n"
-         " (DSA\n"
-         "  (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
-         "      96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
-         "      CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
-         "      44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)\n"
-         "  (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)\n"
-         "  (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
-         "      AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
-         "      B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
-         "      3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)\n"
-         "  (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
-         "      A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
-         "      6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
-         "      42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)\n"
-         "  (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))\n",
-
-         "(public-key\n"
-         " (DSA\n"
-         "  (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
-         "      96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
-         "      CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
-         "      44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)\n"
-         "  (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)\n"
-         "  (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
-         "      AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
-         "      B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
-         "      3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)\n"
-         "  (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
-         "      A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
-         "      6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
-         "      42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)))\n",
-
-         "\xc6\x39\x83\x1a\x43\xe5\x05\x5d\xc6\xd8"
-         "\x4a\xa6\xf9\xeb\x23\xbf\xa9\x12\x2d\x5b" }
-      },
-      {
-       GCRY_PK_ELG, FLAG_SIGN | FLAG_CRYPT,
-
-       { "(private-key\n"
-         " (ELG\n"
-         "  (p #00B93B93386375F06C2D38560F3B9C6D6D7B7506B20C1773F73F8DE56E6CD65D"
-         "      F48DFAAA1E93F57A2789B168362A0F787320499F0B2461D3A4268757A7B27517"
-         "      B7D203654A0CD484DEC6AF60C85FEB84AAC382EAF2047061FE5DAB81A20A0797"
-         "      6E87359889BAE3B3600ED718BE61D4FC993CC8098A703DD0DC942E965E8F18D2A7#)\n"
-         "  (g #05#)\n"
-         "  (y #72DAB3E83C9F7DD9A931FDECDC6522C0D36A6F0A0FEC955C5AC3C09175BBFF2B"
-         "      E588DB593DC2E420201BEB3AC17536918417C497AC0F8657855380C1FCF11C5B"
-         "      D20DB4BEE9BDF916648DE6D6E419FA446C513AAB81C30CB7B34D6007637BE675"
-         "      56CE6473E9F9EE9B9FADD275D001563336F2186F424DEC6199A0F758F6A00FF4#)\n"
-         "  (x #03C28900087B38DABF4A0AB98ACEA39BB674D6557096C01D72E31C16BDD32214#)))\n",
-
-         "(public-key\n"
-         " (ELG\n"
-         "  (p #00B93B93386375F06C2D38560F3B9C6D6D7B7506B20C1773F73F8DE56E6CD65D"
-         "      F48DFAAA1E93F57A2789B168362A0F787320499F0B2461D3A4268757A7B27517"
-         "      B7D203654A0CD484DEC6AF60C85FEB84AAC382EAF2047061FE5DAB81A20A0797"
-         "      6E87359889BAE3B3600ED718BE61D4FC993CC8098A703DD0DC942E965E8F18D2A7#)\n"
-         "  (g #05#)\n"
-         "  (y #72DAB3E83C9F7DD9A931FDECDC6522C0D36A6F0A0FEC955C5AC3C09175BBFF2B"
-         "      E588DB593DC2E420201BEB3AC17536918417C497AC0F8657855380C1FCF11C5B"
-         "      D20DB4BEE9BDF916648DE6D6E419FA446C513AAB81C30CB7B34D6007637BE675"
-         "      56CE6473E9F9EE9B9FADD275D001563336F2186F424DEC6199A0F758F6A00FF4#)))\n",
-
-         "\xa7\x99\x61\xeb\x88\x83\xd2\xf4\x05\xc8"
-         "\x4f\xba\x06\xf8\x78\x09\xbc\x1e\x20\xe5" }
-      },
-    };
+      "(private-key\n"
+      " (rsa\n"
+      "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+      "      2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+      "      ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+      "      891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea2"
+      "      51#)\n"
+      "  (e #010001#)\n"
+      "  (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
+      "      7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
+      "      C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
+      "      C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781"
+      "      #)\n"
+      "  (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
+      "      fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424"
+      "      f1#)\n"
+      "  (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
+      "      35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad3"
+      "      61#)\n"
+      "  (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
+      "      ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b"
+      "      #)))\n",
+
+      "(public-key\n"
+      " (rsa\n"
+      "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
+      "      2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
+      "      ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
+      "      891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea2"
+      "      51#)\n"
+      "  (e #010001#)))\n",
+
+      "\x32\x10\x0c\x27\x17\x3e\xf6\xe9\xc4\xe9"
+      "\xa2\x5d\x3d\x69\xf8\x6d\x37\xa4\xf9\x39"}
+  },
+  {
+    GCRY_PK_DSA, FLAG_SIGN,
+    {
+      "(private-key\n"
+      " (DSA\n"
+      "  (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
+      "      96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
+      "      CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
+      "      44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D877"
+      "      7B#)\n"
+      "  (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)\n"
+      "  (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
+      "      AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
+      "      B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
+      "      3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15"
+      "      #)\n"
+      "  (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
+      "      A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
+      "      6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
+      "      42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB"
+      "      #)\n"
+      "  (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))\n",
+
+      "(public-key\n"
+      " (DSA\n"
+      "  (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
+      "      96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191"
+      "      CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44"
+      "      44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D877"
+      "      7B#)\n"
+      "  (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)\n"
+      "  (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503"
+      "      AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E"
+      "      B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984"
+      "      3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15"
+      "      #)\n"
+      "  (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46"
+      "      A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827"
+      "      6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20"
+      "      42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB"
+      "      #)))\n",
+
+      "\xc6\x39\x83\x1a\x43\xe5\x05\x5d\xc6\xd8"
+      "\x4a\xa6\xf9\xeb\x23\xbf\xa9\x12\x2d\x5b" }
+  },
+  {
+    GCRY_PK_ELG, FLAG_SIGN | FLAG_CRYPT,
+    {
+      "(private-key\n"
+      " (ELG\n"
+      "  (p #00B93B93386375F06C2D38560F3B9C6D6D7B7506B20C1773F73F8DE56E6CD65D"
+      "      F48DFAAA1E93F57A2789B168362A0F787320499F0B2461D3A4268757A7B27517"
+      "      B7D203654A0CD484DEC6AF60C85FEB84AAC382EAF2047061FE5DAB81A20A0797"
+      "      6E87359889BAE3B3600ED718BE61D4FC993CC8098A703DD0DC942E965E8F18D2"
+      "      A7#)\n"
+      "  (g #05#)\n"
+      "  (y #72DAB3E83C9F7DD9A931FDECDC6522C0D36A6F0A0FEC955C5AC3C09175BBFF2B"
+      "      E588DB593DC2E420201BEB3AC17536918417C497AC0F8657855380C1FCF11C5B"
+      "      D20DB4BEE9BDF916648DE6D6E419FA446C513AAB81C30CB7B34D6007637BE675"
+      "      56CE6473E9F9EE9B9FADD275D001563336F2186F424DEC6199A0F758F6A00FF4"
+      "      #)\n"
+      "  (x #03C28900087B38DABF4A0AB98ACEA39BB674D6557096C01D72E31C16BDD32214"
+      "      #)))\n",
+
+      "(public-key\n"
+      " (ELG\n"
+      "  (p #00B93B93386375F06C2D38560F3B9C6D6D7B7506B20C1773F73F8DE56E6CD65D"
+      "      F48DFAAA1E93F57A2789B168362A0F787320499F0B2461D3A4268757A7B27517"
+      "      B7D203654A0CD484DEC6AF60C85FEB84AAC382EAF2047061FE5DAB81A20A0797"
+      "      6E87359889BAE3B3600ED718BE61D4FC993CC8098A703DD0DC942E965E8F18D2"
+      "      A7#)\n"
+      "  (g #05#)\n"
+      "  (y #72DAB3E83C9F7DD9A931FDECDC6522C0D36A6F0A0FEC955C5AC3C09175BBFF2B"
+      "      E588DB593DC2E420201BEB3AC17536918417C497AC0F8657855380C1FCF11C5B"
+      "      D20DB4BEE9BDF916648DE6D6E419FA446C513AAB81C30CB7B34D6007637BE675"
+      "      56CE6473E9F9EE9B9FADD275D001563336F2186F424DEC6199A0F758F6A00FF4"
+      "      #)))\n",
+
+      "\xa7\x99\x61\xeb\x88\x83\xd2\xf4\x05\xc8"
+      "\x4f\xba\x06\xf8\x78\x09\xbc\x1e\x20\xe5" }
+  },
+  { /* ECDSA test.  */
+    GCRY_PK_ECDSA, FLAG_SIGN,
+    {
+      "(private-key\n"
+      " (ecdsa\n"
+      "  (curve nistp192)\n"
+      "  (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE"
+      "        C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)\n"
+      "  (d #00D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D#)))\n",
+
+      "(public-key\n"
+      " (ecdsa\n"
+      "  (curve nistp192)\n"
+      "  (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE"
+      "        C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)))\n",
+
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }
+  },
+  { /* ECDSA test with the public key algorithm given as "ecc".  */
+    GCRY_PK_ECDSA, FLAG_SIGN,
+    {
+      "(private-key\n"
+      " (ecdsa\n"
+      "  (curve nistp192)\n"
+      "  (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE"
+      "        C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)\n"
+      "  (d #00D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D#)))\n",
+
+      "(public-key\n"
+      " (ecc\n"
+      "  (curve nistp192)\n"
+      "  (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE"
+      "        C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)))\n",
+
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }
+  },
+  { /* ECDSA test with the private key algorithm given as "ecc".  */
+    GCRY_PK_ECDSA, FLAG_SIGN,
+    {
+      "(private-key\n"
+      " (ecc\n"
+      "  (curve nistp192)\n"
+      "  (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE"
+      "        C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)\n"
+      "  (d #00D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D#)))\n",
+
+      "(public-key\n"
+      " (ecdsa\n"
+      "  (curve nistp192)\n"
+      "  (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE"
+      "        C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)))\n",
+
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }
+  },
+  { /* ECDSA test with the key algorithms given as "ecc".  */
+    GCRY_PK_ECDSA, FLAG_SIGN,
+    {
+      "(private-key\n"
+      " (ecc\n"
+      "  (curve nistp192)\n"
+      "  (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE"
+      "        C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)\n"
+      "  (d #00D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D#)))\n",
+
+      "(public-key\n"
+      " (ecc\n"
+      "  (curve nistp192)\n"
+      "  (q #048532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE"
+      "        C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966#)))\n",
+
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }
+  },
+  { /* ECDSA test 256 bit.  */
+    GCRY_PK_ECDSA, FLAG_SIGN,
+    {
+      "(private-key\n"
+      " (ecc\n"
+      "  (curve nistp256)\n"
+      "  (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2B"
+      "      EB6644D3609FC781B71F9A8072F58CB66AE2F89BB1245187"
+      "      3ABF7D91F9E1FBF96BF2F70E73AAC9A283#)\n"
+      "  (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F74"
+      "      4715E1D5BBE70378#)))\n",
+
+      "(public-key\n"
+      " (ecc\n"
+      "  (curve nistp256)\n"
+      "  (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2B"
+      "      EB6644D3609FC781B71F9A8072F58CB66AE2F89BB1245187"
+      "      3ABF7D91F9E1FBF96BF2F70E73AAC9A283#)))\n",
+
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }
+  },
+  { /* GOST R 34.10-2001/2012 test 256 bit.  */
+    GCRY_PK_ECDSA, FLAG_SIGN,
+    {
+      "(private-key\n"
+      " (ecc\n"
+      "  (curve GOST2001-test)\n"
+      "  (q #047F2B49E270DB6D90D8595BEC458B50C58585BA1D4E9B78"
+      "      8F6689DBD8E56FD80B26F1B489D6701DD185C8413A977B3C"
+      "      BBAF64D1C593D26627DFFB101A87FF77DA#)\n"
+      "  (d #7A929ADE789BB9BE10ED359DD39A72C11B60961F49397EEE"
+      "      1D19CE9891EC3B28#)))\n",
+
+      "(public-key\n"
+      " (ecc\n"
+      "  (curve GOST2001-test)\n"
+      "  (q #047F2B49E270DB6D90D8595BEC458B50C58585BA1D4E9B78"
+      "      8F6689DBD8E56FD80B26F1B489D6701DD185C8413A977B3C"
+      "      BBAF64D1C593D26627DFFB101A87FF77DA#)))\n",
+
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }
+  },
+  { /* GOST R 34.10-2012 test 512 bit.  */
+    GCRY_PK_ECDSA, FLAG_SIGN,
+    {
+      "(private-key\n"
+      " (ecc\n"
+      "  (curve GOST2012-test)\n"
+      "  (q #04115DC5BC96760C7B48598D8AB9E740D4C4A85A65BE33C1"
+      "        815B5C320C854621DD5A515856D13314AF69BC5B924C8B"
+      "        4DDFF75C45415C1D9DD9DD33612CD530EFE137C7C90CD4"
+      "        0B0F5621DC3AC1B751CFA0E2634FA0503B3D52639F5D7F"
+      "        B72AFD61EA199441D943FFE7F0C70A2759A3CDB84C114E"
+      "        1F9339FDF27F35ECA93677BEEC#)\n"
+      "  (d #0BA6048AADAE241BA40936D47756D7C93091A0E851466970"
+      "      0EE7508E508B102072E8123B2200A0563322DAD2827E2714"
+      "      A2636B7BFD18AADFC62967821FA18DD4#)))\n",
+
+      "(public-key\n"
+      " (ecc\n"
+      "  (curve GOST2001-test)\n"
+      "  (q #04115DC5BC96760C7B48598D8AB9E740D4C4A85A65BE33C1"
+      "        815B5C320C854621DD5A515856D13314AF69BC5B924C8B"
+      "        4DDFF75C45415C1D9DD9DD33612CD530EFE137C7C90CD4"
+      "        0B0F5621DC3AC1B751CFA0E2634FA0503B3D52639F5D7F"
+      "        B72AFD61EA199441D943FFE7F0C70A2759A3CDB84C114E"
+      "        1F9339FDF27F35ECA93677BEEC#)))\n"
+
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+      "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" }
+    }
+  };
   int i;
+
   if (verbose)
     fprintf (stderr, "Starting public key checks.\n");
   for (i = 0; i < sizeof (pubkeys) / sizeof (*pubkeys); i++)
@@ -2837,6 +6006,9 @@ main (int argc, char **argv)
   int debug = 0;
   int use_fips = 0;
   int selftest_only = 0;
+  int pubkey_only = 0;
+  int loop = 0;
+  unsigned int loopcount = 0;
 
   if (argc)
     { argc--; argv++; }
@@ -2870,11 +6042,25 @@ main (int argc, char **argv)
           verbose += 2;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--pubkey"))
+        {
+          pubkey_only = 1;
+          argc--; argv++;
+        }
       else if (!strcmp (*argv, "--die"))
         {
           die_on_error = 1;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--loop"))
+        {
+          argc--; argv++;
+          if (argc)
+            {
+              loop = atoi (*argv);
+              argc--; argv++;
+            }
+        }
     }
 
   gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose);
@@ -2902,16 +6088,29 @@ main (int argc, char **argv)
   /* No valuable keys are create, so we can speed up our RNG. */
   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
 
-  if (!selftest_only)
+  do
     {
-      check_ciphers ();
-      check_cipher_modes ();
-      check_bulk_cipher_modes ();
-      check_digests ();
-      check_hmac ();
-      check_pubkey ();
+      if (pubkey_only)
+        check_pubkey ();
+      else if (!selftest_only)
+        {
+          check_ciphers ();
+          check_cipher_modes ();
+          check_bulk_cipher_modes ();
+          check_digests ();
+          check_hmac ();
+          check_mac ();
+          check_pubkey ();
+        }
+      loopcount++;
+      if (loop)
+        {
+          fprintf (stderr, "Test iteration %u completed.\n", loopcount);
+          if (loop != -1)
+            loop--;
+        }
     }
-
+  while (loop);
 
   if (in_fips_mode && !selftest_only)
     {
diff --git a/tests/bench-slope.c b/tests/bench-slope.c
new file mode 100644 (file)
index 0000000..bd05064
--- /dev/null
@@ -0,0 +1,1624 @@
+/* bench-slope.c - for libgcrypt
+ * Copyright (C) 2013 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 HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <time.h>
+
+#ifdef _GCRYPT_IN_LIBGCRYPT
+# include "../src/gcrypt-int.h"
+# include "../compat/libcompat.h"
+#else
+# include <gcrypt.h>
+#endif
+
+#ifndef STR
+#define STR(v) #v
+#define STR2(v) STR(v)
+#endif
+
+#define PGM "bench-slope"
+
+static int verbose;
+static int csv_mode;
+static int num_measurement_repetitions;
+
+/* CPU Ghz value provided by user, allows constructing cycles/byte and other
+   results.  */
+static double cpu_ghz = -1;
+
+/* Whether we are running as part of the regression test suite.  */
+static int in_regression_test;
+
+/* The name of the currently printed section.  */
+static char *current_section_name;
+/* The name of the currently printed algorithm.  */
+static char *current_algo_name;
+/* The name of the currently printed mode.  */
+static char *current_mode_name;
+
+
+/*************************************** Default parameters for measurements. */
+
+/* Start at small buffer size, to get reasonable timer calibration for fast
+ * implementations (AES-NI etc). Sixteen selected to support the largest block
+ * size of current set cipher blocks. */
+#define BUF_START_SIZE                 16
+
+/* From ~0 to ~4kbytes give comparable results with results from academia
+ * (SUPERCOP). */
+#define BUF_END_SIZE                   (BUF_START_SIZE + 4096)
+
+/* With 128 byte steps, we get (4096)/64 = 64 data points. */
+#define BUF_STEP_SIZE                  64
+
+/* Number of repeated measurements at each data point. The median of these
+ * measurements is selected as data point further analysis. */
+#define NUM_MEASUREMENT_REPETITIONS    64
+
+/**************************************************** High-resolution timers. */
+
+/* This benchmarking module needs needs high resolution timer.  */
+#undef NO_GET_NSEC_TIME
+#if defined(_WIN32)
+struct nsec_time
+{
+  LARGE_INTEGER perf_count;
+};
+
+static void
+get_nsec_time (struct nsec_time *t)
+{
+  BOOL ok;
+
+  ok = QueryPerformanceCounter (&t->perf_count);
+  assert (ok);
+}
+
+static double
+get_time_nsec_diff (struct nsec_time *start, struct nsec_time *end)
+{
+  static double nsecs_per_count = 0.0;
+  double nsecs;
+
+  if (nsecs_per_count == 0.0)
+    {
+      LARGE_INTEGER perf_freq;
+      BOOL ok;
+
+      /* Get counts per second. */
+      ok = QueryPerformanceFrequency (&perf_freq);
+      assert (ok);
+
+      nsecs_per_count = 1.0 / perf_freq.QuadPart;
+      nsecs_per_count *= 1000000.0 * 1000.0;   /* sec => nsec */
+
+      assert (nsecs_per_count > 0.0);
+    }
+
+  nsecs = end->perf_count.QuadPart - start->perf_count.QuadPart;       /* counts */
+  nsecs *= nsecs_per_count;    /* counts * (nsecs / count) => nsecs */
+
+  return nsecs;
+}
+#elif defined(HAVE_CLOCK_GETTIME)
+struct nsec_time
+{
+  struct timespec ts;
+};
+
+static void
+get_nsec_time (struct nsec_time *t)
+{
+  int err;
+
+  err = clock_gettime (CLOCK_REALTIME, &t->ts);
+  assert (err == 0);
+}
+
+static double
+get_time_nsec_diff (struct nsec_time *start, struct nsec_time *end)
+{
+  double nsecs;
+
+  nsecs = end->ts.tv_sec - start->ts.tv_sec;
+  nsecs *= 1000000.0 * 1000.0; /* sec => nsec */
+
+  /* This way we don't have to care if tv_nsec unsigned or signed. */
+  if (end->ts.tv_nsec >= start->ts.tv_nsec)
+    nsecs += end->ts.tv_nsec - start->ts.tv_nsec;
+  else
+    nsecs -= start->ts.tv_nsec - end->ts.tv_nsec;
+
+  return nsecs;
+}
+#elif defined(HAVE_GETTIMEOFDAY)
+struct nsec_time
+{
+  struct timeval tv;
+};
+
+static void
+get_nsec_time (struct nsec_time *t)
+{
+  int err;
+
+  err = gettimeofday (&t->tv, NULL);
+  assert (err == 0);
+}
+
+static double
+get_time_nsec_diff (struct nsec_time *start, struct nsec_time *end)
+{
+  double nsecs;
+
+  nsecs = end->tv.tv_sec - start->tv.tv_sec;
+  nsecs *= 1000000;            /* sec => µsec */
+
+  /* This way we don't have to care if tv_usec unsigned or signed. */
+  if (end->tv.tv_usec >= start->tv.tv_usec)
+    nsecs += end->tv.tv_usec - start->tv.tv_usec;
+  else
+    nsecs -= start->tv.tv_usec - end->tv.tv_usec;
+
+  nsecs *= 1000;               /* µsec => nsec */
+
+  return nsecs;
+}
+#else
+#define NO_GET_NSEC_TIME 1
+#endif
+
+
+/* If no high resolution timer found, provide dummy bench-slope.  */
+#ifdef NO_GET_NSEC_TIME
+
+
+int
+main (void)
+{
+  /* No nsec timer => SKIP test. */
+  return 77;
+}
+
+
+#else /* !NO_GET_NSEC_TIME */
+
+
+/********************************************** Slope benchmarking framework. */
+
+struct bench_obj
+{
+  const struct bench_ops *ops;
+
+  unsigned int num_measure_repetitions;
+  unsigned int min_bufsize;
+  unsigned int max_bufsize;
+  unsigned int step_size;
+
+  void *priv;
+};
+
+typedef int (*const bench_initialize_t) (struct bench_obj * obj);
+typedef void (*const bench_finalize_t) (struct bench_obj * obj);
+typedef void (*const bench_do_run_t) (struct bench_obj * obj, void *buffer,
+                                     size_t buflen);
+
+struct bench_ops
+{
+  bench_initialize_t initialize;
+  bench_finalize_t finalize;
+  bench_do_run_t do_run;
+};
+
+
+double
+get_slope (double (*const get_x) (unsigned int idx, void *priv),
+          void *get_x_priv, double y_points[], unsigned int npoints,
+          double *overhead)
+{
+  double sumx, sumy, sumx2, sumy2, sumxy;
+  unsigned int i;
+  double b, a;
+
+  sumx = sumy = sumx2 = sumy2 = sumxy = 0;
+
+  for (i = 0; i < npoints; i++)
+    {
+      double x, y;
+
+      x = get_x (i, get_x_priv);       /* bytes */
+      y = y_points[i];         /* nsecs */
+
+      sumx += x;
+      sumy += y;
+      sumx2 += x * x;
+      /*sumy2 += y * y;*/
+      sumxy += x * y;
+    }
+
+  b = (npoints * sumxy - sumx * sumy) / (npoints * sumx2 - sumx * sumx);
+  a = (sumy - b * sumx) / npoints;
+
+  if (overhead)
+    *overhead = a;             /* nsecs */
+
+  return b;                    /* nsecs per byte */
+}
+
+
+double
+get_bench_obj_point_x (unsigned int idx, void *priv)
+{
+  struct bench_obj *obj = priv;
+  return (double) (obj->min_bufsize + (idx * obj->step_size));
+}
+
+
+unsigned int
+get_num_measurements (struct bench_obj *obj)
+{
+  unsigned int buf_range = obj->max_bufsize - obj->min_bufsize;
+  unsigned int num = buf_range / obj->step_size + 1;
+
+  while (obj->min_bufsize + (num * obj->step_size) > obj->max_bufsize)
+    num--;
+
+  return num + 1;
+}
+
+
+static int
+double_cmp (const void *_a, const void *_b)
+{
+  const double *a, *b;
+
+  a = _a;
+  b = _b;
+
+  if (*a > *b)
+    return 1;
+  if (*a < *b)
+    return -1;
+  return 0;
+}
+
+
+double
+do_bench_obj_measurement (struct bench_obj *obj, void *buffer, size_t buflen,
+                         double *measurement_raw,
+                         unsigned int loop_iterations)
+{
+  const unsigned int num_repetitions = obj->num_measure_repetitions;
+  const bench_do_run_t do_run = obj->ops->do_run;
+  struct nsec_time start, end;
+  unsigned int rep, loop;
+  double res;
+
+  if (num_repetitions < 1 || loop_iterations < 1)
+    return 0.0;
+
+  for (rep = 0; rep < num_repetitions; rep++)
+    {
+      get_nsec_time (&start);
+
+      for (loop = 0; loop < loop_iterations; loop++)
+       do_run (obj, buffer, buflen);
+
+      get_nsec_time (&end);
+
+      measurement_raw[rep] = get_time_nsec_diff (&start, &end);
+    }
+
+  /* Return median of repeated measurements. */
+  qsort (measurement_raw, num_repetitions, sizeof (measurement_raw[0]),
+        double_cmp);
+
+  if (num_repetitions % 2 == 1)
+    return measurement_raw[num_repetitions / 2];
+
+  res = measurement_raw[num_repetitions / 2]
+    + measurement_raw[num_repetitions / 2 - 1];
+  return res / 2;
+}
+
+
+unsigned int
+adjust_loop_iterations_to_timer_accuracy (struct bench_obj *obj, void *buffer,
+                                         double *measurement_raw)
+{
+  const double increase_thres = 3.0;
+  double tmp, nsecs;
+  unsigned int loop_iterations;
+  unsigned int test_bufsize;
+
+  test_bufsize = obj->min_bufsize;
+  if (test_bufsize == 0)
+    test_bufsize += obj->step_size;
+
+  loop_iterations = 0;
+  do
+    {
+      /* Increase loop iterations until we get other results than zero.  */
+      nsecs =
+       do_bench_obj_measurement (obj, buffer, test_bufsize,
+                                 measurement_raw, ++loop_iterations);
+    }
+  while (nsecs < 1.0 - 0.1);
+  do
+    {
+      /* Increase loop iterations until we get reasonable increase for elapsed time.  */
+      tmp =
+       do_bench_obj_measurement (obj, buffer, test_bufsize,
+                                 measurement_raw, ++loop_iterations);
+    }
+  while (tmp < nsecs * (increase_thres - 0.1));
+
+  return loop_iterations;
+}
+
+
+/* Benchmark and return linear regression slope in nanoseconds per byte.  */
+double
+do_slope_benchmark (struct bench_obj *obj)
+{
+  unsigned int num_measurements;
+  double *measurements = NULL;
+  double *measurement_raw = NULL;
+  double slope, overhead;
+  unsigned int loop_iterations, midx, i;
+  unsigned char *real_buffer = NULL;
+  unsigned char *buffer;
+  size_t cur_bufsize;
+  int err;
+
+  err = obj->ops->initialize (obj);
+  if (err < 0)
+    return -1;
+
+  num_measurements = get_num_measurements (obj);
+  measurements = calloc (num_measurements, sizeof (*measurements));
+  if (!measurements)
+    goto err_free;
+
+  measurement_raw =
+    calloc (obj->num_measure_repetitions, sizeof (*measurement_raw));
+  if (!measurement_raw)
+    goto err_free;
+
+  if (num_measurements < 1 || obj->num_measure_repetitions < 1 ||
+      obj->max_bufsize < 1 || obj->min_bufsize > obj->max_bufsize)
+    goto err_free;
+
+  real_buffer = malloc (obj->max_bufsize + 128);
+  if (!real_buffer)
+    goto err_free;
+  /* Get aligned buffer */
+  buffer = real_buffer;
+  buffer += 128 - ((real_buffer - (unsigned char *) 0) & (128 - 1));
+
+  for (i = 0; i < obj->max_bufsize; i++)
+    buffer[i] = 0x55 ^ (-i);
+
+  /* Adjust number of loop iterations up to timer accuracy.  */
+  loop_iterations = adjust_loop_iterations_to_timer_accuracy (obj, buffer,
+                                                             measurement_raw);
+
+  /* Perform measurements */
+  for (midx = 0, cur_bufsize = obj->min_bufsize;
+       cur_bufsize <= obj->max_bufsize; cur_bufsize += obj->step_size, midx++)
+    {
+      measurements[midx] =
+       do_bench_obj_measurement (obj, buffer, cur_bufsize, measurement_raw,
+                                 loop_iterations);
+      measurements[midx] /= loop_iterations;
+    }
+
+  assert (midx == num_measurements);
+
+  slope =
+    get_slope (&get_bench_obj_point_x, obj, measurements, num_measurements,
+              &overhead);
+
+  free (measurement_raw);
+  free (real_buffer);
+  obj->ops->finalize (obj);
+
+  return slope;
+
+err_free:
+  if (measurement_raw)
+    free (measurement_raw);
+  if (measurements)
+    free (measurements);
+  if (real_buffer)
+    free (real_buffer);
+  obj->ops->finalize (obj);
+
+  return -1;
+}
+
+
+/********************************************************** Printing results. */
+
+static void
+double_to_str (char *out, size_t outlen, double value)
+{
+  const char *fmt;
+
+  if (value < 1.0)
+    fmt = "%.3f";
+  else if (value < 100.0)
+    fmt = "%.2f";
+  else
+    fmt = "%.1f";
+
+  snprintf (out, outlen, fmt, value);
+}
+
+static void
+bench_print_result_csv (double nsecs_per_byte)
+{
+  double cycles_per_byte, mbytes_per_sec;
+  char nsecpbyte_buf[16];
+  char mbpsec_buf[16];
+  char cpbyte_buf[16];
+
+  *cpbyte_buf = 0;
+
+  double_to_str (nsecpbyte_buf, sizeof (nsecpbyte_buf), nsecs_per_byte);
+
+  /* If user didn't provide CPU speed, we cannot show cycles/byte results.  */
+  if (cpu_ghz > 0.0)
+    {
+      cycles_per_byte = nsecs_per_byte * cpu_ghz;
+      double_to_str (cpbyte_buf, sizeof (cpbyte_buf), cycles_per_byte);
+    }
+
+  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);
+
+  /* We print two empty fields to allow for future enhancements.  */
+  printf ("%s,%s,%s,,,%s,ns/B,%s,MiB/s,%s,c/B\n",
+          current_section_name,
+          current_algo_name? current_algo_name : "",
+          current_mode_name? current_mode_name : "",
+          nsecpbyte_buf,
+          mbpsec_buf,
+          cpbyte_buf);
+
+}
+
+static void
+bench_print_result_std (double nsecs_per_byte)
+{
+  double cycles_per_byte, mbytes_per_sec;
+  char nsecpbyte_buf[16];
+  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.  */
+  if (cpu_ghz > 0.0)
+    {
+      cycles_per_byte = nsecs_per_byte * cpu_ghz;
+      double_to_str (cpbyte_buf, sizeof (cpbyte_buf), cycles_per_byte);
+    }
+
+  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);
+}
+
+static void
+bench_print_result (double nsecs_per_byte)
+{
+  if (csv_mode)
+    bench_print_result_csv (nsecs_per_byte);
+  else
+    bench_print_result_std (nsecs_per_byte);
+}
+
+static void
+bench_print_section (const char *section_name, const char *print_name)
+{
+  if (csv_mode)
+    {
+      gcry_free (current_section_name);
+      current_section_name = gcry_xstrdup (section_name);
+    }
+  else
+    printf ("%s:\n", print_name);
+}
+
+static void
+bench_print_header (int algo_width, const char *algo_name)
+{
+  if (csv_mode)
+    {
+      gcry_free (current_algo_name);
+      current_algo_name = gcry_xstrdup (algo_name);
+    }
+  else
+    {
+      if (algo_width < 0)
+        printf (" %-*s | ", -algo_width, algo_name);
+      else
+        printf (" %-*s | ", algo_width, algo_name);
+      printf ("%14s %15s %13s\n", "nanosecs/byte", "mebibytes/sec",
+              "cycles/byte");
+    }
+}
+
+static void
+bench_print_algo (int algo_width, const char *algo_name)
+{
+  if (csv_mode)
+    {
+      gcry_free (current_algo_name);
+      current_algo_name = gcry_xstrdup (algo_name);
+    }
+  else
+    {
+      if (algo_width < 0)
+        printf (" %-*s | ", -algo_width, algo_name);
+      else
+        printf (" %-*s | ", algo_width, algo_name);
+    }
+}
+
+static void
+bench_print_mode (int width, const char *mode_name)
+{
+  if (csv_mode)
+    {
+      gcry_free (current_mode_name);
+      current_mode_name = gcry_xstrdup (mode_name);
+    }
+  else
+    {
+      if (width < 0)
+        printf (" %-*s | ", -width, mode_name);
+      else
+        printf (" %*s | ", width, mode_name);
+      fflush (stdout);
+    }
+}
+
+static void
+bench_print_footer (int algo_width)
+{
+  if (!csv_mode)
+    printf (" %-*s =\n", algo_width, "");
+}
+
+
+/********************************************************* Cipher benchmarks. */
+
+struct bench_cipher_mode
+{
+  int mode;
+  const char *name;
+  struct bench_ops *ops;
+
+  int algo;
+};
+
+
+static int
+bench_encrypt_init (struct bench_obj *obj)
+{
+  struct bench_cipher_mode *mode = obj->priv;
+  gcry_cipher_hd_t hd;
+  int err, keylen;
+
+  obj->min_bufsize = BUF_START_SIZE;
+  obj->max_bufsize = BUF_END_SIZE;
+  obj->step_size = BUF_STEP_SIZE;
+  obj->num_measure_repetitions = num_measurement_repetitions;
+
+  err = gcry_cipher_open (&hd, mode->algo, mode->mode, 0);
+  if (err)
+    {
+      fprintf (stderr, PGM ": error opening cipher `%s'\n",
+              gcry_cipher_algo_name (mode->algo));
+      exit (1);
+    }
+
+  keylen = gcry_cipher_get_algo_keylen (mode->algo);
+  if (keylen)
+    {
+      char key[keylen];
+      int i;
+
+      for (i = 0; i < keylen; i++)
+       key[i] = 0x33 ^ (11 - i);
+
+      err = gcry_cipher_setkey (hd, key, keylen);
+      if (err)
+       {
+         fprintf (stderr, PGM ": gcry_cipher_setkey failed: %s\n",
+                  gpg_strerror (err));
+         gcry_cipher_close (hd);
+         exit (1);
+       }
+    }
+  else
+    {
+      fprintf (stderr, PGM ": failed to get key length for algorithm `%s'\n",
+              gcry_cipher_algo_name (mode->algo));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+
+  obj->priv = hd;
+
+  return 0;
+}
+
+static void
+bench_encrypt_free (struct bench_obj *obj)
+{
+  gcry_cipher_hd_t hd = obj->priv;
+
+  gcry_cipher_close (hd);
+}
+
+static void
+bench_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+  gcry_cipher_hd_t hd = obj->priv;
+  int err;
+
+  err = gcry_cipher_encrypt (hd, buf, buflen, buf, buflen);
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_encrypt failed: %s\n",
+              gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+}
+
+static void
+bench_decrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+  gcry_cipher_hd_t hd = obj->priv;
+  int err;
+
+  err = gcry_cipher_decrypt (hd, buf, buflen, buf, buflen);
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_encrypt failed: %s\n",
+              gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+}
+
+static struct bench_ops encrypt_ops = {
+  &bench_encrypt_init,
+  &bench_encrypt_free,
+  &bench_encrypt_do_bench
+};
+
+static struct bench_ops decrypt_ops = {
+  &bench_encrypt_init,
+  &bench_encrypt_free,
+  &bench_decrypt_do_bench
+};
+
+
+#ifdef HAVE_U64_TYPEDEF
+static void
+bench_ccm_encrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+  gcry_cipher_hd_t hd = obj->priv;
+  int err;
+  char tag[8];
+  char nonce[11] = { 0x80, 0x01, };
+  u64 params[3];
+
+  gcry_cipher_setiv (hd, nonce, sizeof (nonce));
+
+  /* Set CCM lengths */
+  params[0] = buflen;
+  params[1] = 0;               /*aadlen */
+  params[2] = sizeof (tag);
+  err =
+    gcry_cipher_ctl (hd, GCRYCTL_SET_CCM_LENGTHS, params, sizeof (params));
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_ctl failed: %s\n",
+              gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+
+  err = gcry_cipher_encrypt (hd, buf, buflen, buf, buflen);
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_encrypt failed: %s\n",
+              gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+
+  err = gcry_cipher_gettag (hd, tag, sizeof (tag));
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_gettag failed: %s\n",
+              gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+}
+
+static void
+bench_ccm_decrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+  gcry_cipher_hd_t hd = obj->priv;
+  int err;
+  char tag[8] = { 0, };
+  char nonce[11] = { 0x80, 0x01, };
+  u64 params[3];
+
+  gcry_cipher_setiv (hd, nonce, sizeof (nonce));
+
+  /* Set CCM lengths */
+  params[0] = buflen;
+  params[1] = 0;               /*aadlen */
+  params[2] = sizeof (tag);
+  err =
+    gcry_cipher_ctl (hd, GCRYCTL_SET_CCM_LENGTHS, params, sizeof (params));
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_ctl failed: %s\n",
+              gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+
+  err = gcry_cipher_decrypt (hd, buf, buflen, buf, buflen);
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_encrypt failed: %s\n",
+              gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+
+  err = gcry_cipher_checktag (hd, tag, sizeof (tag));
+  if (gpg_err_code (err) == GPG_ERR_CHECKSUM)
+    err = gpg_error (GPG_ERR_NO_ERROR);
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_gettag failed: %s\n",
+              gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+}
+
+static void
+bench_ccm_authenticate_do_bench (struct bench_obj *obj, void *buf,
+                                size_t buflen)
+{
+  gcry_cipher_hd_t hd = obj->priv;
+  int err;
+  char tag[8] = { 0, };
+  char nonce[11] = { 0x80, 0x01, };
+  u64 params[3];
+  char data = 0xff;
+
+  gcry_cipher_setiv (hd, nonce, sizeof (nonce));
+
+  /* Set CCM lengths */
+  params[0] = sizeof (data);   /*datalen */
+  params[1] = buflen;          /*aadlen */
+  params[2] = sizeof (tag);
+  err =
+    gcry_cipher_ctl (hd, GCRYCTL_SET_CCM_LENGTHS, params, sizeof (params));
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_ctl failed: %s\n",
+              gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+
+  err = gcry_cipher_authenticate (hd, buf, buflen);
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_authenticate failed: %s\n",
+              gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+
+  err = gcry_cipher_encrypt (hd, &data, sizeof (data), &data, sizeof (data));
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_encrypt failed: %s\n",
+              gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+
+  err = gcry_cipher_gettag (hd, tag, sizeof (tag));
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_gettag failed: %s\n",
+              gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+}
+
+static struct bench_ops ccm_encrypt_ops = {
+  &bench_encrypt_init,
+  &bench_encrypt_free,
+  &bench_ccm_encrypt_do_bench
+};
+
+static struct bench_ops ccm_decrypt_ops = {
+  &bench_encrypt_init,
+  &bench_encrypt_free,
+  &bench_ccm_decrypt_do_bench
+};
+
+static struct bench_ops ccm_authenticate_ops = {
+  &bench_encrypt_init,
+  &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)
+{
+  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));
+
+  err = gcry_cipher_encrypt (hd, buf, buflen, buf, buflen);
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_encrypt failed: %s\n",
+           gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+
+  err = gcry_cipher_gettag (hd, tag, sizeof (tag));
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_gettag failed: %s\n",
+           gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+}
+
+static void
+bench_gcm_decrypt_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+  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));
+
+  err = gcry_cipher_decrypt (hd, buf, buflen, buf, buflen);
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_encrypt failed: %s\n",
+           gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+
+  err = gcry_cipher_checktag (hd, tag, sizeof (tag));
+  if (gpg_err_code (err) == GPG_ERR_CHECKSUM)
+    err = gpg_error (GPG_ERR_NO_ERROR);
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_gettag failed: %s\n",
+           gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+}
+
+static void
+bench_gcm_authenticate_do_bench (struct bench_obj *obj, void *buf,
+           size_t buflen)
+{
+  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_authenticate (hd, buf, buflen);
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_authenticate failed: %s\n",
+           gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+
+  err = gcry_cipher_encrypt (hd, &data, sizeof (data), &data, sizeof (data));
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_encrypt failed: %s\n",
+           gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+
+  err = gcry_cipher_gettag (hd, tag, sizeof (tag));
+  if (err)
+    {
+      fprintf (stderr, PGM ": gcry_cipher_gettag failed: %s\n",
+           gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+}
+
+static struct bench_ops gcm_encrypt_ops = {
+  &bench_encrypt_init,
+  &bench_encrypt_free,
+  &bench_gcm_encrypt_do_bench
+};
+
+static struct bench_ops gcm_decrypt_ops = {
+  &bench_encrypt_init,
+  &bench_encrypt_free,
+  &bench_gcm_decrypt_do_bench
+};
+
+static struct bench_ops gcm_authenticate_ops = {
+  &bench_encrypt_init,
+  &bench_encrypt_free,
+  &bench_gcm_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},
+  {GCRY_CIPHER_MODE_CBC, "CBC enc", &encrypt_ops},
+  {GCRY_CIPHER_MODE_CBC, "CBC dec", &decrypt_ops},
+  {GCRY_CIPHER_MODE_CFB, "CFB enc", &encrypt_ops},
+  {GCRY_CIPHER_MODE_CFB, "CFB dec", &decrypt_ops},
+  {GCRY_CIPHER_MODE_OFB, "OFB enc", &encrypt_ops},
+  {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},
+  {0},
+};
+
+
+static void
+cipher_bench_one (int algo, struct bench_cipher_mode *pmode)
+{
+  struct bench_cipher_mode mode = *pmode;
+  struct bench_obj obj = { 0 };
+  double result;
+  unsigned int blklen;
+
+  mode.algo = algo;
+
+  /* Check if this mode is ok */
+  blklen = gcry_cipher_get_algo_blklen (algo);
+  if (!blklen)
+    return;
+
+  /* Stream cipher? Only test with ECB. */
+  if (blklen == 1 && mode.mode != GCRY_CIPHER_MODE_ECB)
+    return;
+  if (blklen == 1 && mode.mode == GCRY_CIPHER_MODE_ECB)
+    {
+      mode.mode = GCRY_CIPHER_MODE_STREAM;
+      mode.name = mode.ops == &encrypt_ops ? "STREAM enc" : "STREAM dec";
+    }
+
+  /* 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 */
+  if (mode.mode == GCRY_CIPHER_MODE_GCM && blklen != GCRY_GCM_BLOCK_LEN)
+    return;
+
+  bench_print_mode (14, mode.name);
+
+  obj.ops = mode.ops;
+  obj.priv = &mode;
+
+  result = do_slope_benchmark (&obj);
+
+  bench_print_result (result);
+}
+
+
+static void
+_cipher_bench (int algo)
+{
+  const char *algoname;
+  int i;
+
+  algoname = gcry_cipher_algo_name (algo);
+
+  bench_print_header (14, algoname);
+
+  for (i = 0; cipher_modes[i].mode; i++)
+    cipher_bench_one (algo, &cipher_modes[i]);
+
+  bench_print_footer (14);
+}
+
+
+void
+cipher_bench (char **argv, int argc)
+{
+  int i, algo;
+
+  bench_print_section ("cipher", "Cipher");
+
+  if (argv && argc)
+    {
+      for (i = 0; i < argc; i++)
+       {
+         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);
+    }
+}
+
+
+/*********************************************************** Hash benchmarks. */
+
+struct bench_hash_mode
+{
+  const char *name;
+  struct bench_ops *ops;
+
+  int algo;
+};
+
+
+static int
+bench_hash_init (struct bench_obj *obj)
+{
+  struct bench_hash_mode *mode = obj->priv;
+  gcry_md_hd_t hd;
+  int err;
+
+  obj->min_bufsize = BUF_START_SIZE;
+  obj->max_bufsize = BUF_END_SIZE;
+  obj->step_size = BUF_STEP_SIZE;
+  obj->num_measure_repetitions = num_measurement_repetitions;
+
+  err = gcry_md_open (&hd, mode->algo, 0);
+  if (err)
+    {
+      fprintf (stderr, PGM ": error opening hash `%s'\n",
+              gcry_md_algo_name (mode->algo));
+      exit (1);
+    }
+
+  obj->priv = hd;
+
+  return 0;
+}
+
+static void
+bench_hash_free (struct bench_obj *obj)
+{
+  gcry_md_hd_t hd = obj->priv;
+
+  gcry_md_close (hd);
+}
+
+static void
+bench_hash_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+  gcry_md_hd_t hd = obj->priv;
+
+  gcry_md_reset (hd);
+  gcry_md_write (hd, buf, buflen);
+  gcry_md_final (hd);
+}
+
+static struct bench_ops hash_ops = {
+  &bench_hash_init,
+  &bench_hash_free,
+  &bench_hash_do_bench
+};
+
+
+static struct bench_hash_mode hash_modes[] = {
+  {"", &hash_ops},
+  {0},
+};
+
+
+static void
+hash_bench_one (int algo, struct bench_hash_mode *pmode)
+{
+  struct bench_hash_mode mode = *pmode;
+  struct bench_obj obj = { 0 };
+  double result;
+
+  mode.algo = algo;
+
+  if (mode.name[0] == '\0')
+    bench_print_algo (-14, gcry_md_algo_name (algo));
+  else
+    bench_print_algo (14, mode.name);
+
+  obj.ops = mode.ops;
+  obj.priv = &mode;
+
+  result = do_slope_benchmark (&obj);
+
+  bench_print_result (result);
+}
+
+static void
+_hash_bench (int algo)
+{
+  int i;
+
+  for (i = 0; hash_modes[i].name; i++)
+    hash_bench_one (algo, &hash_modes[i]);
+}
+
+void
+hash_bench (char **argv, int argc)
+{
+  int i, algo;
+
+  bench_print_section ("hash", "Hash");
+  bench_print_header (14, "");
+
+  if (argv && argc)
+    {
+      for (i = 0; i < argc; i++)
+       {
+         algo = gcry_md_map_name (argv[i]);
+         if (algo)
+           _hash_bench (algo);
+       }
+    }
+  else
+    {
+      for (i = 1; i < 400; i++)
+       if (!gcry_md_test_algo (i))
+         _hash_bench (i);
+    }
+
+  bench_print_footer (14);
+}
+
+
+/************************************************************ MAC benchmarks. */
+
+struct bench_mac_mode
+{
+  const char *name;
+  struct bench_ops *ops;
+
+  int algo;
+};
+
+
+static int
+bench_mac_init (struct bench_obj *obj)
+{
+  struct bench_mac_mode *mode = obj->priv;
+  gcry_mac_hd_t hd;
+  int err;
+  unsigned int keylen;
+  void *key;
+
+  obj->min_bufsize = BUF_START_SIZE;
+  obj->max_bufsize = BUF_END_SIZE;
+  obj->step_size = BUF_STEP_SIZE;
+  obj->num_measure_repetitions = num_measurement_repetitions;
+
+  keylen = gcry_mac_get_algo_keylen (mode->algo);
+  if (keylen == 0)
+    keylen = 32;
+  key = malloc (keylen);
+  if (!key)
+    {
+      fprintf (stderr, PGM ": couldn't allocate %d bytes\n", keylen);
+      exit (1);
+    }
+  memset(key, 42, keylen);
+
+  err = gcry_mac_open (&hd, mode->algo, 0, NULL);
+  if (err)
+    {
+      fprintf (stderr, PGM ": error opening mac `%s'\n",
+              gcry_mac_algo_name (mode->algo));
+      free (key);
+      exit (1);
+    }
+
+  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));
+      exit (1);
+    }
+
+  obj->priv = hd;
+
+  return 0;
+}
+
+static void
+bench_mac_free (struct bench_obj *obj)
+{
+  gcry_mac_hd_t hd = obj->priv;
+
+  gcry_mac_close (hd);
+}
+
+static void
+bench_mac_do_bench (struct bench_obj *obj, void *buf, size_t buflen)
+{
+  gcry_mac_hd_t hd = obj->priv;
+  size_t bs;
+  char b;
+
+  gcry_mac_reset (hd);
+  gcry_mac_write (hd, buf, buflen);
+  bs = sizeof(b);
+  gcry_mac_read (hd, &b, &bs);
+}
+
+static struct bench_ops mac_ops = {
+  &bench_mac_init,
+  &bench_mac_free,
+  &bench_mac_do_bench
+};
+
+
+static struct bench_mac_mode mac_modes[] = {
+  {"", &mac_ops},
+  {0},
+};
+
+
+static void
+mac_bench_one (int algo, struct bench_mac_mode *pmode)
+{
+  struct bench_mac_mode mode = *pmode;
+  struct bench_obj obj = { 0 };
+  double result;
+
+  mode.algo = algo;
+
+  if (mode.name[0] == '\0')
+    bench_print_algo (-18, gcry_mac_algo_name (algo));
+  else
+    bench_print_algo (18, mode.name);
+
+  obj.ops = mode.ops;
+  obj.priv = &mode;
+
+  result = do_slope_benchmark (&obj);
+
+  bench_print_result (result);
+}
+
+static void
+_mac_bench (int algo)
+{
+  int i;
+
+  for (i = 0; mac_modes[i].name; i++)
+    mac_bench_one (algo, &mac_modes[i]);
+}
+
+void
+mac_bench (char **argv, int argc)
+{
+  int i, algo;
+
+  bench_print_section ("mac", "MAC");
+  bench_print_header (18, "");
+
+  if (argv && argc)
+    {
+      for (i = 0; i < argc; i++)
+       {
+         algo = gcry_mac_map_name (argv[i]);
+         if (algo)
+           _mac_bench (algo);
+       }
+    }
+  else
+    {
+      for (i = 1; i < 500; i++)
+       if (!gcry_mac_test_algo (i))
+         _mac_bench (i);
+    }
+
+  bench_print_footer (18);
+}
+
+
+/************************************************************** Main program. */
+
+void
+print_help (void)
+{
+  static const char *help_lines[] = {
+    "usage: bench-slope [options] [hash|mac|cipher [algonames]]",
+    "",
+    " options:",
+    "   --cpu-mhz <mhz>           Set CPU speed for calculating cycles",
+    "                             per bytes results.",
+    "   --disable-hwf <features>  Disable hardware acceleration feature(s)",
+    "                             for benchmarking.",
+    "   --repetitions <n>         Use N repetitions (default "
+                                     STR2(NUM_MEASUREMENT_REPETITIONS) ")",
+    "   --csv                     Use CSV output format",
+    NULL
+  };
+  const char **line;
+
+  for (line = help_lines; *line; line++)
+    fprintf (stdout, "%s\n", *line);
+}
+
+
+/* Warm up CPU.  */
+static void
+warm_up_cpu (void)
+{
+  struct nsec_time start, end;
+
+  get_nsec_time (&start);
+  do
+    {
+      get_nsec_time (&end);
+    }
+  while (get_time_nsec_diff (&start, &end) < 1000.0 * 1000.0 * 1000.0);
+}
+
+
+int
+main (int argc, char **argv)
+{
+  int last_argc = -1;
+  int debug = 0;
+
+  if (argc)
+    {
+      argc--;
+      argv++;
+    }
+
+  /* We skip this test if we are running under the test suite (no args
+     and srcdir defined) and GCRYPT_NO_BENCHMARKS is set.  */
+  if (!argc && getenv ("srcdir") && getenv ("GCRYPT_NO_BENCHMARKS"))
+    exit (77);
+
+  if (getenv ("GCRYPT_IN_REGRESSION_TEST"))
+    {
+      in_regression_test = 1;
+      num_measurement_repetitions = 2;
+    }
+  else
+    num_measurement_repetitions = NUM_MEASUREMENT_REPETITIONS;
+
+  while (argc && last_argc != argc)
+    {
+      last_argc = argc;
+
+      if (!strcmp (*argv, "--"))
+       {
+         argc--;
+         argv++;
+         break;
+       }
+      else if (!strcmp (*argv, "--help"))
+       {
+         print_help ();
+         exit (0);
+       }
+      else if (!strcmp (*argv, "--verbose"))
+       {
+         verbose++;
+         argc--;
+         argv++;
+       }
+      else if (!strcmp (*argv, "--debug"))
+       {
+         verbose += 2;
+         debug++;
+         argc--;
+         argv++;
+       }
+      else if (!strcmp (*argv, "--csv"))
+       {
+         csv_mode = 1;
+         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++;
+           }
+       }
+      else if (!strcmp (*argv, "--cpu-mhz"))
+       {
+         argc--;
+         argv++;
+         if (argc)
+           {
+             cpu_ghz = atof (*argv);
+             cpu_ghz /= 1000;  /* Mhz => Ghz */
+
+             argc--;
+             argv++;
+           }
+       }
+      else if (!strcmp (*argv, "--repetitions"))
+       {
+         argc--;
+         argv++;
+         if (argc)
+           {
+             num_measurement_repetitions = atof (*argv);
+              if (num_measurement_repetitions < 2)
+                {
+                  fprintf (stderr,
+                           PGM
+                           ": value for --repetitions too small - using %d\n",
+                           NUM_MEASUREMENT_REPETITIONS);
+                  num_measurement_repetitions = NUM_MEASUREMENT_REPETITIONS;
+                }
+             argc--;
+             argv++;
+           }
+       }
+    }
+
+  gcry_control (GCRYCTL_SET_VERBOSITY, (int) verbose);
+
+  if (!gcry_check_version (GCRYPT_VERSION))
+    {
+      fprintf (stderr, PGM ": version mismatch; pgm=%s, library=%s\n",
+              GCRYPT_VERSION, gcry_check_version (NULL));
+      exit (1);
+    }
+
+  if (debug)
+    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+
+  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+
+  if (in_regression_test)
+    fputs ("Note: " PGM " running in quick regression test mode.\n", stdout);
+
+  if (!argc)
+    {
+      warm_up_cpu ();
+      hash_bench (NULL, 0);
+      mac_bench (NULL, 0);
+      cipher_bench (NULL, 0);
+    }
+  else if (!strcmp (*argv, "hash"))
+    {
+      argc--;
+      argv++;
+
+      warm_up_cpu ();
+      hash_bench ((argc == 0) ? NULL : argv, argc);
+    }
+  else if (!strcmp (*argv, "mac"))
+    {
+      argc--;
+      argv++;
+
+      warm_up_cpu ();
+      mac_bench ((argc == 0) ? NULL : argv, argc);
+    }
+  else if (!strcmp (*argv, "cipher"))
+    {
+      argc--;
+      argv++;
+
+      warm_up_cpu ();
+      cipher_bench ((argc == 0) ? NULL : argv, argc);
+    }
+  else
+    {
+      fprintf (stderr, PGM ": unknown argument: %s\n", *argv);
+      print_help ();
+    }
+
+  return 0;
+}
+
+#endif /* !NO_GET_NSEC_TIME */
index 106e01b..5efc083 100644 (file)
 #endif
 #include <stdio.h>
 #include <stdlib.h>
-#include <time.h>
 #include <stdarg.h>
-#ifdef _WIN32
-#include <windows.h>
-#else
-#include <sys/times.h>
-#endif
 
 #ifdef _GCRYPT_IN_LIBGCRYPT
-# include "../src/gcrypt.h"
+# include "../src/gcrypt-int.h"
 # include "../compat/libcompat.h"
 #else
 # include <gcrypt.h>
 #endif
 
+#include "stopwatch.h"
+
 
 #define PGM "benchmark"
 
@@ -51,6 +47,9 @@ static int cipher_repetitions;
 /* Number of hash repetitions.  */
 static int hash_repetitions;
 
+/* Number of hash repetitions.  */
+static int mac_repetitions;
+
 /* Alignment of the buffers.  */
 static int buffer_alignment;
 
@@ -60,6 +59,9 @@ static int cipher_with_keysetup;
 /* Whether fips mode was active at startup.  */
 static int in_fips_mode;
 
+/* Whether we are running as part of the regression test suite.  */
+static int in_regression_test;
+
 
 static const char sample_private_dsa_key_1024[] =
 "(private-key\n"
@@ -254,15 +256,6 @@ static const char sample_public_dsa_key_3072[] =
                  exit(2);} while(0)
 
 
-/* Helper for the start and stop timer. */
-#ifdef _WIN32
-struct {
-  FILETIME creation_time, exit_time, kernel_time, user_time;
-} started_at, stopped_at;
-#else
-static clock_t started_at, stopped_at;
-#endif
-
 static void
 die (const char *format, ...)
 {
@@ -276,6 +269,7 @@ die (const char *format, ...)
   exit (1);
 }
 
+
 static void
 show_sexp (const char *prefix, gcry_sexp_t a)
 {
@@ -294,74 +288,6 @@ show_sexp (const char *prefix, gcry_sexp_t a)
 
 
 static void
-start_timer (void)
-{
-#ifdef _WIN32
-#ifdef __MINGW32CE__
-  GetThreadTimes (GetCurrentThread (),
-                   &started_at.creation_time, &started_at.exit_time,
-                   &started_at.kernel_time, &started_at.user_time);
-#else
-  GetProcessTimes (GetCurrentProcess (),
-                   &started_at.creation_time, &started_at.exit_time,
-                   &started_at.kernel_time, &started_at.user_time);
-#endif
-  stopped_at = started_at;
-#else
-  struct tms tmp;
-
-  times (&tmp);
-  started_at = stopped_at = tmp.tms_utime;
-#endif
-}
-
-static void
-stop_timer (void)
-{
-#ifdef _WIN32
-#ifdef __MINGW32CE__
-  GetThreadTimes (GetCurrentThread (),
-                   &stopped_at.creation_time, &stopped_at.exit_time,
-                   &stopped_at.kernel_time, &stopped_at.user_time);
-#else
-  GetProcessTimes (GetCurrentProcess (),
-                   &stopped_at.creation_time, &stopped_at.exit_time,
-                   &stopped_at.kernel_time, &stopped_at.user_time);
-#endif
-#else
-  struct tms tmp;
-
-  times (&tmp);
-  stopped_at = tmp.tms_utime;
-#endif
-}
-
-static const char *
-elapsed_time (void)
-{
-  static char buf[50];
-#if _WIN32
-  unsigned long long t1, t2, t;
-
-  t1 = (((unsigned long long)started_at.kernel_time.dwHighDateTime << 32)
-        + started_at.kernel_time.dwLowDateTime);
-  t1 += (((unsigned long long)started_at.user_time.dwHighDateTime << 32)
-        + started_at.user_time.dwLowDateTime);
-  t2 = (((unsigned long long)stopped_at.kernel_time.dwHighDateTime << 32)
-        + 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 );
-#else
-  snprintf (buf, sizeof buf, "%5.0fms",
-            (((double) (stopped_at - started_at))/CLOCKS_PER_SEC)*10000000);
-#endif
-  return buf;
-}
-
-
-static void
 progress_cb (void *cb_data, const char *what, int printchar,
              int current, int total)
 {
@@ -516,6 +442,161 @@ md_bench ( const char *algoname )
   fflush (stdout);
 }
 
+
+
+static void
+mac_bench ( const char *algoname )
+{
+  int algo;
+  gcry_mac_hd_t hd;
+  int step, pos, j, i, repcount;
+  char buf_base[1000+15];
+  size_t bufsize = 1000;
+  char *buf;
+  char mac[3][512];
+  char key[512];
+  unsigned int maclen, keylen;
+  size_t macoutlen;
+  gcry_error_t err = GPG_ERR_NO_ERROR;
+
+  if (!algoname)
+    {
+      for (i=1; i < 500; i++)
+        if (in_fips_mode && i == GCRY_MAC_HMAC_MD5)
+          ; /* Don't use MD5 in fips mode.  */
+        else if ( !gcry_mac_test_algo (i) )
+          mac_bench (gcry_mac_algo_name (i));
+      return;
+    }
+
+  buf = buf_base + ((16 - ((size_t)buf_base & 0x0f)) % buffer_alignment);
+
+  algo = gcry_mac_map_name (algoname);
+  if (!algo)
+    {
+      fprintf (stderr, PGM ": invalid hash algorithm `%s'\n", algoname);
+      exit (1);
+    }
+
+  maclen = gcry_mac_get_algo_maclen (algo);
+  if (maclen > sizeof(mac))
+    maclen = sizeof(mac);
+
+  keylen = gcry_mac_get_algo_keylen (algo);
+  if (keylen == 0)
+    keylen = 32;
+  if (keylen > sizeof(key))
+    keylen = sizeof(key);
+  for (i=0; i < keylen; i++)
+    key[i] = (keylen - i) ^ 0x54;
+
+  err = gcry_mac_open (&hd, algo, 0, NULL);
+  if (err)
+    {
+      fprintf (stderr, PGM ": error opening mac algorithm `%s': %s\n", algoname,
+               gpg_strerror (err));
+      exit (1);
+    }
+
+  err = gcry_mac_setkey (hd, key, keylen);
+  if (err)
+    {
+      fprintf (stderr, PGM ": error setting key for mac algorithm `%s': %s\n",
+               algoname, gpg_strerror (err));
+      exit (1);
+    }
+
+  for (i=0; i < bufsize; i++)
+    buf[i] = i;
+
+  printf ("%-20s", gcry_mac_algo_name (algo));
+
+  start_timer ();
+  for (repcount=0; repcount < mac_repetitions; repcount++)
+    for (i=0; i < 1000; i++)
+      gcry_mac_write (hd, buf, bufsize);
+  macoutlen = maclen;
+  gcry_mac_read (hd, mac[0], &macoutlen);
+  stop_timer ();
+  printf (" %s", elapsed_time ());
+  fflush (stdout);
+
+  gcry_mac_reset (hd);
+  start_timer ();
+  for (repcount=0; repcount < mac_repetitions; repcount++)
+    for (i=0; i < 1000; i++)
+      for (step=bufsize/10, pos=0, j=0; j < 10; j++, pos+=step)
+        gcry_mac_write (hd, &buf[pos], step);
+  macoutlen = maclen;
+  gcry_mac_read (hd, mac[1], &macoutlen);
+  stop_timer ();
+  printf (" %s", elapsed_time ());
+  fflush (stdout);
+
+  gcry_mac_reset (hd);
+  start_timer ();
+  for (repcount=0; repcount < mac_repetitions; repcount++)
+    for (i=0; i < 1000; i++)
+      for (step=bufsize/100, pos=0, j=0; j < 100; j++, pos+=step)
+        gcry_mac_write (hd, &buf[pos], step);
+  macoutlen = maclen;
+  gcry_mac_read (hd, mac[2], &macoutlen);
+  stop_timer ();
+  printf (" %s", elapsed_time ());
+  fflush (stdout);
+
+  gcry_mac_close (hd);
+
+  for (i=1; i < 3; i++)
+    {
+      if (memcmp(mac[i-1], mac[i], maclen))
+        {
+          fprintf (stderr, PGM ": mac mismatch with algorithm `%s'\n",
+                   algoname);
+          exit(1);
+        }
+    }
+
+  putchar ('\n');
+  fflush (stdout);
+}
+
+
+#ifdef HAVE_U64_TYPEDEF
+static void ccm_aead_init(gcry_cipher_hd_t hd, size_t buflen, int authlen)
+{
+  const int _L = 4;
+  const int noncelen = 15 - _L;
+  char nonce[noncelen];
+  u64 params[3];
+  gcry_error_t err = GPG_ERR_NO_ERROR;
+
+  memset (nonce, 0x33, 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);
+    }
+
+  params[0] = buflen; /* encryptedlen */
+  params[1] = 0; /* aadlen */
+  params[2] = authlen; /* authtaglen */
+  err = gcry_cipher_ctl (hd, GCRYCTL_SET_CCM_LENGTHS, params, sizeof(params));
+  if (err)
+    {
+      fprintf (stderr, "gcry_cipher_setiv failed: %s\n",
+               gpg_strerror (err));
+      gcry_cipher_close (hd);
+      exit (1);
+    }
+}
+#endif
+
+
 static void
 cipher_bench ( const char *algoname )
 {
@@ -529,12 +610,25 @@ cipher_bench ( const char *algoname )
   char *raw_outbuf, *raw_buf;
   size_t allocated_buflen, buflen;
   int repetitions;
-  static struct { int mode; const char *name; int blocked; } modes[] = {
+  static const struct {
+    int mode;
+    const char *name;
+    int blocked;
+    void (* const aead_init)(gcry_cipher_hd_t hd, size_t buflen, int authlen);
+    int req_blocksize;
+    int authlen;
+  } 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_STREAM, "", 0 },
     {0}
   };
@@ -562,7 +656,7 @@ cipher_bench ( const char *algoname )
     }
   repetitions *= cipher_repetitions;
 
-  raw_buf = gcry_xmalloc (allocated_buflen+15);
+  raw_buf = gcry_xcalloc (allocated_buflen+15, 1);
   buf = (raw_buf
          + ((16 - ((size_t)raw_buf & 0x0f)) % buffer_alignment));
   outbuf = raw_outbuf = gcry_xmalloc (allocated_buflen+15);
@@ -623,9 +717,16 @@ cipher_bench ( const char *algoname )
   for (modeidx=0; modes[modeidx].mode; modeidx++)
     {
       if ((blklen > 1 && modes[modeidx].mode == GCRY_CIPHER_MODE_STREAM)
-          | (blklen == 1 && modes[modeidx].mode != GCRY_CIPHER_MODE_STREAM))
+          || (blklen == 1 && modes[modeidx].mode != GCRY_CIPHER_MODE_STREAM))
         continue;
 
+      if (modes[modeidx].req_blocksize > 0
+          && blklen != modes[modeidx].req_blocksize)
+        {
+          printf (" %7s %7s", "-", "-" );
+          continue;
+        }
+
       for (i=0; i < sizeof buf; i++)
         buf[i] = i;
 
@@ -666,7 +767,18 @@ cipher_bench ( const char *algoname )
                   exit (1);
                 }
             }
-          err = gcry_cipher_encrypt ( hd, outbuf, buflen, buf, buflen);
+          if (modes[modeidx].aead_init)
+            {
+              (*modes[modeidx].aead_init) (hd, buflen, modes[modeidx].authlen);
+              err = gcry_cipher_encrypt (hd, outbuf, buflen, buf, buflen);
+              if (err)
+                break;
+              err = gcry_cipher_gettag (hd, outbuf, modes[modeidx].authlen);
+            }
+          else
+            {
+              err = gcry_cipher_encrypt (hd, outbuf, buflen, buf, buflen);
+            }
         }
       stop_timer ();
 
@@ -713,7 +825,18 @@ cipher_bench ( const char *algoname )
                   exit (1);
                 }
             }
-          err = gcry_cipher_decrypt ( hd, outbuf, buflen,  buf, buflen);
+          if (modes[modeidx].aead_init)
+            {
+              (*modes[modeidx].aead_init) (hd, buflen, modes[modeidx].authlen);
+              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);
+            }
+          else
+            err = gcry_cipher_decrypt (hd, outbuf, buflen, buf, buflen);
         }
       stop_timer ();
       printf (" %s", elapsed_time ());
@@ -863,7 +986,7 @@ dsa_bench (int iterations, int print_header)
   int p_sizes[3] = { 1024, 2048, 3072 };
   int q_sizes[3] = { 160, 224, 256 };
   gcry_sexp_t data;
-  gcry_sexp_t sig;
+  gcry_sexp_t sig = NULL;
   int i, j;
 
   err = gcry_sexp_sscan (pub_key+0, NULL, sample_public_dsa_key_1024,
@@ -915,6 +1038,7 @@ dsa_bench (int iterations, int print_header)
       start_timer ();
       for (j=0; j < iterations; j++)
         {
+          gcry_sexp_release (sig);
           err = gcry_pk_sign (&sig, data, sec_key[i]);
           if (err)
             {
@@ -946,6 +1070,7 @@ dsa_bench (int iterations, int print_header)
 
       gcry_sexp_release (sig);
       gcry_sexp_release (data);
+      sig = NULL;
     }
 
 
@@ -962,7 +1087,8 @@ ecc_bench (int iterations, int print_header)
 {
 #if USE_ECC
   gpg_error_t err;
-  int p_sizes[] = { 192, 224, 256, 384, 521 };
+  const char *p_sizes[] = { "192", "224", "256", "384", "521", "Ed25519",
+              "gost256", "gost512" };
   int testno;
 
   if (print_header)
@@ -976,12 +1102,42 @@ ecc_bench (int iterations, int print_header)
       gcry_sexp_t data;
       gcry_sexp_t sig = NULL;
       int count;
+      int p_size;
+      int is_ed25519;
+      int is_gost;
 
-      printf ("ECDSA %3d bit ", p_sizes[testno]);
+      is_ed25519 = !strcmp (p_sizes[testno], "Ed25519");
+      is_gost = !strncmp (p_sizes[testno], "gost", 4);
+      if (is_ed25519)
+        {
+          p_size = 256;
+          printf ("EdDSA Ed25519 ");
+          fflush (stdout);
+        }
+      else if (is_gost)
+        {
+          p_size = atoi (p_sizes[testno] + 4);
+          printf ("GOST  %3d bit ", p_size);
+          fflush (stdout);
+        }
+      else
+        {
+          p_size = atoi (p_sizes[testno]);
+          printf ("ECDSA %3d bit ", p_size);
+        }
       fflush (stdout);
 
-      err = gcry_sexp_build (&key_spec, NULL,
-                             "(genkey (ECDSA (nbits %d)))", p_sizes[testno]);
+      if (is_ed25519)
+        err = gcry_sexp_build (&key_spec, NULL,
+                               "(genkey (ecdsa (curve \"Ed25519\")"
+                               "(flags eddsa)))");
+      else if (is_gost)
+        err = gcry_sexp_build (&key_spec, NULL,
+                               "(genkey (ecdsa (curve %s)))",
+                               p_size == 256 ? "GOST2001-test" : "GOST2012-test");
+      else
+        err = gcry_sexp_build (&key_spec, NULL,
+                               "(genkey (ECDSA (nbits %d)))", p_size);
       if (err)
         die ("creating S-expression failed: %s\n", gcry_strerror (err));
 
@@ -989,7 +1145,9 @@ ecc_bench (int iterations, int print_header)
       err = gcry_pk_genkey (&key_pair, key_spec);
       if (err)
         die ("creating %d bit ECC key failed: %s\n",
-             p_sizes[testno], gcry_strerror (err));
+             p_size, gcry_strerror (err));
+      if (verbose > 2)
+        show_sexp ("ECC key:\n", key_pair);
 
       pub_key = gcry_sexp_find_token (key_pair, "public-key", 0);
       if (! pub_key)
@@ -1004,10 +1162,18 @@ ecc_bench (int iterations, int print_header)
       printf ("     %s", elapsed_time ());
       fflush (stdout);
 
-      x = gcry_mpi_new (p_sizes[testno]);
-      gcry_mpi_randomize (x, p_sizes[testno], GCRY_WEAK_RANDOM);
-      err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x);
+      x = gcry_mpi_new (p_size);
+      gcry_mpi_randomize (x, p_size, GCRY_WEAK_RANDOM);
+      if (is_ed25519)
+        err = gcry_sexp_build (&data, NULL,
+                               "(data (flags eddsa)(hash-algo sha512)"
+                               " (value %m))", x);
+      else if (is_gost)
+        err = gcry_sexp_build (&data, NULL, "(data (flags gost) (value %m))", x);
+      else
+        err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x);
       gcry_mpi_release (x);
+
       if (err)
         die ("converting data failed: %s\n", gcry_strerror (err));
 
@@ -1017,7 +1183,15 @@ ecc_bench (int iterations, int print_header)
           gcry_sexp_release (sig);
           err = gcry_pk_sign (&sig, data, sec_key);
           if (err)
-            die ("signing failed: %s\n", gpg_strerror (err));
+            {
+              if (verbose)
+                {
+                  putc ('\n', stderr);
+                  show_sexp ("signing key:\n", sec_key);
+                  show_sexp ("signed data:\n", data);
+                }
+              die ("signing failed: %s\n", gpg_strerror (err));
+            }
         }
       stop_timer ();
       printf ("   %s", elapsed_time ());
@@ -1119,13 +1293,27 @@ main( int argc, char **argv )
   int last_argc = -1;
   int no_blinding = 0;
   int use_random_daemon = 0;
+  int use_secmem = 0;
   int with_progress = 0;
+  int debug = 0;
+  int pk_count = 100;
 
   buffer_alignment = 1;
 
   if (argc)
     { argc--; argv++; }
 
+  /* We skip this test if we are running under the test suite (no args
+     and srcdir defined) and GCRYPT_NO_BENCHMARKS is set.  */
+  if (!argc && getenv ("srcdir") && getenv ("GCRYPT_NO_BENCHMARKS"))
+    exit (77);
+
+  if (getenv ("GCRYPT_IN_REGRESSION_TEST"))
+    {
+      in_regression_test = 1;
+      pk_count = 10;
+    }
+
   while (argc && last_argc != argc )
     {
       last_argc = argc;
@@ -1137,7 +1325,7 @@ main( int argc, char **argv )
       else if (!strcmp (*argv, "--help"))
         {
           fputs ("usage: benchmark "
-                 "[md|cipher|random|mpi|rsa|dsa|ecc [algonames]]\n",
+                 "[md|mac|cipher|random|mpi|rsa|dsa|ecc [algonames]]\n",
                  stdout);
           exit (0);
         }
@@ -1146,11 +1334,39 @@ main( int argc, char **argv )
           verbose++;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--debug"))
+        {
+          verbose += 2;
+          debug++;
+          argc--; argv++;
+        }
       else if (!strcmp (*argv, "--use-random-daemon"))
         {
           use_random_daemon = 1;
           argc--; argv++;
         }
+      else if (!strcmp (*argv, "--use-secmem"))
+        {
+          use_secmem = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--prefer-standard-rng"))
+        {
+          /* This is anyway the default, but we may want to use it for
+             debugging. */
+          gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD);
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--prefer-fips-rng"))
+        {
+          gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS);
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--prefer-system-rng"))
+        {
+          gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM);
+          argc--; argv++;
+        }
       else if (!strcmp (*argv, "--no-blinding"))
         {
           no_blinding = 1;
@@ -1184,6 +1400,24 @@ main( int argc, char **argv )
               argc--; argv++;
             }
         }
+      else if (!strcmp (*argv, "--mac-repetitions"))
+        {
+          argc--; argv++;
+          if (argc)
+            {
+              mac_repetitions = atoi(*argv);
+              argc--; argv++;
+            }
+        }
+      else if (!strcmp (*argv, "--pk-count"))
+        {
+          argc--; argv++;
+          if (argc)
+            {
+              pk_count = atoi(*argv);
+              argc--; argv++;
+            }
+        }
       else if (!strcmp (*argv, "--alignment"))
         {
           argc--; argv++;
@@ -1229,9 +1463,12 @@ main( int argc, char **argv )
       exit (1);
     }
 
+  if (debug)
+    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
+
   if (gcry_fips_mode_active ())
     in_fips_mode = 1;
-  else
+  else if (!use_secmem)
     gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
 
   if (use_random_daemon)
@@ -1246,17 +1483,24 @@ main( int argc, char **argv )
     cipher_repetitions = 1;
   if (hash_repetitions < 1)
     hash_repetitions = 1;
+  if (mac_repetitions < 1)
+    mac_repetitions = 1;
+
+  if (in_regression_test)
+    fputs ("Note: " PGM " running in quick regression test mode.\n", stdout);
 
   if ( !argc )
     {
       gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
       md_bench (NULL);
       putchar ('\n');
+      mac_bench (NULL);
+      putchar ('\n');
       cipher_bench (NULL);
       putchar ('\n');
-      rsa_bench (100, 1, no_blinding);
-      dsa_bench (100, 0);
-      ecc_bench (100, 0);
+      rsa_bench (pk_count, 1, no_blinding);
+      dsa_bench (pk_count, 0);
+      ecc_bench (pk_count, 0);
       putchar ('\n');
       mpi_bench ();
       putchar ('\n');
@@ -1283,6 +1527,14 @@ main( int argc, char **argv )
         for (argc--, argv++; argc; argc--, argv++)
           md_bench ( *argv );
     }
+  else if ( !strcmp (*argv, "mac"))
+    {
+      if (argc == 1)
+        mac_bench (NULL);
+      else
+        for (argc--, argv++; argc; argc--, argv++)
+          mac_bench ( *argv );
+    }
   else if ( !strcmp (*argv, "cipher"))
     {
       if (argc == 1)
@@ -1298,17 +1550,17 @@ main( int argc, char **argv )
   else if ( !strcmp (*argv, "rsa"))
     {
         gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
-        rsa_bench (100, 1, no_blinding);
+        rsa_bench (pk_count, 1, no_blinding);
     }
   else if ( !strcmp (*argv, "dsa"))
     {
         gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
-        dsa_bench (100, 1);
+        dsa_bench (pk_count, 1);
     }
   else if ( !strcmp (*argv, "ecc"))
     {
         gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
-        ecc_bench (100, 1);
+        ecc_bench (pk_count, 1);
     }
   else
     {
index 6cfcd4f..198693e 100644 (file)
 #include <string.h>
 #include <stdarg.h>
 
-#include "../src/gcrypt.h"
+#include "../src/gcrypt-int.h"
 
 /* Number of curves defined in ../cipger/ecc.c */
-#define N_CURVES 12
+#define N_CURVES 15
 
 /* A real world sample public key.  */
 static char const sample_key_1[] =
@@ -51,12 +51,12 @@ static unsigned int sample_key_1_nbits = 256;
 static char const sample_key_2[] =
 "(public-key\n"
 " (ecdh\n"
-"  (p #e95e4a5f737059dc60dfc7ad95b3d8139515620f#)\n"
+"  (p #00e95e4a5f737059dc60dfc7ad95b3d8139515620f#)\n"
 "  (a #340e7be2a280eb74e2be61bada745d97e8f7c300#)\n"
 "  (b #1e589a8595423412134faa2dbdec95c8d8675e58#)\n"
 "  (g #04bed5af16ea3f6a4f62938c4631eb5af7bdbcdbc3"
         "1667cb477a1a8ec338f94741669c976316da6321#)\n"
-"  (n #e95e4a5f737059dc60df5991d45029409e60fc09#)\n"
+"  (n #00e95e4a5f737059dc60df5991d45029409e60fc09#)\n"
 "  (q #041111111111111111111111111111111111111111"
         "2222222222222222222222222222222222222222#)\n"
 "  ))";
diff --git a/tests/dsa-rfc6979.c b/tests/dsa-rfc6979.c
new file mode 100644 (file)
index 0000000..4ecdef9
--- /dev/null
@@ -0,0 +1,1030 @@
+/* dsa-rfc6979.c - Test for Deterministic DSA
+ * Copyright (C) 2008 Free Software Foundation, Inc.
+ * Copyright (C) 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/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#ifdef _GCRYPT_IN_LIBGCRYPT
+# include "../src/gcrypt-int.h"
+#else
+# include <gcrypt.h>
+#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 DIM(v)              (sizeof(v)/sizeof((v)[0]))
+#define DIMof(type,member)   DIM(((type *)0)->member)
+
+static int verbose;
+static int error_count;
+
+static void
+info (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+}
+
+static void
+fail (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+  error_count++;
+}
+
+static void
+die (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+  exit (1);
+}
+
+static void
+show_sexp (const char *prefix, gcry_sexp_t a)
+{
+  char *buf;
+  size_t size;
+
+  if (prefix)
+    fputs (prefix, stderr);
+  size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+  buf = gcry_xmalloc (size);
+
+  gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
+  fprintf (stderr, "%.*s", (int)size, buf);
+  gcry_free (buf);
+}
+
+
+/* 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 *
+data_from_hex (const char *string, size_t *r_length)
+{
+  const char *s;
+  unsigned char *buffer;
+  size_t length;
+
+  buffer = gcry_xmalloc (strlen(string)/2+1);
+  length = 0;
+  for (s=string; *s; s +=2 )
+    {
+      if (!hexdigitp (s) || !hexdigitp (s+1))
+        die ("error parsing hex string `%s'\n", string);
+      ((unsigned char*)buffer)[length++] = xtoi_2 (s);
+    }
+  *r_length = length;
+  return buffer;
+}
+
+
+static void
+extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected)
+{
+  gcry_sexp_t l1;
+  const void *a;
+  size_t alen;
+  void *b;
+  size_t blen;
+
+  l1 = gcry_sexp_find_token (sexp, name, 0);
+  a = gcry_sexp_nth_data (l1, 1, &alen);
+  b = data_from_hex (expected, &blen);
+  if (!a)
+    fail ("parameter \"%s\" missing in key\n", name);
+  else if ( alen != blen || memcmp (a, b, alen) )
+    {
+      fail ("parameter \"%s\" does not match expected value\n", name);
+      if (verbose)
+        {
+          info ("expected: %s\n", expected);
+          show_sexp ("sexp: ", sexp);
+        }
+    }
+  gcry_free (b);
+  gcry_sexp_release (l1);
+}
+
+
+/* These test vectors are from RFC 6979.  */
+static void
+check_dsa_rfc6979 (void)
+{
+  static struct {
+    const char *name;
+    const char *key;
+  } keys[] = {
+    {
+      "DSA, 1024 bits",
+      "(private-key"
+      " (DSA"
+      " (p #86F5CA03DCFEB225063FF830A0C769B9DD9D6153AD91D7CE27F787C43278B447"
+      "     E6533B86B18BED6E8A48B784A14C252C5BE0DBF60B86D6385BD2F12FB763ED88"
+      "     73ABFD3F5BA2E0A8C0A59082EAC056935E529DAF7C610467899C77ADEDFC846C"
+      "     881870B7B19B2B58F9BE0521A17002E3BDD6B86685EE90B3D9A1B02B782B1779#)"
+      " (q #996F967F6C8E388D9E28D01E205FBA957A5698B1#)"
+      " (g #07B0F92546150B62514BB771E2A0C0CE387F03BDA6C56B505209FF25FD3C133D"
+      "     89BBCD97E904E09114D9A7DEFDEADFC9078EA544D2E401AEECC40BB9FBBF78FD"
+      "     87995A10A1C27CB7789B594BA7EFB5C4326A9FE59A070E136DB77175464ADCA4"
+      "     17BE5DCE2F40D10A46A3A3943F26AB7FD9C0398FF8C76EE0A56826A8A88F1DBD#)"
+      " (x #411602CB19A6CCC34494D79D98EF1E7ED5AF25F7#)"
+      " (y #5DF5E01DED31D0297E274E1691C192FE5868FEF9E19A84776454B100CF16F653"
+      "     92195A38B90523E2542EE61871C0440CB87C322FC4B4D2EC5E1E7EC766E1BE8D"
+      "     4CE935437DC11C3C8FD426338933EBFE739CB3465F4D3668C5E473508253B1E6"
+      "     82F65CBDC4FAE93C2EA212390E54905A86E2223170B44EAA7DA5DD9FFCFB7F3B#)"
+      " ))"
+    },
+    {
+      "DSA, 2048 bits",
+      "(private-key"
+      " (DSA"
+      " (p #9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48"
+      "     C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44F"
+      "     FE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5"
+      "     B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE2"
+      "     35567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41"
+      "     F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE"
+      "     92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA15"
+      "     3E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B#)"
+      " (q #F2C3119374CE76C9356990B465374A17F23F9ED35089BD969F61C6DDE9998C1F#)"
+      " (g #5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613"
+      "     D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C4"
+      "     6A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472"
+      "     085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5"
+      "     AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA"
+      "     3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71"
+      "     BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0"
+      "     DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7#)"
+      " (x #69C7548C21D0DFEA6B9A51C9EAD4E27C33D3B3F180316E5BCAB92C933F0E4DBC#)"
+      " (y #667098C654426C78D7F8201EAC6C203EF030D43605032C2F1FA937E5237DBD94"
+      "     9F34A0A2564FE126DC8B715C5141802CE0979C8246463C40E6B6BDAA2513FA61"
+      "     1728716C2E4FD53BC95B89E69949D96512E873B9C8F8DFD499CC312882561ADE"
+      "     CB31F658E934C0C197F2C4D96B05CBAD67381E7B768891E4DA3843D24D94CDFB"
+      "     5126E9B8BF21E8358EE0E0A30EF13FD6A664C0DCE3731F7FB49A4845A4FD8254"
+      "     687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D1"
+      "     23AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA"
+      "     74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF#)"
+      " ))"
+    },
+    {
+      "ECDSA, 192 bits (prime field)",
+      "(private-key"
+      " (ecdsa"
+      " (curve \"NIST P-192\")"
+      " (q #04AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56"
+      "       3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43#)"
+      " (d #6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4#)"
+      " ))"
+    },
+    {
+      "ECDSA, 224 bits (prime field)",
+      "(private-key"
+      " (ecdsa"
+      " (curve \"NIST P-224\")"
+      " (q #04"
+      "     00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C"
+      "     EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A#)"
+      " (d #F220266E1105BFE3083E03EC7A3A654651F45E37167E88600BF257C1#)"
+      " ))"
+    },
+    {
+      "ECDSA, 256 bits (prime field)",
+      "(private-key"
+      " (ecdsa"
+      " (curve \"NIST P-256\")"
+      " (q #04"
+      "     60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6"
+      "     7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299#)"
+      " (d #C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721#)"
+      " ))"
+    },
+    {
+      "ECDSA, 384 bits (prime field)",
+      "(private-key"
+      " (ecdsa"
+      " (curve \"NIST P-384\")"
+      " (q #04"
+      "     EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64"
+      "     DEF8F0EA9055866064A254515480BC13"
+      "     8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1"
+      "     288B231C3AE0D4FE7344FD2533264720#)"
+      " (d #6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D8"
+      "     96D5724E4C70A825F872C9EA60D2EDF5#)"
+      " ))"
+    },
+    {
+      "ECDSA, 521 bits (prime field)",
+      "(private-key"
+      " (ecdsa"
+      " (curve \"NIST P-521\")"
+      " (q #04"
+      "     01894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD"
+      "     371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F50"
+      "     23A4"
+      "     00493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A"
+      "     28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFD"
+      "     FCF5#)"
+      " (d #FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75"
+      "     CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B8"
+      "     3538#)"
+      " ))"
+    },
+    { NULL }
+  };
+
+  static struct {
+    const char *keyname;
+    const char *name;
+    const char *hashname;
+    const char *message;
+    const char *k, *r, *s;
+  } tests[] = {
+    {
+      "DSA, 1024 bits",
+      "With SHA-1, message = \"sample\"",
+      "sha1", "sample",
+      "7BDB6B0FF756E1BB5D53583EF979082F9AD5BD5B",
+      "2E1A0C2562B2912CAAF89186FB0F42001585DA55",
+      "29EFB6B0AFF2D7A68EB70CA313022253B9A88DF5"
+    },
+    {
+      "DSA, 1024 bits",
+      "With SHA-224, message = \"sample\"",
+      "sha224", "sample",
+      "562097C06782D60C3037BA7BE104774344687649",
+      "4BC3B686AEA70145856814A6F1BB53346F02101E",
+      "410697B92295D994D21EDD2F4ADA85566F6F94C1"
+    },
+    {
+      "DSA, 1024 bits",
+      "With SHA-256, message = \"sample\"",
+      "sha256", "sample",
+      "519BA0546D0C39202A7D34D7DFA5E760B318BCFB",
+      "81F2F5850BE5BC123C43F71A3033E9384611C545",
+      "4CDD914B65EB6C66A8AAAD27299BEE6B035F5E89"
+    },
+    {
+      "DSA, 1024 bits",
+      "With SHA-384, message = \"sample\"",
+      "sha384", "sample",
+      "95897CD7BBB944AA932DBC579C1C09EB6FCFC595",
+      "07F2108557EE0E3921BC1774F1CA9B410B4CE65A",
+      "54DF70456C86FAC10FAB47C1949AB83F2C6F7595"
+    },
+    {
+      "DSA, 1024 bits",
+      "With SHA-512, message = \"sample\"",
+      "sha512", "sample",
+      "09ECE7CA27D0F5A4DD4E556C9DF1D21D28104F8B",
+      "16C3491F9B8C3FBBDD5E7A7B667057F0D8EE8E1B",
+      "02C36A127A7B89EDBB72E4FFBC71DABC7D4FC69C"
+    },
+    {
+      "DSA, 1024 bits",
+      "With SHA-1, message = \"test\"",
+      "sha1", "test",
+      "5C842DF4F9E344EE09F056838B42C7A17F4A6433",
+      "42AB2052FD43E123F0607F115052A67DCD9C5C77",
+      "183916B0230D45B9931491D4C6B0BD2FB4AAF088"
+    },
+    {
+      "DSA, 1024 bits",
+      "With SHA-224, message = \"test\"",
+      "sha224", "test",
+      "4598B8EFC1A53BC8AECD58D1ABBB0C0C71E67297",
+      "6868E9964E36C1689F6037F91F28D5F2C30610F2",
+      "49CEC3ACDC83018C5BD2674ECAAD35B8CD22940F"
+    },
+    {
+      "DSA, 1024 bits",
+      "With SHA-256, message = \"test\"",
+      "sha256", "test",
+      "5A67592E8128E03A417B0484410FB72C0B630E1A",
+      "22518C127299B0F6FDC9872B282B9E70D0790812",
+      "6837EC18F150D55DE95B5E29BE7AF5D01E4FE160"
+    },
+    {
+      "DSA, 1024 bits",
+      "With SHA-384, message = \"test\"",
+      "sha384", "test",
+      "220156B761F6CA5E6C9F1B9CF9C24BE25F98CD89",
+      "854CF929B58D73C3CBFDC421E8D5430CD6DB5E66",
+      "91D0E0F53E22F898D158380676A871A157CDA622"
+    },
+    {
+      "DSA, 1024 bits",
+      "With SHA-512, message = \"test\"",
+      "sha512", "test",
+      "65D2C2EEB175E370F28C75BFCDC028D22C7DBE9C",
+      "8EA47E475BA8AC6F2D821DA3BD212D11A3DEB9A0",
+      "7C670C7AD72B6C050C109E1790008097125433E8"
+    },
+    {
+      "DSA, 2048 bits",
+      "With SHA-1, message = \"sample\"",
+      "sha1", "sample",
+      "888FA6F7738A41BDC9846466ABDB8174C0338250AE50CE955CA16230F9CBD53E",
+      "3A1B2DBD7489D6ED7E608FD036C83AF396E290DBD602408E8677DAABD6E7445A",
+      "D26FCBA19FA3E3058FFC02CA1596CDBB6E0D20CB37B06054F7E36DED0CDBBCCF"
+    },
+    {
+      "DSA, 2048 bits",
+      "With SHA-224, message = \"sample\"",
+      "sha224", "sample",
+      "BC372967702082E1AA4FCE892209F71AE4AD25A6DFD869334E6F153BD0C4D806",
+      "DC9F4DEADA8D8FF588E98FED0AB690FFCE858DC8C79376450EB6B76C24537E2C",
+      "A65A9C3BC7BABE286B195D5DA68616DA8D47FA0097F36DD19F517327DC848CEC"
+    },
+    {
+      "DSA, 2048 bits",
+      "With SHA-256, message = \"sample\"",
+      "sha256", "sample",
+      "8926A27C40484216F052F4427CFD5647338B7B3939BC6573AF4333569D597C52",
+      "EACE8BDBBE353C432A795D9EC556C6D021F7A03F42C36E9BC87E4AC7932CC809",
+      "7081E175455F9247B812B74583E9E94F9EA79BD640DC962533B0680793A38D53"
+    },
+    {
+      "DSA, 2048 bits",
+      "With SHA-384, message = \"sample\"",
+      "sha384", "sample",
+      "C345D5AB3DA0A5BCB7EC8F8FB7A7E96069E03B206371EF7D83E39068EC564920",
+      "B2DA945E91858834FD9BF616EBAC151EDBC4B45D27D0DD4A7F6A22739F45C00B",
+      "19048B63D9FD6BCA1D9BAE3664E1BCB97F7276C306130969F63F38FA8319021B"
+    },
+    {
+      "DSA, 2048 bits",
+      "With SHA-512, message = \"sample\"",
+      "sha512", "sample",
+      "5A12994431785485B3F5F067221517791B85A597B7A9436995C89ED0374668FC",
+      "2016ED092DC5FB669B8EFB3D1F31A91EECB199879BE0CF78F02BA062CB4C942E",
+      "D0C76F84B5F091E141572A639A4FB8C230807EEA7D55C8A154A224400AFF2351"
+    },
+    {
+      "DSA, 2048 bits",
+      "With SHA-1, message = \"test\"",
+      "sha1", "test",
+      "6EEA486F9D41A037B2C640BC5645694FF8FF4B98D066A25F76BE641CCB24BA4F",
+      "C18270A93CFC6063F57A4DFA86024F700D980E4CF4E2CB65A504397273D98EA0",
+      "414F22E5F31A8B6D33295C7539C1C1BA3A6160D7D68D50AC0D3A5BEAC2884FAA"
+    },
+    {
+      "DSA, 2048 bits",
+      "With SHA-224, message = \"test\"",
+      "sha224", "test",
+      "06BD4C05ED74719106223BE33F2D95DA6B3B541DAD7BFBD7AC508213B6DA6670",
+      "272ABA31572F6CC55E30BF616B7A265312018DD325BE031BE0CC82AA17870EA3",
+      "E9CC286A52CCE201586722D36D1E917EB96A4EBDB47932F9576AC645B3A60806"
+    },
+    {
+      "DSA, 2048 bits",
+      "With SHA-256, message = \"test\"",
+      "sha256", "test",
+      "1D6CE6DDA1C5D37307839CD03AB0A5CBB18E60D800937D67DFB4479AAC8DEAD7",
+      "8190012A1969F9957D56FCCAAD223186F423398D58EF5B3CEFD5A4146A4476F0",
+      "7452A53F7075D417B4B013B278D1BB8BBD21863F5E7B1CEE679CF2188E1AB19E"
+    },
+    {
+      "DSA, 2048 bits",
+      "With SHA-384, message = \"test\"",
+      "sha384", "test",
+      "206E61F73DBE1B2DC8BE736B22B079E9DACD974DB00EEBBC5B64CAD39CF9F91C",
+      "239E66DDBE8F8C230A3D071D601B6FFBDFB5901F94D444C6AF56F732BEB954BE",
+      "6BD737513D5E72FE85D1C750E0F73921FE299B945AAD1C802F15C26A43D34961"
+    },
+    {
+      "DSA, 2048 bits",
+      "With SHA-512, message = \"test\"",
+      "sha512", "test",
+      "AFF1651E4CD6036D57AA8B2A05CCF1A9D5A40166340ECBBDC55BE10B568AA0AA",
+      "89EC4BB1400ECCFF8E7D9AA515CD1DE7803F2DAFF09693EE7FD1353E90A68307",
+      "C9F0BDABCC0D880BB137A994CC7F3980CE91CC10FAF529FC46565B15CEA854E1"
+    },
+    {
+      "ECDSA, 192 bits (prime field)",
+      "With SHA-1, message = \"sample\"",
+      "sha1", "sample",
+      "37D7CA00D2C7B0E5E412AC03BD44BA837FDD5B28CD3B0021",
+      "98C6BD12B23EAF5E2A2045132086BE3EB8EBD62ABF6698FF",
+      "57A22B07DEA9530F8DE9471B1DC6624472E8E2844BC25B64"
+    },
+    {
+      "ECDSA, 192 bits (prime field)",
+      "With SHA-224, message = \"sample\"",
+      "sha224", "sample",
+      "4381526B3FC1E7128F202E194505592F01D5FF4C5AF015D8",
+      "A1F00DAD97AEEC91C95585F36200C65F3C01812AA60378F5",
+      "E07EC1304C7C6C9DEBBE980B9692668F81D4DE7922A0F97A"
+    },
+    {
+      "ECDSA, 192 bits (prime field)",
+      "With SHA-256, message = \"sample\"",
+      "sha256", "sample",
+      "32B1B6D7D42A05CB449065727A84804FB1A3E34D8F261496",
+      "4B0B8CE98A92866A2820E20AA6B75B56382E0F9BFD5ECB55",
+      "CCDB006926EA9565CBADC840829D8C384E06DE1F1E381B85"
+    },
+    {
+      "ECDSA, 192 bits (prime field)",
+      "With SHA-384, message = \"sample\"",
+      "sha384", "sample",
+      "4730005C4FCB01834C063A7B6760096DBE284B8252EF4311",
+      "DA63BF0B9ABCF948FBB1E9167F136145F7A20426DCC287D5",
+      "C3AA2C960972BD7A2003A57E1C4C77F0578F8AE95E31EC5E"
+    },
+    {
+      "ECDSA, 192 bits (prime field)",
+      "With SHA-512, message = \"sample\"",
+      "sha512", "sample",
+      "A2AC7AB055E4F20692D49209544C203A7D1F2C0BFBC75DB1",
+      "4D60C5AB1996BD848343B31C00850205E2EA6922DAC2E4B8",
+      "3F6E837448F027A1BF4B34E796E32A811CBB4050908D8F67"
+    },
+    {
+      "ECDSA, 192 bits (prime field)",
+      "With SHA-1, message = \"test\"",
+      "sha1", "test",
+      "D9CF9C3D3297D3260773A1DA7418DB5537AB8DD93DE7FA25",
+      "0F2141A0EBBC44D2E1AF90A50EBCFCE5E197B3B7D4DE036D",
+      "EB18BC9E1F3D7387500CB99CF5F7C157070A8961E38700B7"
+    },
+    {
+      "ECDSA, 192 bits (prime field)",
+      "With SHA-224, message = \"test\"",
+      "sha224", "test",
+      "F5DC805F76EF851800700CCE82E7B98D8911B7D510059FBE",
+      "6945A1C1D1B2206B8145548F633BB61CEF04891BAF26ED34",
+      "B7FB7FDFC339C0B9BD61A9F5A8EAF9BE58FC5CBA2CB15293"
+    },
+    {
+      "ECDSA, 192 bits (prime field)",
+      "With SHA-256, message = \"test\"",
+      "sha256", "test",
+      "5C4CE89CF56D9E7C77C8585339B006B97B5F0680B4306C6C",
+      "3A718BD8B4926C3B52EE6BBE67EF79B18CB6EB62B1AD97AE",
+      "5662E6848A4A19B1F1AE2F72ACD4B8BBE50F1EAC65D9124F"
+    },
+    {
+      "ECDSA, 192 bits (prime field)",
+      "With SHA-384, message = \"test\"",
+      "sha384", "test",
+      "5AFEFB5D3393261B828DB6C91FBC68C230727B030C975693",
+      "B234B60B4DB75A733E19280A7A6034BD6B1EE88AF5332367",
+      "7994090B2D59BB782BE57E74A44C9A1C700413F8ABEFE77A"
+    },
+    {
+      "ECDSA, 192 bits (prime field)",
+      "With SHA-512, message = \"test\"",
+      "sha512", "test",
+      "0758753A5254759C7CFBAD2E2D9B0792EEE44136C9480527",
+      "FE4F4AE86A58B6507946715934FE2D8FF9D95B6B098FE739",
+      "74CF5605C98FBA0E1EF34D4B5A1577A7DCF59457CAE52290"
+    },
+
+
+
+    {
+      "ECDSA, 224 bits (prime field)",
+      "With SHA-1, message = \"sample\"",
+      "sha1", "sample",
+      "7EEFADD91110D8DE6C2C470831387C50D3357F7F4D477054B8B426BC",
+      "22226F9D40A96E19C4A301CE5B74B115303C0F3A4FD30FC257FB57AC",
+      "66D1CDD83E3AF75605DD6E2FEFF196D30AA7ED7A2EDF7AF475403D69"
+    },
+    {
+      "ECDSA, 224 bits (prime field)",
+      "With SHA-224, message = \"sample\"",
+      "sha224", "sample",
+      "C1D1F2F10881088301880506805FEB4825FE09ACB6816C36991AA06D",
+      "1CDFE6662DDE1E4A1EC4CDEDF6A1F5A2FB7FBD9145C12113E6ABFD3E",
+      "A6694FD7718A21053F225D3F46197CA699D45006C06F871808F43EBC"
+    },
+    {
+      "ECDSA, 224 bits (prime field)",
+      "With SHA-256, message = \"sample\"",
+      "sha256", "sample",
+      "AD3029E0278F80643DE33917CE6908C70A8FF50A411F06E41DEDFCDC",
+      "61AA3DA010E8E8406C656BC477A7A7189895E7E840CDFE8FF42307BA",
+      "BC814050DAB5D23770879494F9E0A680DC1AF7161991BDE692B10101"
+    },
+    {
+      "ECDSA, 224 bits (prime field)",
+      "With SHA-384, message = \"sample\"",
+      "sha384", "sample",
+      "52B40F5A9D3D13040F494E83D3906C6079F29981035C7BD51E5CAC40",
+      "0B115E5E36F0F9EC81F1325A5952878D745E19D7BB3EABFABA77E953",
+      "830F34CCDFE826CCFDC81EB4129772E20E122348A2BBD889A1B1AF1D"
+    },
+    {
+      "ECDSA, 224 bits (prime field)",
+      "With SHA-512, message = \"sample\"",
+      "sha512", "sample",
+      "9DB103FFEDEDF9CFDBA05184F925400C1653B8501BAB89CEA0FBEC14",
+      "074BD1D979D5F32BF958DDC61E4FB4872ADCAFEB2256497CDAC30397",
+      "A4CECA196C3D5A1FF31027B33185DC8EE43F288B21AB342E5D8EB084"
+    },
+    {
+      "ECDSA, 224 bits (prime field)",
+      "With SHA-1, message = \"test\"",
+      "sha1", "test",
+      "2519178F82C3F0E4F87ED5883A4E114E5B7A6E374043D8EFD329C253",
+      "DEAA646EC2AF2EA8AD53ED66B2E2DDAA49A12EFD8356561451F3E21C",
+      "95987796F6CF2062AB8135271DE56AE55366C045F6D9593F53787BD2"
+    },
+    {
+      "ECDSA, 224 bits (prime field)",
+      "With SHA-224, message = \"test\"",
+      "sha224", "test",
+      "DF8B38D40DCA3E077D0AC520BF56B6D565134D9B5F2EAE0D34900524",
+      "C441CE8E261DED634E4CF84910E4C5D1D22C5CF3B732BB204DBEF019",
+      "902F42847A63BDC5F6046ADA114953120F99442D76510150F372A3F4"
+    },
+    {
+      "ECDSA, 224 bits (prime field)",
+      "With SHA-256, message = \"test\"",
+      "sha256", "test",
+      "FF86F57924DA248D6E44E8154EB69F0AE2AEBAEE9931D0B5A969F904",
+      "AD04DDE87B84747A243A631EA47A1BA6D1FAA059149AD2440DE6FBA6",
+      "178D49B1AE90E3D8B629BE3DB5683915F4E8C99FDF6E666CF37ADCFD"
+    },
+    {
+      "ECDSA, 224 bits (prime field)",
+      "With SHA-384, message = \"test\"",
+      "sha384", "test",
+      "7046742B839478C1B5BD31DB2E862AD868E1A45C863585B5F22BDC2D",
+      "389B92682E399B26518A95506B52C03BC9379A9DADF3391A21FB0EA4",
+      "414A718ED3249FF6DBC5B50C27F71F01F070944DA22AB1F78F559AAB"
+    },
+    {
+      "ECDSA, 224 bits (prime field)",
+      "With SHA-512, message = \"test\"",
+      "sha512", "test",
+      "E39C2AA4EA6BE2306C72126D40ED77BF9739BB4D6EF2BBB1DCB6169D",
+      "049F050477C5ADD858CAC56208394B5A55BAEBBE887FDF765047C17C",
+      "077EB13E7005929CEFA3CD0403C7CDCC077ADF4E44F3C41B2F60ECFF"
+    },
+    {
+      "ECDSA, 256 bits (prime field)",
+      "With SHA-1, message = \"sample\"",
+      "sha1", "sample",
+      "882905F1227FD620FBF2ABF21244F0BA83D0DC3A9103DBBEE43A1FB858109DB4",
+      "61340C88C3AAEBEB4F6D667F672CA9759A6CCAA9FA8811313039EE4A35471D32",
+      "6D7F147DAC089441BB2E2FE8F7A3FA264B9C475098FDCF6E00D7C996E1B8B7EB"
+    },
+    {
+      "ECDSA, 256 bits (prime field)",
+      "With SHA-224, message = \"sample\"",
+      "sha224", "sample",
+      "103F90EE9DC52E5E7FB5132B7033C63066D194321491862059967C715985D473",
+      "53B2FFF5D1752B2C689DF257C04C40A587FABABB3F6FC2702F1343AF7CA9AA3F",
+      "B9AFB64FDC03DC1A131C7D2386D11E349F070AA432A4ACC918BEA988BF75C74C"
+    },
+    {
+      "ECDSA, 256 bits (prime field)",
+      "With SHA-256, message = \"sample\"",
+      "sha256", "sample",
+      "A6E3C57DD01ABE90086538398355DD4C3B17AA873382B0F24D6129493D8AAD60",
+      "EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716",
+      "F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8"
+    },
+    {
+      "ECDSA, 256 bits (prime field)",
+      "With SHA-384, message = \"sample\"",
+      "sha384", "sample",
+      "09F634B188CEFD98E7EC88B1AA9852D734D0BC272F7D2A47DECC6EBEB375AAD4",
+      "0EAFEA039B20E9B42309FB1D89E213057CBF973DC0CFC8F129EDDDC800EF7719",
+      "4861F0491E6998B9455193E34E7B0D284DDD7149A74B95B9261F13ABDE940954"
+    },
+    {
+      "ECDSA, 256 bits (prime field)",
+      "With SHA-512, message = \"sample\"",
+      "sha512", "sample",
+      "5FA81C63109BADB88C1F367B47DA606DA28CAD69AA22C4FE6AD7DF73A7173AA5",
+      "8496A60B5E9B47C825488827E0495B0E3FA109EC4568FD3F8D1097678EB97F00",
+      "2362AB1ADBE2B8ADF9CB9EDAB740EA6049C028114F2460F96554F61FAE3302FE"
+    },
+    {
+      "ECDSA, 256 bits (prime field)",
+      "With SHA-1, message = \"test\"",
+      "sha1", "test",
+      "8C9520267C55D6B980DF741E56B4ADEE114D84FBFA2E62137954164028632A2E",
+      "0CBCC86FD6ABD1D99E703E1EC50069EE5C0B4BA4B9AC60E409E8EC5910D81A89",
+      "01B9D7B73DFAA60D5651EC4591A0136F87653E0FD780C3B1BC872FFDEAE479B1"
+    },
+    {
+      "ECDSA, 256 bits (prime field)",
+      "With SHA-224, message = \"test\"",
+      "sha224", "test",
+      "669F4426F2688B8BE0DB3A6BD1989BDAEFFF84B649EEB84F3DD26080F667FAA7",
+      "C37EDB6F0AE79D47C3C27E962FA269BB4F441770357E114EE511F662EC34A692",
+      "C820053A05791E521FCAAD6042D40AEA1D6B1A540138558F47D0719800E18F2D"
+    },
+    {
+      "ECDSA, 256 bits (prime field)",
+      "With SHA-256, message = \"test\"",
+      "sha256", "test",
+      "D16B6AE827F17175E040871A1C7EC3500192C4C92677336EC2537ACAEE0008E0",
+      "F1ABB023518351CD71D881567B1EA663ED3EFCF6C5132B354F28D3B0B7D38367",
+      "019F4113742A2B14BD25926B49C649155F267E60D3814B4C0CC84250E46F0083"
+    },
+    {
+      "ECDSA, 256 bits (prime field)",
+      "With SHA-384, message = \"test\"",
+      "sha384", "test",
+      "16AEFFA357260B04B1DD199693960740066C1A8F3E8EDD79070AA914D361B3B8",
+      "83910E8B48BB0C74244EBDF7F07A1C5413D61472BD941EF3920E623FBCCEBEB6",
+      "8DDBEC54CF8CD5874883841D712142A56A8D0F218F5003CB0296B6B509619F2C"
+    },
+    {
+      "ECDSA, 256 bits (prime field)",
+      "With SHA-512, message = \"test\"",
+      "sha512", "test",
+      "6915D11632ACA3C40D5D51C08DAF9C555933819548784480E93499000D9F0B7F",
+      "461D93F31B6540894788FD206C07CFA0CC35F46FA3C91816FFF1040AD1581A04",
+      "39AF9F15DE0DB8D97E72719C74820D304CE5226E32DEDAE67519E840D1194E55"
+    },
+    {
+      "ECDSA, 384 bits (prime field)",
+      "With SHA-1, message = \"sample\"",
+      "sha1", "sample",
+      "4471EF7518BB2C7C20F62EAE1C387AD0C5E8E470995DB4ACF694466E6AB09663"
+      "0F29E5938D25106C3C340045A2DB01A7",
+      "EC748D839243D6FBEF4FC5C4859A7DFFD7F3ABDDF72014540C16D73309834FA3"
+      "7B9BA002899F6FDA3A4A9386790D4EB2",
+      "A3BCFA947BEEF4732BF247AC17F71676CB31A847B9FF0CBC9C9ED4C1A5B3FACF"
+      "26F49CA031D4857570CCB5CA4424A443"
+    },
+    {
+      "ECDSA, 384 bits (prime field)",
+      "With SHA-224, message = \"sample\"",
+      "sha224", "sample",
+      "A4E4D2F0E729EB786B31FC20AD5D849E304450E0AE8E3E341134A5C1AFA03CAB"
+      "8083EE4E3C45B06A5899EA56C51B5879",
+      "42356E76B55A6D9B4631C865445DBE54E056D3B3431766D0509244793C3F9366"
+      "450F76EE3DE43F5A125333A6BE060122",
+      "9DA0C81787064021E78DF658F2FBB0B042BF304665DB721F077A4298B095E483"
+      "4C082C03D83028EFBF93A3C23940CA8D"
+    },
+    {
+      "ECDSA, 384 bits (prime field)",
+      "With SHA-256, message = \"sample\"",
+      "sha256", "sample",
+      "180AE9F9AEC5438A44BC159A1FCB277C7BE54FA20E7CF404B490650A8ACC414E"
+      "375572342863C899F9F2EDF9747A9B60",
+      "21B13D1E013C7FA1392D03C5F99AF8B30C570C6F98D4EA8E354B63A21D3DAA33"
+      "BDE1E888E63355D92FA2B3C36D8FB2CD",
+      "F3AA443FB107745BF4BD77CB3891674632068A10CA67E3D45DB2266FA7D1FEEB"
+      "EFDC63ECCD1AC42EC0CB8668A4FA0AB0"
+    },
+    {
+      "ECDSA, 384 bits (prime field)",
+      "With SHA-384, message = \"sample\"",
+      "sha384", "sample",
+      "94ED910D1A099DAD3254E9242AE85ABDE4BA15168EAF0CA87A555FD56D10FBCA"
+      "2907E3E83BA95368623B8C4686915CF9",
+      "94EDBB92A5ECB8AAD4736E56C691916B3F88140666CE9FA73D64C4EA95AD133C"
+      "81A648152E44ACF96E36DD1E80FABE46",
+      "99EF4AEB15F178CEA1FE40DB2603138F130E740A19624526203B6351D0A3A94F"
+      "A329C145786E679E7B82C71A38628AC8"
+    },
+    {
+      "ECDSA, 384 bits (prime field)",
+      "With SHA-512, message = \"sample\"",
+      "sha512", "sample",
+      "92FC3C7183A883E24216D1141F1A8976C5B0DD797DFA597E3D7B32198BD35331"
+      "A4E966532593A52980D0E3AAA5E10EC3",
+      "ED0959D5880AB2D869AE7F6C2915C6D60F96507F9CB3E047C0046861DA4A799C"
+      "FE30F35CC900056D7C99CD7882433709",
+      "512C8CCEEE3890A84058CE1E22DBC2198F42323CE8ACA9135329F03C068E5112"
+      "DC7CC3EF3446DEFCEB01A45C2667FDD5"
+    },
+    {
+      "ECDSA, 384 bits (prime field)",
+      "With SHA-1, message = \"test\"",
+      "sha1", "test",
+      "66CC2C8F4D303FC962E5FF6A27BD79F84EC812DDAE58CF5243B64A4AD8094D47"
+      "EC3727F3A3C186C15054492E30698497",
+      "4BC35D3A50EF4E30576F58CD96CE6BF638025EE624004A1F7789A8B8E43D0678"
+      "ACD9D29876DAF46638645F7F404B11C7",
+      "D5A6326C494ED3FF614703878961C0FDE7B2C278F9A65FD8C4B7186201A29916"
+      "95BA1C84541327E966FA7B50F7382282"
+    },
+    {
+      "ECDSA, 384 bits (prime field)",
+      "With SHA-224, message = \"test\"",
+      "sha224", "test",
+      "18FA39DB95AA5F561F30FA3591DC59C0FA3653A80DAFFA0B48D1A4C6DFCBFF6E"
+      "3D33BE4DC5EB8886A8ECD093F2935726",
+      "E8C9D0B6EA72A0E7837FEA1D14A1A9557F29FAA45D3E7EE888FC5BF954B5E624"
+      "64A9A817C47FF78B8C11066B24080E72",
+      "07041D4A7A0379AC7232FF72E6F77B6DDB8F09B16CCE0EC3286B2BD43FA8C614"
+      "1C53EA5ABEF0D8231077A04540A96B66"
+    },
+    {
+      "ECDSA, 384 bits (prime field)",
+      "With SHA-256, message = \"test\"",
+      "sha256", "test",
+      "0CFAC37587532347DC3389FDC98286BBA8C73807285B184C83E62E26C401C0FA"
+      "A48DD070BA79921A3457ABFF2D630AD7",
+      "6D6DEFAC9AB64DABAFE36C6BF510352A4CC27001263638E5B16D9BB51D451559"
+      "F918EEDAF2293BE5B475CC8F0188636B",
+      "2D46F3BECBCC523D5F1A1256BF0C9B024D879BA9E838144C8BA6BAEB4B53B47D"
+      "51AB373F9845C0514EEFB14024787265"
+    },
+    {
+      "ECDSA, 384 bits (prime field)",
+      "With SHA-384, message = \"test\"",
+      "sha384", "test",
+      "015EE46A5BF88773ED9123A5AB0807962D193719503C527B031B4C2D225092AD"
+      "A71F4A459BC0DA98ADB95837DB8312EA",
+      "8203B63D3C853E8D77227FB377BCF7B7B772E97892A80F36AB775D509D7A5FEB"
+      "0542A7F0812998DA8F1DD3CA3CF023DB",
+      "DDD0760448D42D8A43AF45AF836FCE4DE8BE06B485E9B61B827C2F13173923E0"
+      "6A739F040649A667BF3B828246BAA5A5"
+    },
+    {
+      "ECDSA, 384 bits (prime field)",
+      "With SHA-512, message = \"test\"",
+      "sha512", "test",
+      "3780C4F67CB15518B6ACAE34C9F83568D2E12E47DEAB6C50A4E4EE5319D1E8CE"
+      "0E2CC8A136036DC4B9C00E6888F66B6C",
+      "A0D5D090C9980FAF3C2CE57B7AE951D31977DD11C775D314AF55F76C676447D0"
+      "6FB6495CD21B4B6E340FC236584FB277",
+      "976984E59B4C77B0E8E4460DCA3D9F20E07B9BB1F63BEEFAF576F6B2E8B22463"
+      "4A2092CD3792E0159AD9CEE37659C736"
+    },
+    {
+      "ECDSA, 521 bits (prime field)",
+      "With SHA-1, message = \"sample\"",
+      "sha1", "sample",
+      "0089C071B419E1C2820962321787258469511958E80582E95D8378E0C2CCDB3CB"
+      "42BEDE42F50E3FA3C71F5A76724281D31D9C89F0F91FC1BE4918DB1C03A5838D"
+      "0F9",
+      "343B6EC45728975EA5CBA6659BBB6062A5FF89EEA58BE3C80B619F322C87910"
+      "FE092F7D45BB0F8EEE01ED3F20BABEC079D202AE677B243AB40B5431D497C55D"
+      "75D",
+      "E7B0E675A9B24413D448B8CC119D2BF7B2D2DF032741C096634D6D65D0DBE3D"
+      "5694625FB9E8104D3B842C1B0E2D0B98BEA19341E8676AEF66AE4EBA3D5475D5"
+      "D16"
+    },
+    {
+      "ECDSA, 521 bits (prime field)",
+      "With SHA-224, message = \"sample\"",
+      "sha224", "sample",
+      "121415EC2CD7726330A61F7F3FA5DE14BE9436019C4DB8CB4041F3B54CF31BE0"
+      "493EE3F427FB906393D895A19C9523F3A1D54BB8702BD4AA9C99DAB2597B9211"
+      "3F3",
+      "01776331CFCDF927D666E032E00CF776187BC9FDD8E69D0DABB4109FFE1B5E2A3"
+      "0715F4CC923A4A5E94D2503E9ACFED92857B7F31D7152E0F8C00C15FF3D87E2E"
+      "D2E",
+      "50CB5265417FE2320BBB5A122B8E1A32BD699089851128E360E620A30C7E17B"
+      "A41A666AF126CE100E5799B153B60528D5300D08489CA9178FB610A2006C254B"
+      "41F"
+    },
+    {
+      "ECDSA, 521 bits (prime field)",
+      "With SHA-256, message = \"sample\"",
+      "sha256", "sample",
+      "0EDF38AFCAAECAB4383358B34D67C9F2216C8382AAEA44A3DAD5FDC9C3257576"
+      "1793FEF24EB0FC276DFC4F6E3EC476752F043CF01415387470BCBD8678ED2C7E"
+      "1A0",
+      "01511BB4D675114FE266FC4372B87682BAECC01D3CC62CF2303C92B3526012659"
+      "D16876E25C7C1E57648F23B73564D67F61C6F14D527D54972810421E7D87589E"
+      "1A7",
+      "4A171143A83163D6DF460AAF61522695F207A58B95C0644D87E52AA1A347916"
+      "E4F7A72930B1BC06DBE22CE3F58264AFD23704CBB63B29B931F7DE6C9D949A7E"
+      "CFC"
+    },
+    {
+      "ECDSA, 521 bits (prime field)",
+      "With SHA-384, message = \"sample\"",
+      "sha384", "sample",
+      "1546A108BC23A15D6F21872F7DED661FA8431DDBD922D0DCDB77CC878C8553FF"
+      "AD064C95A920A750AC9137E527390D2D92F153E66196966EA554D9ADFCB109C4"
+      "211",
+      "01EA842A0E17D2DE4F92C15315C63DDF72685C18195C2BB95E572B9C5136CA4B4"
+      "B576AD712A52BE9730627D16054BA40CC0B8D3FF035B12AE75168397F5D50C67"
+      "451",
+      "01F21A3CEE066E1961025FB048BD5FE2B7924D0CD797BABE0A83B66F1E35EEAF5"
+      "FDE143FA85DC394A7DEE766523393784484BDF3E00114A1C857CDE1AA203DB65"
+      "D61"
+    },
+    {
+      "ECDSA, 521 bits (prime field)",
+      "With SHA-512, message = \"sample\"",
+      "sha512", "sample",
+      "1DAE2EA071F8110DC26882D4D5EAE0621A3256FC8847FB9022E2B7D28E6F1019"
+      "8B1574FDD03A9053C08A1854A168AA5A57470EC97DD5CE090124EF52A2F7ECBF"
+      "FD3",
+      "C328FAFCBD79DD77850370C46325D987CB525569FB63C5D3BC53950E6D4C5F1"
+      "74E25A1EE9017B5D450606ADD152B534931D7D4E8455CC91F9B15BF05EC36E37"
+      "7FA",
+      "617CCE7CF5064806C467F678D3B4080D6F1CC50AF26CA209417308281B68AF2"
+      "82623EAA63E5B5C0723D8B8C37FF0777B1A20F8CCB1DCCC43997F1EE0E44DA4A"
+      "67A"
+    },
+    {
+      "ECDSA, 521 bits (prime field)",
+      "With SHA-1, message = \"test\"",
+      "sha1", "test",
+      "0BB9F2BF4FE1038CCF4DABD7139A56F6FD8BB1386561BD3C6A4FC818B20DF5DD"
+      "BA80795A947107A1AB9D12DAA615B1ADE4F7A9DC05E8E6311150F47F5C57CE8B"
+      "222",
+      "013BAD9F29ABE20DE37EBEB823C252CA0F63361284015A3BF430A46AAA80B87B0"
+      "693F0694BD88AFE4E661FC33B094CD3B7963BED5A727ED8BD6A3A202ABE009D0"
+      "367",
+      "01E9BB81FF7944CA409AD138DBBEE228E1AFCC0C890FC78EC8604639CB0DBDC90"
+      "F717A99EAD9D272855D00162EE9527567DD6A92CBD629805C0445282BBC91679"
+      "7FF"
+    },
+    {
+      "ECDSA, 521 bits (prime field)",
+      "With SHA-224, message = \"test\"",
+      "sha224", "test",
+      "040D09FCF3C8A5F62CF4FB223CBBB2B9937F6B0577C27020A99602C25A011369"
+      "87E452988781484EDBBCF1C47E554E7FC901BC3085E5206D9F619CFF07E73D6F"
+      "706",
+      "01C7ED902E123E6815546065A2C4AF977B22AA8EADDB68B2C1110E7EA44D42086"
+      "BFE4A34B67DDC0E17E96536E358219B23A706C6A6E16BA77B65E1C595D43CAE1"
+      "7FB",
+      "0177336676304FCB343CE028B38E7B4FBA76C1C1B277DA18CAD2A8478B2A9A9F5"
+      "BEC0F3BA04F35DB3E4263569EC6AADE8C92746E4C82F8299AE1B8F1739F8FD51"
+      "9A4"
+    },
+    {
+      "ECDSA, 521 bits (prime field)",
+      "With SHA-256, message = \"test\"",
+      "sha256", "test",
+      "01DE74955EFAABC4C4F17F8E84D881D1310B5392D7700275F82F145C61E84384"
+      "1AF09035BF7A6210F5A431A6A9E81C9323354A9E69135D44EBD2FCAA7731B909"
+      "258",
+      "0E871C4A14F993C6C7369501900C4BC1E9C7B0B4BA44E04868B30B41D807104"
+      "2EB28C4C250411D0CE08CD197E4188EA4876F279F90B3D8D74A3C76E6F1E4656"
+      "AA8",
+      "CD52DBAA33B063C3A6CD8058A1FB0A46A4754B034FCC644766CA14DA8CA5CA9"
+      "FDE00E88C1AD60CCBA759025299079D7A427EC3CC5B619BFBC828E7769BCD694"
+      "E86"
+    },
+    {
+      "ECDSA, 521 bits (prime field)",
+      "With SHA-384, message = \"test\"",
+      "sha384", "test",
+      "1F1FC4A349A7DA9A9E116BFDD055DC08E78252FF8E23AC276AC88B1770AE0B5D"
+      "CEB1ED14A4916B769A523CE1E90BA22846AF11DF8B300C38818F713DADD85DE0"
+      "C88",
+      "014BEE21A18B6D8B3C93FAB08D43E739707953244FDBE924FA926D76669E7AC8C"
+      "89DF62ED8975C2D8397A65A49DCC09F6B0AC62272741924D479354D74FF60755"
+      "78C",
+      "0133330865C067A0EAF72362A65E2D7BC4E461E8C8995C3B6226A21BD1AA78F0E"
+      "D94FE536A0DCA35534F0CD1510C41525D163FE9D74D134881E35141ED5E8E95B"
+      "979"
+    },
+    {
+      "ECDSA, 521 bits (prime field)",
+      "With SHA-512, message = \"test\"",
+      "sha512", "test",
+      "16200813020EC986863BEDFC1B121F605C1215645018AEA1A7B215A564DE9EB1"
+      "B38A67AA1128B80CE391C4FB71187654AAA3431027BFC7F395766CA988C964DC"
+      "56D",
+      "013E99020ABF5CEE7525D16B69B229652AB6BDF2AFFCAEF38773B4B7D08725F10"
+      "CDB93482FDCC54EDCEE91ECA4166B2A7C6265EF0CE2BD7051B7CEF945BABD47E"
+      "E6D",
+      "01FBD0013C674AA79CB39849527916CE301C66EA7CE8B80682786AD60F98F7E78"
+      "A19CA69EFF5C57400E3B3A0AD66CE0978214D13BAF4E9AC60752F7B155E2DE4D"
+      "CE3"
+    },
+    { NULL }
+  };
+
+  gpg_error_t err;
+  int tno, i, hashalgo;
+  gcry_sexp_t seckey, data, sig;
+  unsigned char digest[64];
+  int digestlen;
+
+  for (tno = 0; tests[tno].keyname; tno++)
+    {
+      if (verbose)
+        info ("Test %d: %s. %s.\n", tno, tests[tno].keyname, tests[tno].name);
+
+      {
+        for (i=0; keys[i].name; i++)
+          if (!strcmp (tests[tno].keyname, keys[i].name))
+            break;
+        if (!keys[i].name)
+          die ("Key '%s' used by test '%s' not found\n",
+               tests[tno].keyname, tests[tno].name);
+
+        err = gcry_sexp_new (&seckey, keys[i].key, 0, 1);
+        if (err)
+          die ("reading key failed: %s\n", gpg_strerror (err));
+      }
+
+      hashalgo = gcry_md_map_name (tests[tno].hashname);
+      if (!hashalgo)
+        die ("hash with name '%s' is not supported\n", tests[tno].hashname);
+
+      digestlen = gcry_md_get_algo_dlen (hashalgo);
+      if (digestlen > sizeof digest)
+        die ("internal error: digest does not fit into our buffer\n");
+
+      gcry_md_hash_buffer (hashalgo, digest,
+                           tests[tno].message, strlen (tests[tno].message));
+
+      err = gcry_sexp_build (&data, NULL,
+                             "(data "
+                             " (flags rfc6979)"
+                             " (hash %s %b))",
+                             tests[tno].hashname, digestlen, digest);
+      if (err)
+        die ("building data sexp failed: %s\n", gpg_strerror (err));
+
+      err = gcry_pk_sign (&sig, data, seckey);
+      if (err)
+        fail ("signing failed: %s\n", gpg_strerror (err));
+
+      extract_cmp_data (sig, "r", tests[tno].r);
+      extract_cmp_data (sig, "s", tests[tno].s);
+
+      err = gcry_pk_verify (sig, data, seckey);
+      if (err)
+        fail ("verification failed: %s\n", gpg_strerror (err));
+
+      gcry_sexp_release (sig);
+      gcry_sexp_release (data);
+      gcry_sexp_release (seckey);
+    }
+}
+
+
+
+int
+main (int argc, char **argv)
+{
+  int debug = 0;
+
+  if (argc > 1 && !strcmp (argv[1], "--verbose"))
+    verbose = 1;
+  else if (argc > 1 && !strcmp (argv[1], "--debug"))
+    {
+      verbose = 2;
+      debug = 1;
+    }
+
+  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+  /* Check that we test exactly our version - including the patchlevel.  */
+  if (strcmp (GCRYPT_VERSION, gcry_check_version (NULL)))
+    die ("version mismatch; pgm=%s, library=%s\n",
+         GCRYPT_VERSION,gcry_check_version (NULL));
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+  if (debug)
+    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+  /* No valuable keys are create, so we can speed up our RNG. */
+  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+
+  check_dsa_rfc6979 ();
+
+  return error_count ? 1 : 0;
+}
index 401acff..10b18ab 100644 (file)
@@ -26,7 +26,7 @@
 #include <stdarg.h>
 
 #ifdef _GCRYPT_IN_LIBGCRYPT
-# include "../src/gcrypt.h"
+# include "../src/gcrypt-int.h"
 #else
 # include <gcrypt.h>
 #endif
index 2d4c362..eef2ddd 100644 (file)
@@ -35,7 +35,7 @@
 #include <unistd.h>
 
 #ifdef _GCRYPT_IN_LIBGCRYPT
-# include "../src/gcrypt.h"
+# include "../src/gcrypt-int.h"
 #else
 # include <gcrypt.h>
 # define PACKAGE_BUGREPORT "devnull@example.org"
diff --git a/tests/genhashdata.c b/tests/genhashdata.c
new file mode 100644 (file)
index 0000000..e16c49b
--- /dev/null
@@ -0,0 +1,171 @@
+/* genhashdata.c - Create data for hash tests
+ * Copyright (C) 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/>.
+ */
+
+/* Results:
+
+$  for i in -64 -1 0 1 64; do ./genhashdata --gigs 256 --bytes $i|sha1sum;done
+92fc51850c7b750e6e774b75f294f6979d4059f0  -
+4bddeeb4c08683f02d4944d93dbcb02ebab50134  -
+71b923afde1c8c040884c723a2e3335b333e64c6  -
+2d99f9b5b86e9c9c937104f4242bd6b8bc0927ef  -
+a60dabe8d749f798b7ec3a684cc3eab487451482  -
+
+$ for i in -64 -1 0 1 64; do ./genhashdata --gigs 256 --bytes $i|sha224sum;done
+b5672b54d2480a5688a2dc727a1ad4db7a81ef31ce8999e0bbaeffdc  -
+814ea7159473e6ffc1c64b90026a542e13ac6980f7f3ca3c4582a9b8  -
+9ec0e1829455db8650ec7a8b06912196f97a7358bc3a73c79911cd4e  -
+e578d5d523320876565bbbc892511a485427caee6dd754d57e3e58c2  -
+ff0464df248cd298b63765bc4f87f21e25c93c657fdf3656d3c878e5  -
+
+$ for i in -64 -1 0 1 64; do ./genhashdata --gigs 256 --bytes $i|sha256sum;done
+87a9828d3de78d55d252341db2a622908c4e0ceaee9961ecf9768700fc799ec8  -
+823bf95f64ef04a4a77579c38760b1d401b56bf3a8e664bdf56ca15afb468a03  -
+2d0723878cb2c3d5c59dfad910cdb857f4430a6ba2a7d687938d7a20e63dde47  -
+5a2e21b1e79cd866acf53a2a18ca76bd4e02c4b01bf4627354171824c812d95f  -
+34444808af8e9d995e67f9e155ed94bf55f195a51dc1d8a989e6bcf95511c8a2  -
+
+
+$ for i in -64 -1 0 1 64; do ./genhashdata --gigs 256 --bytes $i|sha512sum;done
+e01bf8140874bf240e8426cb2bcbc377cbed2e6037334116637149e1cd8cd462 \
+96828b71f32b9f002771d4cb51172ce578b73b7939221e4df655ecd08601e655  -
+4917ff94514b1757705c289fdc3e7d6ffcce5771b20ae237ebc03d2ec9eb435f \
+b7ce9f0e27272be8cced77a5edae1a01a0ad62b0a44169d88bbee45474a17734  -
+1e28e8b3c79f2f47da11f3c0b7da4e7981e7d932db6d17d528a31e191922edda \
+8fc4bb2df10ea876232db5a1c606bc41886e8b2c570a3e721221f60c8c7dc4ab  -
+027d3324dd1cf127770ceb53681f4c70937c9bca4e3acd5fd76cb266c7d4527d \
+58140290a1822e8d60c4d3ae9725fb923183230d6dfd2d7d73c0d74a4757f34a  -
+49920704ea9d6ee19f0742d6c868110fa3eda8ac09f026e9ef22cc731af53020 \
+de40eedef66cb1afd94c61e285fa9327e01336e804903740a9145ab1f065c2d5  -
+
+*/
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#define PGM "genhashdata"
+
+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);
+}
+
+int
+main (int argc, char **argv)
+{
+  int last_argc = -1;
+  int gigs = 0;
+  int bytes = 0;
+  char pattern[1024];
+  int i, g;
+
+  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"
+                 "  --gigs  N     Emit N GiB of test bytes\n"
+                 "  --bytes DIFF  Stop DIFF bytes earlier or later\n",
+                 stdout);
+          exit (0);
+        }
+      else if (!strcmp (*argv, "--gigs"))
+        {
+          argc--; argv++;
+          if (argc)
+            {
+              gigs = atoi (*argv);
+              argc--; argv++;
+            }
+        }
+      else if (!strcmp (*argv, "--bytes"))
+        {
+          argc--; argv++;
+          if (argc)
+            {
+              bytes = atoi (*argv);
+              argc--; argv++;
+            }
+        }
+      else if (!strncmp (*argv, "--", 2))
+        die ("unknown option '%s'", *argv);
+    }
+
+  if (gigs < 0 || gigs > 1024*1024)
+    die ("value for --gigs must be in the range 0 to %d", 1024*1024);
+  if (bytes < -1024 || bytes > 1024)
+      die ("value for --bytes must be in the range -1024 to 1024");
+  if (sizeof pattern != 1024)
+    die ("internal error");
+
+  if (argc > 1)
+    die ("arguments are not expected");
+
+  memset (pattern, 'a', sizeof pattern);
+
+  for (g=0; g < gigs; g++)
+    {
+      if (g + 1 == gigs && bytes < 0)
+        {
+          for (i = 0; i < 1024*1023; i++)
+            if (fwrite (pattern, sizeof pattern, 1, stdout) != 1)
+              die ("writing to stdout failed: %s", strerror (errno));
+          for (i = 0; i < 1023; i++)
+            if (fwrite (pattern, sizeof pattern, 1, stdout) != 1)
+              die ("writing to stdout failed: %s", strerror (errno));
+          if (fwrite (pattern, sizeof pattern + bytes, 1, stdout) != 1)
+            die ("writing to stdout failed: %s", strerror (errno));
+        }
+      else
+        {
+          for (i = 0; i < 1024*1024; i++)
+            if (fwrite (pattern, sizeof pattern, 1, stdout) != 1)
+              die ("writing to stdout failed: %s", strerror (errno));
+        }
+    }
+  if (bytes > 0)
+    if (fwrite (pattern, bytes, 1, stdout) != 1)
+      die ("writing to stdout failed: %s", strerror (errno));
+  if (fflush (stdout))
+    die ("writing to stdout failed: %s", strerror (errno));
+
+  return 0;
+}
diff --git a/tests/hashtest-256g.in b/tests/hashtest-256g.in
new file mode 100755 (executable)
index 0000000..e897c54
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+algos="SHA1 SHA256 SHA512"
+
+test "@RUN_LARGE_DATA_TESTS@" = yes || exit 77
+echo "      now running 256 GiB tests for $algos - this takes looong"
+exec ./hashtest --gigs 256 $algos
diff --git a/tests/hashtest.c b/tests/hashtest.c
new file mode 100644 (file)
index 0000000..6fbce0c
--- /dev/null
@@ -0,0 +1,489 @@
+/* hashtest.c - Check the hash fucntions
+ * Copyright (C) 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/>.
+ */
+
+#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 "hashtest"
+
+#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 int missing_test_vectors;
+
+static struct {
+  int algo;
+  int gigs;
+  int bytes;
+  const char *hex;
+} testvectors[] = {
+  { GCRY_MD_SHA1, 256, -64, "92fc51850c7b750e6e774b75f294f6979d4059f0" },
+  { GCRY_MD_SHA1, 256,  -1, "4bddeeb4c08683f02d4944d93dbcb02ebab50134" },
+  { GCRY_MD_SHA1, 256,  -0, "71b923afde1c8c040884c723a2e3335b333e64c6" },
+  { GCRY_MD_SHA1, 256,   1, "2d99f9b5b86e9c9c937104f4242bd6b8bc0927ef" },
+  { GCRY_MD_SHA1, 256,  64, "a60dabe8d749f798b7ec3a684cc3eab487451482" },
+
+  { GCRY_MD_SHA224, 256, -64,
+    "b5672b54d2480a5688a2dc727a1ad4db7a81ef31ce8999e0bbaeffdc" },
+  { GCRY_MD_SHA224, 256,  -1,
+    "814ea7159473e6ffc1c64b90026a542e13ac6980f7f3ca3c4582a9b8" },
+  { GCRY_MD_SHA224, 256,   0,
+    "9ec0e1829455db8650ec7a8b06912196f97a7358bc3a73c79911cd4e" },
+  { GCRY_MD_SHA224, 256,   1,
+    "e578d5d523320876565bbbc892511a485427caee6dd754d57e3e58c2" },
+  { GCRY_MD_SHA224, 256,  64,
+    "ff0464df248cd298b63765bc4f87f21e25c93c657fdf3656d3c878e5" },
+
+  { GCRY_MD_SHA256, 256, -64,
+    "87a9828d3de78d55d252341db2a622908c4e0ceaee9961ecf9768700fc799ec8" },
+  { GCRY_MD_SHA256, 256,  -1,
+    "823bf95f64ef04a4a77579c38760b1d401b56bf3a8e664bdf56ca15afb468a03" },
+  { GCRY_MD_SHA256, 256,   0,
+    "2d0723878cb2c3d5c59dfad910cdb857f4430a6ba2a7d687938d7a20e63dde47" },
+  { GCRY_MD_SHA256, 256,   1,
+    "5a2e21b1e79cd866acf53a2a18ca76bd4e02c4b01bf4627354171824c812d95f" },
+  { GCRY_MD_SHA256, 256,  64,
+    "34444808af8e9d995e67f9e155ed94bf55f195a51dc1d8a989e6bcf95511c8a2" },
+
+  { GCRY_MD_SHA512, 256, -64,
+    "e01bf8140874bf240e8426cb2bcbc377cbed2e6037334116637149e1cd8cd462"
+    "96828b71f32b9f002771d4cb51172ce578b73b7939221e4df655ecd08601e655" },
+  { GCRY_MD_SHA512, 256,  -1,
+    "4917ff94514b1757705c289fdc3e7d6ffcce5771b20ae237ebc03d2ec9eb435f"
+    "b7ce9f0e27272be8cced77a5edae1a01a0ad62b0a44169d88bbee45474a17734" },
+  { GCRY_MD_SHA512, 256,   0,
+    "1e28e8b3c79f2f47da11f3c0b7da4e7981e7d932db6d17d528a31e191922edda"
+    "8fc4bb2df10ea876232db5a1c606bc41886e8b2c570a3e721221f60c8c7dc4ab" },
+  { GCRY_MD_SHA512, 256,   1,
+    "027d3324dd1cf127770ceb53681f4c70937c9bca4e3acd5fd76cb266c7d4527d"
+    "58140290a1822e8d60c4d3ae9725fb923183230d6dfd2d7d73c0d74a4757f34a" },
+  { GCRY_MD_SHA512, 256,  64,
+    "49920704ea9d6ee19f0742d6c868110fa3eda8ac09f026e9ef22cc731af53020"
+    "de40eedef66cb1afd94c61e285fa9327e01336e804903740a9145ab1f065c2d5" },
+
+  { 0 }
+};
+
+
+
+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;
+
+  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
+showhex (const void *buffer, size_t buflen, const char *format, ...)
+{
+  va_list arg_ptr;
+  const unsigned char *s;
+
+  fprintf (stderr, "%s: ", PGM);
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+
+  for (s=buffer; buflen; buflen--, s++)
+    fprintf (stderr, "%02x", *s);
+  putc ('\n', stderr);
+}
+
+
+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
+run_selftest (int algo)
+{
+  gpg_error_t err;
+  size_t n;
+
+  n = 1;
+  err = gcry_md_algo_info (algo, GCRYCTL_SELFTEST, NULL, &n);
+  if (err && gpg_err_code (err) != GPG_ERR_NOT_IMPLEMENTED)
+    fail ("extended selftest for %s (%d) failed: %s",
+          gcry_md_algo_name (algo), algo, gpg_strerror (err));
+  else if (err && verbose)
+    show ("extended selftest for %s (%d) not implemented",
+          gcry_md_algo_name (algo), algo);
+  else if (verbose)
+    show ("extended selftest for %s (%d) passed",
+          gcry_md_algo_name (algo), algo);
+}
+
+/* Compare DIGEST of length DIGESTLEN generated using ALGO and GIGS
+   plus BYTES with the test vector and print an error message if the
+   don't match.  Return 0 on match.  */
+static int
+cmp_digest (const unsigned char *digest, size_t digestlen,
+            int algo, int gigs, int bytes)
+{
+  int idx;
+  unsigned char *tv_digest;
+  size_t tv_digestlen = 0;
+
+  for (idx=0; testvectors[idx].algo; idx++)
+    {
+      if (testvectors[idx].algo == algo
+          && testvectors[idx].gigs == gigs
+          && testvectors[idx].bytes == bytes)
+        break;
+    }
+  if (!testvectors[idx].algo)
+    {
+      show ("%d GiB %+3d %-10s warning: %s",
+            gigs, bytes, gcry_md_algo_name (algo), "no test vector");
+      missing_test_vectors++;
+      return 1;
+    }
+
+  tv_digest = hex2buffer (testvectors[idx].hex, &tv_digestlen);
+  if (tv_digestlen != digestlen) /* Ooops.  */
+    {
+      fail ("%d GiB %+3d %-10s error: %s",
+            gigs, bytes, gcry_md_algo_name (algo), "digest length mismatch");
+      xfree (tv_digest);
+      return 1;
+    }
+  if (memcmp (tv_digest, digest, tv_digestlen))
+    {
+      fail ("%d GiB %+3d %-10s error: %s",
+            gigs, bytes, gcry_md_algo_name (algo), "mismatch");
+      xfree (tv_digest);
+      return 1;
+    }
+  xfree (tv_digest);
+
+  return 0;
+}
+
+
+static void
+run_longtest (int algo, int gigs)
+{
+  gpg_error_t err;
+  gcry_md_hd_t hd;
+  gcry_md_hd_t hd_pre = NULL;
+  gcry_md_hd_t hd_pre2 = NULL;
+  gcry_md_hd_t hd_post = NULL;
+  gcry_md_hd_t hd_post2 = NULL;
+  char pattern[1024];
+  int i, g;
+  const unsigned char *digest;
+  unsigned int digestlen;
+
+  memset (pattern, 'a', sizeof pattern);
+
+  err = gcry_md_open (&hd, algo, 0);
+  if (err)
+    {
+      fail ("gcry_md_open failed for %s (%d): %s",
+            gcry_md_algo_name (algo), algo, gpg_strerror (err));
+      return;
+    }
+
+  digestlen = gcry_md_get_algo_dlen (algo);
+
+
+  for (g=0; g < gigs; g++)
+    {
+      if (g == gigs - 1)
+        {
+          for (i = 0; i < 1024*1023; i++)
+            gcry_md_write (hd, pattern, sizeof pattern);
+          for (i = 0; i < 1023; i++)
+            gcry_md_write (hd, pattern, sizeof pattern);
+          err = gcry_md_copy (&hd_pre, hd);
+          if (!err)
+            err = gcry_md_copy (&hd_pre2, hd);
+          if (err)
+            die ("gcry_md_copy failed for %s (%d): %s",
+                 gcry_md_algo_name (algo), algo, gpg_strerror (err));
+          gcry_md_write (hd, pattern, sizeof pattern);
+        }
+      else
+        {
+          for (i = 0; i < 1024*1024; i++)
+            gcry_md_write (hd, pattern, sizeof pattern);
+        }
+      if (g && !(g % 16))
+        show_note ("%d GiB so far hashed with %s", g, gcry_md_algo_name (algo));
+    }
+  if (g >= 16)
+    show_note ("%d GiB hashed with %s", g, gcry_md_algo_name (algo));
+
+  err = gcry_md_copy (&hd_post, hd);
+  if (err)
+    die ("gcry_md_copy failed for %s (%d): %s",
+         gcry_md_algo_name (algo), algo, gpg_strerror (err));
+  err = gcry_md_copy (&hd_post2, hd);
+  if (err)
+    die ("gcry_md_copy failed for %s (%d): %s",
+         gcry_md_algo_name (algo), algo, gpg_strerror (err));
+
+  gcry_md_write (hd_pre2, pattern, sizeof pattern - 64);
+  gcry_md_write (hd_pre, pattern, sizeof pattern - 1);
+  gcry_md_write (hd_post, pattern, 1);
+  gcry_md_write (hd_post2, pattern, 64);
+
+  digest = gcry_md_read (hd_pre2, algo);
+  if (cmp_digest (digest, digestlen, algo, gigs, -64) || verbose)
+    showhex (digest, digestlen, "%d GiB %+3d %-10s ",
+             gigs, -64, gcry_md_algo_name (algo));
+  digest = gcry_md_read (hd_pre, algo);
+  if (cmp_digest (digest, digestlen, algo, gigs, -1) || verbose)
+    showhex (digest, digestlen, "%d GiB %+3d %-10s ",
+             gigs, -1, gcry_md_algo_name (algo));
+  digest = gcry_md_read (hd, algo);
+  if (cmp_digest (digest, digestlen, algo, gigs, 0) || verbose)
+    showhex (digest, digestlen, "%d GiB %+3d %-10s ",
+             gigs, 0, gcry_md_algo_name (algo));
+  digest = gcry_md_read (hd_post, algo);
+  if (cmp_digest (digest, digestlen, algo, gigs, 1) || verbose)
+    showhex (digest, digestlen, "%d GiB %+3d %-10s ",
+             gigs, 1, gcry_md_algo_name (algo));
+  digest = gcry_md_read (hd_post2, algo);
+  if (cmp_digest (digest, digestlen, algo, gigs, 64) || verbose)
+    showhex (digest, digestlen, "%d GiB %+3d %-10s ",
+             gigs, 64, gcry_md_algo_name (algo));
+
+  gcry_md_close (hd);
+  gcry_md_close (hd_pre);
+  gcry_md_close (hd_pre2);
+  gcry_md_close (hd_post);
+  gcry_md_close (hd_post2);
+}
+
+
+int
+main (int argc, char **argv)
+{
+  int last_argc = -1;
+  int gigs = 0;
+  int algo = 0;
+  int idx;
+
+  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] [algos]\n"
+                 "Options:\n"
+                 "  --verbose       print timings etc.\n"
+                 "  --debug         flyswatter\n"
+                 "  --gigs N        Run a test on N GiB\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, "--gigs"))
+        {
+          argc--; argv++;
+          if (argc)
+            {
+              gigs = atoi (*argv);
+              argc--; argv++;
+            }
+        }
+      else if (!strncmp (*argv, "--", 2))
+        die ("unknown option '%s'", *argv);
+    }
+
+  if (gigs < 0 || gigs > 1024*1024)
+    die ("value for --gigs must be in the range 0 to %d", 1024*1024);
+
+  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);
+
+  /* A quick check that all given algorithms are valid.  */
+  for (idx=0; idx < argc; idx++)
+    {
+      algo = gcry_md_map_name (argv[idx]);
+      if (!algo)
+        fail ("invalid algorithm '%s'", argv[idx]);
+    }
+  if (error_count)
+    exit (1);
+
+  /* Start checking.  */
+  start_timer ();
+  if (!argc)
+    {
+      for (algo=1; algo < 400; algo++)
+        if (!gcry_md_test_algo (algo))
+          {
+            if (!gigs)
+              run_selftest (algo);
+            else
+              run_longtest (algo, gigs);
+          }
+     }
+  else
+    {
+      for (idx=0; idx < argc; idx++)
+        {
+          algo = gcry_md_map_name (argv[idx]);
+          if (!algo)
+            die ("invalid algorithm '%s'", argv[idx]);
+
+          if (!gigs)
+            run_selftest (algo);
+          else
+            run_longtest (algo, gigs);
+        }
+    }
+  stop_timer ();
+
+  if (missing_test_vectors)
+    fail ("Some test vectors are missing");
+
+  if (verbose)
+    show ("All tests completed in %s.  Errors: %d\n",
+          elapsed_time (), error_count);
+  return !!error_count;
+}
index 292a2fa..f4dc945 100644 (file)
@@ -26,7 +26,7 @@
 #include <string.h>
 #include <stdarg.h>
 
-#include "../src/gcrypt.h"
+#include "../src/gcrypt-int.h"
 
 static int verbose;
 static int error_count;
@@ -148,6 +148,63 @@ check_hmac (void)
 
 }
 
+
+static void
+check_hmac_multi (void)
+{
+  gpg_error_t err;
+  unsigned char key[128];
+  const char msg[] = "Sample #1";
+  const char mac[] = ("\x4f\x4c\xa3\xd5\xd6\x8b\xa7\xcc\x0a\x12"
+                      "\x08\xc9\xc6\x1e\x9c\x5d\xa0\x40\x3c\x0a");
+  gcry_buffer_t iov[4];
+  char digest[64];
+  int i;
+  int algo;
+  int maclen;
+
+  if (verbose)
+    fprintf (stderr, "checking HMAC using multiple buffers\n");
+  for (i=0; i < 64; i++)
+    key[i] = i;
+
+  memset (iov, 0, sizeof iov);
+  iov[0].data = key;
+  iov[0].len = 64;
+  iov[1].data = (void*)msg;
+  iov[1].off = 0;
+  iov[1].len = 3;
+  iov[2].data = (void*)msg;
+  iov[2].off = 3;
+  iov[2].len = 1;
+  iov[3].data = (void*)msg;
+  iov[3].off = 4;
+  iov[3].len = 5;
+
+  algo = GCRY_MD_SHA1;
+  maclen = gcry_md_get_algo_dlen (algo);
+  err = gcry_md_hash_buffers (algo, GCRY_MD_FLAG_HMAC, digest, iov, 4);
+  if (err)
+    {
+      fail ("gcry_md_hash_buffers failed: %s\n", algo, gpg_strerror (err));
+      return;
+    }
+
+  if (memcmp (digest, mac, maclen))
+    {
+      printf ("computed: ");
+      for (i = 0; i < maclen; i++)
+       printf ("%02x ", digest[i] & 0xFF);
+      printf ("\nexpected: ");
+      for (i = 0; i < maclen; i++)
+       printf ("%02x ", mac[i] & 0xFF);
+      printf ("\n");
+
+      fail ("gcry_md_hash_buffers, algo %d, MAC does not match\n", algo);
+    }
+}
+
+
 int
 main (int argc, char **argv)
 {
@@ -166,6 +223,7 @@ main (int argc, char **argv)
   if (debug)
     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
   check_hmac ();
+  check_hmac_multi ();
 
   return error_count ? 1 : 0;
 }
index 3774624..4aff9c9 100644 (file)
@@ -1,5 +1,5 @@
 /* keygen.c  -  key generation regression tests
- *     Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2003, 2005, 2012 Free Software Foundation, Inc.
  *
  * This file is part of Libgcrypt.
  *
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
-#include "../src/gcrypt.h"
+#include "../src/gcrypt-int.h"
 
 
+#define PGM "keygen"
+
+#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
-fail ( const char *format, ... )
+die (const char *format, ...)
 {
-    va_list arg_ptr ;
+  va_list arg_ptr ;
 
-    va_start( arg_ptr, format ) ;
-    vfprintf (stderr, format, arg_ptr );
-    va_end(arg_ptr);
-    error_count++;
+  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
-die ( const char *format, ... )
+fail (const char *format, ...)
 {
-    va_list arg_ptr ;
+  va_list arg_ptr;
 
-    va_start( arg_ptr, format ) ;
-    vfprintf (stderr, format, arg_ptr );
-    va_end(arg_ptr);
-    exit (1);
+  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;
+
+  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); */
+/* } */
+
+
+static void
+show_sexp (const char *prefix, gcry_sexp_t a)
+{
+  char *buf;
+  size_t size;
+
+  fprintf (stderr, "%s: ", PGM);
+  if (prefix)
+    fputs (prefix, stderr);
+  size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+  buf = xmalloc (size);
+
+  gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
+  fprintf (stderr, "%.*s", (int)size, buf);
+  gcry_free (buf);
 }
 
 
 static void
-print_mpi (const char *text, gcry_mpi_t a)
+show_mpi (const char *prefix, gcry_mpi_t a)
 {
   char *buf;
   void *bufaddr = &buf;
   gcry_error_t rc;
 
+  fprintf (stderr, "%s: ", PGM);
+  if (prefix)
+    fputs (prefix, stderr);
   rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a);
   if (rc)
-    fprintf (stderr, "%s=[error printing number: %s]\n",
-             text, gpg_strerror (rc));
+    fprintf (stderr, "[error printing number: %s]\n",  gpg_strerror (rc));
   else
     {
-      fprintf (stderr, "%s=0x%s\n", text, buf);
+      fprintf (stderr, "%s\n", buf);
       gcry_free (buf);
     }
 }
@@ -93,11 +164,11 @@ check_generated_rsa_key (gcry_sexp_t key, unsigned long expected_e)
       else if (!expected_e)
         {
           if (verbose)
-            print_mpi ("e", e);
+            show_mpi ("public exponent: ", e);
         }
       else if ( gcry_mpi_cmp_ui (e, expected_e))
         {
-          print_mpi ("e", e);
+          show_mpi ("public exponent: ", e);
           fail ("public exponent is not %lu\n", expected_e);
         }
       gcry_sexp_release (list);
@@ -115,20 +186,108 @@ check_generated_rsa_key (gcry_sexp_t key, unsigned long expected_e)
         fail ("gcry_pk_testkey failed: %s\n", gpg_strerror (rc));
       gcry_sexp_release (skey);
     }
+}
 
- }
 
 static void
 check_rsa_keys (void)
 {
   gcry_sexp_t keyparm, key;
   int rc;
+
+  if (verbose)
+    show ("creating 1024 bit RSA key\n");
+  rc = gcry_sexp_new (&keyparm,
+                      "(genkey\n"
+                      " (rsa\n"
+                      "  (nbits 4:1024)\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);
+  gcry_sexp_release (key);
+
+
+  if (verbose)
+    show ("creating 512 bit RSA key with e=257\n");
+  rc = gcry_sexp_new (&keyparm,
+                      "(genkey\n"
+                      " (rsa\n"
+                      "  (nbits 3:512)\n"
+                      "  (rsa-use-e 3:257)\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));
+
+  check_generated_rsa_key (key, 257);
+  gcry_sexp_release (key);
+
+  if (verbose)
+    show ("creating 512 bit RSA key with default e\n");
+  rc = gcry_sexp_new (&keyparm,
+                      "(genkey\n"
+                      " (rsa\n"
+                      "  (nbits 3:512)\n"
+                      "  (rsa-use-e 1:0)\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));
+
+  check_generated_rsa_key (key, 0); /* We don't expect a constant exponent. */
+  gcry_sexp_release (key);
+}
+
+
+static void
+check_elg_keys (void)
+{
+  gcry_sexp_t keyparm, key;
+  int rc;
+
+  if (verbose)
+    show ("creating 1024 bit Elgamal key\n");
+  rc = gcry_sexp_new (&keyparm,
+                      "(genkey\n"
+                      " (elg\n"
+                      "  (nbits 4:1024)\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 Elgamal key: %s\n", gpg_strerror (rc));
+  if (verbose > 1)
+    show_sexp ("1024 bit Elgamal key:\n", key);
+  gcry_sexp_release (key);
+}
+
+
+static void
+check_dsa_keys (void)
+{
+  gcry_sexp_t keyparm, key;
+  int rc;
   int i;
 
   /* Check that DSA generation works and that it can grok the qbits
      argument. */
   if (verbose)
-    fprintf (stderr, "creating 5 1024 bit DSA keys\n");
+    show ("creating 5 1024 bit DSA keys\n");
   for (i=0; i < 5; i++)
     {
       rc = gcry_sexp_new (&keyparm,
@@ -142,13 +301,13 @@ check_rsa_keys (void)
       gcry_sexp_release (keyparm);
       if (rc)
         die ("error generating DSA key: %s\n", gpg_strerror (rc));
+      if (!i && verbose > 1)
+        show_sexp ("1024 bit DSA key:\n", key);
       gcry_sexp_release (key);
-      if (verbose)
-        fprintf (stderr, "  done\n");
     }
 
   if (verbose)
-    fprintf (stderr, "creating 1536 bit DSA key\n");
+    show ("creating 1536 bit DSA key\n");
   rc = gcry_sexp_new (&keyparm,
                       "(genkey\n"
                       " (dsa\n"
@@ -161,70 +320,120 @@ check_rsa_keys (void)
   gcry_sexp_release (keyparm);
   if (rc)
     die ("error generating DSA key: %s\n", gpg_strerror (rc));
-  if (debug)
+  if (verbose > 1)
+    show_sexp ("1536 bit DSA key:\n", key);
+  gcry_sexp_release (key);
+}
+
+
+static void
+check_generated_ecc_key (gcry_sexp_t key)
+{
+  gcry_sexp_t skey, pkey;
+
+  pkey = gcry_sexp_find_token (key, "public-key", 0);
+  if (!pkey)
+    fail ("public part missing in return value\n");
+  else
     {
-      char buffer[20000];
-      gcry_sexp_sprint (key, GCRYSEXP_FMT_ADVANCED, buffer, sizeof buffer);
-      if (verbose)
-        printf ("=============================\n%s\n"
-                "=============================\n", buffer);
+      /* Fixme: Check more stuff.  */
+      gcry_sexp_release (pkey);
     }
-  gcry_sexp_release (key);
 
-  if (verbose)
-    fprintf (stderr, "creating 1024 bit RSA key\n");
-  rc = gcry_sexp_new (&keyparm,
-                      "(genkey\n"
-                      " (rsa\n"
-                      "  (nbits 4:1024)\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));
+  skey = gcry_sexp_find_token (key, "private-key", 0);
+  if (!skey)
+    fail ("private part missing in return value\n");
+  else
+    {
+      int rc = gcry_pk_testkey (skey);
+      if (rc)
+        fail ("gcry_pk_testkey failed: %s\n", gpg_strerror (rc));
+      gcry_sexp_release (skey);
+    }
+
+  /* Finally check that gcry_pk_testkey also works on the entire
+     S-expression.  */
+  {
+    int rc = gcry_pk_testkey (key);
+    if (rc)
+      fail ("gcry_pk_testkey failed on key pair: %s\n", gpg_strerror (rc));
+  }
+}
 
-  check_generated_rsa_key (key, 65537);
-  gcry_sexp_release (key);
 
+static void
+check_ecc_keys (void)
+{
+  const char *curves[] = { "NIST P-521", "NIST P-384", "NIST P-256",
+                           "Ed25519", NULL };
+  int testno;
+  gcry_sexp_t keyparm, key;
+  int rc;
+
+  for (testno=0; curves[testno]; testno++)
+    {
+      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]);
+      else
+        rc = gcry_sexp_build (&keyparm, NULL,
+                              "(genkey(ecc(curve %s)(flags param)))",
+                              curves[testno]);
+      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 %s: %s\n",
+             curves[testno], gpg_strerror (rc));
+
+      if (verbose > 1)
+        show_sexp ("ECC key:\n", key);
+
+      check_generated_ecc_key (key);
+
+      gcry_sexp_release (key);
+    }
 
   if (verbose)
-    fprintf (stderr, "creating 512 bit RSA key with e=257\n");
-  rc = gcry_sexp_new (&keyparm,
-                      "(genkey\n"
-                      " (rsa\n"
-                      "  (nbits 3:512)\n"
-                      "  (rsa-use-e 3:257)\n"
-                      " ))", 0, 1);
+    show ("creating ECC key using curve Ed25519 for ECDSA\n");
+  rc = gcry_sexp_build (&keyparm, NULL, "(genkey(ecc(curve Ed25519)))");
   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));
+    die ("error generating ECC key using curve Ed25519 for ECDSA: %s\n",
+         gpg_strerror (rc));
 
-  check_generated_rsa_key (key, 257);
+  if (verbose > 1)
+    show_sexp ("ECC key:\n", key);
+
+  check_generated_ecc_key (key);
   gcry_sexp_release (key);
 
   if (verbose)
-    fprintf (stderr, "creating 512 bit RSA key with default e\n");
-  rc = gcry_sexp_new (&keyparm,
-                      "(genkey\n"
-                      " (rsa\n"
-                      "  (nbits 3:512)\n"
-                      "  (rsa-use-e 1:0)\n"
-                      " ))", 0, 1);
+    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)
-    die ("error generating RSA key: %s\n", gpg_strerror (rc));
+    die ("error generating ECC key using curve Ed25519 for ECDSA"
+         " (nocomp): %s\n",
+         gpg_strerror (rc));
 
-  check_generated_rsa_key (key, 0); /* We don't expect a constant exponent. */
-  gcry_sexp_release (key);
+  if (verbose > 1)
+    show_sexp ("ECC key:\n", key);
+
+  check_generated_ecc_key (key);
 
+  gcry_sexp_release (key);
 }
 
 
@@ -236,20 +445,20 @@ check_nonce (void)
   int oops=0;
 
   if (verbose)
-    fprintf (stderr, "checking gcry_create_nonce\n");
+    show ("checking gcry_create_nonce\n");
 
   gcry_create_nonce (a, sizeof a);
   for (i=0; i < 10; i++)
     {
       gcry_create_nonce (b, sizeof b);
       if (!memcmp (a, b, sizeof a))
-        die ("identical nounce found\n");
+        die ("identical nonce found\n");
     }
   for (i=0; i < 10; i++)
     {
       gcry_create_nonce (a, sizeof a);
       if (!memcmp (a, b, sizeof a))
-        die ("identical nounce found\n");
+        die ("identical nonce found\n");
     }
 
  again:
@@ -284,13 +493,62 @@ progress_cb (void *cb_data, const char *what, int printchar,
 }
 
 
+static void
+usage (int mode)
+{
+  fputs ("usage: " PGM " [options] [{rsa|elg|dsa|ecc|nonce}]\n"
+         "Options:\n"
+         "  --verbose       be verbose\n"
+         "  --debug         flyswatter\n"
+         "  --progress      print progress indicators\n",
+         mode? stderr : stdout);
+  if (mode)
+    exit (1);
+}
+
 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;
+  int with_progress = 0;
+
+  if (argc)
+    { argc--; argv++; }
+
+  while (argc && last_argc != argc )
+    {
+      last_argc = argc;
+      if (!strcmp (*argv, "--"))
+        {
+          argc--; argv++;
+          break;
+        }
+      else if (!strcmp (*argv, "--help"))
+        {
+          usage (0);
+          exit (0);
+        }
+      else if (!strcmp (*argv, "--verbose"))
+        {
+          verbose++;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--debug"))
+        {
+          verbose += 2;
+          debug++;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--progress"))
+        {
+          argc--; argv++;
+          with_progress = 1;
+        }
+      else if (!strncmp (*argv, "--", 2))
+        die ("unknown option '%s'", *argv);
+      else
+        break;
+    }
 
   if (!gcry_check_version (GCRYPT_VERSION))
     die ("version mismatch\n");
@@ -300,11 +558,33 @@ main (int argc, char **argv)
     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
   /* No valuable keys are create, so we can speed up our RNG. */
   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
-  if (verbose)
-    gcry_set_progress_handler ( progress_cb, NULL );
+  if (with_progress)
+    gcry_set_progress_handler (progress_cb, NULL);
 
-  check_rsa_keys ();
-  check_nonce ();
+  if (!argc)
+    {
+      check_rsa_keys ();
+      check_elg_keys ();
+      check_dsa_keys ();
+      check_ecc_keys ();
+      check_nonce ();
+    }
+  else
+    {
+      for (; argc; argc--, argv++)
+        if (!strcmp (*argv, "rsa"))
+          check_rsa_keys ();
+        else if (!strcmp (*argv, "elg"))
+          check_elg_keys ();
+        else if (!strcmp (*argv, "dsa"))
+          check_dsa_keys ();
+        else if (!strcmp (*argv, "ecc"))
+          check_ecc_keys ();
+        else if (!strcmp (*argv, "nonce"))
+          check_nonce ();
+        else
+          usage (1);
+    }
 
   return error_count? 1:0;
 }
index a496ca2..330935d 100644 (file)
@@ -28,7 +28,7 @@
 #include <stdarg.h>
 #include <assert.h>
 
-#include "../src/gcrypt.h"
+#include "../src/gcrypt-int.h"
 
 static int verbose;
 static int repetitions;
@@ -104,7 +104,7 @@ static struct
     {
       GCRY_PK_ECDSA,
       "(public-key"
-      " (ecdsa"
+      " (ecdsa(flags param)"
       " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)"
       " (a #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC#)"
       " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)"
@@ -116,6 +116,18 @@ static struct
     {
       GCRY_PK_ECDSA,
       "(public-key"
+      " (ecdsa(flags param)"
+      " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)"
+      " (curve \"NIST P-256\")"
+      " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)"
+      " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)"
+      " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)"
+      " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))",
+      "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6"
+    },
+    {
+      GCRY_PK_ECDSA,
+      "(public-key"
       " (ecdsa"
       " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)"
       " (curve \"NIST P-256\")"
@@ -132,10 +144,52 @@ static struct
       " (curve secp256r1)"
       " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))",
       "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6"
+    },
+    {
+      GCRY_PK_ECC,
+      "(public-key"
+      " (ecc"
+      " (curve secp256r1)"
+      " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))",
+      "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6"
+    },
+    { /* Ed25519 standard */
+      GCRY_PK_ECC,
+      "(public-key"
+      " (ecc"
+      " (curve Ed25519)"
+      " (q #04"
+      "     1CC662926E7EFF4982B7FB8B928E61CD74CCDD85277CC57196C3AD20B611085F"
+      "     47BD24842905C049257673B3F5249524E0A41FAA17B25B818D0F97E625F1A1D0#)"
+      "     ))",
+      "\x0C\xCA\xB2\xFD\x48\x9A\x33\x40\x2C\xE8"
+      "\xE0\x4A\x1F\xB2\x45\xEA\x80\x3D\x0A\xF1"
+    },
+    { /* Ed25519+EdDSA */
+      GCRY_PK_ECC,
+      "(public-key"
+      " (ecc"
+      " (curve Ed25519)(flags eddsa)"
+      " (q #773E72848C1FD5F9652B29E2E7AF79571A04990E96F2016BF4E0EC1890C2B7DB#)"
+      " ))",
+      "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70"
+      "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47"
+    },
+    { /* Ed25519+EdDSA  (same but uncompressed)*/
+      GCRY_PK_ECC,
+      "(public-key"
+      " (ecc"
+      " (curve Ed25519)(flags eddsa)"
+      " (q #04"
+      "     629ad237d1ed04dcd4abe1711dd699a1cf51b1584c4de7a4ef8b8a640180b26f"
+      "     5bb7c29018ece0f46b01f2960e99041a5779afe7e2292b65f9d51f8c84723e77#)"
+      " ))",
+      "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70"
+      "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47"
     }
-
   };
 
+
 static void
 check (void)
 {
index cf82842..d75aca9 100644 (file)
@@ -1,5 +1,6 @@
 /* mpitests.c  -  basic mpi tests
  *     Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc.
+ * Copyright (C) 2013 g10 Code GmbH
  *
  * This file is part of Libgcrypt.
  *
@@ -14,9 +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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
- * USA.
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
 #ifdef HAVE_CONFIG_H
 #include <stdarg.h>
 
 #ifdef _GCRYPT_IN_LIBGCRYPT
-# include "../src/gcrypt.h"
+# include "../src/gcrypt-int.h"
 #else
 # include <gcrypt.h>
 #endif
 
+#define PGM "mpitests"
+
 static int verbose;
 static int debug;
+static int error_count;
 
 
 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);
   va_start (arg_ptr, format);
   vfprintf (stderr, format, arg_ptr);
   va_end (arg_ptr);
-  exit (1);
+  if (*format && format[strlen(format)-1] != '\n')
+    putc ('\n', stderr);
+  error_count++;
+  if (error_count >= 50)
+    die ("stopped after 50 errors.");
 }
 
 
-
 /* Set up some test patterns */
 
 /* 48 bytes with value 1: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */
@@ -88,6 +110,236 @@ unsigned char manyff[] = {
 };
 
 
+static int
+test_const_and_immutable (void)
+{
+  gcry_mpi_t one, second_one;
+
+  one = gcry_mpi_set_ui (NULL, 1);
+  if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE)
+      || gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
+    die ("immutable or const flag initially set\n");
+
+  second_one = gcry_mpi_copy (one);
+  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
+    die ("immutable flag set after copy\n");
+  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
+    die ("const flag set after copy\n");
+  gcry_mpi_release (second_one);
+
+  gcry_mpi_set_flag (one, GCRYMPI_FLAG_IMMUTABLE);
+  if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
+    die ("failed to set immutable flag\n");
+  if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
+    die ("const flag unexpectly set\n");
+
+  second_one = gcry_mpi_copy (one);
+  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
+    die ("immutable flag not cleared after copy\n");
+  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
+    die ("const flag unexpectly set after copy\n");
+  gcry_mpi_release (second_one);
+
+  gcry_mpi_clear_flag (one, GCRYMPI_FLAG_IMMUTABLE);
+  if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
+    die ("failed to clear immutable flag\n");
+  if (gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
+    die ("const flag unexpectly set\n");
+
+  gcry_mpi_set_flag (one, GCRYMPI_FLAG_CONST);
+  if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
+    die ("failed to set const flag\n");
+  if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
+    die ("failed to set immutable flag with const flag\n");
+
+  second_one = gcry_mpi_copy (one);
+  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
+    die ("immutable flag not cleared after copy\n");
+  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
+    die ("const flag not cleared after copy\n");
+  gcry_mpi_release (second_one);
+
+  gcry_mpi_clear_flag (one, GCRYMPI_FLAG_IMMUTABLE);
+  if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_IMMUTABLE))
+    die ("clearing immutable flag not ignored for a constant MPI\n");
+  if (!gcry_mpi_get_flag (one, GCRYMPI_FLAG_CONST))
+    die ("const flag unexpectly cleared\n");
+
+
+  second_one = gcry_mpi_set (NULL, GCRYMPI_CONST_ONE);
+  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
+    die ("immutable flag not cleared by mpi_set (NULL,x)\n");
+  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
+    die ("const flag not cleared by mpi_set (NULL,x)\n");
+  gcry_mpi_release (second_one);
+
+  second_one = gcry_mpi_set_ui (NULL, 42);
+  gcry_mpi_set (second_one, GCRYMPI_CONST_ONE);
+  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_IMMUTABLE))
+    die ("immutable flag not cleared after mpi_set (a,x)\n");
+  if (gcry_mpi_get_flag (second_one, GCRYMPI_FLAG_CONST))
+    die ("const flag not cleared mpi_set (a,x)\n");
+  gcry_mpi_release (second_one);
+
+
+  /* Due to the the constant flag the release below should be a NOP
+     and will leak memory.  */
+  gcry_mpi_release (one);
+  return 1;
+}
+
+
+static void
+test_opaque (void)
+{
+  gcry_mpi_t a;
+  char *p;
+  unsigned int nbits;
+
+  p = gcry_xstrdup ("This is a test buffer");
+  a = gcry_mpi_set_opaque (NULL, p, 21*8+1); /* (a non byte aligned length) */
+
+  if (!gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
+    die ("opaque flag not set\n");
+
+  p = gcry_mpi_get_opaque (a, &nbits);
+  if (!p)
+    die ("gcry_mpi_get_opaque returned NULL\n");
+  if (nbits != 21*8+1)
+    die ("gcry_mpi_get_opaque returned a changed bit size\n");
+  if (strcmp (p, "This is a test buffer"))
+    die ("gcry_mpi_get_opaque returned a changed buffer\n");
+
+  if (debug)
+    gcry_log_debugmpi ("mpi", a);
+  gcry_mpi_release (a);
+
+  p = gcry_xstrdup ("This is a test buffer");
+  a = gcry_mpi_set_opaque_copy (NULL, p, 21*8+1);
+  gcry_free (p);
+
+  if (!gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
+    die ("opaque flag not set\n");
+
+  p = gcry_mpi_get_opaque (a, &nbits);
+  if (!p)
+    die ("gcry_mpi_get_opaque returned NULL\n");
+  if (nbits != 21*8+1)
+    die ("gcry_mpi_get_opaque returned a changed bit size\n");
+  if (strcmp (p, "This is a test buffer"))
+    die ("gcry_mpi_get_opaque returned a changed buffer\n");
+
+  if (debug)
+    gcry_log_debugmpi ("mpi", a);
+
+  gcry_mpi_release (a);
+}
+
+
+static void
+test_cmp (void)
+{
+  gpg_error_t rc;
+  gcry_mpi_t zero, zero2;
+  gcry_mpi_t one;
+  gcry_mpi_t two;
+  gcry_mpi_t all_ones;
+  gcry_mpi_t opa1, opa2;
+  gcry_mpi_t opa1s, opa2s;
+  gcry_mpi_t opa0, opa02;
+
+  zero = gcry_mpi_new (0);
+  zero2= gcry_mpi_set_ui (NULL, 0);
+  one  = gcry_mpi_set_ui (NULL, 1);
+  two  = gcry_mpi_set_ui (NULL, 2);
+  rc = gcry_mpi_scan (&all_ones, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL);
+  if (rc)
+    die ("scanning number failed at line %d", __LINE__);
+  opa0  = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("a"), 0);
+  opa02 = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("b"), 0);
+  opa1  = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("aaaaaaaaaaaaaaaa"), 16*8);
+  opa1s = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("a"), 1*8);
+  opa2  = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("bbbbbbbbbbbbbbbb"), 16*8);
+  opa2s = gcry_mpi_set_opaque (NULL, gcry_xstrdup ("b"), 1*8);
+
+
+  /* Single limb test with cmp_ui */
+  if (gcry_mpi_cmp_ui (zero, 0))
+    fail ("mpi_cmp_ui failed at line %d", __LINE__);
+  if (!(gcry_mpi_cmp_ui (zero, 1) < 0))
+    fail ("mpi_cmp_ui failed at line %d", __LINE__);
+  if (!(gcry_mpi_cmp_ui (zero, (-1)) < 0))
+    fail ("mpi_cmp_ui failed at line %d", __LINE__);
+
+  if (gcry_mpi_cmp_ui (two, 2))
+    fail ("mpi_cmp_ui failed at line %d", __LINE__);
+  if (!(gcry_mpi_cmp_ui (two, 3) < 0))
+    fail ("mpi_cmp_ui failed at line %d", __LINE__);
+  if (!(gcry_mpi_cmp_ui (two, 1) > 0))
+    fail ("mpi_cmp_ui failed at line %d", __LINE__);
+
+  /* Multi limb tests with cmp_ui.  */
+  if (!(gcry_mpi_cmp_ui (all_ones, 0) > 0))
+    fail ("mpi_cmp_ui failed at line %d", __LINE__);
+  if (!(gcry_mpi_cmp_ui (all_ones, (-1)) > 0))
+    fail ("mpi_cmp_ui failed at line %d", __LINE__);
+
+  /* Single limb test with cmp */
+  if (gcry_mpi_cmp (zero, zero2))
+    fail ("mpi_cmp failed at line %d", __LINE__);
+  if (!(gcry_mpi_cmp (zero, one) < 0))
+    fail ("mpi_cmp failed at line %d", __LINE__);
+  if (!(gcry_mpi_cmp (one, zero) > 0))
+    fail ("mpi_cmp failed at line %d", __LINE__);
+
+  gcry_mpi_neg (one, one);
+  if (!(gcry_mpi_cmp (zero, one) > 0))
+    fail ("mpi_cmp failed at line %d", __LINE__);
+  if (!(gcry_mpi_cmp (one, zero) < 0))
+    fail ("mpi_cmp failed at line %d", __LINE__);
+  if (!(gcry_mpi_cmp (one, two) < 0))
+    fail ("mpi_cmp failed at line %d", __LINE__);
+  gcry_mpi_neg (one, one);
+
+  if (!(gcry_mpi_cmp (one, two) < 0))
+    fail ("mpi_cmp failed at line %d", __LINE__);
+  if (!(gcry_mpi_cmp (two, one) > 0))
+    fail ("mpi_cmp failed at line %d", __LINE__);
+  if (!(gcry_mpi_cmp (one, all_ones) < 0))
+    fail ("mpi_cmp failed at line %d", __LINE__);
+
+  /* Tests with opaque values.  */
+  if (!(gcry_mpi_cmp (opa1, one) < 0))
+    fail ("mpi_cmp failed at line %d", __LINE__);
+  if (!(gcry_mpi_cmp (one, opa1) > 0))
+    fail ("mpi_cmp failed at line %d", __LINE__);
+  if (!(gcry_mpi_cmp (opa0, opa02) == 0))
+    fail ("mpi_cmp failed at line %d", __LINE__);
+  if (!(gcry_mpi_cmp (opa1s, opa1) < 0))
+    fail ("mpi_cmp failed at line %d", __LINE__);
+  if (!(gcry_mpi_cmp (opa2, opa1s) > 0))
+    fail ("mpi_cmp failed at line %d", __LINE__);
+  if (!(gcry_mpi_cmp (opa1, opa2) < 0))
+    fail ("mpi_cmp failed at line %d", __LINE__);
+  if (!(gcry_mpi_cmp (opa2, opa1) > 0))
+    fail ("mpi_cmp failed at line %d", __LINE__);
+  if (!(gcry_mpi_cmp (opa1, opa1) == 0))
+    fail ("mpi_cmp failed at line %d", __LINE__);
+
+
+  gcry_mpi_release(opa2s);
+  gcry_mpi_release(opa2);
+  gcry_mpi_release(opa1s);
+  gcry_mpi_release(opa1);
+  gcry_mpi_release(opa02);
+  gcry_mpi_release(opa0);
+  gcry_mpi_release(all_ones);
+  gcry_mpi_release(two);
+  gcry_mpi_release(one);
+  gcry_mpi_release(zero2);
+  gcry_mpi_release(zero);
+}
+
 
 static int
 test_add (void)
@@ -105,14 +357,14 @@ test_add (void)
 
   gcry_mpi_add(result, one, two);
   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
-  if (verbose)
-    printf("Result of one plus two:\n%s\n", pc);
+  if (debug)
+    gcry_log_debug ("Result of one plus two:\n%s\n", pc);
   gcry_free(pc);
 
   gcry_mpi_add(result, ff, one);
   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
-  if (verbose)
-    printf("Result of ff plus one:\n%s\n", pc);
+  if (debug)
+    gcry_log_debug ("Result of ff plus one:\n%s\n", pc);
   gcry_free(pc);
 
   gcry_mpi_release(one);
@@ -137,8 +389,8 @@ test_sub (void)
   gcry_mpi_sub(result, two, one);
 
   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
-  if (verbose)
-    printf("Result of two minus one:\n%s\n", pc);
+  if (debug)
+    gcry_log_debug ("Result of two minus one:\n%s\n", pc);
   gcry_free(pc);
 
   gcry_mpi_release(one);
@@ -162,8 +414,8 @@ test_mul (void)
   gcry_mpi_mul(result, two, three);
 
   gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result);
-  if (verbose)
-    printf("Result of two mul three:\n%s\n", pc);
+  if (debug)
+    gcry_log_debug ("Result of two mul three:\n%s\n", pc);
   gcry_free(pc);
 
   gcry_mpi_release(two);
@@ -269,6 +521,29 @@ test_powm (void)
   if (gcry_mpi_cmp (res, base))
     die ("test_powm failed at %d\n", __LINE__);
 
+  /* Check for a case: base is negative and expo is even.  */
+  gcry_mpi_set_ui (base, b_int);
+  gcry_mpi_neg (base, base);
+  gcry_mpi_set_ui (exp, e_int * 2);
+  gcry_mpi_set_ui(mod, m_int);
+  gcry_mpi_powm (res, base, exp, mod);
+  /* Result should be positive and it's 7 = (-17)^6 mod 19.  */
+  if (gcry_mpi_is_neg (res) || gcry_mpi_cmp_ui (res, 7))
+    {
+      if (verbose)
+        {
+          fprintf (stderr, "is_neg: %d\n", gcry_mpi_is_neg (res));
+          fprintf (stderr, "mpi: ");
+          gcry_mpi_dump (res);
+          putc ('\n', stderr);
+        }
+      die ("test_powm failed for negative base at %d\n", __LINE__);
+    }
+
+  gcry_mpi_release (base);
+  gcry_mpi_release (exp);
+  gcry_mpi_release (mod);
+  gcry_mpi_release (res);
   /* Fixme: We should add the rest of the cases of course.  */
 
 
@@ -292,10 +567,13 @@ main (int argc, char* argv[])
     }
   gcry_control(GCRYCTL_DISABLE_SECMEM);
 
+  test_const_and_immutable ();
+  test_opaque ();
+  test_cmp ();
   test_add ();
   test_sub ();
   test_mul ();
   test_powm ();
 
-  return 0;
+  return !!error_count;
 }
index bb06292..20f1b64 100644 (file)
@@ -26,7 +26,7 @@
 #include <stdarg.h>
 
 #ifdef _GCRYPT_IN_LIBGCRYPT
-# include "../src/gcrypt.h"
+# include "../src/gcrypt-int.h"
 #else
 # include <gcrypt.h>
 #endif
index b365a14..89800e8 100644 (file)
@@ -24,7 +24,7 @@
 #include <string.h>
 #include <stdlib.h>
 
-#include "../src/gcrypt.h"
+#include "../src/gcrypt-int.h"
 
 static int verbose;
 
@@ -95,18 +95,147 @@ check_primes (void)
       gcry_mpi_add_ui (prime, prime, 1);
       err = gcry_prime_check (prime, 0);
       assert (err);
+      gcry_mpi_release (prime); prime = NULL;
     }
 }
 
+
+/* Print an MPI S-expression.  */
+static void
+print_mpi (const char *name, gcry_mpi_t a)
+{
+  gcry_error_t err;
+  unsigned char *buf;
+  int writerr = 0;
+
+  err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, a);
+  if (err)
+    die ("gcry_mpi_aprint failed: %s\n", gcry_strerror (err));
+
+  printf ("  (%s #%s#)\n", name, buf);
+  if (ferror (stdout))
+    writerr++;
+  if (!writerr && fflush (stdout) == EOF)
+    writerr++;
+  if (writerr)
+    die ("writing output failed\n");
+  gcry_free (buf);
+}
+
+
+/* Create the key for our public standard dummy CA.  */
+static void
+create_42prime (void)
+{
+  gcry_error_t err;
+  char string[128*2+1];
+  int i;
+  gcry_mpi_t start = NULL;
+  gcry_mpi_t p, q, n, t1, t2, phi, f, g, e, d, u;
+
+
+  /* Our start value is a string of 0x42 values, with the exception
+     that the two high order bits are set.  This is to resemble the
+     way Lingcrypt generates RSA primes.  */
+  for (i=0; i < 128;)
+    {
+      string[i++] = '4';
+      string[i++] = '2';
+    }
+  string[i] = 0;
+  string[0] = 'C';
+
+  err = gcry_mpi_scan (&start, GCRYMPI_FMT_HEX, string, 0, NULL);
+  if (err)
+    die ("gcry_mpi_scan failed: %s\n", gcry_strerror (err));
+  fputs ("start:", stderr); gcry_mpi_dump (start); putc ('\n', stderr);
+
+  /* Generate two primes with p < q.  We take the first primes below
+     and above a start value. */
+  p = gcry_mpi_copy (start);
+  gcry_mpi_sub_ui (p, p, 1);
+  while (gcry_prime_check (p, 0))
+    gcry_mpi_sub_ui (p, p, 2);
+  fputs ("    p:", stderr); gcry_mpi_dump (p); putc ('\n', stderr);
+  q = gcry_mpi_copy (start);
+  gcry_mpi_add_ui (q, q, 1);
+  while (gcry_prime_check (q, 0))
+    gcry_mpi_add_ui (q, q, 2);
+  fputs ("    q:", stderr); gcry_mpi_dump (q); putc ('\n', stderr);
+
+  /* Compute the modulus.  */
+  n = gcry_mpi_new (1024);
+  gcry_mpi_mul (n, p, q);
+  fputs ("    n:", stderr); gcry_mpi_dump (n); putc ('\n', stderr);
+  if (gcry_mpi_get_nbits (n) != 1024)
+    die ("Oops: the size of N is not 1024 but %u\n", gcry_mpi_get_nbits (n));
+
+  /* Calculate Euler totient: phi = (p-1)(q-1) */
+  t1 = gcry_mpi_new (0);
+  t2 = gcry_mpi_new (0);
+  phi = gcry_mpi_new (0);
+  g   = gcry_mpi_new (0);
+  f   = gcry_mpi_new (0);
+  gcry_mpi_sub_ui (t1, p, 1);
+  gcry_mpi_sub_ui (t2, q, 1);
+  gcry_mpi_mul (phi, t1, t2);
+  gcry_mpi_gcd (g, t1, t2);
+  gcry_mpi_div (f, NULL, phi, g, -1);
+
+  /* Check the public exponent.  */
+  e = gcry_mpi_set_ui (NULL, 65537);
+  if (!gcry_mpi_gcd (t1, e, phi))
+    die ("Oops: E is not a generator\n");
+  fputs ("    e:", stderr); gcry_mpi_dump (e); putc ('\n', stderr);
+
+  /* Compute the secret key:  d = e^-1 mod phi */
+  d = gcry_mpi_new (0);
+  gcry_mpi_invm (d, e, f );
+  fputs ("    d:", stderr); gcry_mpi_dump (d); putc ('\n', stderr);
+
+  /* Compute the inverse of p and q. */
+  u = gcry_mpi_new (0);
+  gcry_mpi_invm (u, p, q);
+  fputs ("    u:", stderr); gcry_mpi_dump (u); putc ('\n', stderr);
+
+  /* Print the S-expression.  */
+  fputs ("(private-key\n (rsa\n", stdout);
+  print_mpi ("n", n);
+  print_mpi ("e", e);
+  print_mpi ("d", d);
+  print_mpi ("p", p);
+  print_mpi ("q", q);
+  print_mpi ("u", u);
+  fputs ("))\n", stdout);
+
+  gcry_mpi_release (p);
+  gcry_mpi_release (q);
+  gcry_mpi_release (n);
+  gcry_mpi_release (t1);
+  gcry_mpi_release (t2);
+  gcry_mpi_release (phi);
+  gcry_mpi_release (f);
+  gcry_mpi_release (g);
+  gcry_mpi_release (e);
+  gcry_mpi_release (d);
+  gcry_mpi_release (u);
+}
+
+
+
+
 int
 main (int argc, char **argv)
 {
   int debug = 0;
+  int mode42 = 0;
 
   if ((argc > 1) && (! strcmp (argv[1], "--verbose")))
     verbose = 1;
   else if ((argc > 1) && (! strcmp (argv[1], "--debug")))
     verbose = debug = 1;
+  else if ((argc > 1) && (! strcmp (argv[1], "--42")))
+    verbose = debug = mode42 = 1;
 
   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
   if (! gcry_check_version (GCRYPT_VERSION))
@@ -116,7 +245,10 @@ main (int argc, char **argv)
   if (debug)
     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
 
-  check_primes ();
+  if (mode42)
+    create_42prime ();
+  else
+    check_primes ();
 
   return 0;
 }
index 92e5f5d..ae5eea2 100644 (file)
 #include <string.h>
 
 
-#include "../src/gcrypt.h"
+#include "../src/gcrypt-int.h"
+
+#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 DIM(v)              (sizeof(v)/sizeof((v)[0]))
+#define DIMof(type,member)   DIM(((type *)0)->member)
+
 
 /* Sample RSA keys, taken from basic.c.  */
 
@@ -101,6 +113,7 @@ static const char sample_public_key_1[] =
 
 
 static int verbose;
+static int error_count;
 
 static void
 die (const char *format, ...)
@@ -110,10 +123,33 @@ die (const char *format, ...)
   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;
+
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+  error_count++;
+}
+
+static void
+info (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  va_start (arg_ptr, format);
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+}
+
+static void
 show_sexp (const char *prefix, gcry_sexp_t a)
 {
   char *buf;
@@ -130,6 +166,59 @@ show_sexp (const char *prefix, gcry_sexp_t a)
 }
 
 
+/* 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 *
+data_from_hex (const char *string, size_t *r_length)
+{
+  const char *s;
+  unsigned char *buffer;
+  size_t length;
+
+  buffer = gcry_xmalloc (strlen(string)/2+1);
+  length = 0;
+  for (s=string; *s; s +=2 )
+    {
+      if (!hexdigitp (s) || !hexdigitp (s+1))
+        die ("error parsing hex string `%s'\n", string);
+      ((unsigned char*)buffer)[length++] = xtoi_2 (s);
+    }
+  *r_length = length;
+  return buffer;
+}
+
+
+static void
+extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected)
+{
+  gcry_sexp_t l1;
+  const void *a;
+  size_t alen;
+  void *b;
+  size_t blen;
+
+  l1 = gcry_sexp_find_token (sexp, name, 0);
+  a = gcry_sexp_nth_data (l1, 1, &alen);
+  b = data_from_hex (expected, &blen);
+  if (!a)
+    fail ("parameter \"%s\" missing in key\n", name);
+  else if ( alen != blen || memcmp (a, b, alen) )
+    {
+      fail ("parameter \"%s\" does not match expected value\n", name);
+      if (verbose)
+        {
+          info ("expected: %s\n", expected);
+          show_sexp ("sexp: ", sexp);
+        }
+    }
+  gcry_free (b);
+  gcry_sexp_release (l1);
+}
+
+
 static void
 check_keys_crypt (gcry_sexp_t pkey, gcry_sexp_t skey,
                  gcry_sexp_t plain0, gpg_err_code_t decrypt_fail_code)
@@ -142,6 +231,7 @@ check_keys_crypt (gcry_sexp_t pkey, gcry_sexp_t skey,
   /* Extract data from plaintext.  */
   l = gcry_sexp_find_token (plain0, "value", 0);
   x0 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
+  gcry_sexp_release (l);
 
   /* Encrypt data.  */
   rc = gcry_pk_encrypt (&cipher, plain0, pkey);
@@ -158,7 +248,10 @@ check_keys_crypt (gcry_sexp_t pkey, gcry_sexp_t skey,
   if (rc)
     {
       if (decrypt_fail_code && gpg_err_code (rc) == decrypt_fail_code)
-        return; /* This is the expected failure code.  */
+       {
+         gcry_mpi_release (x0);
+         return; /* This is the expected failure code.  */
+       }
       die ("decryption failed: %s\n", gcry_strerror (rc));
     }
 
@@ -187,6 +280,8 @@ check_keys_crypt (gcry_sexp_t pkey, gcry_sexp_t skey,
   /* Compare.  */
   if (gcry_mpi_cmp (x0, x1))
     die ("data corrupted\n");
+  gcry_mpi_release (x0);
+  gcry_mpi_release (x1);
 }
 
 static void
@@ -216,6 +311,7 @@ check_keys (gcry_sexp_t pkey, gcry_sexp_t skey, unsigned int nbits_data,
 
   rc = gcry_sexp_build (&plain, NULL,
                         "(data (flags raw no-blinding) (value %m))", x);
+  gcry_mpi_release (x);
   if (rc)
     die ("converting data for encryption failed: %s\n",
         gcry_strerror (rc));
@@ -856,6 +952,220 @@ check_x931_derived_key (int what)
 
 
 
+static void
+check_ecc_sample_key (void)
+{
+  static const char ecc_private_key[] =
+    "(private-key\n"
+    " (ecdsa\n"
+    "  (curve \"NIST P-256\")\n"
+    "  (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2BEB6644D3609FC781"
+    "B71F9A8072F58CB66AE2F89BB12451873ABF7D91F9E1FBF96BF2F70E73AAC9A283#)\n"
+    "  (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F744715E1D5BBE70378#)"
+    "))";
+  static const char ecc_private_key_wo_q[] =
+    "(private-key\n"
+    " (ecdsa\n"
+    "  (curve \"NIST P-256\")\n"
+    "  (d #5A1EF0035118F19F3110FB81813D3547BCE1E5BCE77D1F744715E1D5BBE70378#)"
+    "))";
+  static const char ecc_public_key[] =
+    "(public-key\n"
+    " (ecdsa\n"
+    "  (curve \"NIST P-256\")\n"
+    "  (q #04D4F6A6738D9B8D3A7075C1E4EE95015FC0C9B7E4272D2BEB6644D3609FC781"
+    "B71F9A8072F58CB66AE2F89BB12451873ABF7D91F9E1FBF96BF2F70E73AAC9A283#)"
+    "))";
+  static const char hash_string[] =
+    "(data (flags raw)\n"
+    " (value #00112233445566778899AABBCCDDEEFF"
+    /* */    "000102030405060708090A0B0C0D0E0F#))";
+  static const char hash2_string[] =
+    "(data (flags raw)\n"
+    " (hash sha1 #00112233445566778899AABBCCDDEEFF"
+    /* */    "000102030405060708090A0B0C0D0E0F"
+    /* */    "000102030405060708090A0B0C0D0E0F"
+    /* */    "00112233445566778899AABBCCDDEEFF#))";
+  /* hash2, but longer than curve length, so it will be truncated */
+  static const char hash3_string[] =
+    "(data (flags raw)\n"
+    " (hash sha1 #00112233445566778899AABBCCDDEEFF"
+    /* */    "000102030405060708090A0B0C0D0E0F"
+    /* */    "000102030405060708090A0B0C0D0E0F"
+    /* */    "00112233445566778899AABBCCDDEEFF"
+    /* */    "000102030405060708090A0B0C0D0E0F#))";
+
+  gpg_error_t err;
+  gcry_sexp_t key, hash, hash2, hash3, sig, sig2;
+
+  if (verbose)
+    fprintf (stderr, "Checking sample ECC key.\n");
+
+  if ((err = gcry_sexp_new (&hash, hash_string, 0, 1)))
+    die ("line %d: %s", __LINE__, gpg_strerror (err));
+
+  if ((err = gcry_sexp_new (&hash2, hash2_string, 0, 1)))
+    die ("line %d: %s", __LINE__, gpg_strerror (err));
+
+  if ((err = gcry_sexp_new (&hash3, hash3_string, 0, 1)))
+    die ("line %d: %s", __LINE__, gpg_strerror (err));
+
+  if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1)))
+    die ("line %d: %s", __LINE__, gpg_strerror (err));
+
+  if ((err = gcry_pk_sign (&sig, hash, key)))
+    die ("gcry_pk_sign failed: %s", gpg_strerror (err));
+
+  gcry_sexp_release (key);
+  if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
+    die ("line %d: %s", __LINE__, gpg_strerror (err));
+
+  if ((err = gcry_pk_verify (sig, hash, key)))
+    die ("gcry_pk_verify failed: %s", gpg_strerror (err));
+
+  /* Verify hash truncation */
+  gcry_sexp_release (key);
+  if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1)))
+    die ("line %d: %s", __LINE__, gpg_strerror (err));
+
+  if ((err = gcry_pk_sign (&sig2, hash2, key)))
+    die ("gcry_pk_sign failed: %s", gpg_strerror (err));
+
+  gcry_sexp_release (sig);
+  if ((err = gcry_pk_sign (&sig, hash3, key)))
+    die ("gcry_pk_sign failed: %s", gpg_strerror (err));
+
+  gcry_sexp_release (key);
+  if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
+    die ("line %d: %s", __LINE__, gpg_strerror (err));
+
+  if ((err = gcry_pk_verify (sig, hash2, key)))
+    die ("gcry_pk_verify failed: %s", gpg_strerror (err));
+
+  if ((err = gcry_pk_verify (sig2, hash3, key)))
+    die ("gcry_pk_verify failed: %s", gpg_strerror (err));
+
+  /* Now try signing without the Q parameter.  */
+
+  gcry_sexp_release (key);
+  if ((err = gcry_sexp_new (&key, ecc_private_key_wo_q, 0, 1)))
+    die ("line %d: %s", __LINE__, gpg_strerror (err));
+
+  gcry_sexp_release (sig);
+  if ((err = gcry_pk_sign (&sig, hash, key)))
+    die ("gcry_pk_sign without Q failed: %s", gpg_strerror (err));
+
+  gcry_sexp_release (key);
+  if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
+    die ("line %d: %s", __LINE__, gpg_strerror (err));
+
+  if ((err = gcry_pk_verify (sig, hash, key)))
+    die ("gcry_pk_verify signed without Q failed: %s", gpg_strerror (err));
+
+  gcry_sexp_release (sig);
+  gcry_sexp_release (sig2);
+  gcry_sexp_release (key);
+  gcry_sexp_release (hash);
+  gcry_sexp_release (hash2);
+  gcry_sexp_release (hash3);
+}
+
+
+static void
+check_ed25519ecdsa_sample_key (void)
+{
+  static const char ecc_private_key[] =
+    "(private-key\n"
+    " (ecc\n"
+    "  (curve \"Ed25519\")\n"
+    "  (q #044C056555BE4084BB3D8D8895FDF7C2893DFE0256251923053010977D12658321"
+    "        156D1ADDC07987713A418783658B476358D48D582DB53233D9DED3C1C2577B04#)"
+    "  (d #09A0C38E0F1699073541447C19DA12E3A07A7BFDB0C186E4AC5BCE6F23D55252#)"
+    "))";
+  static const char ecc_private_key_wo_q[] =
+    "(private-key\n"
+    " (ecc\n"
+    "  (curve \"Ed25519\")\n"
+    "  (d #09A0C38E0F1699073541447C19DA12E3A07A7BFDB0C186E4AC5BCE6F23D55252#)"
+    "))";
+  static const char ecc_public_key[] =
+    "(public-key\n"
+    " (ecc\n"
+    "  (curve \"Ed25519\")\n"
+    "  (q #044C056555BE4084BB3D8D8895FDF7C2893DFE0256251923053010977D12658321"
+    "        156D1ADDC07987713A418783658B476358D48D582DB53233D9DED3C1C2577B04#)"
+    "))";
+  static const char ecc_public_key_comp[] =
+    "(public-key\n"
+    " (ecc\n"
+    "  (curve \"Ed25519\")\n"
+    "  (q #047b57c2c1d3ded93332b52d588dd45863478b658387413a718779c0dd1a6d95#)"
+    "))";
+  static const char hash_string[] =
+    "(data (flags rfc6979)\n"
+    " (hash sha256 #00112233445566778899AABBCCDDEEFF"
+    /* */          "000102030405060708090A0B0C0D0E0F#))";
+
+  gpg_error_t err;
+  gcry_sexp_t key, hash, sig;
+
+  if (verbose)
+    fprintf (stderr, "Checking sample Ed25519/ECDSA key.\n");
+
+  /* Sign.  */
+  if ((err = gcry_sexp_new (&hash, hash_string, 0, 1)))
+    die ("line %d: %s", __LINE__, gpg_strerror (err));
+  if ((err = gcry_sexp_new (&key, ecc_private_key, 0, 1)))
+    die ("line %d: %s", __LINE__, gpg_strerror (err));
+  if ((err = gcry_pk_sign (&sig, hash, key)))
+    die ("gcry_pk_sign failed: %s", gpg_strerror (err));
+
+  /* Verify.  */
+  gcry_sexp_release (key);
+  if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
+    die ("line %d: %s", __LINE__, gpg_strerror (err));
+  if ((err = gcry_pk_verify (sig, hash, key)))
+    die ("gcry_pk_verify failed: %s", gpg_strerror (err));
+
+  /* Verify again using a compressed public key.  */
+  gcry_sexp_release (key);
+  if ((err = gcry_sexp_new (&key, ecc_public_key_comp, 0, 1)))
+    die ("line %d: %s", __LINE__, gpg_strerror (err));
+  if ((err = gcry_pk_verify (sig, hash, key)))
+    die ("gcry_pk_verify failed (comp): %s", gpg_strerror (err));
+
+  /* Sign without a Q parameter.  */
+  gcry_sexp_release (key);
+  if ((err = gcry_sexp_new (&key, ecc_private_key_wo_q, 0, 1)))
+    die ("line %d: %s", __LINE__, gpg_strerror (err));
+  gcry_sexp_release (sig);
+  if ((err = gcry_pk_sign (&sig, hash, key)))
+    die ("gcry_pk_sign w/o Q failed: %s", gpg_strerror (err));
+
+  /* Verify.  */
+  gcry_sexp_release (key);
+  if ((err = gcry_sexp_new (&key, ecc_public_key, 0, 1)))
+    die ("line %d: %s", __LINE__, gpg_strerror (err));
+  if ((err = gcry_pk_verify (sig, hash, key)))
+    die ("gcry_pk_verify signed w/o Q failed: %s", gpg_strerror (err));
+
+  /* Verify again using a compressed public key.  */
+  gcry_sexp_release (key);
+  if ((err = gcry_sexp_new (&key, ecc_public_key_comp, 0, 1)))
+    die ("line %d: %s", __LINE__, gpg_strerror (err));
+  if ((err = gcry_pk_verify (sig, hash, key)))
+    die ("gcry_pk_verify signed w/o Q failed (comp): %s", gpg_strerror (err));
+
+  extract_cmp_data (sig, "r", ("a63123a783ef29b8276e08987daca4"
+                               "655d0179e22199bf63691fd88eb64e15"));
+  extract_cmp_data (sig, "s", ("0d9b45c696ab90b96b08812b485df185"
+                               "623ddaf5d02fa65ca5056cb6bd0f16f1"));
+
+  gcry_sexp_release (sig);
+  gcry_sexp_release (key);
+  gcry_sexp_release (hash);
+}
+
 
 int
 main (int argc, char **argv)
@@ -886,5 +1196,8 @@ main (int argc, char **argv)
   for (i=0; i < 4; i++)
     check_x931_derived_key (i);
 
-  return 0;
+  check_ecc_sample_key ();
+  check_ed25519ecdsa_sample_key ();
+
+  return !!error_count;
 }
index a243529..10bf646 100644 (file)
 #include <string.h>
 #include <stdlib.h>
 #include <errno.h>
-#include <signal.h>
-#include <unistd.h>
-#include <sys/wait.h>
+#ifndef HAVE_W32_SYSTEM
+# include <signal.h>
+# include <unistd.h>
+# include <sys/wait.h>
+#endif
+
+#include "../src/gcrypt-int.h"
+
+#define PGM "random"
 
-#include "../src/gcrypt.h"
 
 static int verbose;
+static int debug;
+static int with_progress;
 
 static void
 die (const char *format, ...)
@@ -38,6 +45,7 @@ die (const char *format, ...)
   va_list arg_ptr;
 
   va_start (arg_ptr, format);
+  fputs ( PGM ": ", stderr);
   vfprintf (stderr, format, arg_ptr);
   va_end (arg_ptr);
   exit (1);
@@ -45,17 +53,41 @@ die (const char *format, ...)
 
 
 static void
+inf (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  va_start (arg_ptr, format);
+  fputs ( PGM ": ", stderr);
+  vfprintf (stderr, format, arg_ptr);
+  va_end (arg_ptr);
+}
+
+
+static void
 print_hex (const char *text, const void *buf, size_t n)
 {
   const unsigned char *p = buf;
 
-  fputs (text, stdout);
+  inf ("%s", text);
   for (; n; n--, p++)
-    printf ("%02X", *p);
-  putchar ('\n');
+    fprintf (stderr, "%02X", *p);
+  putc ('\n', stderr);
+}
+
+
+static void
+progress_cb (void *cb_data, const char *what, int printchar,
+             int current, int total)
+{
+  (void)cb_data;
+
+  inf ("progress (%s %c %d %d)\n", what, printchar, current, total);
+  fflush (stderr);
 }
 
 
+
 static int
 writen (int fd, const void *buf, size_t nbytes)
 {
@@ -111,12 +143,19 @@ readn (int fd, void *buf, size_t buflen, size_t *ret_nread)
 static void
 check_forking (void)
 {
+#ifdef HAVE_W32_SYSTEM
+  if (verbose)
+    inf ("check_forking skipped: not applicable on Windows\n");
+#else /*!HAVE_W32_SYSTEM*/
   pid_t pid;
   int rp[2];
   int i, status;
   size_t nread;
   char tmp1[16], tmp1c[16], tmp1p[16];
 
+  if (verbose)
+    inf ("checking that a fork won't cause the same random output\n");
+
   /* We better make sure that the RNG has been initialzied. */
   gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
   if (verbose)
@@ -160,6 +199,7 @@ check_forking (void)
 
   if (!memcmp (tmp1p, tmp1c, sizeof tmp1c))
     die ("parent and child got the same random number\n");
+#endif  /*!HAVE_W32_SYSTEM*/
 }
 
 
@@ -168,12 +208,19 @@ check_forking (void)
 static void
 check_nonce_forking (void)
 {
+#ifdef HAVE_W32_SYSTEM
+  if (verbose)
+    inf ("check_nonce_forking skipped: not applicable on Windows\n");
+#else /*!HAVE_W32_SYSTEM*/
   pid_t pid;
   int rp[2];
   int i, status;
   size_t nread;
   char nonce1[10], nonce1c[10], nonce1p[10];
 
+  if (verbose)
+    inf ("checking that a fork won't cause the same nonce output\n");
+
   /* We won't get the same nonce back if we never initialized the
      nonce subsystem, thus we get one nonce here and forget about
      it. */
@@ -219,35 +266,323 @@ check_nonce_forking (void)
 
   if (!memcmp (nonce1p, nonce1c, sizeof nonce1c))
     die ("parent and child got the same nonce\n");
+#endif  /*!HAVE_W32_SYSTEM*/
+}
+
+
+/* Check that a closed random device os re-opened if needed. */
+static void
+check_close_random_device (void)
+{
+#ifdef HAVE_W32_SYSTEM
+  if (verbose)
+    inf ("check_close_random_device skipped: not applicable on Windows\n");
+#else /*!HAVE_W32_SYSTEM*/
+  pid_t pid;
+  int i, status;
+  char buf[4];
+
+  if (verbose)
+    inf ("checking that close_random_device works\n");
+
+  gcry_randomize (buf, sizeof buf, GCRY_STRONG_RANDOM);
+  if (verbose)
+    print_hex ("parent random: ", buf, sizeof buf);
+
+  pid = fork ();
+  if (pid == (pid_t)(-1))
+    die ("fork failed: %s\n", strerror (errno));
+  if (!pid)
+    {
+      gcry_control (GCRYCTL_CLOSE_RANDOM_DEVICE, 0);
+
+      /* The next call will re-open the device.  */
+      gcry_randomize (buf, sizeof buf, GCRY_STRONG_RANDOM);
+      if (verbose)
+        {
+          print_hex ("child random : ", buf, sizeof buf);
+          fflush (stdout);
+        }
+      _exit (0);
+    }
+
+  while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
+    ;
+  if (i != (pid_t)(-1)
+      && WIFEXITED (status) && !WEXITSTATUS (status))
+    ;
+  else
+    die ("child failed\n");
+
+#endif  /*!HAVE_W32_SYSTEM*/
+}
+
+
+static int
+rng_type (void)
+{
+  int rngtype;
+  if (gcry_control (GCRYCTL_GET_CURRENT_RNG_TYPE, &rngtype))
+    die ("retrieving RNG type failed\n");
+  return rngtype;
+}
+
+
+static void
+check_rng_type_switching (void)
+{
+  int rngtype, initial;
+  char tmp1[4];
+
+  if (verbose)
+    inf ("checking whether RNG type switching works\n");
+
+  rngtype = rng_type ();
+  if (debug)
+    inf ("rng type: %d\n", rngtype);
+  initial = rngtype;
+  gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
+  if (debug)
+    print_hex ("  sample: ", tmp1, sizeof tmp1);
+  if (rngtype != rng_type ())
+    die ("RNG type unexpectedly changed\n");
+
+  gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM);
+
+  rngtype = rng_type ();
+  if (debug)
+    inf ("rng type: %d\n", rngtype);
+  if (rngtype != initial)
+    die ("switching to System RNG unexpectedly succeeded\n");
+  gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
+  if (debug)
+    print_hex ("  sample: ", tmp1, sizeof tmp1);
+  if (rngtype != rng_type ())
+    die ("RNG type unexpectedly changed\n");
+
+  gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS);
+
+  rngtype = rng_type ();
+  if (debug)
+    inf ("rng type: %d\n", rngtype);
+  if (rngtype != initial)
+    die ("switching to FIPS RNG unexpectedly succeeded\n");
+  gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
+  if (debug)
+    print_hex ("  sample: ", tmp1, sizeof tmp1);
+  if (rngtype != rng_type ())
+    die ("RNG type unexpectedly changed\n");
+
+  gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD);
+
+  rngtype = rng_type ();
+  if (debug)
+    inf ("rng type: %d\n", rngtype);
+  if (rngtype != GCRY_RNG_TYPE_STANDARD)
+    die ("switching to standard RNG failed\n");
+  gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
+  if (debug)
+    print_hex ("  sample: ", tmp1, sizeof tmp1);
+  if (rngtype != rng_type ())
+    die ("RNG type unexpectedly changed\n");
 }
 
 
+static void
+check_early_rng_type_switching (void)
+{
+  int rngtype, initial;
 
+  if (verbose)
+    inf ("checking whether RNG type switching works in the early stage\n");
+
+  rngtype = rng_type ();
+  if (debug)
+    inf ("rng type: %d\n", rngtype);
+  initial = rngtype;
+
+  gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM);
+
+  rngtype = rng_type ();
+  if (debug)
+    inf ("rng type: %d\n", rngtype);
+  if (initial >= GCRY_RNG_TYPE_SYSTEM && rngtype != GCRY_RNG_TYPE_SYSTEM)
+    die ("switching to System RNG failed\n");
+
+  gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS);
+
+  rngtype = rng_type ();
+  if (debug)
+    inf ("rng type: %d\n", rngtype);
+  if (initial >= GCRY_RNG_TYPE_FIPS && rngtype != GCRY_RNG_TYPE_FIPS)
+    die ("switching to FIPS RNG failed\n");
 
+  gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD);
+
+  rngtype = rng_type ();
+  if (debug)
+    inf ("rng type: %d\n", rngtype);
+  if (rngtype != GCRY_RNG_TYPE_STANDARD)
+    die ("switching to standard RNG failed\n");
+}
+
+
+/* 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.  */
+static void
+run_all_rng_tests (const char *program)
+{
+  static const char *options[] = {
+    "--early-rng-check",
+    "--early-rng-check --prefer-standard-rng",
+    "--early-rng-check --prefer-fips-rng",
+    "--early-rng-check --prefer-system-rng",
+    "--prefer-standard-rng",
+    "--prefer-fips-rng",
+    "--prefer-system-rng",
+    NULL
+  };
+  int idx;
+  size_t len, maxlen;
+  char *cmdline;
+
+  maxlen = 0;
+  for (idx=0; options[idx]; idx++)
+    {
+      len = strlen (options[idx]);
+      if (len > maxlen)
+        maxlen = len;
+    }
+  maxlen += strlen (program);
+  maxlen += strlen (" --in-recursion --verbose --debug --progress");
+  maxlen++;
+  cmdline = malloc (maxlen + 1);
+  if (!cmdline)
+    die ("out of core\n");
+
+  for (idx=0; options[idx]; idx++)
+    {
+      if (verbose)
+        inf ("now running with options '%s'\n", options[idx]);
+      strcpy (cmdline, program);
+      strcat (cmdline, " --in-recursion");
+      if (verbose)
+        strcat (cmdline, " --verbose");
+      if (debug)
+        strcat (cmdline, " --debug");
+      if (with_progress)
+        strcat (cmdline, " --progress");
+      strcat (cmdline, " ");
+      strcat (cmdline, options[idx]);
+      if (system (cmdline))
+        die ("running '%s' failed\n", cmdline);
+    }
 
+  free (cmdline);
+}
 
 int
 main (int argc, char **argv)
 {
-  int debug = 0;
+  int last_argc = -1;
+  int early_rng = 0;
+  int in_recursion = 0;
+  const char *program = NULL;
 
-  if ((argc > 1) && (! strcmp (argv[1], "--verbose")))
-    verbose = 1;
-  else if ((argc > 1) && (! strcmp (argv[1], "--debug")))
-    verbose = debug = 1;
+  if (argc)
+    {
+      program = *argv;
+      argc--; argv++;
+    }
+  else
+    die ("argv[0] missing\n");
 
+  while (argc && last_argc != argc )
+    {
+      last_argc = argc;
+      if (!strcmp (*argv, "--"))
+        {
+          argc--; argv++;
+          break;
+        }
+      else if (!strcmp (*argv, "--help"))
+        {
+          fputs ("usage: random [options]\n", stdout);
+          exit (0);
+        }
+      else if (!strcmp (*argv, "--verbose"))
+        {
+          verbose = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--debug"))
+        {
+          debug = verbose = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--progress"))
+        {
+          argc--; argv++;
+          with_progress = 1;
+        }
+      else if (!strcmp (*argv, "--in-recursion"))
+        {
+          in_recursion = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--early-rng-check"))
+        {
+          early_rng = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--prefer-standard-rng"))
+        {
+          /* This is anyway the default, but we may want to use it for
+             debugging. */
+          gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_STANDARD);
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--prefer-fips-rng"))
+        {
+          gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_FIPS);
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--prefer-system-rng"))
+        {
+          gcry_control (GCRYCTL_SET_PREFERRED_RNG_TYPE, GCRY_RNG_TYPE_SYSTEM);
+          argc--; argv++;
+        }
+    }
+
+#ifndef HAVE_W32_SYSTEM
   signal (SIGPIPE, SIG_IGN);
+#endif
+
+  if (early_rng)
+    check_early_rng_type_switching ();
 
   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
   if (!gcry_check_version (GCRYPT_VERSION))
     die ("version mismatch\n");
 
+  if (with_progress)
+    gcry_set_progress_handler (progress_cb, NULL);
+
   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
   if (debug)
     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
 
-  check_forking ();
-  check_nonce_forking ();
+  if (!in_recursion)
+    {
+      check_forking ();
+      check_nonce_forking ();
+      check_close_random_device ();
+    }
+  check_rng_type_switching ();
+
+  if (!in_recursion)
+    run_all_rng_tests (program);
 
   return 0;
 }
diff --git a/tests/register.c b/tests/register.c
deleted file mode 100644 (file)
index 4d8cebe..0000000
+++ /dev/null
@@ -1,187 +0,0 @@
-/* register.c - Test for registering of additional cipher modules.
- *     Copyright (C) 2001, 2002, 2003, 2005 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
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#include "../src/gcrypt.h"
-
-static int verbose;
-static int in_fips_mode;
-
-static void
-die (const char *format, ...)
-{
-  va_list arg_ptr ;
-
-  va_start( arg_ptr, format ) ;
-  vfprintf (stderr, format, arg_ptr );
-  va_end(arg_ptr);
-  exit (1);
-}
-
-gcry_err_code_t
-foo_setkey (void *c, const unsigned char *key, unsigned keylen)
-{
-  (void)c;
-  (void)key;
-  (void)keylen;
-
-  return 0;
-}
-
-#define FOO_BLOCKSIZE 16
-
-void
-foo_encrypt (void *c, unsigned char *outbuf, const unsigned char *inbuf)
-{
-  int i;
-
-  (void)c;
-
-  for (i = 0; i < FOO_BLOCKSIZE; i++)
-    outbuf[i] = inbuf[i] ^ 0x42;
-}
-
-void
-foo_decrypt (void *c, unsigned char *outbuf, const unsigned char *inbuf)
-{
-  int i;
-
-  (void)c;
-
-  for (i = 0; i < FOO_BLOCKSIZE; i++)
-    outbuf[i] = inbuf[i] ^ 0x42;
-}
-
-gcry_cipher_spec_t cipher_spec_foo =
-  {
-    "FOO", NULL, NULL, 16, 0, 0,
-    foo_setkey, foo_encrypt, foo_decrypt,
-    NULL, NULL,
-  };
-
-int
-check_list (int algorithm)
-{
-  gcry_error_t err = GPG_ERR_NO_ERROR;
-  int *list, list_length;
-  int i, ret = 0;
-
-  err = gcry_cipher_list (NULL, &list_length);
-  assert (! err);
-  list = malloc (sizeof (int) * list_length);
-  assert (list);
-  err = gcry_cipher_list (list, &list_length);
-
-  for (i = 0; i < list_length && (! ret); i++)
-    if (list[i] == algorithm)
-      ret = 1;
-
-  return ret;
-}
-
-void
-check_run (void)
-{
-  int err, algorithm;
-  gcry_cipher_hd_t h;
-  char plain[16] = "Heil Discordia!";
-  char encrypted[16], decrypted[16];
-  gcry_module_t module;
-  int ret;
-
-  err = gcry_cipher_register (&cipher_spec_foo, &algorithm, &module);
-  if (in_fips_mode)
-    {
-      if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED)
-        die ("register cipher failed in fips mode: %s\n", gpg_strerror (err));
-      return;
-    }
-  else
-    {
-      if (err)
-        die ("register cipher failed: %s\n", gpg_strerror (err));
-    }
-
-  err = gcry_cipher_open (&h, algorithm, GCRY_CIPHER_MODE_CBC, 0);
-  if (err)
-    die ("gcry_cipher_open failed: %s\n", gpg_strerror (err));
-
-  err = gcry_cipher_encrypt (h,
-                            (unsigned char *) encrypted, sizeof (encrypted),
-                            (unsigned char *) plain, sizeof (plain));
-  assert (! err);
-  assert (memcmp ((void *) plain, (void *) encrypted, sizeof (plain)));
-
-  err = gcry_cipher_reset (h);
-  assert (! err);
-
-  err = gcry_cipher_decrypt (h,
-                            (unsigned char *) decrypted, sizeof (decrypted),
-                            (unsigned char *) encrypted, sizeof (encrypted));
-  assert (! err);
-  assert (! memcmp ((void *) plain, (void *) decrypted, sizeof (plain)));
-
-  ret = check_list (algorithm);
-  assert (ret);
-
-  gcry_cipher_close (h);
-
-  gcry_cipher_unregister (module);
-
-  ret = check_list (algorithm);
-  assert (! ret);
-}
-
-int
-main (int argc, char **argv)
-{
-  int debug = 0;
-  int i = 1;
-
-  if (argc > 1 && !strcmp (argv[1], "--verbose"))
-    verbose = 1;
-  else if (argc > 1 && !strcmp (argv[1], "--debug"))
-    verbose = debug = 1;
-
-  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
-  if (!gcry_check_version (GCRYPT_VERSION))
-    die ("version mismatch\n");
-  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
-  if (debug)
-    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
-
-  if ( gcry_control (GCRYCTL_FIPS_MODE_P, 0) )
-    in_fips_mode = 1;
-
-  for (; i > 0; i--)
-    check_run ();
-
-  /* In fips mode we let the Makefile skip this test because a PASS
-     would not make much sense with all egistering disabled. */
-  return in_fips_mode? 77:0;
-}
index 014cd2a..6fb5c76 100644 (file)
@@ -52,7 +52,7 @@ e7a7ca5367c661f8e6[...]71
 #include <unistd.h>
 
 #ifdef _GCRYPT_IN_LIBGCRYPT
-# include "../src/gcrypt.h"
+# include "../src/gcrypt-int.h"
 #else
 # include <gcrypt.h>
 # define PACKAGE_BUGREPORT "devnull@example.org"
diff --git a/tests/stopwatch.h b/tests/stopwatch.h
new file mode 100644 (file)
index 0000000..bdca9ce
--- /dev/null
@@ -0,0 +1,105 @@
+/* stopwatch.h - Helper code for timing
+ * Copyright (C) 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/>.
+ */
+
+
+#include <time.h>
+#ifdef _WIN32
+# include <winsock2.h>
+# include <windows.h>
+#else
+# include <sys/times.h>
+#endif
+
+
+#ifdef _WIN32
+struct
+{
+  FILETIME creation_time, exit_time, kernel_time, user_time;
+} started_at, stopped_at;
+#else
+static clock_t started_at, stopped_at;
+#endif
+
+
+static void
+start_timer (void)
+{
+#ifdef _WIN32
+#ifdef __MINGW32CE__
+  GetThreadTimes (GetCurrentThread (),
+                   &started_at.creation_time, &started_at.exit_time,
+                   &started_at.kernel_time, &started_at.user_time);
+#else
+  GetProcessTimes (GetCurrentProcess (),
+                   &started_at.creation_time, &started_at.exit_time,
+                   &started_at.kernel_time, &started_at.user_time);
+#endif
+  stopped_at = started_at;
+#else
+  struct tms tmp;
+
+  times (&tmp);
+  started_at = stopped_at = tmp.tms_utime;
+#endif
+}
+
+static void
+stop_timer (void)
+{
+#ifdef _WIN32
+#ifdef __MINGW32CE__
+  GetThreadTimes (GetCurrentThread (),
+                   &stopped_at.creation_time, &stopped_at.exit_time,
+                   &stopped_at.kernel_time, &stopped_at.user_time);
+#else
+  GetProcessTimes (GetCurrentProcess (),
+                   &stopped_at.creation_time, &stopped_at.exit_time,
+                   &stopped_at.kernel_time, &stopped_at.user_time);
+#endif
+#else
+  struct tms tmp;
+
+  times (&tmp);
+  stopped_at = tmp.tms_utime;
+#endif
+}
+
+static const char *
+elapsed_time (void)
+{
+  static char buf[50];
+#if _WIN32
+  unsigned long long t1, t2, t;
+
+  t1 = (((unsigned long long)started_at.kernel_time.dwHighDateTime << 32)
+        + started_at.kernel_time.dwLowDateTime);
+  t1 += (((unsigned long long)started_at.user_time.dwHighDateTime << 32)
+        + started_at.user_time.dwLowDateTime);
+  t2 = (((unsigned long long)stopped_at.kernel_time.dwHighDateTime << 32)
+        + 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 );
+#else
+  snprintf (buf, sizeof buf, "%5.0fms",
+            (((double) (stopped_at - started_at))/CLOCKS_PER_SEC)*10000000);
+#endif
+  return buf;
+}
diff --git a/tests/t-common.h b/tests/t-common.h
new file mode 100644 (file)
index 0000000..288963d
--- /dev/null
@@ -0,0 +1,99 @@
+/* t-common.h - Common code for the tests.
+ * Copyright (C) 2013 g10 Code GmbH
+ *
+ * This file is part of libgpg-error.
+ *
+ * libgpg-error 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.
+ *
+ * libgpg-error 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 <stdarg.h>
+
+#include "../src/gcrypt.h"
+
+#ifndef PGM
+# error Macro PGM not defined.
+#endif
+
+
+static int verbose;
+static int debug;
+static int errorcount;
+
+
+static void
+die (const char *format, ...)
+{
+  va_list arg_ptr ;
+
+  fflush (stdout);
+#ifdef HAVE_FLOCKFILE
+  flockfile (stderr);
+#endif
+  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);
+#ifdef HAVE_FLOCKFILE
+  funlockfile (stderr);
+#endif
+  exit (1);
+}
+
+
+static void
+fail (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  fflush (stdout);
+#ifdef HAVE_FLOCKFILE
+  flockfile (stderr);
+#endif
+  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);
+#ifdef HAVE_FLOCKFILE
+  funlockfile (stderr);
+#endif
+  errorcount++;
+  if (errorcount >= 50)
+    die ("stopped after 50 errors.");
+}
+
+
+static void
+show (const char *format, ...)
+{
+  va_list arg_ptr;
+
+  if (!verbose)
+    return;
+#ifdef HAVE_FLOCKFILE
+  flockfile (stderr);
+#endif
+  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);
+#ifdef HAVE_FLOCKFILE
+  funlockfile (stderr);
+#endif
+}
diff --git a/tests/t-convert.c b/tests/t-convert.c
new file mode 100644 (file)
index 0000000..072bf32
--- /dev/null
@@ -0,0 +1,588 @@
+/* t-convert.c  - Tests for mpi print and scna functions
+ * Copyright (C) 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/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdarg.h>
+
+#include "../src/gcrypt-int.h"
+
+#define PGM "t-convert"
+
+#define DIM(v)              (sizeof(v)/sizeof((v)[0]))
+#define DIMof(type,member)   DIM(((type *)0)->member)
+
+static const char *wherestr;
+static int verbose;
+static int debug;
+static int error_count;
+
+
+#define xmalloc(a)    gcry_xmalloc ((a))
+#define xcalloc(a,b)  gcry_xcalloc ((a),(b))
+#define xfree(a)      gcry_free ((a))
+#define pass() do { ; } while (0)
+
+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);
+  va_end (arg_ptr);
+}
+
+static void
+showhex (const char *prefix, const void *buffer, size_t buflen)
+{
+  const unsigned char *s;
+
+  if (!verbose)
+    return;
+  fprintf (stderr, "%s: %s ", PGM, prefix);
+  for (s= buffer; buflen; buflen--, s++)
+    fprintf (stderr, "%02x", *s);
+  putc ('\n', stderr);
+}
+
+
+/* Allocate a bit string consisting of '0' and '1' from the MPI A.  Do
+   not return any leading zero bits.  Caller needs to gcry_free the
+   result. */
+static char *
+mpi2bitstr_nlz (gcry_mpi_t a)
+{
+  char *p, *buf;
+  size_t length = gcry_mpi_get_nbits (a);
+
+  if (!length)
+    {
+      buf = p = xmalloc (3);
+      *p++ = ' ';
+      *p++ = '0';
+    }
+  else
+    {
+      buf = p = xmalloc (length + 1 + 1);
+      *p++ = gcry_mpi_is_neg (a)? '-':' ';
+      while (length-- > 1)
+        *p++ = gcry_mpi_test_bit (a, length) ? '1':'0';
+      *p++ = gcry_mpi_test_bit (a, 0) ? '1':'0';
+    }
+  *p = 0;
+  return buf;
+}
+
+
+static void
+showmpi (const char *prefix, gcry_mpi_t a)
+{
+  char *bitstr;
+
+  if (!verbose)
+    return;
+  bitstr = mpi2bitstr_nlz (a);
+  fprintf (stderr, "%s: %s%s\n", PGM, prefix, bitstr);
+  xfree (bitstr);
+}
+
+
+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);
+  error_count++;
+}
+
+static void
+die (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);
+  exit (1);
+}
+
+
+/* Check that mpi_print does not return a negative zero.  */
+static void
+negative_zero (void)
+{
+  gpg_error_t err;
+  gcry_mpi_t a;
+  char *buf;
+  void *bufaddr = &buf;
+  struct { const char *name; enum gcry_mpi_format format; } fmts[] =
+    {
+      { "STD", GCRYMPI_FMT_STD },
+      { "PGP", GCRYMPI_FMT_PGP },
+      { "SSH", GCRYMPI_FMT_SSH },
+      { "HEX", GCRYMPI_FMT_HEX },
+      { "USG", GCRYMPI_FMT_USG },
+      { NULL, 0 }
+    };
+  int i;
+
+  if (debug)
+    show ("negative zero printing\n");
+
+  a = gcry_mpi_new (0);
+  for (i=0; fmts[i].name; i++)
+    {
+      err = gcry_mpi_aprint (fmts[i].format, bufaddr, NULL, a);
+      if (err)
+        fail ("error printing a zero as %s: %s\n",
+              fmts[i].name,gpg_strerror (err) );
+      else
+        gcry_free (buf);
+    }
+
+  /* With the current version of libgcrypt the next two statements
+     should set a to -0. */
+  gcry_mpi_sub_ui (a, a, 1);
+  gcry_mpi_add_ui (a, a, 1);
+
+  for (i=0; fmts[i].name; i++)
+    {
+      err = gcry_mpi_aprint (fmts[i].format, bufaddr, NULL, a);
+      if (err)
+        fail ("error printing a negative zero as %s: %s\n",
+              fmts[i].name,gpg_strerror (err) );
+      else
+        gcry_free (buf);
+    }
+
+  gcry_mpi_release (a);
+}
+
+
+static void
+check_formats (void)
+{
+  static struct {
+    int value;
+    struct {
+      const char *hex;
+      size_t stdlen;
+      const char *std;
+      size_t sshlen;
+      const char *ssh;
+      size_t usglen;
+      const char *usg;
+      size_t pgplen;
+      const char *pgp;
+    } a;
+  } data[] = {
+    {    0, { "00",
+              0, "",
+              4, "\x00\x00\x00\x00",
+              0, "",
+              2, "\x00\x00"}
+    },
+    {    1, { "01",
+              1, "\x01",
+              5, "\x00\x00\x00\x01\x01",
+              1, "\x01",
+              3, "\x00\x01\x01" }
+    },
+    {    2, { "02",
+              1, "\x02",
+              5, "\x00\x00\x00\x01\x02",
+              1, "\x02",
+              3, "\x00\x02\x02" }
+    },
+    {  127, { "7F",
+              1, "\x7f",
+              5, "\x00\x00\x00\x01\x7f",
+              1, "\x7f",
+              3, "\x00\x07\x7f" }
+    },
+    {  128, { "0080",
+              2, "\x00\x80",
+              6, "\x00\x00\x00\x02\x00\x80",
+              1, "\x80",
+              3, "\x00\x08\x80" }
+    },
+    {  129, { "0081",
+              2, "\x00\x81",
+              6, "\x00\x00\x00\x02\x00\x81",
+              1, "\x81",
+              3, "\x00\x08\x81" }
+    },
+    {  255, { "00FF",
+              2, "\x00\xff",
+              6, "\x00\x00\x00\x02\x00\xff",
+              1, "\xff",
+              3, "\x00\x08\xff" }
+    },
+    {  256, { "0100",
+              2, "\x01\x00",
+              6, "\x00\x00\x00\x02\x01\x00",
+              2, "\x01\x00",
+              4, "\x00\x09\x01\x00" }
+    },
+    {  257, { "0101",
+              2, "\x01\x01",
+              6, "\x00\x00\x00\x02\x01\x01",
+              2, "\x01\x01",
+              4, "\x00\x09\x01\x01" }
+    },
+    {   -1, { "-01",
+              1, "\xff",
+              5, "\x00\x00\x00\x01\xff",
+              1,"\x01" }
+    },
+    {   -2, { "-02",
+              1, "\xfe",
+              5, "\x00\x00\x00\x01\xfe",
+              1, "\x02" }
+    },
+    { -127, { "-7F",
+              1, "\x81",
+              5, "\x00\x00\x00\x01\x81",
+              1, "\x7f" }
+    },
+    { -128, { "-0080",
+              1, "\x80",
+              5, "\x00\x00\x00\x01\x80",
+              1, "\x80" }
+    },
+    { -129, { "-0081",
+              2, "\xff\x7f",
+              6, "\x00\x00\x00\x02\xff\x7f",
+              1, "\x81" }
+    },
+    { -255, { "-00FF",
+              2, "\xff\x01",
+              6, "\x00\x00\x00\x02\xff\x01",
+              1, "\xff" }
+    },
+    { -256, { "-0100",
+              2, "\xff\x00",
+              6, "\x00\x00\x00\x02\xff\x00",
+              2, "\x01\x00" }
+    },
+    { -257, { "-0101",
+              2, "\xfe\xff",
+              6, "\x00\x00\x00\x02\xfe\xff",
+              2, "\x01\x01" }
+    },
+    {  65535, { "00FFFF",
+                3, "\x00\xff\xff",
+                7, "\x00\x00\x00\x03\x00\xff\xff",
+                2, "\xff\xff",
+                4, "\x00\x10\xff\xff" }
+    },
+    {  65536, { "010000",
+                3, "\x01\00\x00",
+                7, "\x00\x00\x00\x03\x01\x00\x00",
+                3, "\x01\x00\x00",
+                5, "\x00\x11\x01\x00\x00 "}
+    },
+    {  65537, { "010001",
+                3, "\x01\00\x01",
+                7, "\x00\x00\x00\x03\x01\x00\x01",
+                3, "\x01\x00\x01",
+                5, "\x00\x11\x01\x00\x01" }
+    },
+    { -65537, { "-010001",
+                3, "\xfe\xff\xff",
+                7, "\x00\x00\x00\x03\xfe\xff\xff",
+                3, "\x01\x00\x01" }
+    },
+    { -65536, { "-010000",
+                3, "\xff\x00\x00",
+                7, "\x00\x00\x00\x03\xff\x00\x00",
+                3, "\x01\x00\x00" }
+    },
+    { -65535, { "-00FFFF",
+                3, "\xff\x00\x01",
+                7, "\x00\x00\x00\x03\xff\x00\x01",
+                2, "\xff\xff" }
+    }
+  };
+  gpg_error_t err;
+  gcry_mpi_t a, b;
+  char *buf;
+  void *bufaddr = &buf;
+  int idx;
+  size_t buflen;
+
+  a = gcry_mpi_new (0);
+  for (idx=0; idx < DIM(data); idx++)
+    {
+      if (debug)
+        show ("print test %d\n", data[idx].value);
+
+      if (data[idx].value < 0)
+        {
+          gcry_mpi_set_ui (a, -data[idx].value);
+          gcry_mpi_neg (a, a);
+        }
+      else
+        gcry_mpi_set_ui (a, data[idx].value);
+
+      err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a);
+      if (err)
+        fail ("error printing value %d as %s: %s\n",
+              data[idx].value, "HEX", gpg_strerror (err));
+      else
+        {
+          if (strcmp (buf, data[idx].a.hex))
+            {
+              fail ("error printing value %d as %s: %s\n",
+                    data[idx].value, "HEX", "wrong result");
+              show ("expected: '%s'\n", data[idx].a.hex);
+              show ("     got: '%s'\n", buf);
+            }
+          gcry_free (buf);
+        }
+
+      err = gcry_mpi_aprint (GCRYMPI_FMT_STD, bufaddr, &buflen, a);
+      if (err)
+        fail ("error printing value %d as %s: %s\n",
+              data[idx].value, "STD", gpg_strerror (err));
+      else
+        {
+          if (buflen != data[idx].a.stdlen
+              || memcmp (buf, data[idx].a.std, data[idx].a.stdlen))
+            {
+              fail ("error printing value %d as %s: %s\n",
+                    data[idx].value, "STD", "wrong result");
+              showhex ("expected:", data[idx].a.std, data[idx].a.stdlen);
+              showhex ("     got:", buf, buflen);
+            }
+          gcry_free (buf);
+        }
+
+      err = gcry_mpi_aprint (GCRYMPI_FMT_SSH, bufaddr, &buflen, a);
+      if (err)
+        fail ("error printing value %d as %s: %s\n",
+              data[idx].value, "SSH", gpg_strerror (err));
+      else
+        {
+          if (buflen != data[idx].a.sshlen
+              || memcmp (buf, data[idx].a.ssh, data[idx].a.sshlen))
+            {
+              fail ("error printing value %d as %s: %s\n",
+                    data[idx].value, "SSH", "wrong result");
+              showhex ("expected:", data[idx].a.ssh, data[idx].a.sshlen);
+              showhex ("     got:", buf, buflen);
+            }
+          gcry_free (buf);
+        }
+
+      err = gcry_mpi_aprint (GCRYMPI_FMT_USG, bufaddr, &buflen, a);
+      if (err)
+        fail ("error printing value %d as %s: %s\n",
+              data[idx].value, "USG", gpg_strerror (err));
+      else
+        {
+          if (buflen != data[idx].a.usglen
+              || memcmp (buf, data[idx].a.usg, data[idx].a.usglen))
+            {
+              fail ("error printing value %d as %s: %s\n",
+                    data[idx].value, "USG", "wrong result");
+              showhex ("expected:", data[idx].a.usg, data[idx].a.usglen);
+              showhex ("     got:", buf, buflen);
+            }
+          gcry_free (buf);
+        }
+
+      err = gcry_mpi_aprint (GCRYMPI_FMT_PGP, bufaddr, &buflen, a);
+      if (gcry_mpi_is_neg (a))
+        {
+          if (gpg_err_code (err) != GPG_ERR_INV_ARG)
+            fail ("error printing value %d as %s: %s\n",
+                  data[idx].value, "PGP", "Expected error not returned");
+        }
+      else if (err)
+        fail ("error printing value %d as %s: %s\n",
+              data[idx].value, "PGP", gpg_strerror (err));
+      else
+        {
+          if (buflen != data[idx].a.pgplen
+              || memcmp (buf, data[idx].a.pgp, data[idx].a.pgplen))
+            {
+              fail ("error printing value %d as %s: %s\n",
+                    data[idx].value, "PGP", "wrong result");
+              showhex ("expected:", data[idx].a.pgp, data[idx].a.pgplen);
+              showhex ("     got:", buf, buflen);
+            }
+          gcry_free (buf);
+        }
+    }
+
+
+  /* Now for the other direction.  */
+  for (idx=0; idx < DIM(data); idx++)
+    {
+      if (debug)
+        show ("scan test %d\n", data[idx].value);
+
+      if (data[idx].value < 0)
+        {
+          gcry_mpi_set_ui (a, -data[idx].value);
+          gcry_mpi_neg (a, a);
+        }
+      else
+        gcry_mpi_set_ui (a, data[idx].value);
+
+      err = gcry_mpi_scan (&b, GCRYMPI_FMT_HEX, data[idx].a.hex, 0, &buflen);
+      if (err)
+        fail ("error scanning value %d from %s: %s\n",
+              data[idx].value, "HEX", gpg_strerror (err));
+      else
+        {
+          if (gcry_mpi_cmp (a, b))
+            {
+              fail ("error scanning value %d from %s: %s\n",
+                    data[idx].value, "HEX", "wrong result");
+              showmpi ("expected:", a);
+              showmpi ("     got:", b);
+            }
+          gcry_mpi_release (b);
+        }
+
+      err = gcry_mpi_scan (&b, GCRYMPI_FMT_STD,
+                           data[idx].a.std, data[idx].a.stdlen, &buflen);
+      if (err)
+        fail ("error scanning value %d as %s: %s\n",
+              data[idx].value, "STD", gpg_strerror (err));
+      else
+        {
+          if (gcry_mpi_cmp (a, b) || data[idx].a.stdlen != buflen)
+            {
+              fail ("error scanning value %d from %s: %s (%u)\n",
+                    data[idx].value, "STD", "wrong result", buflen);
+              showmpi ("expected:", a);
+              showmpi ("     got:", b);
+            }
+          gcry_mpi_release (b);
+        }
+
+      err = gcry_mpi_scan (&b, GCRYMPI_FMT_SSH,
+                           data[idx].a.ssh, data[idx].a.sshlen, &buflen);
+      if (err)
+        fail ("error scanning value %d as %s: %s\n",
+              data[idx].value, "SSH", gpg_strerror (err));
+      else
+        {
+          if (gcry_mpi_cmp (a, b) || data[idx].a.sshlen != buflen)
+            {
+              fail ("error scanning value %d from %s: %s (%u)\n",
+                    data[idx].value, "SSH", "wrong result", buflen);
+              showmpi ("expected:", a);
+              showmpi ("     got:", b);
+            }
+          gcry_mpi_release (b);
+        }
+
+      err = gcry_mpi_scan (&b, GCRYMPI_FMT_USG,
+                           data[idx].a.usg, data[idx].a.usglen, &buflen);
+      if (err)
+        fail ("error scanning value %d as %s: %s\n",
+              data[idx].value, "USG", gpg_strerror (err));
+      else
+        {
+          if (gcry_mpi_is_neg (a))
+            gcry_mpi_neg (b, b);
+          if (gcry_mpi_cmp (a, b) || data[idx].a.usglen != buflen)
+            {
+              fail ("error scanning value %d from %s: %s (%u)\n",
+                    data[idx].value, "USG", "wrong result", buflen);
+              showmpi ("expected:", a);
+              showmpi ("     got:", b);
+            }
+          gcry_mpi_release (b);
+        }
+
+      /* Negative values are not supported by PGP, thus we don't have
+         an samples.  */
+      if (!gcry_mpi_is_neg (a))
+        {
+          err = gcry_mpi_scan (&b, GCRYMPI_FMT_PGP,
+                               data[idx].a.pgp, data[idx].a.pgplen, &buflen);
+          if (err)
+            fail ("error scanning value %d as %s: %s\n",
+                  data[idx].value, "PGP", gpg_strerror (err));
+          else
+            {
+              if (gcry_mpi_cmp (a, b) || data[idx].a.pgplen != buflen)
+                {
+                  fail ("error scanning value %d from %s: %s (%u)\n",
+                        data[idx].value, "PGP", "wrong result", buflen);
+                  showmpi ("expected:", a);
+                  showmpi ("     got:", b);
+                }
+              gcry_mpi_release (b);
+            }
+        }
+    }
+
+  gcry_mpi_release (a);
+}
+
+
+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;
+
+  if (!gcry_check_version (GCRYPT_VERSION))
+    die ("version mismatch\n");
+
+  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+  if (debug)
+    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+  negative_zero ();
+  check_formats ();
+
+  show ("All tests completed. Errors: %d\n", error_count);
+  return error_count ? 1 : 0;
+}
diff --git a/tests/t-ed25519.c b/tests/t-ed25519.c
new file mode 100644 (file)
index 0000000..465a217
--- /dev/null
@@ -0,0 +1,560 @@
+/* t-ed25519.c - Check the Ed25519 crypto
+ * Copyright (C) 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/>.
+ */
+
+#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-ed25519"
+#define N_TESTS 1025
+
+#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 int sign_with_pk;
+static int no_verify;
+static int custom_data_file;
+
+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);
+}
+
+
+static void
+show_sexp (const char *prefix, gcry_sexp_t a)
+{
+  char *buf;
+  size_t size;
+
+  fprintf (stderr, "%s: ", PGM);
+  if (prefix)
+    fputs (prefix, stderr);
+  size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+  buf = xmalloc (size);
+
+  gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
+  fprintf (stderr, "%.*s", (int)size, buf);
+  gcry_free (buf);
+}
+
+
+/* Prepend FNAME with the srcdir environment variable's value and
+   retrun an allocated filename. */
+char *
+prepend_srcdir (const char *fname)
+{
+  static const char *srcdir;
+  char *result;
+
+  if (!srcdir && !(srcdir = getenv ("srcdir")))
+    srcdir = ".";
+
+  result = xmalloc (strlen (srcdir) + 1 + strlen (fname) + 1);
+  strcpy (result, srcdir);
+  strcat (result, "/");
+  strcat (result, fname);
+  return result;
+}
+
+
+/* Read next line but skip over empty and comment lines.  Caller must
+   xfree the result.  */
+static char *
+read_textline (FILE *fp, int *lineno)
+{
+  char line[4096];
+  char *p;
+
+  do
+    {
+      if (!fgets (line, sizeof line, fp))
+        {
+          if (feof (fp))
+            return NULL;
+          die ("error reading input line: %s\n", strerror (errno));
+        }
+      ++*lineno;
+      p = strchr (line, '\n');
+      if (!p)
+        die ("input line %d not terminated or too long\n", *lineno);
+      *p = 0;
+      for (p--;p > line && my_isascii (*p) && isspace (*p); p--)
+        *p = 0;
+    }
+  while (!*line || *line == '#');
+  /* if (debug) */
+  /*   show ("read line: '%s'\n", line); */
+  return xstrdup (line);
+}
+
+
+/* Copy the data after the tag to BUFFER.  BUFFER will be allocated as
+   needed.  */
+static void
+copy_data (char **buffer, const char *line, int lineno)
+{
+  const char *s;
+
+  xfree (*buffer);
+  *buffer = NULL;
+
+  s = strchr (line, ':');
+  if (!s)
+    {
+      fail ("syntax error at input line %d", lineno);
+      return;
+    }
+  for (s++; my_isascii (*s) && isspace (*s); s++)
+    ;
+  *buffer = xstrdup (s);
+}
+
+
+/* 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
+hexdowncase (char *string)
+{
+  char *p;
+
+  for (p=string; *p; p++)
+    if (my_isascii (*p))
+      *p = tolower (*p);
+}
+
+
+static void
+one_test (int testno, const char *sk, const char *pk,
+          const char *msg, const char *sig)
+{
+  gpg_error_t err;
+  int i;
+  char *p;
+  void *buffer = NULL;
+  void *buffer2 = NULL;
+  size_t buflen, buflen2;
+  gcry_sexp_t s_tmp, s_tmp2;
+  gcry_sexp_t s_sk = NULL;
+  gcry_sexp_t s_pk = NULL;
+  gcry_sexp_t s_msg= NULL;
+  gcry_sexp_t s_sig= NULL;
+  unsigned char *sig_r = NULL;
+  unsigned char *sig_s = NULL;
+  char *sig_rs_string = NULL;
+  size_t sig_r_len, sig_s_len;
+
+  if (verbose > 1)
+    show ("Running test %d\n", testno);
+
+  if (!(buffer = hex2buffer (sk, &buflen)))
+    {
+      fail ("error building s-exp for test %d, %s: %s",
+            testno, "sk", "invalid hex string");
+      goto leave;
+    }
+  if (!(buffer2 = hex2buffer (pk, &buflen2)))
+    {
+      fail ("error building s-exp for test %d, %s: %s",
+            testno, "pk", "invalid hex string");
+      goto leave;
+    }
+  if (sign_with_pk)
+    err = gcry_sexp_build (&s_sk, NULL,
+                           "(private-key"
+                           " (ecc"
+                           "  (curve \"Ed25519\")"
+                           "  (flags eddsa)"
+                           "  (q %b)"
+                           "  (d %b)))",
+                           (int)buflen2, buffer2,
+                           (int)buflen, buffer);
+  else
+    err = gcry_sexp_build (&s_sk, NULL,
+                           "(private-key"
+                           " (ecc"
+                           "  (curve \"Ed25519\")"
+                           "  (flags eddsa)"
+                           "  (d %b)))",
+                           (int)buflen, buffer);
+  if (err)
+    {
+      fail ("error building s-exp for test %d, %s: %s",
+            testno, "sk", gpg_strerror (err));
+      goto leave;
+    }
+
+  if ((err = gcry_sexp_build (&s_pk, NULL,
+                              "(public-key"
+                              " (ecc"
+                              "  (curve \"Ed25519\")"
+                              "  (flags eddsa)"
+                              "  (q %b)))",  (int)buflen2, buffer2)))
+    {
+      fail ("error building s-exp for test %d, %s: %s",
+            testno, "pk", gpg_strerror (err));
+      goto leave;
+    }
+
+  xfree (buffer);
+  if (!(buffer = hex2buffer (msg, &buflen)))
+    {
+      fail ("error building s-exp for test %d, %s: %s",
+            testno, "msg", "invalid hex string");
+      goto leave;
+    }
+  if ((err = gcry_sexp_build (&s_msg, NULL,
+                              "(data"
+                              " (flags eddsa)"
+                              " (hash-algo sha512)"
+                              " (value %b))",  (int)buflen, buffer)))
+    {
+      fail ("error building s-exp for test %d, %s: %s",
+            testno, "msg", gpg_strerror (err));
+      goto leave;
+    }
+
+  if ((err = gcry_pk_sign (&s_sig, s_msg, s_sk)))
+    fail ("gcry_pk_sign failed for test %d: %s", testno, gpg_strerror (err));
+  if (debug)
+    show_sexp ("sig=", s_sig);
+
+  s_tmp2 = NULL;
+  s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0);
+  if (s_tmp)
+    {
+      s_tmp2 = s_tmp;
+      s_tmp = gcry_sexp_find_token (s_tmp2, "eddsa", 0);
+      if (s_tmp)
+        {
+          gcry_sexp_release (s_tmp2);
+          s_tmp2 = s_tmp;
+          s_tmp = gcry_sexp_find_token (s_tmp2, "r", 0);
+          if (s_tmp)
+            {
+              sig_r = gcry_sexp_nth_buffer (s_tmp, 1, &sig_r_len);
+              gcry_sexp_release (s_tmp);
+            }
+          s_tmp = gcry_sexp_find_token (s_tmp2, "s", 0);
+          if (s_tmp)
+            {
+              sig_s = gcry_sexp_nth_buffer (s_tmp, 1, &sig_s_len);
+              gcry_sexp_release (s_tmp);
+            }
+        }
+    }
+  gcry_sexp_release (s_tmp2); s_tmp2 = NULL;
+
+  if (!sig_r || !sig_s)
+    fail ("gcry_pk_sign failed for test %d: %s", testno, "r or s missing");
+  else
+    {
+      sig_rs_string = xmalloc (2*(sig_r_len + sig_s_len)+1);
+      p = sig_rs_string;
+      *p = 0;
+      for (i=0; i < sig_r_len; i++, p += 2)
+        snprintf (p, 3, "%02x", sig_r[i]);
+      for (i=0; i < sig_s_len; i++, p += 2)
+        snprintf (p, 3, "%02x", sig_s[i]);
+      if (strcmp (sig_rs_string, sig))
+        {
+          fail ("gcry_pk_sign failed for test %d: %s",
+                testno, "wrong value returned");
+          show ("  expected: '%s'", sig);
+          show ("       got: '%s'", sig_rs_string);
+        }
+    }
+
+  if (!no_verify)
+    if ((err = gcry_pk_verify (s_sig, s_msg, s_pk)))
+      fail ("gcry_pk_verify failed for test %d: %s",
+            testno, gpg_strerror (err));
+
+
+ leave:
+  gcry_sexp_release (s_sig);
+  gcry_sexp_release (s_sk);
+  gcry_sexp_release (s_pk);
+  gcry_sexp_release (s_msg);
+  xfree (buffer);
+  xfree (buffer2);
+  xfree (sig_r);
+  xfree (sig_s);
+  xfree (sig_rs_string);
+}
+
+
+static void
+check_ed25519 (const char *fname)
+{
+  FILE *fp;
+  int lineno, ntests;
+  char *line;
+  int testno;
+  char *sk, *pk, *msg, *sig;
+
+  show ("Checking Ed25519.\n");
+
+  fp = fopen (fname, "r");
+  if (!fp)
+    die ("error opening '%s': %s\n", fname, strerror (errno));
+
+  testno = 0;
+  sk = pk = msg = sig = NULL;
+  lineno = ntests = 0;
+  while ((line = read_textline (fp, &lineno)))
+    {
+      if (!strncmp (line, "TST:", 4))
+        testno = atoi (line+4);
+      else if (!strncmp (line, "SK:", 3))
+        copy_data (&sk, line, lineno);
+      else if (!strncmp (line, "PK:", 3))
+        copy_data (&pk, line, lineno);
+      else if (!strncmp (line, "MSG:", 4))
+        copy_data (&msg, line, lineno);
+      else if (!strncmp (line, "SIG:", 4))
+        copy_data (&sig, line, lineno);
+      else
+        fail ("unknown tag at input line %d", lineno);
+
+      xfree (line);
+      if (testno && sk && pk && msg && sig)
+        {
+          hexdowncase (sig);
+          one_test (testno, sk, pk, msg, sig);
+          ntests++;
+          if (!(ntests % 256))
+            show_note ("%d of %d tests done\n", ntests, N_TESTS);
+          xfree (pk);  pk = NULL;
+          xfree (sk);  sk = NULL;
+          xfree (msg); msg = NULL;
+          xfree (sig); sig = NULL;
+        }
+
+    }
+  xfree (pk);
+  xfree (sk);
+  xfree (msg);
+  xfree (sig);
+
+  if (ntests != N_TESTS && !custom_data_file)
+    fail ("did %d tests but expected %d", ntests, N_TESTS);
+  else if ((ntests % 256))
+    show_note ("%d tests done\n", ntests);
+
+  fclose (fp);
+}
+
+
+int
+main (int argc, char **argv)
+{
+  int last_argc = -1;
+  char *fname = NULL;
+
+  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"
+                 "  --sign-with-pk  also use the public key for signing\n"
+                 "  --no-verify     skip the verify test\n"
+                 "  --data FNAME    take test data from file FNAME\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, "--sign-with-pk"))
+        {
+          sign_with_pk = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--no-verify"))
+        {
+          no_verify = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--data"))
+        {
+          argc--; argv++;
+          if (argc)
+            {
+              xfree (fname);
+              fname = xstrdup (*argv);
+              argc--; argv++;
+            }
+        }
+      else if (!strncmp (*argv, "--", 2))
+        die ("unknown option '%s'", *argv);
+
+    }
+
+  if (!fname)
+    fname = prepend_srcdir ("t-ed25519.inp");
+  else
+    custom_data_file = 1;
+
+  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_ed25519 (fname);
+  stop_timer ();
+
+  xfree (fname);
+
+  show ("All tests completed in %s.  Errors: %d\n",
+        elapsed_time (), error_count);
+  return !!error_count;
+}
diff --git a/tests/t-ed25519.inp b/tests/t-ed25519.inp
new file mode 100644 (file)
index 0000000..61387c4
--- /dev/null
@@ -0,0 +1,6164 @@
+# t-ed25519.inp  - 1024 test data sets
+# This has been taken from
+#    http://ed25519.cr.yp.to/python/sign.input
+# which distributed them as public domain.
+# For our use converted using this script:
+#    awk -F: 'BEGIN {n=1} { print "TST: " n; n++; \
+#      print "SK:  " substr($1,0,64); print "PK:  " $2;\
+#      print "MSG: " $3; print "SIG: " substr($4,0,128); print ""}'
+#
+# The PK appended to the SK and the MSG appended to the SIG have been
+# stripped.  A few additional tests have been added to the 1024
+# original tests.
+
+TST: 1
+SK:  9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60
+PK:  d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a
+MSG:
+SIG: e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b
+
+TST: 2
+SK:  4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb
+PK:  3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c
+MSG: 72
+SIG: 92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00
+
+TST: 3
+SK:  c5aa8df43f9f837bedb7442f31dcb7b166d38535076f094b85ce3a2e0b4458f7
+PK:  fc51cd8e6218a1a38da47ed00230f0580816ed13ba3303ac5deb911548908025
+MSG: af82
+SIG: 6291d657deec24024827e69c3abe01a30ce548a284743a445e3680d7db5ac3ac18ff9b538d16f290ae67f760984dc6594a7c15e9716ed28dc027beceea1ec40a
+
+TST: 4
+SK:  0d4a05b07352a5436e180356da0ae6efa0345ff7fb1572575772e8005ed978e9
+PK:  e61a185bcef2613a6c7cb79763ce945d3b245d76114dd440bcf5f2dc1aa57057
+MSG: cbc77b
+SIG: d9868d52c2bebce5f3fa5a79891970f309cb6591e3e1702a70276fa97c24b3a8e58606c38c9758529da50ee31b8219cba45271c689afa60b0ea26c99db19b00c
+
+TST: 5
+SK:  6df9340c138cc188b5fe4464ebaa3f7fc206a2d55c3434707e74c9fc04e20ebb
+PK:  c0dac102c4533186e25dc43128472353eaabdb878b152aeb8e001f92d90233a7
+MSG: 5f4c8989
+SIG: 124f6fc6b0d100842769e71bd530664d888df8507df6c56dedfdb509aeb93416e26b918d38aa06305df3095697c18b2aa832eaa52edc0ae49fbae5a85e150c07
+
+TST: 6
+SK:  b780381a65edf8b78f6945e8dbec7941ac049fd4c61040cf0c324357975a293c
+PK:  e253af0766804b869bb1595be9765b534886bbaab8305bf50dbc7f899bfb5f01
+MSG: 18b6bec097
+SIG: b2fc46ad47af464478c199e1f8be169f1be6327c7f9a0a6689371ca94caf04064a01b22aff1520abd58951341603faed768cf78ce97ae7b038abfe456aa17c09
+
+TST: 7
+SK:  78ae9effe6f245e924a7be63041146ebc670dbd3060cba67fbc6216febc44546
+PK:  fbcfbfa40505d7f2be444a33d185cc54e16d615260e1640b2b5087b83ee3643d
+MSG: 89010d855972
+SIG: 6ed629fc1d9ce9e1468755ff636d5a3f40a5d9c91afd93b79d241830f7e5fa29854b8f20cc6eecbb248dbd8d16d14e99752194e4904d09c74d639518839d2300
+
+TST: 8
+SK:  691865bfc82a1e4b574eecde4c7519093faf0cf867380234e3664645c61c5f79
+PK:  98a5e3a36e67aaba89888bf093de1ad963e774013b3902bfab356d8b90178a63
+MSG: b4a8f381e70e7a
+SIG: 6e0af2fe55ae377a6b7a7278edfb419bd321e06d0df5e27037db8812e7e3529810fa5552f6c0020985ca17a0e02e036d7b222a24f99b77b75fdd16cb05568107
+
+TST: 9
+SK:  3b26516fb3dc88eb181b9ed73f0bcd52bcd6b4c788e4bcaf46057fd078bee073
+PK:  f81fb54a825fced95eb033afcd64314075abfb0abd20a970892503436f34b863
+MSG: 4284abc51bb67235
+SIG: d6addec5afb0528ac17bb178d3e7f2887f9adbb1ad16e110545ef3bc57f9de2314a5c8388f723b8907be0f3ac90c6259bbe885ecc17645df3db7d488f805fa08
+
+TST: 10
+SK:  edc6f5fbdd1cee4d101c063530a30490b221be68c036f5b07d0f953b745df192
+PK:  c1a49c66e617f9ef5ec66bc4c6564ca33de2a5fb5e1464062e6d6c6219155efd
+MSG: 672bf8965d04bc5146
+SIG: 2c76a04af2391c147082e33faacdbe56642a1e134bd388620b852b901a6bc16ff6c9cc9404c41dea12ed281da067a1513866f9d964f8bdd24953856c50042901
+
+TST: 11
+SK:  4e7d21fb3b1897571a445833be0f9fd41cd62be3aa04040f8934e1fcbdcacd45
+PK:  31b2524b8348f7ab1dfafa675cc538e9a84e3fe5819e27c12ad8bbc1a36e4dff
+MSG: 33d7a786aded8c1bf691
+SIG: 28e4598c415ae9de01f03f9f3fab4e919e8bf537dd2b0cdf6e79b9e6559c9409d9151a4c40f083193937627c369488259e99da5a9f0a87497fa6696a5dd6ce08
+
+TST: 12
+SK:  a980f892db13c99a3e8971e965b2ff3d41eafd54093bc9f34d1fd22d84115bb6
+PK:  44b57ee30cdb55829d0a5d4f046baef078f1e97a7f21b62d75f8e96ea139c35f
+MSG: 3486f68848a65a0eb5507d
+SIG: 77d389e599630d934076329583cd4105a649a9292abc44cd28c40000c8e2f5ac7660a81c85b72af8452d7d25c070861dae91601c7803d656531650dd4e5c4100
+
+TST: 13
+SK:  5b5a619f8ce1c66d7ce26e5a2ae7b0c04febcd346d286c929e19d0d5973bfef9
+PK:  6fe83693d011d111131c4f3fbaaa40a9d3d76b30012ff73bb0e39ec27ab18257
+MSG: 5a8d9d0a22357e6655f9c785
+SIG: 0f9ad9793033a2fa06614b277d37381e6d94f65ac2a5a94558d09ed6ce922258c1a567952e863ac94297aec3c0d0c8ddf71084e504860bb6ba27449b55adc40e
+
+TST: 14
+SK:  940c89fe40a81dafbdb2416d14ae469119869744410c3303bfaa0241dac57800
+PK:  a2eb8c0501e30bae0cf842d2bde8dec7386f6b7fc3981b8c57c9792bb94cf2dd
+MSG: b87d3813e03f58cf19fd0b6395
+SIG: d8bb64aad8c9955a115a793addd24f7f2b077648714f49c4694ec995b330d09d640df310f447fd7b6cb5c14f9fe9f490bcf8cfadbfd2169c8ac20d3b8af49a0c
+
+TST: 15
+SK:  9acad959d216212d789a119252ebfe0c96512a23c73bd9f3b202292d6916a738
+PK:  cf3af898467a5b7a52d33d53bc037e2642a8da996903fc252217e9c033e2f291
+MSG: 55c7fa434f5ed8cdec2b7aeac173
+SIG: 6ee3fe81e23c60eb2312b2006b3b25e6838e02106623f844c44edb8dafd66ab0671087fd195df5b8f58a1d6e52af42908053d55c7321010092748795ef94cf06
+
+TST: 16
+SK:  d5aeee41eeb0e9d1bf8337f939587ebe296161e6bf5209f591ec939e1440c300
+PK:  fd2a565723163e29f53c9de3d5e8fbe36a7ab66e1439ec4eae9c0a604af291a5
+MSG: 0a688e79be24f866286d4646b5d81c
+SIG: f68d04847e5b249737899c014d31c805c5007a62c0a10d50bb1538c5f35503951fbc1e08682f2cc0c92efe8f4985dec61dcbd54d4b94a22547d24451271c8b00
+
+TST: 17
+SK:  0a47d10452ae2febec518a1c7c362890c3fc1a49d34b03b6467d35c904a8362d
+PK:  34e5a8508c4743746962c066e4badea2201b8ab484de5c4f94476ccd2143955b
+MSG: c942fa7ac6b23ab7ff612fdc8e68ef39
+SIG: 2a3d27dc40d0a8127949a3b7f908b3688f63b7f14f651aacd715940bdbe27a0809aac142f47ab0e1e44fa490ba87ce5392f33a891539caf1ef4c367cae54500c
+
+TST: 18
+SK:  f8148f7506b775ef46fdc8e8c756516812d47d6cfbfa318c27c9a22641e56f17
+PK:  0445e456dacc7d5b0bbed23c8200cdb74bdcb03e4c7b73f0a2b9b46eac5d4372
+MSG: 7368724a5b0efb57d28d97622dbde725af
+SIG: 3653ccb21219202b8436fb41a32ba2618c4a133431e6e63463ceb3b6106c4d56e1d2ba165ba76eaad3dc39bffb130f1de3d8e6427db5b71938db4e272bc3e20b
+
+TST: 19
+SK:  77f88691c4eff23ebb7364947092951a5ff3f10785b417e918823a552dab7c75
+PK:  74d29127f199d86a8676aec33b4ce3f225ccb191f52c191ccd1e8cca65213a6b
+MSG: bd8e05033f3a8bcdcbf4beceb70901c82e31
+SIG: fbe929d743a03c17910575492f3092ee2a2bf14a60a3fcacec74a58c7334510fc262db582791322d6c8c41f1700adb80027ecabc14270b703444ae3ee7623e0a
+
+TST: 20
+SK:  ab6f7aee6a0837b334ba5eb1b2ad7fcecfab7e323cab187fe2e0a95d80eff132
+PK:  5b96dca497875bf9664c5e75facf3f9bc54bae913d66ca15ee85f1491ca24d2c
+MSG: 8171456f8b907189b1d779e26bc5afbb08c67a
+SIG: 73bca64e9dd0db88138eedfafcea8f5436cfb74bfb0e7733cf349baa0c49775c56d5934e1d38e36f39b7c5beb0a836510c45126f8ec4b6810519905b0ca07c09
+
+TST: 21
+SK:  8d135de7c8411bbdbd1b31e5dc678f2ac7109e792b60f38cd24936e8a898c32d
+PK:  1ca281938529896535a7714e3584085b86ef9fec723f42819fc8dd5d8c00817f
+MSG: 8ba6a4c9a15a244a9c26bb2a59b1026f21348b49
+SIG: a1adc2bc6a2d980662677e7fdff6424de7dba50f5795ca90fdf3e96e256f3285cac71d3360482e993d0294ba4ec7440c61affdf35fe83e6e04263937db93f105
+
+TST: 22
+SK:  0e765d720e705f9366c1ab8c3fa84c9a44370c06969f803296884b2846a652a4
+PK:  7fae45dd0a05971026d410bc497af5be7d0827a82a145c203f625dfcb8b03ba8
+MSG: 1d566a6232bbaab3e6d8804bb518a498ed0f904986
+SIG: bb61cf84de61862207c6a455258bc4db4e15eea0317ff88718b882a06b5cf6ec6fd20c5a269e5d5c805bafbcc579e2590af414c7c227273c102a10070cdfe80f
+
+TST: 23
+SK:  db36e326d676c2d19cc8fe0c14b709202ecfc761d27089eb6ea4b1bb021ecfa7
+PK:  48359b850d23f0715d94bb8bb75e7e14322eaf14f06f28a805403fbda002fc85
+MSG: 1b0afb0ac4ba9ab7b7172cddc9eb42bba1a64bce47d4
+SIG: b6dcd09989dfbac54322a3ce87876e1d62134da998c79d24b50bd7a6a797d86a0e14dc9d7491d6c14a673c652cfbec9f962a38c945da3b2f0879d0b68a921300
+
+TST: 24
+SK:  c89955e0f7741d905df0730b3dc2b0ce1a13134e44fef3d40d60c020ef19df77
+PK:  fdb30673402faf1c8033714f3517e47cc0f91fe70cf3836d6c23636e3fd2287c
+MSG: 507c94c8820d2a5793cbf3442b3d71936f35fe3afef316
+SIG: 7ef66e5e86f2360848e0014e94880ae2920ad8a3185a46b35d1e07dea8fa8ae4f6b843ba174d99fa7986654a0891c12a794455669375bf92af4cc2770b579e0c
+
+TST: 25
+SK:  4e62627fc221142478aee7f00781f817f662e3b75db29bb14ab47cf8e84104d6
+PK:  b1d39801892027d58a8c64335163195893bfc1b61dbeca3260497e1f30371107
+MSG: d3d615a8472d9962bb70c5b5466a3d983a4811046e2a0ef5
+SIG: 836afa764d9c48aa4770a4388b654e97b3c16f082967febca27f2fc47ddfd9244b03cfc729698acf5109704346b60b230f255430089ddc56912399d1122de70a
+
+TST: 26
+SK:  6b83d7da8908c3e7205b39864b56e5f3e17196a3fc9c2f5805aad0f5554c142d
+PK:  d0c846f97fe28585c0ee159015d64c56311c886eddcc185d296dbb165d2625d6
+MSG: 6ada80b6fa84f7034920789e8536b82d5e4678059aed27f71c
+SIG: 16e462a29a6dd498685a3718b3eed00cc1598601ee47820486032d6b9acc9bf89f57684e08d8c0f05589cda2882a05dc4c63f9d0431d6552710812433003bc08
+
+TST: 27
+SK:  19a91fe23a4e9e33ecc474878f57c64cf154b394203487a7035e1ad9cd697b0d
+PK:  2bf32ba142ba4622d8f3e29ecd85eea07b9c47be9d64412c9b510b27dd218b23
+MSG: 82cb53c4d5a013bae5070759ec06c3c6955ab7a4050958ec328c
+SIG: 881f5b8c5a030df0f75b6634b070dd27bd1ee3c08738ae349338b3ee6469bbf9760b13578a237d5182535ede121283027a90b5f865d63a6537dca07b44049a0f
+
+TST: 28
+SK:  1d5b8cb6215c18141666baeefcf5d69dad5bea9a3493dddaa357a4397a13d4de
+PK:  94d23d977c33e49e5e4992c68f25ec99a27c41ce6b91f2bfa0cd8292fe962835
+MSG: a9a8cbb0ad585124e522abbfb40533bdd6f49347b55b18e8558cb0
+SIG: 3acd39bec8c3cd2b44299722b5850a0400c1443590fd4861d59aae7496acb3df73fc3fdf7969ae5f50ba47dddc435246e5fd376f6b891cd4c2caf5d614b6170c
+
+TST: 29
+SK:  6a91b3227c472299089bdce9356e726a40efd840f11002708b7ee55b64105ac2
+PK:  9d084aa8b97a6b9bafa496dbc6f76f3306a116c9d917e681520a0f914369427e
+MSG: 5cb6f9aa59b80eca14f6a68fb40cf07b794e75171fba96262c1c6adc
+SIG: f5875423781b66216cb5e8998de5d9ffc29d1d67107054ace3374503a9c3ef811577f269de81296744bd706f1ac478caf09b54cdf871b3f802bd57f9a6cb9101
+
+TST: 30
+SK:  93eaa854d791f05372ce72b94fc6503b2ff8ae6819e6a21afe825e27ada9e4fb
+PK:  16cee8a3f2631834c88b670897ff0b08ce90cc147b4593b3f1f403727f7e7ad5
+MSG: 32fe27994124202153b5c70d3813fdee9c2aa6e7dc743d4d535f1840a5
+SIG: d834197c1a3080614e0a5fa0aaaa808824f21c38d692e6ffbd200f7dfb3c8f44402a7382180b98ad0afc8eec1a02acecf3cb7fde627b9f18111f260ab1db9a07
+
+TST: 31
+SK:  941cac69fb7b1815c57bb987c4d6c2ad2c35d5f9a3182a79d4ba13eab253a8ad
+PK:  23be323c562dfd71ce65f5bba56a74a3a6dfc36b573d2f94f635c7f9b4fd5a5b
+MSG: bb3172795710fe00054d3b5dfef8a11623582da68bf8e46d72d27cece2aa
+SIG: 0f8fad1e6bde771b4f5420eac75c378bae6db5ac6650cd2bc210c1823b432b48e016b10595458ffab92f7a8989b293ceb8dfed6c243a2038fc06652aaaf16f02
+
+TST: 32
+SK:  1acdbb793b0384934627470d795c3d1dd4d79cea59ef983f295b9b59179cbb28
+PK:  3f60c7541afa76c019cf5aa82dcdb088ed9e4ed9780514aefb379dabc844f31a
+MSG: 7cf34f75c3dac9a804d0fcd09eba9b29c9484e8a018fa9e073042df88e3c56
+SIG: be71ef4806cb041d885effd9e6b0fbb73d65d7cdec47a89c8a994892f4e55a568c4cc78d61f901e80dbb628b86a23ccd594e712b57fa94c2d67ec26634878507
+
+TST: 33
+SK:  8ed7a797b9cea8a8370d419136bcdf683b759d2e3c6947f17e13e2485aa9d420
+PK:  b49f3a78b1c6a7fca8f3466f33bc0e929f01fba04306c2a7465f46c3759316d9
+MSG: a750c232933dc14b1184d86d8b4ce72e16d69744ba69818b6ac33b1d823bb2c3
+SIG: 04266c033b91c1322ceb3446c901ffcf3cc40c4034e887c9597ca1893ba7330becbbd8b48142ef35c012c6ba51a66df9308cb6268ad6b1e4b03e70102495790b
+
+TST: 34
+SK:  f2ab396fe8906e3e5633e99cabcd5b09df0859b516230b1e0450b580b65f616c
+PK:  8ea074245159a116aa7122a25ec16b891d625a68f33660423908f6bdc44f8c1b
+MSG: 5a44e34b746c5fd1898d552ab354d28fb4713856d7697dd63eb9bd6b99c280e187
+SIG: a06a23d982d81ab883aae230adbc368a6a9977f003cebb00d4c2e4018490191a84d3a282fdbfb2fc88046e62de43e15fb575336b3c8b77d19ce6a009ce51f50c
+
+TST: 35
+SK:  550a41c013f79bab8f06e43ad1836d51312736a9713806fafe6645219eaa1f9d
+PK:  af6b7145474dc9954b9af93a9cdb34449d5b7c651c824d24e230b90033ce59c0
+MSG: 8bc4185e50e57d5f87f47515fe2b1837d585f0aae9e1ca383b3ec908884bb900ff27
+SIG: 16dc1e2b9fa909eefdc277ba16ebe207b8da5e91143cde78c5047a89f681c33c4e4e3428d5c928095903a811ec002d52a39ed7f8b3fe1927200c6dd0b9ab3e04
+
+TST: 36
+SK:  19ac3e272438c72ddf7b881964867cb3b31ff4c793bb7ea154613c1db068cb7e
+PK:  f85b80e050a1b9620db138bfc9e100327e25c257c59217b601f1f6ac9a413d3f
+MSG: 95872d5f789f95484e30cbb0e114028953b16f5c6a8d9f65c003a83543beaa46b38645
+SIG: ea855d781cbea4682e350173cb89e8619ccfddb97cdce16f9a2f6f6892f46dbe68e04b12b8d88689a7a31670cdff409af98a93b49a34537b6aa009d2eb8b4701
+
+TST: 37
+SK:  ca267de96c93c238fafb1279812059ab93ac03059657fd994f8fa5a09239c821
+PK:  017370c879090a81c7f272c2fc80e3aac2bc603fcb379afc98691160ab745b26
+MSG: e05f71e4e49a72ec550c44a3b85aca8f20ff26c3ee94a80f1b431c7d154ec9603ee02531
+SIG: ac957f82335aa7141e96b59d63e3ccee95c3a2c47d026540c2af42dc9533d5fd81827d1679ad187aeaf37834915e75b147a9286806c8017516ba43dd051a5e0c
+
+TST: 38
+SK:  3dff5e899475e7e91dd261322fab09980c52970de1da6e2e201660cc4fce7032
+PK:  f30162bac98447c4042fac05da448034629be2c6a58d30dfd578ba9fb5e3930b
+MSG: 938f0e77621bf3ea52c7c4911c5157c2d8a2a858093ef16aa9b107e69d98037ba139a3c382
+SIG: 5efe7a92ff9623089b3e3b78f352115366e26ba3fb1a416209bc029e9cadccd9f4affa333555a8f3a35a9d0f7c34b292cae77ec96fa3adfcaadee2d9ced8f805
+
+TST: 39
+SK:  9a6b847864e70cfe8ba6ab22fa0ca308c0cc8bec7141fbcaa3b81f5d1e1cfcfc
+PK:  34ad0fbdb2566507a81c2b1f8aa8f53dccaa64cc87ada91b903e900d07eee930
+MSG: 838367471183c71f7e717724f89d401c3ad9863fd9cc7aa3cf33d3c529860cb581f3093d87da
+SIG: 2ab255169c489c54c732232e37c87349d486b1eba20509dbabe7fed329ef08fd75ba1cd145e67b2ea26cb5cc51cab343eeb085fe1fd7b0ec4c6afcd9b979f905
+
+TST: 40
+SK:  575be07afca5d063c238cd9b8028772cc49cda34471432a2e166e096e2219efc
+PK:  94e5eb4d5024f49d7ebf79817c8de11497dc2b55622a51ae123ffc749dbb16e0
+MSG: 33e5918b66d33d55fe717ca34383eae78f0af82889caf6696e1ac9d95d1ffb32cba755f9e3503e
+SIG: 58271d44236f3b98c58fd7ae0d2f49ef2b6e3affdb225aa3ba555f0e11cc53c23ad19baf24346590d05d7d5390582082cf94d39cad6530ab93d13efb39279506
+
+TST: 41
+SK:  15ffb45514d43444d61fcb105e30e135fd268523dda20b82758b179423110441
+PK:  1772c5abc2d23fd2f9d1c3257be7bc3c1cd79cee40844b749b3a7743d2f964b8
+MSG: da9c5559d0ea51d255b6bd9d7638b876472f942b330fc0e2b30aea68d77368fce4948272991d257e
+SIG: 6828cd7624e793b8a4ceb96d3c2a975bf773e5ff6645f353614058621e58835289e7f31f42dfe6af6d736f2644511e320c0fa698582a79778d18730ed3e8cb08
+
+TST: 42
+SK:  fe0568642943b2e1afbfd1f10fe8df87a4236bea40dce742072cb21886eec1fa
+PK:  299ebd1f13177dbdb66a912bbf712038fdf73b06c3ac020c7b19126755d47f61
+MSG: c59d0862ec1c9746abcc3cf83c9eeba2c7082a036a8cb57ce487e763492796d47e6e063a0c1feccc2d
+SIG: d59e6dfcc6d7e3e2c58dec81e985d245e681acf6594a23c59214f7bed8015d813c7682b60b3583440311e72a8665ba2c96dec23ce826e160127e18132b030404
+
+TST: 43
+SK:  5ecb16c2df27c8cf58e436a9d3affbd58e9538a92659a0f97c4c4f994635a8ca
+PK:  da768b20c437dd3aa5f84bb6a077ffa34ab68501c5352b5cc3fdce7fe6c2398d
+MSG: 56f1329d9a6be25a6159c72f12688dc8314e85dd9e7e4dc05bbecb7729e023c86f8e0937353f27c7ede9
+SIG: 1c723a20c6772426a670e4d5c4a97c6ebe9147f71bb0a415631e44406e290322e4ca977d348fe7856a8edc235d0fe95f7ed91aefddf28a77e2c7dbfd8f552f0a
+
+TST: 44
+SK:  d599d637b3c30a82a9984e2f758497d144de6f06b9fba04dd40fd949039d7c84
+PK:  6791d8ce50a44689fc178727c5c3a1c959fbeed74ef7d8e7bd3c1ab4da31c51f
+MSG: a7c04e8ba75d0a03d8b166ad7a1d77e1b91c7aaf7befdd99311fc3c54a684ddd971d5b3211c3eeaff1e54e
+SIG: ebf10d9ac7c96108140e7def6fe9533d727646ff5b3af273c1df95762a66f32b65a09634d013f54b5dd6011f91bc336ca8b355ce33f8cfbec2535a4c427f8205
+
+TST: 45
+SK:  30ab8232fa7018f0ce6c39bd8f782fe2e159758bb0f2f4386c7f28cfd2c85898
+PK:  ecfb6a2bd42f31b61250ba5de7e46b4719afdfbc660db71a7bd1df7b0a3abe37
+MSG: 63b80b7956acbecf0c35e9ab06b914b0c7014fe1a4bbc0217240c1a33095d707953ed77b15d211adaf9b97dc
+SIG: 9af885344cc7239498f712df80bc01b80638291ed4a1d28baa5545017a72e2f65649ccf9603da6eb5bfab9f5543a6ca4a7af3866153c76bf66bf95def615b00c
+
+TST: 46
+SK:  0ddcdc872c7b748d40efe96c2881ae189d87f56148ed8af3ebbbc80324e38bdd
+PK:  588ddadcbcedf40df0e9697d8bb277c7bb1498fa1d26ce0a835a760b92ca7c85
+MSG: 65641cd402add8bf3d1d67dbeb6d41debfbef67e4317c35b0a6d5bbbae0e034de7d670ba1413d056f2d6f1de12
+SIG: c179c09456e235fe24105afa6e8ec04637f8f943817cd098ba95387f9653b2add181a31447d92d1a1ddf1ceb0db62118de9dffb7dcd2424057cbdff5d41d0403
+
+TST: 47
+SK:  89f0d68299ba0a5a83f248ae0c169f8e3849a9b47bd4549884305c9912b46603
+PK:  aba3e795aab2012acceadd7b3bd9daeeed6ff5258bdcd7c93699c2a3836e3832
+MSG: 4f1846dd7ad50e545d4cfbffbb1dc2ff145dc123754d08af4e44ecc0bc8c91411388bc7653e2d893d1eac2107d05
+SIG: 2c691fa8d487ce20d5d2fa41559116e0bbf4397cf5240e152556183541d66cf753582401a4388d390339dbef4d384743caa346f55f8daba68ba7b9131a8a6e0b
+
+TST: 48
+SK:  0a3c1844e2db070fb24e3c95cb1cc6714ef84e2ccd2b9dd2f1460ebf7ecf13b1
+PK:  72e409937e0610eb5c20b326dc6ea1bbbc0406701c5cd67d1fbde09192b07c01
+MSG: 4c8274d0ed1f74e2c86c08d955bde55b2d54327e82062a1f71f70d536fdc8722cdead7d22aaead2bfaa1ad00b82957
+SIG: 87f7fdf46095201e877a588fe3e5aaf476bd63138d8a878b89d6ac60631b3458b9d41a3c61a588e1db8d29a5968981b018776c588780922f5aa732ba6379dd05
+
+TST: 49
+SK:  c8d7a8818b98dfdb20839c871cb5c48e9e9470ca3ad35ba2613a5d3199c8ab23
+PK:  90d2efbba4d43e6b2b992ca16083dbcfa2b322383907b0ee75f3e95845d3c47f
+MSG: 783e33c3acbdbb36e819f544a7781d83fc283d3309f5d3d12c8dcd6b0b3d0e89e38cfd3b4d0885661ca547fb9764abff
+SIG: fa2e994421aef1d5856674813d05cbd2cf84ef5eb424af6ecd0dc6fdbdc2fe605fe985883312ecf34f59bfb2f1c9149e5b9cc9ecda05b2731130f3ed28ddae0b
+
+TST: 50
+SK:  b482703612d0c586f76cfcb21cfd2103c957251504a8c0ac4c86c9c6f3e429ff
+PK:  fd711dc7dd3b1dfb9df9704be3e6b26f587fe7dd7ba456a91ba43fe51aec09ad
+MSG: 29d77acfd99c7a0070a88feb6247a2bce9984fe3e6fbf19d4045042a21ab26cbd771e184a9a75f316b648c6920db92b87b
+SIG: 58832bdeb26feafc31b46277cf3fb5d7a17dfb7ccd9b1f58ecbe6feb979666828f239ba4d75219260ecac0acf40f0e5e2590f4caa16bbbcd8a155d347967a607
+
+TST: 51
+SK:  84e50dd9a0f197e3893c38dbd91fafc344c1776d3a400e2f0f0ee7aa829eb8a2
+PK:  2c50f870ee48b36b0ac2f8a5f336fb090b113050dbcc25e078200a6e16153eea
+MSG: f3992cde6493e671f1e129ddca8038b0abdb77bb9035f9f8be54bd5d68c1aeff724ff47d29344391dc536166b8671cbbf123
+SIG: 69e6a4491a63837316e86a5f4ba7cd0d731ecc58f1d0a264c67c89befdd8d3829d8de13b33cc0bf513931715c7809657e2bfb960e5c764c971d733746093e500
+
+TST: 52
+SK:  b322d46577a2a991a4d1698287832a39c487ef776b4bff037a05c7f1812bdeec
+PK:  eb2bcadfd3eec2986baff32b98e7c4dbf03ff95d8ad5ff9aa9506e5472ff845f
+MSG: 19f1bf5dcf1750c611f1c4a2865200504d82298edd72671f62a7b1471ac3d4a30f7de9e5da4108c52a4ce70a3e114a52a3b3c5
+SIG: c7b55137317ca21e33489ff6a9bfab97c855dc6f85684a70a9125a261b56d5e6f149c5774d734f2d8debfc77b721896a8267c23768e9badb910eef83ec258802
+
+TST: 53
+SK:  960cab5034b9838d098d2dcbf4364bec16d388f6376d73a6273b70f82bbc98c0
+PK:  5e3c19f2415acf729f829a4ebd5c40e1a6bc9fbca95703a9376087ed0937e51a
+MSG: f8b21962447b0a8f2e4279de411bea128e0be44b6915e6cda88341a68a0d818357db938eac73e0af6d31206b3948f8c48a447308
+SIG: 27d4c3a1811ef9d4360b3bdd133c2ccc30d02c2f248215776cb07ee4177f9b13fc42dd70a6c2fed8f225c7663c7f182e7ee8eccff20dc7b0e1d5834ec5b1ea01
+
+TST: 54
+SK:  eb77b2638f23eebc82efe45ee9e5a0326637401e663ed029699b21e6443fb48e
+PK:  9ef27608961ac711de71a6e2d4d4663ea3ecd42fb7e4e8627c39622df4af0bbc
+MSG: 99e3d00934003ebafc3e9fdb687b0f5ff9d5782a4b1f56b9700046c077915602c3134e22fc90ed7e690fddd4433e2034dcb2dc99ab
+SIG: 18dc56d7bd9acd4f4daa78540b4ac8ff7aa9815f45a0bba370731a14eaabe96df8b5f37dbf8eae4cb15a64b244651e59d6a3d6761d9e3c50f2d0cbb09c05ec06
+
+TST: 55
+SK:  b625aa89d3f7308715427b6c39bbac58effd3a0fb7316f7a22b99ee5922f2dc9
+PK:  65a99c3e16fea894ec33c6b20d9105e2a04e2764a4769d9bbd4d8bacfeab4a2e
+MSG: e07241dbd3adbe610bbe4d005dd46732a4c25086ecb8ec29cd7bca116e1bf9f53bfbf3e11fa49018d39ff1154a06668ef7df5c678e6a
+SIG: 01bb901d83b8b682d3614af46a807ba2691358feb775325d3423f549ff0aa5757e4e1a74e9c70f9721d8f354b319d4f4a1d91445c870fd0ffb94fed64664730d
+
+TST: 56
+SK:  b1c9f8bd03fe82e78f5c0fb06450f27dacdf716434db268275df3e1dc177af42
+PK:  7fc88b1f7b3f11c629be671c21621f5c10672fafc8492da885742059ee6774cf
+MSG: 331da7a9c1f87b2ac91ee3b86d06c29163c05ed6f8d8a9725b471b7db0d6acec7f0f702487163f5eda020ca5b493f399e1c8d308c3c0c2
+SIG: 4b229951ef262f16978f7914bc672e7226c5f8379d2778c5a2dc0a2650869f7acfbd0bcd30fdb0619bb44fc1ae5939b87cc318133009c20395b6c7eb98107701
+
+TST: 57
+SK:  6d8cdb2e075f3a2f86137214cb236ceb89a6728bb4a200806bf3557fb78fac69
+PK:  57a04c7a5113cddfe49a4c124691d46c1f9cdc8f343f9dcb72a1330aeca71fda
+MSG: 7f318dbd121c08bfddfeff4f6aff4e45793251f8abf658403358238984360054f2a862c5bb83ed89025d2014a7a0cee50da3cb0e76bbb6bf
+SIG: a6cbc947f9c87d1455cf1a708528c090f11ecee4855d1dbaadf47454a4de55fa4ce84b36d73a5b5f8f59298ccf21992df492ef34163d87753b7e9d32f2c3660b
+
+TST: 58
+SK:  47adc6d6bf571ee9570ca0f75b604ac43e303e4ab339ca9b53cacc5be45b2ccb
+PK:  a3f527a1c1f17dfeed92277347c9f98ab475de1755b0ab546b8a15d01b9bd0be
+MSG: ce497c5ff5a77990b7d8f8699eb1f5d8c0582f70cb7ac5c54d9d924913278bc654d37ea227590e15202217fc98dac4c0f3be2183d133315739
+SIG: 4e8c318343c306adbba60c92b75cb0569b9219d8a86e5d57752ed235fc109a43c2cf4e942cacf297279fbb28675347e08027722a4eb7395e00a17495d32edf0b
+
+TST: 59
+SK:  3c19b50b0fe47961719c381d0d8da9b9869d312f13e3298b97fb22f0af29cbbe
+PK:  0f7eda091499625e2bae8536ea35cda5483bd16a9c7e416b341d6f2c83343612
+MSG: 8ddcd63043f55ec3bfc83dceae69d8f8b32f4cdb6e2aebd94b4314f8fe7287dcb62732c9052e7557fe63534338efb5b6254c5d41d2690cf5144f
+SIG: efbd41f26a5d62685516f882b6ec74e0d5a71830d203c231248f26e99a9c6578ec900d68cdb8fa7216ad0d24f9ecbc9ffa655351666582f626645395a31fa704
+
+TST: 60
+SK:  34e1e9d539107eb86b393a5ccea1496d35bc7d5e9a8c5159d957e4e5852b3eb0
+PK:  0ecb2601d5f7047428e9f909883a12420085f04ee2a88b6d95d3d7f2c932bd76
+MSG: a6d4d0542cfe0d240a90507debacabce7cbbd48732353f4fad82c7bb7dbd9df8e7d9a16980a45186d8786c5ef65445bcc5b2ad5f660ffc7c8eaac0
+SIG: 32d22904d3e7012d6f5a441b0b4228064a5cf95b723a66b048a087ecd55920c31c204c3f2006891a85dd1932e3f1d614cfd633b5e63291c6d8166f3011431e09
+
+TST: 61
+SK:  49dd473ede6aa3c866824a40ada4996c239a20d84c9365e4f0a4554f8031b9cf
+PK:  788de540544d3feb0c919240b390729be487e94b64ad973eb65b4669ecf23501
+MSG: 3a53594f3fba03029318f512b084a071ebd60baec7f55b028dc73bfc9c74e0ca496bf819dd92ab61cd8b74be3c0d6dcd128efc5ed3342cba124f726c
+SIG: d2fde02791e720852507faa7c3789040d9ef86646321f313ac557f4002491542dd67d05c6990cdb0d495501fbc5d5188bfbb84dc1bf6098bee0603a47fc2690f
+
+TST: 62
+SK:  331c64da482b6b551373c36481a02d8136ecadbb01ab114b4470bf41607ac571
+PK:  52a00d96a3148b4726692d9eff89160ea9f99a5cc4389f361fed0bb16a42d521
+MSG: 20e1d05a0d5b32cc8150b8116cef39659dd5fb443ab15600f78e5b49c45326d9323f2850a63c3808859495ae273f58a51e9de9a145d774b40ba9d753d3
+SIG: 22c99aa946ead39ac7997562810c01c20b46bd610645bd2d56dcdcbaacc5452c74fbf4b8b1813b0e94c30d808ce5498e61d4f7ccbb4cc5f04dfc6140825a9600
+
+TST: 63
+SK:  5c0b96f2af8712122cf743c8f8dc77b6cd5570a7de13297bb3dde1886213cce2
+PK:  0510eaf57d7301b0e1d527039bf4c6e292300a3a61b4765434f3203c100351b1
+MSG: 54e0caa8e63919ca614b2bfd308ccfe50c9ea888e1ee4446d682cb5034627f97b05392c04e835556c31c52816a48e4fb196693206b8afb4408662b3cb575
+SIG: 06e5d8436ac7705b3a90f1631cdd38ec1a3fa49778a9b9f2fa5ebea4e7d560ada7dd26ff42fafa8ba420323742761aca6904940dc21bbef63ff72daab45d430b
+
+TST: 64
+SK:  de84f2435f78dedb87da18194ff6a336f08111150def901c1ac418146eb7b54a
+PK:  d3a92bbaa4d63af79c2226a7236e6427428df8b362427f873023b22d2f5e03f2
+MSG: 205135ec7f417c858072d5233fb36482d4906abd60a74a498c347ff248dfa2722ca74e879de33169fadc7cd44d6c94a17d16e1e630824ba3e0df22ed68eaab
+SIG: 471ebc973cfdaceec07279307368b73be35bc6f8d8312b70150567369096706dc471126c3576f9f0eb550df5ac6a525181110029dd1fc11174d1aaced48d630f
+
+TST: 65
+SK:  ba4d6e67b2ce67a1e44326494044f37a442f3b81725bc1f9341462718b55ee20
+PK:  f73fa076f84b6db675a5fda5ad67e351a41e8e7f29add16809ca010387e9c6cc
+MSG: 4bafdac9099d4057ed6dd08bcaee8756e9a40f2cb9598020eb95019528409bbea38b384a59f119f57297bfb2fa142fc7bb1d90dbddde772bcde48c5670d5fa13
+SIG: 57b9d2a711207f837421bae7dd48eaa18eab1a9a70a0f1305806fee17b458f3a0964b302d1834d3e0ac9e8496f000b77f0083b41f8a957e632fbc7840eee6a06
+
+TST: 66
+SK:  0d131c45aea6f3a4e1b9a2cf60c55104587efaa846b222bf0a7b74ce7a3f63b6
+PK:  3c6729dbe93b499c4e614a2f21beb729438d498e1ac8d14cbad9717a5dbd97cd
+MSG: b4291d08b88fb2f7b8f99d0dce40079fcbab718bbd8f4e8eabc3c1428b6a071fb2a3c8eba1cacccfa871b365c708bef2685bc13e6b80bc14a5f249170ffc56d014
+SIG: a9c5ee86fb06d9e46b379c32dda7c92c9c13db274dc24116fbdd878696045488cc75a52fff67d1a5113d06e333ac67ff664b3f2a405fa1d14dd5bbb97409b606
+
+TST: 67
+SK:  a75e3b6b4170e444781be4eeac3e0fdaa4b4356f705486bcb071a325ae071fba
+PK:  993d38a7d72f0aee15ff6f4fdc37ca7724fd1373a3766b275dbc77e647980e0a
+MSG: 4037866f6548b01cc6bcf3a940e3945aa2d188b4b7f182aa77ec4d6b0428ab5b84d85df192a5a38ada089d76fa26bf67736a7041a5eb8f0c5719eb396693c45160f8
+SIG: a5db4d3d3329abe3697959e6b5947ea8601b03ef8e1d6fe202144931272ca0a09b5eb0f390572ea7ef03c6131e9de5f16bf0b034244f7e104ff5311bbf663a0d
+
+TST: 68
+SK:  bcbcf561ecc05a41c7d7e55e696d32ce39b4d03c1f5f3f3a8927fe5e62e844b2
+PK:  4ddf53fad6a7a9ed30f3afecca136fd7843b72c243090891ae4021a32cadff1a
+MSG: 6f6716b6784740980aebc3248807e31c1286ac7b681c00b66c88ff7a336d441fa5c3eb256d20cf6d1ac92ccfe4be6dcc41b1aff846d360c243001cabdfbf1a9b240455
+SIG: 9ff15115f6661f3211d7a40764967629ba6a5263951bdc3c6a4c90d070f7be00024b80d83b6bc27587fcff5f5ccc0eb3cde1497cf56895147a063f61f08adf0b
+
+TST: 69
+SK:  210532805fa9cc9be916d213cac374e3cd6fc2602a544d0c1ce29d30105d69ab
+PK:  10699e499be99e2b11b98f6f86b67cdc4ccf69f3c53ce094875647d2d0d0ecc5
+MSG: 9fc4d28cfd25e6c0c5e724e19ca39d71e53bf4aa2796c54c3351f108fc70f2611a62e0ab90af6ade5216788e9eb2a873059b1e79d7d59debd68f2d4d80ffe31bf74b928c
+SIG: 4c2d31d5bbc42e026dc1e079ecc4dd072c5d2cce65e3db8d8a1dd9057faa0371727f727231a0f060fa27097533b6db3b8f6252f2793d75662caadf5f0fcc710e
+
+TST: 70
+SK:  185d64b69479e0ba0a5844a10ad84125ba11c4b40d63eda2c57afc7e019c8e0c
+PK:  a5764f6398a5ae2266a38f9714533c4bbd8d07826f63e204cbac374b0acef1bd
+MSG: 4a0824fe70d4315413d0a0cafbf4f5fe117d5e07e1c3a4effb9d0ae91490234878ccf6792a91f68c6a520de16071f08abe35dc5ea428f1957b663371ce24c609dd55b8f493
+SIG: 43e0387da5ba09a190f6e7b2680578d889769bcc445e5ef571b492871c155c5b9f620bfacfbf2df1fd87444604b71b2e237baaa7ee2093ede4a601edf883e307
+
+TST: 71
+SK:  cfa9d9164b3c4f6f722635d2066cd7ea5e5533d2c74f8add669c371faa476426
+PK:  41169a66f9a63f285782a6c2db81cc3f70b3ada21a68c84745c88a74c3b0a2de
+MSG: 757621b1675db7cacef7f2782587ff3af51a3ef2f4bcf9279c4ce94002e1f00424bf0eb621982cc85cb4d171e564a0c2f6e3567a1aae2cddb7e9b25f47dc20a51050542969ca
+SIG: 01d7c9b5701af71e2f4877ffc9b7b5305f52816d4458e37e41c7719fac1d76a01fff3f50fe1a5875ccc3fb70001c947a33fc8b207de13572ccdb8ba98933ab01
+
+TST: 72
+SK:  1acb4a256c2f8993ca24de1e0014606d668b5e756032d269f1d24d351c8eea4a
+PK:  cbbdcd8cbc885ab43a057e5f9579f1161954159e7b562ea26cd9a43c88d3f96d
+MSG: c46a6d61aa0aed1c1d8547a70b89b7196475d5a4870881b1ecd0f0cb9c745f8a2adc8024e2dc55b53aa5d383a81aabc1a47e8d07d00b7f0b56ceddbfb1f424bb5c02184678a666
+SIG: 05aa76f7fe51892303d78914715995e7d768ff7714ce270f175e56af17ae018d3fa939f5f620de82bcd1549687b205c7871203e624238c4e309fab7f92fbaa05
+
+TST: 73
+SK:  ace3c46424823622979fc3a84a7da69c1d527d8312e8fb018375bd3a96c29c18
+PK:  937cf34136d9e1cce0de11b12c70cbfb7455448421e92c82e7c40934bff8c676
+MSG: a9f137bc9021bf105aee25be21cd9ee5b3547cf10cc5f98476fb588bd70e2d6d6b0834e842e4ee94303cf96b09c1715381b36e14a491b80f895ea421b8ec2b1d3c187e02935c5526
+SIG: feb8896dd3fe6001ffea171b37b788a69f7f850193a63406f56376dd263d099aef80ece67e2c43f40eca462c6b71e79406b18db74ae5d49844e3b132bc2a1307
+
+TST: 74
+SK:  88f681934e33c35c07dc6e5a832942ae3d59903ccde2f76ccb7587cea7ec41b6
+PK:  6a4e8aa5adb63d22fd7b14a26fdb03b7c8aa6ccd5a196f2c54b0465adb5092e1
+MSG: 6e8bac1f853b81fef94707e18cc61c6f0a9cbc2a41d078dcc83fc0229c7f8dbe6dbdd90854b1f1ae2b9f2b120b86a8786b4e78ce23ab86baaf88754af0f3d88881dae0bc5261bfd038
+SIG: 45b27bf1b9eac06b62b686f6d546563b2dfe5b175dbef32bf78c35a16c958a9d4f26d291de9bb2066c0a286113cc09172d40a36d4cbd951708860226eb30cd05
+
+TST: 75
+SK:  48050a6e0158f6ad253412e4497cff62d5ee555edffe59e4dc401522813295ce
+PK:  975e010abb9a3e56659137b0506057f283982f886ca172c7bc2c500ed9bd26c1
+MSG: ed6eec29fb7049dff707f0a4426ebc8f5b350e95870b9d6198c8139e9c3e1e409937d1a858a0dea482a5cb1a854ed3b5a9397acb63bff6b64039ef2eb1159e99858310bbbd86125c3e0e
+SIG: 7216ab60c35168187d0fce4753c86e80058d540b76bf95843a5898841060a99a44de6f439625a3f6365f59c377bf45909bbfef5c50b25f3194e5fbd34ea5e706
+
+TST: 76
+SK:  18d13d0c00e8e3386a5cfb30a9e79fe88b1861ed2d1201eb170038e194770403
+PK:  a4afc833401876090d9b880c41267d68cbbeeaa38afb20884e27328f3b7f535e
+MSG: 910f6c272dd97931ac47310d244cadb43251365e02ba9f6a5b3c3226be9d7d3a74a2ba4906e8e71a4bf3d3556ebdfc666cd6b12f20c4a00834b88fbb244575199286b0b9344cf334aff007
+SIG: 033988154c5d79d2510be83e778015dfe2fb85b8111f7ec139918b5400e3d656ee80a9f5c9072b5b467a5cc5a57cc8ad1062b5bff10862d9d369dde2cc966701
+
+TST: 77
+SK:  4adc8c28646a93a817293a14d29b48e2c6d712a68993547a5c5e4d1452acbc3a
+PK:  7f40473628f23fc0dff0021afd487740d4916a9122e6c97d36433e5ebf04f88c
+MSG: 09fb5501f1688f80a0ab9e22d778ae130acaf74d7f5185b4da198c6b9edac4302e2b753e578766e17d4056dc40d95cf4ca8bcc6565795e97d68bcda79fa77c493397716356164caab5d19cfd
+SIG: 6d3b4e90ec408311f9b15b9253d3d95c5d152620c260d56302555a8804a5104ba5e8d29ee108e764a64219297298ab7674bbca784dee28773b34e185a386c208
+
+TST: 78
+SK:  f26e1c84697a4908151b447dcf6c7c7a38b04081db9e7c7738e6fec900bed0c1
+PK:  a86e1422c1235ff8e1aa083470d5e42288cb007ab50e795dd0b4ff87394966c4
+MSG: 54ed47606a1487c2f900cefb6e899dbaf6c31cc88ebe3558b83b93f6d422c31e888e48e520eeaedd7e554a9cd40c2c519d533b6144cee484c389e976b1e4022b50e7dbb87ead7e541a2004daf7
+SIG: 44f3344b9566c9dfd22d6198e1cbf95d9e28f2982fc7f166ab25dda30c46f768c558e0394fb9ab3e1d4db4cf487c17641a13f3f48939e0c64827a75103c57406
+
+TST: 79
+SK:  cc0c33f3a86f5a17d30c186ce0f3b740bafa5fe3c7090f143541e2b2c1e534bc
+PK:  967a71c7cf9b82cc78cbe109104d8b438a8d1fd71d260d029046a9a4526866ff
+MSG: 1944e5e155d75e0d0be92e1be14cec370ad13791f2bfd40f271214e94fcf213c71bc20d7ce0c7584421ac4efc451883cc3f4956f21f73a4216720438bc38ff2cfdf3709905a50a9d94b1d9e7932b
+SIG: e277b3dd655c33ff75fa920af1fcc859401e6c7a6ef4c6bfbfac5069638f19ca115baf13c09c82af793facb6abd0cd58e8481b08c1b68ad7a2665c4a614a2806
+
+TST: 80
+SK:  f0bc979375a7073068dba7f6c094db6598b4e45df7d549583c22fded8048fa2e
+PK:  b42b6c57a78f1d90090a7181ab2ae09f426cbc2be96eb2cf27abc70d7d32a4b3
+MSG: 27ab3049b5c6351f6cfe38b13a059f5037257ee3d65d6079656856edc876ea081fd8a9480466f8839478088466f51ecbfaf2d65def25f0c4dd8d08588202812232f57945df8a6fa161ed8c0343b583
+SIG: 19dbc3027f9fae707deb76f588f9fd07aa8eae29bd4e1d04c2c984388286b3b122248a6c03ed67eca35df4db3dc1e4237f267892518497d9552a21de19b5140f
+
+TST: 81
+SK:  3022975f298c0ad5ddbe90954f20e63ae0c0d2704cf13c221f5b3720af4dba32
+PK:  b845bce38e26ab027b8247463d437a71bbddca2a2381d81fad4c297df9140bd5
+MSG: 9aa19a595d989378cdc06891887ef5f9c246e5f83c0b658710673e4e7db760c76354c4f5d1e90db04a23b4fb434c69384593d010e312b11d299c9f97482de887cecfe82ea723bca79a1bd64d03ef19ee
+SIG: ae14a860fad0051b3eb72b3721a82f7b9546b2867261e2b7b638979e2561bdeb89b600768f82450a66c8b0481283fa21cb6c53bde350effb68a7d1114bfdb203
+
+TST: 82
+SK:  0f710b6c481f71449589753312ef64932b4652ebe0e07597f7da1c4f3dcffb80
+PK:  6973ff2932ccddfc1d16c4c0da50c8b29fe6452d1ee84d52064ebf3d628d403e
+MSG: 85d85744ad55e9ef9a65ca91e85c8a4f80e4c58f8e4e9354e833986098b7d9fe9fdc0dedb0d75d2539fba00034fc0c2e84344d1edaa09d4f63d5546d67803dd6b54ddcc0b1d3f2582dd75289e31de42e69
+SIG: 02a8d26aee11420fb4f09d1163e14b867df7c6f6c8f8dc7a78034659f0401cad0aa90397efdd0704b798db1936503026e2a1adc297e27974d4be312a3753f804
+
+TST: 83
+SK:  7a05f121f60112dd16fee8c91bc2a11479f4b67ee33456042c8de167fc588017
+PK:  b3b05be989cea7197505d4b54335e5e1d77a4b52ba7282604bbc1cf6c4e87a6c
+MSG: d9c59e8cc4ede537be2122ab492a5b915a9b0a114b2ade356fc0457ef98722d5f567b86211e28369d14168ec4a3c804076e154adc70a668cf64a20d13cf190d115cd688d036e46938251df4964dc3517b10c
+SIG: d30ce8a322b450a2fb1afd329cec8559ccf112bd83965f9ec4736270a0914e061196bf5209778c9f8ccf39c4668bbf0e1363f81afe45dd74e80d5875ddbf6f01
+
+TST: 84
+SK:  bf381f8dfb5d0c6d64e416ac23e0d0fcb86ebb899b1d146abd911b92a7808eb6
+PK:  863fad8d1f1bc630a15f6fe8ecefe6b4497b60b21ae8830da46742045fef156f
+MSG: 8654f2f5c6dcd2cfcbb6ed8d2bc5fb5fec53e3effb0de65aac507fa56c897732395aa09946d3b6586a92edd6dc99315e1ba74c6a0247c4ba7760b948eb3c0932d9fe1f0e9fea6eb61a548a9ab48ffdf1547329
+SIG: 99b75378738fcac8067669e8509b5d2607e1ef76af9004e13fe5d3932df60b168216f58565340fa4d638055a89044ee7d45e2bd082a53382289a34700648980e
+
+TST: 85
+SK:  36983241a0a8e60ce02a61b3fafab15a7313a5a270d015b9c9ec070dc42deeda
+PK:  6647984d42b9a5b3b1afa3b7f8f49d4c2b05e38984e99cea8fd68235d2ae4627
+MSG: cebb9e404451818253c0392a4554ee7323c5d5b8b226775700b806ed5b91337916ea7ecbc3d4103fc65e5372ae7e5f9ba2d8f5aee24ccf6e631ae20c4af9b5f728cdf89e8189def1a5b3d35347aa203525ea1d2e
+SIG: ee37df8af422f91f85dfe43efe79f62378068ccdbaf3916eecbc3adfed0508bdebaf5ce06b3bc279f78087f0db8db3c6823edfb32c12217830be723d8872b30c
+
+TST: 86
+SK:  d06899f93a408dacb41c969718346f1e289bb5ea65e283ff79c705a074517c35
+PK:  46bf2a08a076c47d7f11b733f8141c355363ed85d7def26ba6a0ce15ac5f2be8
+MSG: 0864c39ac4fda8eb9048597bd40be0401021fd2dd3a3390a8facce984b260a13fa2c7cfc00d192fadf134a0ad5a181ee89eff0c795eaa0fbfe2f3b26115d07168db42ed21a51303b1958e4a42dc065b22ce48f17a6
+SIG: 6f89de92a66bc5f4144339124950bdf588144cb372f6736245351c9476becc59a258f9a933ffff2bef4b46cd1057395225799fd09dede6823db0e325dbc8140d
+
+TST: 87
+SK:  eebca7966970ee9f2cc4d74c6f1d8e0ebff7c45aebad349fb9f86df628dfff0e
+PK:  89101e0309f767e64ae9c98c4a5d8d2328fb3ef262d082f49b64ca209e1990f6
+MSG: 0fac790adb9f59e5cb0ddcb2b667172f2a21034d93bcaddf188606fa9e776db33a8fcc6bd7f5567883fc0de351aa9afaa36d2075b1ba853bada849b8661d5c8154e7b0afea656dd15e01a9c5ba21589b02f8fc5481c2
+SIG: 7d447ee5328c9fe7f11936cc42998754a56cd1d2a6951af4fee7c4a8eb319d4923707c793c55d79067f822d5b16bb5776e38dffabc67237a916a81a63339b003
+
+TST: 88
+SK:  3820b6b15939d0afe18c9cb3d9a2a08f167dd458eb6c7e3f1558b0c6db4c6890
+PK:  80b85c6559fea8b400e1999cc5bfed507ad7fc294cd9ba0ce2dd2584a91089b0
+MSG: 3e5ad92d44b40e8614d8087c9c743de0c0861a07f1f5146d71cac2f3740024e841cc2d46027cf5d261d3ee7c1875b39551017b5fb1468114fc3e098a899cdbd558b39f098e156b6e9801ebcdd65fed56dbfcaf2c8c787b
+SIG: 823ee2c0c8d87faa0ec0141e9ce08b51e57c839792d1fbd97a967207fd415849ebfb5dadb5a1dc2c0a8b7fc63fc354857b8c90c44720e13f45cd01e7aa23140c
+
+TST: 89
+SK:  0d20fa4a37ff30c4dcc3e44ea7ac501137e5807e9781330ac310982cc3d39dbd
+PK:  67bb0a01bc8617b491eff1a326c1c70f7d0c5b95a5ad48241aedce1c6f0883cf
+MSG: 35e0f4b4a517f9c7aa4514f03e6d65f19b27c62cc069f6bf07dd6378bd6afe2b766560006cbd5730a00919ed11191fb0c8dac56e153fc1cea4bdce5046cccb717759a4083e1c16f740763264cc804de0d0e1a4b5a23067af
+SIG: deab12ed82ba94b469ca98b66fa20444b4b7881c4f0f853409c9a1504a5b2b6d7860f26ada6bf73459b9cdb573c8017121338efa60f4148086d7a3a8ed59bb07
+
+TST: 90
+SK:  bee161881d819b370d240d509ba46b06fb828e20310d9f6b309780703e98927b
+PK:  10854380de89162bfb9f7835a2716a3a6e0265671b250b389d01c3bcc03736b8
+MSG: 5a6fe599b6b09b05c0ba6a622df3a92b3d376d24d04ea85ebe767bc2ec4d14e83e6937dc0b914b4809fdb607906841a6fd1dcdf61aaea8f9bb81b2ccaa32df412989ae53646680a71a211c8440eab0f1aec5e4fc00e6a2c96d
+SIG: b07d072eb3831fae8a06effa9201797496dce126b8e11fef2fa07f664dc5cf3d4bf9c38a8b3c09fb5f14fa2deb219e7d852fdd27c7ba32d309942f2746dfe404
+
+TST: 91
+SK:  70150e9516164a3d7b7e8b6f255b65cac9f07459b32d11bb94b3d277208abc99
+PK:  2328bec8e40351047882e8b43bc1ab085386fa47987e46ea87608814c5da713c
+MSG: 77be8eceaab431a13c2a28d0d1556489d8c392fd7ae41157f7caf082cb54e45f08626be0076be844d38fde901a5eab0e8832d69dac22fb8507fb8ec4faf7c88fd26da308461afe385987972b5e760a34a5e18b9a82b4aaa529b7
+SIG: eda3f5033ea7953a0d583c6457522e84ad78445304d48e577d4d69e8641febe15248d8d90ce0944a8f801d39099bc77494bac4ce2a20b38369c6adfb71e03d0f
+
+TST: 92
+SK:  3f87fcfdb421422a9c5fb98268313c15128c78844ef9eb3b3713fa77b6718903
+PK:  533ec59228374bd03a4699e3a8896b86182fcf8fc3085fdb8f5c4671524d6fe0
+MSG: c00fed2d689468bcbacccd446e8d8f299e2a86925e62e59709afaf4857469ff1e006d00fa3e18a3615f8f06b6ebdff785dde58851d2c239038a0c344dce985bd1fc8deb4779ae5f8932e2f9ed5990b6472dbe4e6fef6917657e0b5
+SIG: f6519d7edb6134111974033f03b8d89e9c76caec8965a8e17cd45fff19de2615d73eccdb4a6664a8f0e23adf98988e96251bf26eb7a4ccaac1079f0a772f9b05
+
+TST: 93
+SK:  44ceef044ff998d4abeaaf374eb41d086718b63097b1e35f89634c14897132ea
+PK:  e83c86677d03ed3a5e8c95f41f0b325ff4333702f2ff6936f57ff30aa31485c7
+MSG: 8d3e2dec4644c7b51633b13e6375ca42ff9138465f43d7800c7313199f67c9cf1b520b1820bd630ecf1c992e2767b38eb5bbc441a4ab8d317db441db35a0fe3abe7a9e4541881c2d7b1a2612306959815d1da41267d9649dd4494ace
+SIG: 554552d6b790d421d06b0a67f8e002ad7a1ed01c06cf00cbeaec2a268bda29f1183f0ceafc625fa5fdb847dc86fae1a20406e459d4a0177cb515220a568e0800
+
+TST: 94
+SK:  98ef2a44d4c8476dff05aa78dcf9c6dc086cb2f622a06745d60cbf223faaba66
+PK:  42fdb1daa39f0159119beec1bedf6f0394b26a2a29bd1fde081eccdadecc226a
+MSG: c8b5fcfc3c18c7d95957b668e91c731d50c7fcea4f9575bbf784625870e238df546e2cb1a19d2808dd5b230d3871fdec16100ee1fbf9b722fa3744a750a3b396b05f9c21b8c0f61ead57a78c5ecf72b579cfe88a3f404c8acf524f9ab9
+SIG: ab5e8724a3e6ff76058cfb214d574e04d05574ecdd4ffe8c07c7af396e882687c5d79ef1e62fbb4c5f1bd06b9bd897826edde0d111d918e8ef961ff2a00d7700
+
+TST: 95
+SK:  93a8c792a239c931917c114824a0174f8bc4ebbf98af8c7e321e0f5bea4015ec
+PK:  9b2eaa8a9c2c25ff4f6e13bb12bae5d06fda0eb1105fafae5880ff168740bb74
+MSG: 901bf4e041caf16e04f2ffde8d6fe97e93d0900f6bc0fc09a9a0179d137b4b7788e57eb92766a9c634f35adb5c2988af1e86208f461998f59cfec99204b484fbcad3951e7ee4405523705d9739b44307db03f713fda78db421ef3121b3ba
+SIG: cfe32c4435d911d772dc0727e78d689d0164c5069597cb441b22c1d26236479f1afd7089121b9ab4f61bbb1fae1ab42f7635a92a53784d7170916b703aa5cc09
+
+TST: 96
+SK:  7001fa0c4404c28aa5b5fcff30a961f21a22f5b85a9e382e07aea8a8924d0ec1
+PK:  daebb63c4d8f40ceba8ec35e3dd946a6b75bc74fcb29ade7b55eee3cc3aea5ca
+MSG: 44f48cfb02f08777a57873855f96be4c0291323f2739b275d90757a15472e5750436e0107408fe3026c00625689983f990eba9becbfce403ccd56356ad2741fd21445dfb23d76112e578b3395cf9d960955f1da8f399ca286f21390e25a59a
+SIG: 64eac9ce87460618636b41fd2decc1673bfc48c5f479dfacb51e86686407374b1d10bf65d6d7474214d7770c9e5c7f806c80d53d48b720870e5e78f32e3a7e05
+
+TST: 97
+SK:  3adce3a3d3fbc977dd4b300a74749f13a3b04a5d73a2cd75a994e3195efebdac
+PK:  6ff19b1f18d64851d5c74845c6407f0bf596a52e385e020127e83e54cff5ac19
+MSG: fe6c1a31068e332d12aab37d99406568deaa36bdb277cee55304633bd0a267a850e203bb3fabe5110bcc1ca4316698ab1cf00f0b0f1d97ef2180887f0ec0991e8c1111f0c0e1d2b712433ad2b3071bd66e1d81f7fa47bb4bb31ac0f059bb3cb8
+SIG: 7dda89f85b40539f5ad8c6de4953f7094a715b63dda30ec7cf65a785ceae5fc688707ee00be682cecbe7ee37d8fc39ee6d83c64409681708a0898a183b288a06
+
+TST: 98
+SK:  14803c1f23a47fcdd35e5d146e20ca630cd712c047d5330b652e31857acbc9e8
+PK:  36f2d5bd6d8324fa6e9db7f7d854ebe48c0e6299998122e9d44b8adbef54f093
+MSG: 555983679d026e5354b4cc055ae1bc14653c7281ec722372f3feb778e841da821b3d0b8ee7a9a9129ea06824be8379fbbdcb0748f423721ccb172a1bafa1d5ae9fc1c51e93d41dd551c3086079b620286c1c40c1223bbcbb76722e92ca21d8410a
+SIG: 07a7de6ce97664b3ea0928e1385c3309be08a47cbf4daa9186a1b948c86fbba39c4efcfcb7a0a3866bc94c6788ffe6be0d4972e56d0c3292d1cc6e25447b9904
+
+TST: 99
+SK:  1a61154d3472cd96b328ee674beb4fc86763a969fb410494e0678414e31a46a6
+PK:  7576d93ac85d0fc61f258c55cf90bd87a635099c0e810ed0b937258d13b42559
+MSG: 64c565efbcb8b9528ed47253f3c6a4035db781d6f0976b5e5ba8447d4ed54b04105293ef4c000d8b2e1b5b75e727e5d2a077743b50d183b491764801a2504d16ee6d7d8ac4fe40e6bfc2a8129c7285a5ac691c35e642ed162cf7fbc64516733a23b3
+SIG: ada1666c9c3b8284b8a21c4f2618ef0808a646f3f10941e470f738e1785e2de9fdd9c8cb526f945c7a8c6994f151b7d066581b1d755307947c62befc8ab7070f
+
+TST: 100
+SK:  f215d34fe2d757cff9cf5c05430994de587987ce45cb0459f61ec6c825c62259
+PK:  1ed506485b09a6450be7c9337d9fe87ef99c96f8bd11cd631ca160d0fd73067e
+MSG: fbed2a7df418ec0e8036312ec239fcee6ef97dc8c2df1f2e14adee287808b788a6072143b851d975c8e8a0299df846b19113e38cee83da71ea8e9bd6f57bdcd3557523f4feb616caa595aea01eb0b3d490b99b525ea4fbb9258bc7fbb0deea8f568cb2
+SIG: cbef65b6f3fd580969fc3340cfae4f7c99df1340cce54626183144ef468871634b0a5c0033534108e1c67c0dc99d3014f01084e98c95e1014b309b1dbb2e6704
+
+TST: 101
+SK:  8c9f95083075a43fe426d19f1e87719b40043de88eb0ee971f70e10c7694ce4e
+PK:  e91d167aa3ebc23e70aab45dabe905e416262f910e2a955dd8619efc74c24e85
+MSG: b69d70e860f55c427ef2a71df36e05bbc43bb2e06463aa5de34419c6a614eea6695335a87526c1226488d842891d0574df343c9c1e17aed6958ecee87474221eb77a599ecb059344c0d052c0002a66e5a6013185af69a01ba5dbc660d36cae235f67fe0e
+SIG: cac555222dafec76a0b47b9d2c586b3b3b9b3b9c8364beb3cae1e8dd7f1ae9dd74f22b8dd4ad2b290f81351a415a99f030f10778be4cda85d1d353331e70f109
+
+TST: 102
+SK:  d7eb1fba424feed100777eedb4874bf20810ad686b67e31d27ecf610609a33f5
+PK:  a25acb11a6c825713a085fa754692886a87d07fb9be1a53eb961728bb66c9060
+MSG: a1d0f81e3d59089cc2b19e07d2fce43db4cf171faa642f3b0bbde77ae3d53af5c02bf8fc12ffb4e57f7c8a015d6c2d178944fae9f7c8fc969d4b77bea51876ae99d59e94ad2456e0ed72c52cf4e5340da17c44dbff86457a519b6fffe269066290d629fe69
+SIG: 2bf719682b07cc5ecc0480f37e9d123ff6f44c26e6958e59f080466f9cd373a16500daf123dc3f1334774bfc9fa84503b16dbf21a815c1ada6ebef4920461702
+
+TST: 103
+SK:  4f6aeb35fce14fbcbb9aa8a4f6451bf95b98df047fa8c43f1ead3b404d3f928f
+PK:  bf66a9edd09481db8444a176c8ce0578d2934f0cdc9734e86fcaac05bf3330f1
+MSG: 2dfbb3f59e19ea17d44a5bde4ad227a1a351dda17af840ee0a75da21a5cca89b6d1c567c333e9cc910e2157e05e86ad5d931145064594c47baeea8663a34649c43e90eb95ca10f7d51597b378a722f1f704adf9f22e9f885b89d1f938006a2efcdb42aaff5e3
+SIG: 6adb07e364f2a455cb05867abc511acd9d658977f0cacafc92828e7b724f6bbf98bf0bfb29f4e5e6c74738d4fdd816d9252407ae4f3afc574c4f00614824e203
+
+TST: 104
+SK:  ef4a6762b400975204ccc13abb47344015454906850ff14940cbb83aa22414ae
+PK:  eaca450996f50cfaf2bd7f9d7fa7087f09ad49664206a80bc2e5bbbb85bb668e
+MSG: a4b63eaed5a64a94f2cad212ce2ae71092fd3ea744f5bd89562b2fc2a6c9e4d7aa27add56264a5a55016610be6c19ff7d4989e9504740853012715a79ece9e12c301b3317c7d9b6730db862a4a1d28058e0f8b5ddd9738c7c62ea572cfe59eae08e2b8b6593b58
+SIG: 02697d44cad862f1daf5708205f450d408525b10c01ffd06cfee80374f3db16fa9a49c19a9844b345f2f9559ea74aab173baa078c54370a5166700c6dafb780a
+
+TST: 105
+SK:  55017e5f61f0c5bafbcde6f849f42a31e5e7a878c1d3f9126fc569fd417ea9f2
+PK:  66914f74ed932fc881ff0166683f675a7c28a926fddd6469cdb3f28e6dec42cc
+MSG: 2fc84a0998fa6e168a866410bb68105df249a28cfc76604be94fd7dffff2fc1dedd220199465575e8df860190f16aca4084169be16c6ba32eb67042ffd4f230316a26b2624a42f8f90ad57f6916486fa91fd94ed68aded4e632430ef719446979bfaf345409c387f
+SIG: b1a5e7c49b8fc6b4331e0416ce7e4ed59edd56300b802e0d72abca4a6fcb876c03bf331579124ae0d3fe43f7898bc87e93fc2da3970fc8638957d18c6613c808
+
+TST: 106
+SK:  0553fba866942341217cf278ac57cb21acd09d9916cc6af0ac46941ea139d545
+PK:  840c66e57c2d4f52a4a2796d2a53c5709b96a628c2e063fe6efd47f283ef5e82
+MSG: c1fae6262a0e98a6b1235fcb62283b7f0a097f9d002416d318fefc60c5a1584f900ad0ab26ccfae0d6d84aa9aa2df16d4c117ea2724676cb866d4870a872fc829a7c2a5d21ba83340adb339a34c5184c7f5ead0f077289b33677ed6a1ba34be1994e25763bd1d9faec
+SIG: bc3364c152ee5c808ac340f49ea2cc404e93517121220cce6f7c30a22500e41bcdb6e820480f8fccdd22ff9ad96da532802f431e94240fb83d4bceaa09b92b0d
+
+TST: 107
+SK:  7a5ac602de19f3c21040bcddbff42f6aee6f95c1b093868f48e50482dbf4f9c7
+PK:  fbb6c7531cda21e7d17ea903c4d14be6c68b4ca803a16bd87120f5aaf7dce1d4
+MSG: bd1685419279eb81e4cf3c909031f0f09c5ffae7e2ce6ba9d96c2bce87b8ba0dd763231001e532c7ddd62103abf701288e19dd8f5302e8f5d31b64cc339bd8b7a95550c8a116fd486948772bd5af8dfd46001c59767b0d6bdce383a7078992d1022fbcaf90710687b9aa
+SIG: 84101dd4b5e8ca3ed98c1e8a06e11d7e424b0d12ca714ee7374b64c29d51a2021cc77ac75389d9b0a646a447623d7d04d1241866b0ca6edd1b7ac015666b700d
+
+TST: 108
+SK:  50414cf549bcc55b5b6b75ea3782b2ea7c087b6a0106175e469ca2cc764aeb01
+PK:  d0f30c12e997f96e7aeecd1bff6a012ec388ebf8f3f4af664804d1638e4c346a
+MSG: 75ad77e8c54b0b05fb2d162e7cadb8a7528081b863f76a441b374469413e5714edf54f800496af0157c17e425583414d4361f2134171c0b87c22ce6820a4850ab49d99a9badce9e36110e7f3060118b3590f82b43771e9fbb081afe62227e024d98de6cdec028d7c49490d
+SIG: b309800160de43a63a89a0acb8a6050059589b3eaecac20b256fece438042f69415d8a56883ee3836d3134a7fc1de64fa8c8cecc3ce27589f606058820857a0c
+
+TST: 109
+SK:  93cb00d8fe9c9777a683631f39ba0f48761482cf1c366bd863cf715101532555
+PK:  87e94a1ea5258d61180cb828590ff1418a87d01e702686ba8abc2692c8dc3c91
+MSG: 88d8538d31867813d88fef7228d49a7e950d738396f116dda1025f7913547c5d1dc5677a6de4b4a5880507b361780b61b43f7795263db22ff341645f2f5914fd6088c2811211ed4756ac019a6035d66e3170c1d82bfaa30596b396b3260cc1d10d413dd47ebe6daa0c30dc42
+SIG: 09824fa2dfbc4d6ef76a9e4145961116769130553b3edffa50d04f39b8b79facbd237acf71354a53a6e5fee754e823b0b290f9619320a13d561269a221639f03
+
+TST: 110
+SK:  2b4cae380e95ce694c26ac7957447347f98e31b4bf02d744e131529071e2301d
+PK:  e6fc705a79c98e115b4e28d3aa1506b74ee74276c5fc1109a7f4d89c6fafb889
+MSG: e0b8250e27b7c0291dbc47a6da6f1268987afdf0a1e90be69bcbc4370865217830d5208693be7b7045099a22ea27f952eb3f79a9a0f1b5a87b19367790788d34c219c2e2a6b834020fb4fd149dc56b544fddbb42071a162fc7cb33c146cac05a31b183e9daadc616f3af449b17
+SIG: 555e45656ba9cfbf5155d0e52576e5197abbbc9dd233993eec2a1ee7f6a86409c0b71b0a661978ff5e0acdc9463dc449906f474f8e79bb86168bf70741e34b02
+
+TST: 111
+SK:  b56491e54999bb5a1715ebfa2feb14a545a3a43c2fdfd4be0c95fc11819ad695
+PK:  cd42bf414f9bfc72ec069882a800557cdf31bc3464fb102c310e6dbd3ae20863
+MSG: eb4418ba30683ec7959bdb1ec7b263f83e81f054ddcdbe0a6738ca7763e246935bac419026c22bfbdd1236336cc16107c53513e3ddf34e120846962c3bdd54f5ad5749597208f15a8bb56667baa895f08340db89b85c435e770931928d8abc99262f839aedd9be2aa138c9259adf
+SIG: e3be3e71a89852df3cffd72d68207869dd3eceb49b1f029493eccbb932444ebe8c8c6db5f0a5a67e2194408df9841913a5ac1a606896419a668f4f47c56c2b08
+
+TST: 112
+SK:  6579c247dd2cd02ba2f7d7a950a330752681e92c0dc62984bbea279ea521c381
+PK:  0b087bea1a1b3d15805cb604f4bb8d68edde274faf521fe6df50c55f8ad4a70d
+MSG: df7c552ffc89374b9571a6024a8d0471d7eb6be8dfca6f4166b581b65479015a0568129074cc04d6342c758ca18f7987dec536b7033d5f9681504340e20986f027b8cf1f263be76db3525d173422950ea8dceddc585640918aa9d25ca89cba701c2020153873f46108c772cb388d55
+SIG: eccaf801ae0a912e21c6b83a5f0e4e88d4b2713459ff93449fc0b21a9f416050113cbae4e814d20c0a798f76d2f9d326ed83959ea02abdc1ab350a467123f709
+
+TST: 113
+SK:  18fba60c5026f3c9dd7aedc04209d5260361de400e190aeb60169e05a3367c9f
+PK:  dfff347f3dd255530bf7fb34d02ba486d112bb46e950e2ef80e517014cc95734
+MSG: 34f08a804d7829cc3914f000ce1a3288acce2149c8a02086b9f67afccd83a178b0bcfd4970c056997da7dc3d47562f16663cedc52f82d710850cf4050379efdac23bee17c330a383ad137f788473b2b0723603b6deb1fdbf6c523fc948a0ccc4ff100fb946d874c1f990436ae8c4f3b2
+SIG: 4bc011e40f0f59c618f6bbe230b6f7bc2f50e3617c7faab7f4c21cb84f77eba994cb7c2a1bf10b01bb20084497fdf0a6ab5d9bcd22c4a2c5a78f79926825940f
+
+TST: 114
+SK:  073cc15b0536285933b2be39253cf4fd696b81610f5dd3adac2e9cbf338ef2f6
+PK:  00b551d371544375dac5c4e96cd1f0215207e8e166a1fe49d5b0a51ac18443ec
+MSG: c285362bc8ef628f7aedf654231ee51acdf2cf69a886b942bb9bfed8155105d9209ded2af24f169ad5fcd451370f5827a85111c7a52e032c5038617c0c0170e2a6c231dc401d12062edb186036114e38793b79089077581b9783f40007103ef17472491c00e7138aecc5084d3c85010470
+SIG: 3aa52a83062a8f28a5d6b7607f484b66cc374896b766123126333c579581316c742806f627b5bc55cad705cc1d4782b044080c8ac840f38c0c50d35e345c7803
+
+TST: 115
+SK:  fd894a1e8232203b289505d5c68c68791ffc0e54f2a87530fbba5b3a3f2caf00
+PK:  e95ab565945c7ae5d533df5d0cccc7e9abbc838e20a0b61c930f5d41d81a6fe7
+MSG: 2669624a94f2c44a05b7dc3ebf93e58a4bf3a01c273657e7e7878976f6b6ea737fa3f22cc8365b8b220c007d5b642726a408fe2fab69ebb3bd072b349f4dc3377ee7cc752934254215d23989bd3cd02ce999adec9784993f4c19940815f39c9e229247f5205c36cba44e714266369289b4a7
+SIG: f51102219e8804be713e556df4e4afa2f8866fe86541a1c2a0934d24c3c9beb280a70dd8d527fe8b7e0b948214d5f2f9638619914b72d55dc198b0229a848708
+
+TST: 116
+SK:  18ef464e28f87ffcfa4d3a9c09a22910951b8c719fdacdb56de62c4b406df00c
+PK:  c5064c9d43ee2da75b06bb09c77267dbd0d39128f1cdc6bfa451a03e93af4a70
+MSG: 9c825707d9358365ab9d38f7e728d628aa722a4f1a20a38e47c999fff8fc32417fbe072f96eb6a0e11e4da9b6de9615445280e93c77a3634d3d2c6879856c248f9800f60a0d38dc1cea8b7f31f286cb0374827b4c6ba144a6694f2b908ead68d18340124cb59cf1701863bd4f3efc709f3627a
+SIG: d1e7f16e8e597d428adea65591d551b54b667aff2020c464f7f4e53c4773f70433249a3c71b4d11c89c3faa892809227b9f29ef4f7f5d020d4674d4021359405
+
+TST: 117
+SK:  c911bdf2f9e7cc5fff35c96e15cc12eafd05ab0db31f649f7408acd0cada76e0
+PK:  de44696cd6bd2cbe9b11a0ef18b88164801a969d5e06ed453eb4008cce9a5725
+MSG: 76c471241d17192984b00362696e4d9d4d2b7f839c2064117e50a1598f3a1172b16c55e5396866084752024f3a7eb68bb3ffdb80979a0af6d0f6af26b6f0bc0c0384433bcfd44c75eb654a8a8225cb9c4a7fb3c824c3af6125fd46db287e70492d154632cb8f62432659d958d6281d04a54f5f5f
+SIG: d584b5da371ae4f5c9859b25f70dc56c1b7b4e02d1ae6636283b1b7b11217afdcdf65d1b49ca2c8ef17966e9bc65f10c310b77bb5df7aff5ec1b379a2ce55d0d
+
+TST: 118
+SK:  d3703299c41db36d77dd3a49541f3fb21d0b2bad1f6e074affd96f1c40d0f927
+PK:  862c5ef616a5f066fd87758a56ab45056fea4bd33f008be24f7b540e095e148e
+MSG: ac92edbe22257bb06d94aa950e62d18ca2ac0a8fc106000d2231f8a13b8d7a209ccd8cc49a6cd68a7f36c02fb8f728d15595167f0ba8cfe95c8a1e435f327513014ac428b75d4f72e7c834dd70e1a448f1847d3498475f74e3d9334dc7dcc4fed72bf6c7fe3b1d4f53d429616f1df44f19733158b6
+SIG: df28277121eac44630084cce75917ae9f6bec65af5572dc30719bde661cf696b85b8672dd4983cab30bd05cc3a119d7db9babd522d7b3a6bcf3886ecd25e080f
+
+TST: 119
+SK:  d411cd33576d0efe9ec413ccdaabd4fcbafec01a3af4b3cbe34f8b05ef8b59ba
+PK:  e870344df98dd3a8702c4519bf9e8b35a9d189e746f7203dbbf9bbfab22d6f63
+MSG: 11d2c2a7f0190988126696431b4bbcd90ab7b56a32da6404ae446aa762a4ddc66094971538eeb85bde0470a510be0d6d85780ee730a9854138728ae6816162268da852858eaed4ec74c7ac62e6e7096dc002df0bdf5fa40da565b41d181a3f0ad0c5e0b976743e315d9db8ed4160abe69c13a2b3f09a
+SIG: 83460d15461d6717710bafd6a47a1eaa900a80f2bf8b8aae2468773614ee84bd628c9717476368ef3640cf760acac83ad60232a76963b7d52588b11dc004d70d
+
+TST: 120
+SK:  e10a2f1380c3e4720e8a8707a9bcb25a0f58270d7059cd7626c7153447edfb87
+PK:  a3c717acab366a40b51187bbf35b2d15e97cfeacd7349c06ef1c91ac93e90656
+MSG: 135212a9cf00d0a05220be7323bfa4a5ba7fc5465514007702121a9c92e46bd473062f00841af83cb7bc4b2cd58dc4d5b151244cc8293e795796835ed36822c6e09893ec991b38ada4b21a06e691afa887db4e9d7b1d2afc65ba8d2f5e6926ff53d2d44d55fa095f3fad62545c714f0f3f59e4bfe91af8
+SIG: 094bf6f953ca0eb77df45129b7bf10d192cf6ddeae94ad6202b8eacfbec119e5291578fe64a084ae600fe07efdb8a782610dbdb0b49eb5f2a46c432355552f01
+
+TST: 121
+SK:  b2e697b3d3efec976ef3369530c792717bdbb428d9ed0c11ec0ea9b2e5f39f82
+PK:  c4d2e4b3c236d6c9b8c74fa384612c4710d83aa16ad7ef01fbb7421d4fb3f0f6
+MSG: 7b436232ac2111a84059510c48362588fcb7383426be5e6f62f372e4f7cca83c81c2357f9b54f4a15291065b6d41aad1ea93cffa776b9acaa58afe2b51644b97af9a3e53f84e40aa6d86051e6914cd039d4170a9a526dd69955ff507c33f74e2176591fb0b3cd7f00ee418f2c258a9981cccee72f01c8430
+SIG: 5047fa38197b8328e78dd8a10e966afb7bd3d43608280f1c257d25ca43bc1c06e94a5747ab6215ece54cdeff8c56567d70d2f91f9ec8c260aa1080a6ab5a7a02
+
+TST: 122
+SK:  19a679a7a905a1e2b3038e6e418b3da97c3089c7cd351ea07bc8d1af64eacc46
+PK:  19f08361f469b4ae1e0ceb94f47a7de7317410a92dd013b16ae0d0532fa4b3ef
+MSG: 980c7b4d2939061ac7b9ba441117a19485661781a4083067c55acf93026c082a93cc124f095e1b4f2c3f6c135412a5096228e8a071e8b4b668ba9d9644ea9f4dabfc54a9856c3e965e6363395ab709037dda229baf927cd01f9af5e039afc42f3cec634f5d832d2ab7c7cad3ad7b8cf27ebdac698431ad8236
+SIG: 4347b7b4f7c3c4dd315b8384a0b0caeed84bdabe24b2915f12512dfd04770fc996a1bfb729afef9edd611447081a5330617eaea1c1dab1bf13cea8997204910c
+
+TST: 123
+SK:  f03b8363ee5b0eef7018a49bc02adf731da54ee50a7f03b88a29a2082b189c43
+PK:  31287ef5a2e64104ab7790b312f35c7ad4af6beb0d7ceb8a58f36a54ce272c3e
+MSG: 24191b5464b35ac7bcf4a375f033efba8943b09b9ff0fc403ca7aae702a3cbf396c5131bc008132cf5f12910d586dc1db9c084574a96babee95642f922371c0382ec0402a26feb142e4146bbd3360c2b36834fe45af5e2868d4d56fdd504cebf0c2d7f5791b4429417c8b65a98e0b15c466c137f410524fce737
+SIG: e8fa967e6afadf6a877d87e5f5c52bb634b75a7804199a2bc9d027b63a35654d9ddd06830455641dbfb49edce42e20e7d4104a071c2cbbec23018c297ced9908
+
+TST: 124
+SK:  11086b0d11e415ab1ce02aaf8f0621b54430f6fb135c74f40d38e8c64737064b
+PK:  7166dfbc691eb8c201114ba0d1a2c7b87f7a1fd8d0b36058b0d7dcabe1ae30da
+MSG: 4b5b2936c5e360a38455503721078f8adb404a7ee7ecc14801dc87a67a152b769569fbeac0afa25a2070a1686b900ac1633d499808cdb2e81ce3916d5a3c04d19c5bb2699a662b8aba4af94d390bac7ccc8ec910ed2acdf86ebb71adb601877885eef3c91662fc30738e352cc74353ccf8d8edeefacc042c10a0e5
+SIG: e907459d5adcd0d0c36418581f19d0eebda7138ebd9faa0b262201f458c856310bb77f4c7de922495dcfe8b248eda2ad0df6a73f47bbfb894baa7d8869875802
+
+TST: 125
+SK:  efce7667a8ef91228caed14eb477a345e5e8239234080848760ed0970713fa86
+PK:  9193055a84df1eacca28ce2a08c2a07a50f04c024ecf1fe4a47d2efbaf63ed58
+MSG: aa1bc80d7bcc1d94a23a57cedf5027482477dc46b86890bc0e5ac29ae6c91bbc43130348797305f75543580a8a069b348a7bd8fc3e015230b7c1940c7f80a82b12900910dbcf0630da03f081d44c7f955d4a1172f56ecc7c5ac646696bffdf4eb6d88bdd9cc3843528b72583abb3bad02e56ef7646eed5139551cdeb
+SIG: e5a63124db1696b64140b6e9612fa9587b3eef710109398d44ba0ca63c0ebad06f0a6c8994ea34b3a2af91a89bf41ae614d7727d716fd42f8b92e1ac64fdbf03
+
+TST: 126
+SK:  88fccaa96ad884d1165be71dd0c4f5f8f4421c60fbfa498bfee9b967462443bd
+PK:  c75cb0e0237b45b8656eea9f3d1a9d4acd01a103aa269bb24fd54122fd81f2ac
+MSG: 9d0eac98556bfa8672c35705d1d61ac4d0fca19dc0d993015877857d27fd80f74acace666c563485d81e53603a6aef40875fa551cc105f2cc10b39694679cdf4a6b073bc88645fc51a36da179d3d1e3c7722454c5e73577c61aa7d148c4ba50ea46c56a1c3b3b3c470f93100494e08bc5514ac763a85483c42c7cdc27c
+SIG: 27d3a197cc9994212063bce8d799e77b6853b7355ebe369bcf1889a418a82caa3a7987a663f621defe86b3ac4ad44faeed16c9116ace28fccf915557fa779903
+
+TST: 127
+SK:  670b30626fe367d8b45f43733d6f25b37eccbcb551963f0ac8b666b48041c72d
+PK:  65aa4c6d4ba0ab34bc75b39f09527ca6f2425f52415cdffdf2dff273f8ea612c
+MSG: d00bcca7e184d10e1f1fe420b50639e1d5deba52a751236e68c59bb4bff9802f5fc165ed42fd6d534670a7c6fb60e4307d947915a248bf2f93465c2cb44d8f453d2c015afbc8ed58818ea51726a25177930e9ea192ef4514f4bb0eb4e0f5d4ae3c46e357c81187f7ed174733fff959c3f9fae6486cfa1356a95699211de5
+SIG: 1b6b4377d2b98e0f9d24ae8dfe30e2396e2004380d3431488e5843cf8d2d7a0070ab21f8a3b51ce84d2f4ba209f739f922bebf798096693f5622873d79ae6f04
+
+TST: 128
+SK:  813c4daed67a190d68bb635d73af6da74f32fdf7c48cca6e59262946b8e8c71f
+PK:  a2095457d7697020e2b884d95a96578c2a900a7666ac0dc7bd38f1931d7945d8
+MSG: ce54cb0450e689a0dbef785308b3177472fcd6d38203e58a0590b31fa253f9ea590be5368a922de88b63450102684443fb8189e601282003323b89c81e92eaef2b5ddc4a55c53fa3cfad4160248b3c286ff80d31d161b7b8dee713552b56f1507fb72eadfa89054e9d1600ac874c4b0a961004eb6d0d4bfd2ecb9c734f00ba
+SIG: b446574ff6a4bd2b572e487c4ab443ca641075168aa4e1092f71f30bdb068ce46a395efee1ee660b9fac26d54109722c15cdb791bfb87fff63c6596ad4f2270c
+
+TST: 129
+SK:  8400962bb769f63868cae5a3fec8db6a9c8d3f1c846c8dceeb642b6946efa8e3
+PK:  98be21001993a7eb1a1277ff74c15504183d25fdfcc05f0d4dea892f6e301890
+MSG: f7e67d982a2ff93ecda4087152b4864c943b1ba7021f5407043ccb4253d348c27b9283acb26c194fd1cbb79e6afc32ff686b55b0b3617218dcf39316b4b66b3c8c0d67267a86db8adf3750801bcf9327d4c25441b96197832b4cde0eac3ff22892a2f0bc17c2c213c02377a333e308ed271658049383b7e2e57b6b8b125512e0
+SIG: 0ad71b0025f3d9a50db338414d6d670e7799b7270a8444f6ae7f12ae7eb71bd03ffd3c4f36631f69fdcc4061468ff582ede495243ef1361a3b3295fa813ba205
+
+TST: 130
+SK:  6288722035d1ea699bc7cfdf18d89625423180b683fa74639f4f30f15359cc85
+PK:  e17faa019572861a064e1bc571256dea1468f3a48590a89138aaa85925080cd7
+MSG: 8b6caacac51d8949fb86acbcb1b99d859ff67c64147bc1216909dcab07ee6ef09f403863327394689dc34abc778fcb5c1f5091acf5a08f9d842211d1ae2eb40be9bb8d6679077471547a6c71ff77b519d4b7108e32bc46251c60dee8e332b6229316e6d57c22ab826ff1bc33f2b0213807c19280af110fd26ee27468201cff49cb
+SIG: 9dec92b6e89adbe8f4e1b5e93ac4fcf957de7d1970a226770ec4eda647c8e3b3dffb2731a39e16e4a0119d3662a937e560522491ec7a1696be04c076b12e3501
+
+TST: 131
+SK:  13038a3a65ef32759a9cd903acb554b252de00e7cdb77bbed1970b20680ee17b
+PK:  b6a308e67f9b46c66499456ab5cd135cb2fe84a32eb045358626604da4122c8f
+MSG: ddf00b4033a2a088022dabe93356432f50ddc6c6e1a659dc1a93124a4c2ffffd182765a2f56c43ea0bfd8de8015060889ae6941c3f3e255d4421a1c36201be846a2738a71f120cad598ca8527d70ff8d5a0993b55cb5153517110a41962daff42250158f2096d1ddaf7186e50298cbe51fcb429cbea411293f8a7bd9cf069fa237e4
+SIG: 5261558ecc3c98ff36351f42f504cad4a32ffda5a744560960b4c106e4492f02e20478887afee4f770f05597a7e388caceae805ae351e0e45e8e578e6a6ff20c
+
+TST: 132
+SK:  b9de5b063d3ca3a773f114941b2e4227c07511c0f5c06017b9c8845018f23432
+PK:  5295243c8646e096674dda15979b322b9dd0faf27d024a0ed5771334e1179ed2
+MSG: 9493cc23896b84096046ae1053afe39499e9424254b366fe143f4da321e2dc9e4784208e12a542d899828dde7eff625a7f12416990c2841ffb095bf94c0c610e5a663918b689031ccd6b519349d04de1c212ca2a9d7abf52e1b4fd467bb665b6919ef8f91617e205565bf56647e5f8d508ea200a84467f8fa122e74bc3b9979f1174e5
+SIG: 92ba760d14d1415cfaf218ca847014088ae51ad821113a6f8630356f7ba85c005e2330f1066d0df464806052a4174610050462f3e013d702e7c77185a032580b
+
+TST: 133
+SK:  8ff0297cc08842b5e67552ec2843e04353a34d74ef89b8565d97205b74ca133a
+PK:  0f7ef98c5ba4af984dfb77bc4e537b2b39e6273bb3e7b95fe1b7e6781952bd4a
+MSG: 2bdc3a486c5e4ea62dcfec8a9d4fcf9ea9490dbcc715615d58490a72ce833fa22387ca50a0052508cf0aff1ca727f0fed46ffa7d3c8e23c5bb01d47e90ff06d3858a557d9926481579daf4384aea50e96ec615d2a3bf3c1122f1f24dd6ed98a5de421883589c213998ca5432373e68bbbe89428ca9885d0593d5e6215116b8266386452b
+SIG: 0783737f706e6ff36614f850074fca1f485f24fcde2a28af544f37abd69b7a581defd8c771b031e108d19d788c74c5f20bb3f1c21cd92be317bacd8f650b4905
+
+TST: 134
+SK:  050d553d282dca3269c83c181768ec067b81c9fe0c94f2a0ebbb0c942d0fcd7c
+PK:  63e230b003c53a5672e832ff7f24430be223e497de840233f595a3e200c7127e
+MSG: 15e13b8c01004f6aa5b236dbb281677f746d81e548e0aa80f0e414521521d856cd694e7c9152bb5e43776b60f6b560ed1ad3e4b390dbf3e46ef9257443f39c149e0240a02d021e1e3d7d046b26fd004eee7ca16a8059e126c74cb3f2194db47bf60465ecef5c704d2e2c75e2e50060ea2a31cb72b7b3c6b1b5ec72ab38004085281a22fe86
+SIG: 3f0e83765b31bbe8e1fb92e9678d6cde571a03ba7f1dcc1128461f708525457f4e0e2353aa2b598c063ff1bffdac916b5a2200655156904b0585577a1628560d
+
+TST: 135
+SK:  69497cd7b4e868cfa0328d92bd6052d772b2767395c14595b279851a9cdd31aa
+PK:  5d276d626e230d18e7bcd61141cb93c90ef0f79e01321212d838ec71457b1aac
+MSG: 53cd080a0c61f1a093d3b3a74571c296303f363b4107edbe880b7aa9dfe44ab5d5dc5f74be9c8d876f04d754653491ab51b135fc953f71287b62ff41b67c742bd3445671a9d4f2dc174ca1b0335f78627a0dd4b30650504178039e7393638510ffe84091b57298d3ac9001c367c1452fbcb33dc54a5dc316fb2a5270764a2ac820a0b63fbdc6
+SIG: beafa58340960908e8d86e40329e3a4523fc7be770addb86e34c3772f84cd9fb338d1f3b65bfcdb09f35c6da36d1a3adf8f91f1ffd5782cc830206433a08410d
+
+TST: 136
+SK:  2165a486b612bbff529cd00346964a3cb8cdcffa51dc3d524dd5adc5ac936d68
+PK:  7ebc839a465e14f5892476e4a13b3988f83b3cd27ef79e193f86fa16f34a1ce1
+MSG: b728da7a36167c6085bd2d962cf63959facd95c9ad4542028afba90ec9c6c0760bdae935429c3feb3933e2f00042c672ad2cd7348d92bc33f81751e294ae9171b945b193144ef8acb9a1bd9abf0475ce0d0ac789b200c32e9c9a2736b168369ce5f97b1e8d2e7900e1a759178441f1fc430564ae129bae7857740511a668f32c0a3b077a9d8b19
+SIG: 7ec6fba56ba52460a1b4f2738689c1883dda9aaffc8bde17cb6029bdce3a0ebe2fffda55939b70bbd07fdbf6fc5cda87fed8ba58575f894a366e45e5705eea09
+
+TST: 137
+SK:  1c64ad63dd147034598e128f7406ec0530746ea1c5b72ecf79e888065486fa1b
+PK:  baa6bcc1c3d8d3b11ffc1587adddc58bfd96c2b992b6c6f59fcc50ccbcdd0eb9
+MSG: 9ebd8e337893bb053ef2b9e3269df54848494f03cd63576b33e64b1080be4be015264a403fb9602bbf90ca19b241a9b66863909b9008ce1b2ffcf236efa4c2668f0f47db9ff5fa157d9cb605412be7dd8b07ea878cccae6bf50f935b86d19e1b648b69e528553a56d8afb78221ad53307b7a4ec8d2fd4861b55dc5dae8e93ef387fbbe0b4ce7f788
+SIG: 7477e54158f13b7128c0a110ca6b65f42514fb70cd5cf28a8b1cc6110ea06fcf94290da13f85a11c2351d3bbccbb4c64e0215d6d0f0099e7f27bc94e949b150b
+
+TST: 138
+SK:  55abbc5dac4128134dc8c6018a213ed4b60fcc8e90cbd41db2d21eda5373e936
+PK:  251afaa2646926b2a371f2a09d5865b98c9a5eb6ca047cd0d8ee36e5e0416974
+MSG: 47010e1398ad55fabe371dd8648f768d90df4b965a3b396100b303b40a17518bed6d86b09f734ab7c10b5f3a01b53deec5f8534b70c79f3f29b284fdec486f22f44c22ccd5c6463594415267baa611f70b1b316caa1b68b5e0e99b31c5bb0ce13679a23c31a63999698164cbf37d103ba92490188be59937f123043ec786efe3d411f9b0623a6ad972
+SIG: f6a61c2e661a9eb7bde182e38ec99af985f61698a5d7fa430d16e3f1a93709b75522320de48afcc595ab209122ae0ce132cdf4b0391746e7ff341177570c8108
+
+TST: 139
+SK:  f2dcf4a1a0d46ddb2d72f8fdd80bbec5b7dea5913da4966c2f4d12c261f0bf98
+PK:  d39570a25ca59f2257f93f96600df4f63e684bf63ae8dffd914e4629c3d5095f
+MSG: 3b00e808fca4c11651d853d6b90f952ccf5647e102d4ee0ad7a5d181d5b4258c523cd39e3d9825298d84c8cba09f43dbba119988222c76059caf17b4bf9931c45e617448aeade151181497b24552367e52bc45ac79088806d3368207aafefd3057845dce819d5aaaa77b218e2aed3da76d40c1f07699f8172e4a5c803f7a2aceb9a47a8952e1b2f053f2
+SIG: 42882a811dad2d851885e4cbe9044708d91a86f15dfa1d66c3eb304314531f3015208c711b9bdbc5fb233951e569b59d34e415eec4b37ffd374d412c9a360d0c
+
+TST: 140
+SK:  2246bfb06155859e10a748ff8f5919ad5d1daab756f01057b790d07474775f4f
+PK:  fa6349b62dc8c6a2feeef6ffc33ae085c649795c1c9d9898e75c13ae1625db34
+MSG: 63ee1c7bbb15cebe1c22532d481682754bdaf58b8bc997ae30a34c9d23c33f1690c346ab0a7365ff62457424b6105f8421eca0ce3c630acfeb9a1cc416390edf4920e22b2367e9fb5d2ab25bee56da03ea55e3f57882d48b89229314d734cb83c79f4e17ee64bae6f7addbe9b525fcd03a91409a2dde907751db8cc97e08d0ea89c4d18718d26d0b897b64
+SIG: 2be4915a352f7785483046d8ae9625b8b63257af57c073691256ee076d6e1b972a101f551c705d3f96157c33b56ea049be4af4dc561cbe3c1ec5072d7f134e07
+
+TST: 141
+SK:  c088a3dd2cb8bd5d684db8538dc22473b6f014f64fe86af168b4bb01b90a1dd0
+PK:  aad615a9c28759f03d373abe666691dead8b84f9b8b50a67f8f0aa4a701580d1
+MSG: 74906ae05a5af8e9968b6feb498569d6345a24f9711befb136e6c3b5ed49339e59a7938b4ba1a118f169b9ace0f7842a26a645f14c0ad22ebbcda93e67e4c348efc3d9ecbb1419e6262d0436a58ea82c2202389065ccf67c4f550e45b5f6a12a6c011b2e0a30101d5c62328bbf99c8c95563a6e33bdd9cce72b1f720139c2fd3e04913146ae5bac5288e0e3e
+SIG: 3bb459d1ac575a180c1728d8b8924970492a0c8d2a378c29d1d41785c8379a58e2ba3606785e1c5da29e5527552bc6dc89a2b69c27fe51ed253a9f3b565b2700
+
+TST: 142
+SK:  45667d1e7b5910979c4a328317968371c864d564a661c5cce557c9ecc61bab9e
+PK:  edcdf5e1a170e00c8c687e7e9c18f9893b5fe495cd2977ceb7f446c0149aa9d3
+MSG: cd66cec476c87c8dbf47ec91dac48fb5b42db1282a573e0a5cf0b91768986608e1d7ebd05f5251bcf8b47a17093229acefbd44beb21c0c0c928dd3cd3f8966ecce6910331c508ea76baf904d8c21f6c17c2c58d00afd3259b8bf794c146b12b995cddd1c4289c5be3168ebd616b384c281ce1b38a10e1807808853c681a640a009b4d2acd7934f8c6d07578161
+SIG: 6de668f1ca6f292814625289a0808020c87c89ac94f5b0508e557bdf8000a5ca808f021c9679b50ee2f320064c95a464a8439379828c3b76cfa766455e128c0b
+
+TST: 143
+SK:  24897428ae6546d85b3190ebe3f1f7bf7c712528ac851a588b07d5c8f94eecd1
+PK:  5f348fe3ea5b2c023d0af7ede60e55f91aa55199699da15a11c3791d68d710bd
+MSG: 5201d9725f1dffa1863fa4d84c301861141acdfb64be1fbfdd5b9386db20ef394099eebcfdfecc62c6268607a84d55c55cd0efdc372ecf3067343e7b0731c2685461e24b953f99949e59ba3e67ed0f0848313793962a292c459814c5e28690ec1f45171f1abab86fdd14568b00caf48581115ee5ea83b000282fbbf0c0b2a1116039a35cfa3f201422207a3d4948
+SIG: 1b5e75def49f51d6b2de008c71fc1a909bd42ca813298dce4eeef717815d7a6c078c2f3d9a3fce1ab5b3ad8ef8d45cdf2eb4901c32eea2d5e018dcf2833cad0c
+
+TST: 144
+SK:  7b04aca7cf926216cb960a3890786339d0a615967680190123fda3b60c6aeb11
+PK:  cdbc3e70e4e8fd13d0cce2852a3b9372c3a6160cd6deaba90f9b3022f70c91f9
+MSG: 1cb09624b1f14a0260c7f56d8c60b5fe45837114232551ef5966386e0c2b441b75cfdb8df2185785d22cf526fa9df7fd45d9d83881b66c1feee0913e238121eedbb7ab504da0bee8998016684535031991f11bfcd9b95690aad2d19bd6a9de1844ed1362302df4217230b25c0552ce277534c650cae526577f25d8b1fe9f9febca2c814670d4805b21adef852daf94
+SIG: 25d2d361751d52b4fe66ea18e4b9866bde3d121a7312fd9e28a1e295e087e3176c94c874a2e81600f24c4654f43d1b67d47b64822648590ce5ce44f3b5ddc502
+
+TST: 145
+SK:  ea73bf64a1a97877c3c3e7ca4644b71aaa66314c8f1b66bafaebd5edfb888bcd
+PK:  caac93902e5764ade47294edd51faa14620940c668b5c1c392a6928325d4c3fd
+MSG: 362eec68b912852786bb4f9afff9ecf7cb28c9de6b18422a8ca940b0d7e6dcb83aa44be0afb5f1806d43f0e31d71f922f853615a26e287a27f08a04fbce3d45a0c6c311d4b7cb17e425bbeb0a6b410b5d6dbb7ac11df9850a131a691e3b60b0b214ebe044106e982433287595267b031b5d4a09262ded8934fdfdf964d868ef9a2c842f804eafddefcb71d9f16a59bf8
+SIG: bd86cb9c70a055279a86a9e64870988b8a7345c3cd2948a0fabcfb38abce3c420b4d5521618e11d2de827d9de569f6bc3be66aad40636cdaa64760ded3b7c209
+
+TST: 146
+SK:  b8123c116b33bad0dcbc2c4dc06a3d66850dab360cdb5a033c14895c4ee31bfb
+PK:  bdca151ba32c6bb31531b05fdf86c6d78c8cd1935611d5ff111a0f00635b1885
+MSG: 7970f6666634548c848bb52338817b26a4d0ca68df3d28afff207c2d028067a18e4c9543025f5b0228aa691e5088513151a94494e15d1f54210328e0df159b352c30aaa7a844f18a9f4c395dcbb3fb9fcfbed1103e0706fbf9c35fe2666848fa35dc2cf5227ebee89e7d3bcfae2721b25fdec3d3174ea7ce267a55dd61d58201e96bda303cf418edf6e32fb92f5dc1a0b1
+SIG: 9cf13eba3dcc37b8fc70ccb2327436b9f08855e726aa7ed82bd5cb7df45fdf9ec1f96afad193f47572d770444b65b74a37cc034fc514cb3f91b2d8ada5b02006
+
+TST: 147
+SK:  b18e1d0045995ec3d010c387ccfeb984d783af8fbb0f40fa7db126d889f6dadd
+PK:  77f48b59caeda77751ed138b0ec667ff50f8768c25d48309a8f386a2bad187fb
+MSG: 916c7d1d268fc0e77c1bef238432573c39be577bbea0998936add2b50a653171ce18a542b0b7f96c1691a3be6031522894a8634183eda38798a0c5d5d79fbd01dd04a8646d71873b77b221998a81922d8105f892316369d5224c9983372d2313c6b1f4556ea26ba49d46e8b561e0fc76633ac9766e68e21fba7edca93c4c7460376d7f3ac22ff372c18f613f2ae2e856af40
+SIG: 6bd710a368c1249923fc7a1610747403040f0cc30815a00f9ff548a896bbda0b4eb2ca19ebcf917f0f34200a9edbad3901b64ab09cc5ef7b9bcc3c40c0ff7509
+
+TST: 148
+SK:  93649c63910b35718e48c590d261c48e4ef8336613f6aa077b462676b3ba8829
+PK:  06a685898b855212ebc289915d105a4320d620d85771b8c6b15bf10a1be6e9b8
+MSG: 2cd1a951056c9ebae1399b6bd2d82c0ae277856290d06920ac56cac8fb42435101c72aa9c08dd2d12426325562c2f0a49cd821b11b939aafa593b4095c021bcb4827b107b9664d68282888bc4a44af3e3bdc861be6af309044c3daab57b77023dc902d47ebc326f9bdd02dbc02cd540ff81b2ddf7cf679a41193dfe5f8c8ca1aaefc41ef740280d9823e30a354717c8431f5d8
+SIG: 6274f2d4f431d5affefa35e7cf584a599017193da99094ca908b75acb608d1bf981857be93a7dafb0fadb3ff0906f48a5ee950456f782c2d605b14095ba0ff0f
+
+TST: 149
+SK:  1c15cbeb89362d69476a2aa4a5f3ef2089cf87286349e0dfe0e72d9e3e5a66c7
+PK:  13a882a1064182582c211847e19b4dac59722c9ffd34826d96f33113400fac7a
+MSG: 091c9b9b116ae83d23d01a6295211785d446b6228dd687ddf79bd0d5a4daa8c79d2cbfc37365f1f285e361738123e34e2bcbfc664ce1253a11d9e4a7982e58cf9468e1017ea14d2cc6d0865d40fde8cb560241e96ac1617c791f0ca7c6410cadf328611b18aef333d8350ac497f0a4ae2d03fdf0e23e426d34f4514780d1474e113583541f3c043672057172618cb2059eaaed56
+SIG: 5998b2808adfdeeaebe2c3eac026d3f825f9c7f2af97ca324fbd57aac1bedff78a8ee621d037ee3ad2a712e9a009c58ea3e6f2a828f74b86da275a44a4b1e50b
+
+TST: 150
+SK:  11241ffdf34ae8ab875475e94c6cc3291f0b8820dc85e20f32fc53b24ae68978
+PK:  09c045e4bd5137314c0ec1d031faf914910c45a4676f5a3cd8f581bcccb03c97
+MSG: 3b89deccb7023e4b2b7aff2c3951870af413a9b04dd86ac78b7c8fd887492d8dde49d8fda149edd54781ae2b508030d14416a9a38bed2b9aebbbb20250b3c931acd4e32fbeeec5a26501beab7268d144fce8951a101c4b5178166fbb5927b1dfb1e1ce90d1d123068e3f472c888fdb01fdf70e7f8de9b0adb284b7119f55354316f84ed090030f9c2662061ca48447cc0aef964126
+SIG: 72ce9f91be2e66cfc90f952595946ffc90bfce53087d49e5dd7c087f3faa8f18f2356de971e4429d985a99194b4f92ced3ef47cd7114379e0b3267a9f8b1e706
+
+TST: 151
+SK:  3bdb162465eaceff98d69c86f70039c517d168aefe6bb101b4f769a86b17c972
+PK:  d76cb7be74328289fd1c64be747cca5bb30295dfaccd0f2e43f51703fd5d3683
+MSG: fbf368feaeba87918b1b8c7b8a26832be6e7fc1cbdb8902519281a0654ec73de0bb07101a9d603f745d4ec2357aee9870cb19a56cb44fbd9c91fc34752612fbd83d6fc1a16bf8a85a215d0148e4af37d298467e5cc486b131352ce092182ce8284159a3812b30bacbff595863811bf9a30a9da494565c3ac1814430018ea0eeed39cdbca27f93140e46949db570bfa2ed4f4073f8833
+SIG: 6f1362a402063791f950984f544928e616a4ef79bbeb6854e9615aab9cdbaec483fb9a04bf22de5d97a15bda2d390483c7f61dbee07bb5141fc173b1aa47650d
+
+TST: 152
+SK:  d5efe51d5cd8e108bd922fc0ea126190a94628ffa53c433a518022792ddc78ef
+PK:  426b01cc61ff5e0e724da1d3b297f5325c18c62f64d5eb48d4a5216a8e9a4073
+MSG: 9d17bcfe2dfc742f411cb53a94f359c001abf096c741f34af48679f281e7ce6bbd9e87709fc0728a563db2b9cf8ea4fbdcc344c1848e653ce970c6ce29de2ccd520300649adcddfc753971f846aac1ba42ae4528952d94980aa7c6cfa2142907647f894ae974a74d59035a73ef56a10b6612624809520190ace661c3a47095e0322efd781d50d1163598f2da32f31bc9c4f913d1b14861
+SIG: 2306f58fcd4cff2222d81b05a475532b8b19dc67e6d78ddb4205a3b7621cc5aef0b393d5d24dd96c88ccbc53a3208da323be4587d5ec067c820f0723aa44e90e
+
+TST: 153
+SK:  18af89025ebfa76bd557cfb2dff148245214641fd5bda159f73da04b08e87c88
+PK:  0c584459b9ebcccad587b272160bc60b27f4f772b4321de7723afef577edc7b4
+MSG: e82f46652ab914af535d8fb720b557ac95018d9f2a3fcce85771bb40ab14cb9a986e096f3afe5bee829dfd8b97335c536ac971a21655af16a2f8fdba183a4e18564c21492956537a419abbbbb02a4bbdc01481f5c6e658ecf3c34f011ad846f5edcd4939195df85e41303fb9a88fdfbd704396f7559a327318b952b3e60ce8ddde56378579232faf950c78e7f0b17c3b8dece36b788a8473
+SIG: 26bb0882297c2c08a752d3981145dcde55893a11df77f8aa4c19d0b9ed6e5220ed12e9fac3af13d0f0c71568f4a547d30114a6599a236806c4beee6765284408
+
+TST: 154
+SK:  0c93d99815fff8fe22b9e45aa02b3e6445ce1d6bf5a65dce3da107aa1055940e
+PK:  4d27a47b0fc80800d84d244eebb1deb4436d97633a83e67125ad52ea01685057
+MSG: 11e877de58c134eaf4c9f1b53c3dc451d3c055f16b09622725b279768512fe10a7adb0765b689ec21d5b6efaa19f1b9d36254df0a9367f441b26bdb90b28cbc403e5074082fa1fed58e140dac97aeaf483e2c13f3cc560abffaba05b763feedb51e60698151cf56efdf1d37d6ce0564486210f052e937f2ea26f63efa5d247ff188329bb1aa83ce3f4f35a3d7dec14599e5feb7b6d5fe4296a
+SIG: 7dc4467abcf6431adb7ccfe868eac8cd8a615a0ff65f6a9e338375b1aae3c49a126c9eba79426d1641c6b97c3e92c194e5ee4431efa2439fd450f2cd018c8700
+
+TST: 155
+SK:  989e99945635192c023cc5186fc25bbaef47240775d15a56195d88cd07c3748e
+PK:  ca0beafdf731d89301f7723c5bb7e5a1c3ff3eab27c97d711bcd76e42054bee4
+MSG: c48414f5c757d03c523ef3f3b8510771b0ff3b4b97de279625d349ec185a29927a66b9593ba19338c2f5e4131f1ac07ea46d2c1b6e4ab5229280b2e2bb9d140d1ef7af7b1692bf2d097b80f811adcfa95d5cbf9eee92a1641c552b4be4a0d734f0afd470b9d7f4e45778951e21fc534f200a128b96adb8373f10cecec2dac2996a062fb3c294315965a9d5d7b077c4b013c64a38429769d23eab
+SIG: aef756bfb8a7266e17d15f3f11ee50ed25be420e95a0742271ebd12294e2cb96ead083b8ff0b829d2edeb14da86e402ef25e6d4a5a7958c184ed10c176cb570b
+
+TST: 156
+SK:  6bdbbe06d9f4219eea6403a357b25e561992fae0f0f614561dd86d23de415a43
+PK:  ed52dd1cce32d9b485e0940746421d36b9fde6cdf0211545b634044d4b3cb8f1
+MSG: 582ada13d69293e49bbd461032dfea1ca2025b52e013a33a0387fcfc5f7c0b8ec955982607fc901e1b7f636a9d371e1f91fe476bdd44856e275d67efa14238164354c231124c84de8f5b89d5a58ea6744b4d3b3d7906905233cce694a64d696f5a7024fc9033b1ce390899a3b441a48e53c7c9b30ba12e7d61f35f15e658c7cc4407e2f689ea8a55d01bf5dbacb11954754f920f09dbd48409bbb5
+SIG: 950206605b0f417c90843e2c8d8e66c828bb10b99b36eeeee8caf2e0e5484d93fe02bf533405f4bb74a50e5585fa0daef4821f0301d01b46321baa31e1f08d03
+
+TST: 157
+SK:  d761c8c5a9601b9145b7d051249b004107e452e563100c6c788038c9ee8adad7
+PK:  e6488775d6407efc7b2bca890a7fc62266fc54cdac893343b4f59a196d948898
+MSG: 84ead5eabd2fd4b7c79a9a928ab8ee0a16a5fd667a057f8a254663d56daae156d1a49affb2996137b9d8b340e635732f9d2b4c60218442541e72d2b00e1ee7a73c3f67caa499fa9d070b57d076dcde96b0764723c3c659c7a00c1b78b15ccc2223890b51067fc81e23e9458ab0683ba626a53d0c3793a58a9857bb44b3bd85bb6ce53a85694e7f53cc1bd46d50eda37d81f5381b513d1f38339d291b
+SIG: 7ab78b64e6db359a2dc8302e1092ed66fa736b536253a1cd90fdb8c10efd78300225e191963599ba549cc859209df0ff61cd069b03d254e6e7d76c798440f907
+
+TST: 158
+SK:  c5e0c7a7bb8b7ca07bf0a05ea67eff6deebfe3714ee3e1a227f4dc8e242a2fa0
+PK:  5135efcd9052bec57a4431caabe82680eec0a33afd59b30203b280ba12be485c
+MSG: 3770a6786652c4b78a043edce07f3e204d81997c42afc22331f75a5494a826d7cb69ab4314a473721058a1839981d5b7022d0cd8670377daf3320476d25b9f559561d66ee0a709fe17361e2a52898f5753c4fb43bd0c98b368f512adc09cd927c6622676926d8c2d91a14aca32f226f70036c1c858bcffc2b59f54c1c37bf81eb52ecb3f00da602c94361b52a5afddbfd7e05036e377503050333be512
+SIG: 2e7fdeb3484d0a5e8dce94448979496b0642cabc3733a51f8c3c5c51c19ae319018da91091c2385f2f4e9a59edbca2abd0d085ee40d3f0d42061a5a9832a370c
+
+TST: 159
+SK:  11bb4748d2547e6196be823c9be7aa18150c204b12ca8d73c1bd46b11a54b475
+PK:  efeb42da28d764966403dd300d9f9451b258ab1c80df06fe5943153f5301cccb
+MSG: f4b765b258ba35b427525c7f10a46f0bccd357ec1ad52a5b139417a9d3894c512d89eb88e681b1f30aac4c115ccf36545e83f37834c82e8300cc1eb289af4375968c29c0ffefb40e156c20c0432669ac8dc0a83c13b1e855a84ad0133c40c82c87ee1e7dd4084d741c80de8a7a9f7759e843a562099c4d7df875352039ff4d3824651386c97759ff7dba52064e6d3112e080819aee8ce723a1a2aa464d8a
+SIG: 44c58da49d2365d27029d1eebb3bebf7c032d858aa07e0756b1c26a5412d22691176031341ad37d7bb7843289eb39db491584c1b2a1da2e4a2649c2293826606
+
+TST: 160
+SK:  7452a00156d794edebff4adb1f7a7eec26217fef67c3d268352b2b5460a7dc25
+PK:  5f4dc338cfbd384b5f1c14c226701446b52b1e3e2a3cba1a40ee2825080d1de6
+MSG: 8c4ee2867656e33f5269414d77b42d8e4750dba93c418bacca10938cc3b570c6603d52c2344488607b2f934f6d269fcb2ad966219b1ab11472f42c672ce20592490ec5baf6a2d2fc8a3ee35374b1902fdefc7870b1b626fa46b12b6cee241f601a9b3fe4c50812e573e6752ce2c7644e3367a6a6b77758d8e4934b58af23abae8fecac25edd734030ee7cf39907e3eed8186a19a807103a9fc49d38f4c8460
+SIG: a8f9fa24a3dea1022e73f0d88b1c37d06d0f0b20bbff0ecdb4a40c86d7e475617c03570a7419d74ba0f1327096bf19f0d0cf9f51d483112f26922378682f4807
+
+TST: 161
+SK:  880ef106733f04e76195eba280b3fadda0f25dcf96a6a99c8ccf842c68afdae5
+PK:  70cee33d41c728ce7b141931e6e8524567d7601eb79f67fdcd07b9d682c650f0
+MSG: f4f38d077f2b03da821bd36fde673d666e52f4832e1c0dcfeef049328acb7bd71ad2bfc49c123516e196c470df0847b3848a45a2c69bea03e2afa7e58205b63b523814fc8e242f059c69ff7e40f97be8125b70a54fdaf35aeafac79114a7b419e6bb9e70bf07adb559819600dc25e51b4b700d27ca5472a0e7cbbfd14e099faa3a72002da538cbe45d621ef0d5252ba29d83f8b3ec8389c9ceb6c6b2e8d8a20f
+SIG: ff6caedd8a468aa07d4c6e7131bbda76182ba958649376e711f44c7bbacba6077bea878ba5949cdeeef05cfd4983b0057d275ea3e18c32659468c30c47ac8f0b
+
+TST: 162
+SK:  a2d88f37ecc2b2c05dd6cb3159962c5f646a9815b2fb37791fc7b606e2913ed5
+PK:  58dd67d7a15d4ca0341a4c869566cad8c4ee16e583a10b4824173b08290d92d1
+MSG: d1b87e9e886dfbbdc8ca8ab9010ecf9bbaf23f72ab3cbe769db1d43c2a474a81651c464e9fb92734634641c9485a0239b3110771e7f75e05252e4d8f4c0aa1ba08626d7e96317c20acde2ad99b23bdadfd6f17468eb402ec5eefa57b47caf972b3dd21d89f0e2989ff87d51ed2e2d639c1644e698cbe0221b8e179f3cfb04a20cb2470216a6882fb4ff799e11536cf64219f0c075176bc7cf0f6c5b7925fcd6155
+SIG: ccf2400cd673e1effd20161d7b68a5fb87c1e99d3635d78c2da1b509fac33346c069163a6c46c7826a48bbbd03b05e6e2351fa62bf89bf7ccf9a9024bd157d07
+
+TST: 163
+SK:  42aafd0ae26df1e7aa0276860d752783af97280439bb23eae46e3f84caac78de
+PK:  daa2350adb55dba9df7d7af5101998fe515d311c3cba3eeab9138233190c3b4e
+MSG: 72131b80ad599b6f5ff698547d16e7499d71275e4e9b30526a5aac0b0c8b14fa4a540cfb1145fc004418bcd318c1a70e6269a3fb69baed86f363f5b8f97f569c20d4f4990e7bb4d0c39921268d636ed0554bd62acfcacd3b8e030217aafac3044c037e0f94da18c6b9a0932c3c5875d3a93fbdadcf67964eec9ec2be69b48f020f6c9874de5f8a5167b5ee024a2c2efd0cdcd2acd8c1f787814141e30b38b163175b
+SIG: 116143650b6c133d617859db2429c2913579790b2197d7b7b1b4962b328721032ceeca58b2d56439e233bb84dc525e284ff8df2bde1db4986fafd21b3d7d6a0a
+
+TST: 164
+SK:  b69c33b11ba67841c3d4e6f9234e35370a28b47662ac560b27c078b66ab1b021
+PK:  9df68e9acf67379261744db5d1e377892f2b692ed5a38b37073c04de5d226737
+MSG: f9ea126d3ab21961aa2433900a3982b83e0ef86d52d13440afa4817f9b822fb582cc3932bf450d4677c9188181fe7526ad6fe5abc61d0ae759f215013c0b2b41064cb6278ba7e39e2f4c10d6cc9605b3869e169d7da42e88eb857870fe6118bb02bc08c8055f0c189b62f79fb146b4c543aa30cc0cd57f037e9ef7a63711f66e6f2878931702202702614277d513f0850b758549336b30cf40ab8bd460e60e12deed04
+SIG: 24368fee5bd848b4c661a3be4f310cfc436e79ec4a78501b81095fe51614231b6ca1ab1269996ad2e98e299781af8e29804b24fe5679ca3ba650c5c4cc58ce01
+
+TST: 165
+SK:  7b63613f6dae01cdcd5e6b37686971cd8d8a99542f6329a12854a9d8ff8105ac
+PK:  72ec43faf34d8730177d1f0743c74c20bf72c2394b8a7d471ffe2a04ab00811c
+MSG: 1816488f1fc83e1ed5911637dd42ba2077657dfe1ae422ad0aee59df9dd56a2763c2dd0ef61a12bb825b0dac1eda5fbb691c5ed58f3fb325050b4563a4042099982fffa5d6ed742d95823da8e1787cf746ef63b3fbb0e88a6c0beae4f7318366936b4917f507336068b194680900a7bf4a6fb69a5c387b97e31bc7f9be53c2a89e3651ce1de41b10e921b206ebf32e5621ef8081616dcd7a2059437efad014bb8e2c8221
+SIG: 76f50b2b9c2ad97bfb9499ee41928ac072da5e8bc71d0212550942332b62e70c8bfe1c722542394688decd917aec8f95353e1d72624b70ebed5d17f6c5497702
+
+TST: 166
+SK:  3558d3a74395bdcba560e2c45a91960cec6cb3edbcd30e722f7f055210f37b51
+PK:  534f43eba403a84f25967c152d93a0175ec8293e6f4375319eadf957401fbbd2
+MSG: be75444f9ce6be1d83af622a8c478d510127db56f1de6eb8a5126522b09fdc6ca0862cec0b8b2aafa31c17a2cc477da533d276a1ae4f8e0759d6afa0b17411b5170b52f20547c72f3e88d48cb456fe625b62feb0f81317edf1ec09ece534b9f500d4e1b1bda2db21982aa95094226ee9f5b0a65da83f91121c96b3b4010ae7826c9e80636cba00f70c3c8a279b01b95294cb850f91709f4376662a580b15ac2981afe9f854
+SIG: b365b5561a13a54517cf90d88b35eb0967d6d58414b8c1547e693159e01378563654c50fb42323f09dd78ffe28056ddfa54febf44891e8a741b6a1687d728605
+
+TST: 167
+SK:  a35b92f244063a19bb5e3ed4d699ed2069607116d2bd08113f0d8373613f35b7
+PK:  7ec93601864ee4995a4f7abcd3dfc101e9e7f369e63de1ae68a07aa7f075b329
+MSG: 65cd36dae0168d69974f95f09dd9a59db799f911e1a15b85a00893b8c9a3d48a2f58ac126bfaa0a606c05d94701d273abf7d68817f2c71b1c541795c4f6095e26c9dff803f032f75663fd1698edd97ff3a0e72e1b7c9948b08bacb5f7de502b2fea67ca2fef190d60eae92d15158da444a49d2e9d5a573e8e177e8bbf7e6c49f907136e71d2a66cb07636d48768ff417c8beccf4323181fefb3124e434049ea45dd5019e40b4
+SIG: a23dbe3757e478dbc84d3db3a933b0428cedb6b01b86d8d73f3959878dae6f0588f505cd4d39f2ab4677b64805d629652a22529825c3a91d043749fc71f03706
+
+TST: 168
+SK:  72d4a564ca15499b5e4e75d8ac0f28217d32114a0c649a7c8eaadd0cc78c520b
+PK:  c766bd73837c4faa5215502f1efc90c003f711bbef55170091028a34493408a9
+MSG: 6c7e7b62eb244a45d78436e2970dcd6c0f7db82297a86140ea58dd22c2195adbc956d4c4ec05354b21efe24cfcfe10e17622368848180d2c4680cc215e8ceea6cce222161f1e092239253b9746f7887df2425ab5a880bdba98153be786dc838cbeca016b1d06524bd6bfba809a8bb37adab15d42415f86ec0358365ea87b8150b05441d9d49846871485caae6de359736c27189736d8f1765f3e5c5f6b92168396390bee94cfbd
+SIG: 8fc4f179330b642dd86ca9362651b83b006d8375ccef811d3c6706f91594651df2769953723046ccb9bfe66a667e0d11fc3ea2d8226234fdd5164765260f7b05
+
+TST: 169
+SK:  2e5aaab298e66c2dc1d77ea7421ff895255f9d900db0450d63f9f79c1a7013cf
+PK:  0381f3f19045719b9e8ceb562f0e965dc07b09f371a963a281c749c2532f654a
+MSG: 3df0e54c711e3132d7ae953deb7b66869ee531ee40b63ce693206cdb2f4bda0a2569e913ac3e6532c5d9648efd4627780fb8a31d107e033f054d19ed8b7c49dc407d2e949de25f99307221d35843f6d5eb7de5cdf41b91dbbf34cb6c9c530021014b56abc44ac2300313615608a7b4a235e99c14cef8050887032209488b9eaeaa82c09405fc75bec94dd42d6ff1b599a63ee5742f3364093ac92cabab3035822aa867ae56dcc99d
+SIG: 7c7430305b361a9e35b2780c4d4408071b2130931d39830ec8d313aafbc83a65dae19cb747d9d1c4ce3f359cc824ea8c92f66a42b8614e7848b884ac8aa4ae02
+
+TST: 170
+SK:  b636a02448003543db864b40b5d8d6dd9ad611624c9b0fc6890c51ea5592c790
+PK:  1ef360495968e56e6d3fe740b1c84c4e4490ed682deb4305afd596efb280223b
+MSG: 4aa85aac25034f614ed44f7adcdbeeec25fcc2a9eea32ab6a8699506f7a1cad3bc892e9dce934e75b0a8cd14642b778599286cfd8f50a9e4f2edf9f9d6291a2e2979cf1806b93ed8c9a78fae199b2854a03ec406ab3f720835ee263fbbc91cb4ef0758d775fc784c7d5b251ac8937919a9e67be88c9e44cf2ec7f560269aa0f1113d91b84401db15a3c48c7dacff4939ee01babb982fb95625c6c3ad78749060551bfde8cce4fb8a29
+SIG: d4ba80300d5cb51353c03f28c44fd0a424ffe1e40d78ed7bb1133e8fe4e187505293b20a391da962c6a8ac0acec9c67226af3b6195dabe39b3662294da3e0e09
+
+TST: 171
+SK:  5ca0543c71f568a00eedf50a9520f4c15b526e3fb0da816c29ea3d50b2f62a12
+PK:  d4a2933ce19454e331b5280100209a6ce8e569f993c2acab51dbe864c5cb2563
+MSG: 4ef8496978d28c10abd54a26356ee55921ceb350dd4b742c4161fbeba8a1601f8ad0484b21a8cf5a294fac00ec8a6f59e3362e47bfae1e28a2e6d017c5caa75fb0f48482808037ca21476954d778ff1a0586da3ef69d6cef6d2d8df4ae7a85442a1e46c998cf407a6ad4c5463a43c248f3b6937fdbc845b60c6d85e0563cc16ba9675d364f525f669aaac95f428bb58205099f9e4a6dbbd0151fb65babe123e5393ad64026935cb488aa
+SIG: 436823eeff3edce5d8587d68e5473ef3d8dc9465b558b6e8e7cd3137eccc80b4c4e806edf13619d8e717e69f48d7061b68de02c8209be1f7ac26ba8edf606d02
+
+TST: 172
+SK:  5f87117da9bbb6091c94da6b230b7d8f6de0ed2a076413b92eacdc43abbc6897
+PK:  aa786a146226832aa73c434b0edc2d41d2558f820ab8f87e09e6cda91072b9b6
+MSG: 2297c40a2e8365bae4c5f0630c50b13bdd9ad9770a5d9a9451d00874b023d25ecd468b96571b2f16dcb1b0d3d756c1f044fcddd1c51f27727a0369c9cf25bd6aa59551b5b07cf8f807d92b159198639704740fe6eda0f26dba7e75d4530b2800f03fb6aa677d84df75d68d4fbb64ad21001e3fc87b609b9c251e8ccb12bbca927447e2054e07688eb8a20521a52249e7b943bed60e6a93c01e3eb621f0460c18a690b6f6b66edc6e8743a6
+SIG: 0f19e6ea0c05f38185c01c2d6477995daf5065ba9d80173fa6bb23a774dc88b3aae879d8a62471d2d304cc3dc66278a7abcb0bb0771cd278e11e7b932e9f9b0f
+
+TST: 173
+SK:  b53a644c92ba2dc7108b16833f09ad5917846437225a773d32d79c97733c0a58
+PK:  515818c69c0e0a1706b04143842f3e9e271448fbaf3a899119c32f42566ffd33
+MSG: 13036daaee45fcfde0c53e06d05aa9c01ea94a67e86c6c538ccb283b368daf7078d3fbab580c76ecf82b4e9660f068dcbb500b80595017c5be3c448fbd8a17d97c5643197890e167b35345bf65e75b82c8d65229f2f60aae2772581bc99c49d416bc3d78746ef830f1af944f4a6715ab4ffb01591bac2857f1a9c9d1700888780006a31607338f7af7bedf6efe0b57299ac915526fe5e1e101298708c6e61b84220afe95b53f895987456152
+SIG: 13d2cbac7976ad27f0bf669ad588efb2c91bab8507d57fb16bfea9caff2b0964e75625c4d808d7bbb78c5b464edffe4949ecfbc8b95ff6fdb1bdca2742068100
+
+TST: 174
+SK:  d27c9eafcf88151990bb5b2fa8443e709b5fd8d78d233803322dc86d93d93295
+PK:  08e0eff529776714686196d817fdf71eb5b6e8326516ef489bfe186ac5c5bf6d
+MSG: 77c35bda32a5967d8b302fa7a47583ceab89c9a609a667b753155fa6996f8631d0ebedfe0ac364c77e85ba37311f0de57a0dc2c1e9e400d58b424a322e1d5771e0a9fd9502ad0232ce544f07d8c66e7c3147f8607ac6189bb69066f2fad631185f457f467eba33228ecc40e894a77b571698a9bfac841a54eac5219da99c6a9125c469a22fe81f3b951433896f19ce39b373fd7e5c7b650a5ef2365ae7510b0da5e49d7c07073cf166a98387e8
+SIG: c254e371445633137442eefe40ad4a82e69b1ebf48a685a2bc6ffbac126d228487b2e3537c97ef7410342091962e50c0cb85de7b39ceb41ac4078d40f3407106
+
+TST: 175
+SK:  70213d3a79c65d6dbba542a3679635003a682af5fa58de6b0d65bfa24184901c
+PK:  4402fb92cc1249dd1ae1690f03b3ec4f1e9bdab0de5bfd289f10296830fd403e
+MSG: cd6e1cd9c90f566de043d75d7244ecfdb38e8bde2f9a6cd5a4fdac72b5ede6af62d981918c5e610a38789274fa10e527f85fad209b76ca1c281ad5890f9c96d35de522f1ddccb539b8798a0067acdd45b6e344a5d9a97731f545ffa4b17b875c67b48e9d4c4ba72c98a4505583fdbf1e12f22b5a7a494746cc9b6c1b571906c67fcc883a9c15a3806875b659e5816b4276c3190e25cc1ac3de47bf99c49965388f54f3ef8eb569906c6008e5fbbd
+SIG: 5b6ce2774d400ecea8a808f5fd0a797ffc6116752376cd7bfa3b2cca3a84d5593f5c03ad3eec1d89532275c47b7ce2a0e9c59cc4028a8a65e5bb9097ea71c208
+
+TST: 176
+SK:  5d540b3b14f0c0175c047eaf026c9070659ef13e9d28e0c5c516a428269b14eb
+PK:  1d2d4d551a57c6fb2b04181049d4039d575cf80c0bc6ec7033067f27309344de
+MSG: e4c9e8706898cad4ac68d73c130efa04a54f8ca25919ea6bfaa54c8c720ced854c5e9509102c7b885aeddffbd1b7f2c5922583677ac9eea9a108c7e83e8871aed5a084f5440b0f391ad7ffc6bab4574af1b96770f4370e8e988e85ecb1a8d6034fc3d7f49f7422023b9dab5d0c16beab5f5d37b0a4d7de197ad87cd4ff8ce78eb12e1daf739d8b47ab380abe9093356db5b59717751a49e1948472fdacc259ffffc8c1dbae592607d4ec71cc6a8f6b
+SIG: 32527da755312889935dd5ee91b1bb117a5d377dd23ef5b7e15baffae9a54391a3fd234bdce073e098c58d05bf195b4c3cc63972383ba4b51072971aebcb620d
+
+TST: 177
+SK:  ca41769caf1717b4e45c93c121dc82a534fbc6ec0986662c3222d71492bd1176
+PK:  af3f89f6187dbcf9217750c67ef89ed47b039f9eb062ffec9df64ab52b0b45cb
+MSG: 9de8476c5813848ab1451537841cc178002181a2182af305b12e5f7c3b1d56b22cf46ae6276d1826ec0a8c9a7d9f68083b7225bbfaefce82b3b64594052a7700f309233a79fffdfccc5c21400c91cc0e418d5141d486b5219901d6dd2447c1f7b7cf5a0879e70e1dd658d0f2ecf31ebeee11a5c74440c63b9d8b45318c3465d7ff03365edd0385edf80d4fded51f0f7533ee4099f19e93bc9d08dadcd13485db239522ffc81e2c051f8796d62e979fcf
+SIG: 5cda872f7ed6d7c90218ac10bee8e214f3b34d15d25c39255ec9e6b0177aa3cb7368d11cb8ed6ff5cf0c04281d06bc4272b8bc09c23f6f4cd5a810ddc7b9c103
+
+TST: 178
+SK:  fedd63ffd4cfbf618894962e121a9025eea318a80a1adf169d6490445d2e02a0
+PK:  542f2244bdb7d84b87e628a8e6a12f17bf74a9a6d0ea46c595dbfdc680c04b26
+MSG: 2e2ae584641be03dd48f9c618077aeaa18212a4241f0c0194ed23e370d741a3ae11a5fec3b040c16eafa4ac8d18abaa7ce8f286967337189f0495ffdd61995cde31dd8dfc3df5700b57a7a29980e9c823fee85d61451176729e72787c6109b47359b93dfd62e1e5a2d642c057242dae500a94ca1a93bc57be1ade76fe4501c0f6377ed0e9246179aecdd9946b671e8190e1ed23f966e96409b948222d8ea5839de904fc51348073b8f40edbd9b4a4b2275
+SIG: ed59d9e23dec3494b0fbc5d10cd02bab86b3eb35abbf9e4d4a926479f134583a44ce72dc4122aca377a4072b7156462b74e8df46b686698636836ef203179c07
+
+TST: 179
+SK:  38f2184eaa553656ee2902706bcec4acb5af25157ca0f6a2d48de85285fa3bc0
+PK:  7ff03fb4c82e9c15d659df424b3e73ed1d78006f3e0b79eb64d98c13aec6ba37
+MSG: c2df77c9e479f61983b6c7483ef93fb85a103b213923926523065ebff2257e85427e05cdc27582ef6c16be353a3b250372d6370eecb6c8962917eb656f2641690189d172a111051557abc2494e32cab65ed0633affe92408b55c4ed8af65e2c5e7aab887a3cc8d28c52e9e1336d0b7bb3fe2cd843e7fa1680342f8a4aafa02c4ab252f08c3d46d5f00fd01484263ee635284f6db26d6298de5b0dd238da40a8d2a93376da0302783a0e3be23d9e7f990d25b
+SIG: 4a6413c2c87f2b3856a8decbce493adeae0c69c94134707fb0f18f3049fd3e3d051abdb9d4bee253c6107c02d57ad7cc9f3101db660afac2b7981938e9564f01
+
+TST: 180
+SK:  8bfca48462d2536f74b84f6af59f5d8582ff8f7ec28745d672e72eb72e79d3e9
+PK:  9d10d275c3d3fe459f7fe2901bce389191cc8483c0f51140d9c62b08fade81bb
+MSG: 81ee4cb9c45da691dacd7dd09aff59737267bb55c3ade1ba32c17b7d0d2d0c6079c39d5fd5b29ba5f9c1762097709843eee5612bd20bc8185bf64d5c934184e13624e6f877a2a5dda15c0df62afbb97057cc91cac9a18406a0e0109cc39b2e3f812e227a4062d5ef81c92c22a7dc797c845d71eb6ea9e42ec8417fba90a96d2bb1439418330b4bb2f99c6d63d304a0e506dca9653e5de0dd56e309db1a76a0faabab163774f000088cef3d1b7a6cf661d2e1d9
+SIG: 44d77e439ef6ca5eb940c60ff8732ddc16269ea023bb2613bd447eba7fd69851226c4819ce8d44985a49f3f41ac7af33c47ffe5f89304a3256e445f8d686e307
+
+TST: 181
+SK:  d7480d4272bcb1557b1bbee04915c126a52ca6d6a8bb5314a0e1a52b59bfc99c
+PK:  99c839d36d8f5b8652618ed7b0fe9ec3d94efff4c453c540631476a5979bbbe0
+MSG: 615cc19f942017365ba8bfa256ceccc85ee289a1c34bb1442acc0716c7fc2caeb76a9de19adec106371e47a30d2e1239ce1f7dca25526d604bdd647659d942bcbac368911349c3b946a97da10a42dbcf3c73416d2e6ba22bd29d9f705672e9e338944cef01ad21f009742e07bcd888ca31e1ee953e8c1b1fd954b7dcf1a0b1d5a069065a66cb721adc020f4efe1abdd16742746939285780d753137ae0140bb410fb6ce33676c27aeec593a88cbc73afd9f40511
+SIG: e04dc8442d352173e931818e290858de85688a4649ea3e3c3ae74edaa54ad01b64622ad8a090b6ad60adfd01881882828d39078bb5b2714fd3ea8397a342fd04
+
+TST: 182
+SK:  3c2d3650735b41ef9006bb45e4be2e0aa5cde851aeac421ee9c1b492d87aa18a
+PK:  3e46ddce298844fcafa00a1b47eaf3de70596df1bbee3c809d1be7dd94080e34
+MSG: 1425d8d218da1a10a80b6a9c3c2750efe41657984abd5100f451ba949db01046b7126be8402334ed57528bac05622553a86b726722695a8fb331d8565417c4ff0f251a320ad06dedbb750def35d521c3c4cd571a45ada8450653d5e81fe0beb53aaae787b3eb653c2381ed55aaf2590ee5ed8b6626f1c4b0430a54f39658624e6635fefc98fee8fc3e1cc7ff3dd420de9da11a62fcae0e0cb454fc6f7df03954291d26202f1b188b657b3bae07389449b75e67422f
+SIG: 3f2af01ad5377ac39040d41a41e36e7b93fa7235b841791f432ecd7f91a3b21ab7196c883ad5a7db446f6c06672460f3f63ef863d9432be9caeabb79e87e2208
+
+TST: 183
+SK:  74965996268cdc4c09220bd31ce07b217a03826ee981fa89f3a2359ced095ef1
+PK:  4096d027c1c5ee4cbfc04b9d534174029fdb50cf5610d3021ef933b4caf33985
+MSG: 45b2f064615bf774fce97f51c464685d7b3e4fefff9231240a719b3b0621cd4ad83305675cd6eaaebff791000b0b1fa31d82d8181b7fe57c5e00cec56ff9022e9ce8db66356e408e3ee262fe627789e65535ef1a63e8fec933be3dee34d2facdb8928cc456abf2f3e8cab47eff1ca42e8b0e48d2c73e7bcc5de3f1056fc523dfef6b0023f32889ed394eeda032abf6bcaadaa7f3ee74118760ab6d91df528bdc5807972c85fa7cb56e387d7332e779e52d0dd7db0cfb
+SIG: 8c6628344317a63aca6f78cfaea965b3aa5522ce914195141c08870a1b8dacf34b79c7abc693cd9e5ebe1a2e86f0332d2048db3cbdef01687962d6df249e3800
+
+TST: 184
+SK:  0abf069c08b2691c3a26f79dc8ed05cb71d220ff78f3a5c5780ae9da18e45643
+PK:  9ef3b5cc016cc82dbdda705766aa448bd61fa1aaf1170efe9149daa9fe64a1ae
+MSG: 0d055291b2e861eae19ea0fb2069d8c9eef4f1347f3576d78411ae7c0b1c1caf31fde736dc8accacb662df76b620b62ce90b9f92c83309128621d057cf845805949088e938ddbc3d41c5e5541fec8298687ad2f79acda01aa215d25821436eac9d268716d4cd6050260cb4ef6aada4835e073a845821ff211ae2baadceb6e57f06f88345edbf93bfdf54fb74123b57c0fb4a79608d8db6740889e15733507799f7a1fd3017bcd77b28a2bb6c91ecd154e9c5a5ffa0eb62
+SIG: c7566fb3b4d8def667e040f276d3ed98d36dff460126a75b4cc2100386bb01c642f6d8de7e649be6e0818b08d77ce60f4ee5e7717a50884bdee02034ecf1cd0c
+
+TST: 185
+SK:  f3fd5ec5e230b6dad1ac3d3aebadc7863ff89de2a1317f424d15989a3efb0afd
+PK:  f99e5d5eeeaed1205cfb5c2cc4e5e9f6b4e7f64129f860104ca6244eb9feb564
+MSG: 71f28973ed3df05945fa0bdb23e9beca651d3ee6bf9fa45ffdc6061e42fa2e8d76235f0e9e2daa65e52631fc3bead33da055bb492e4758e598a030a33b3c40b34371459b233ccc043cccc3a3cbce549e20e0b2b43305b64aec661aadba6556b17d76e3bbed62c4a4eac4f88603996752d2363c8d4a2789d128f6e959945c68c30146d194ccb6839ec65344601652c18b0074e2bc7668311697d960c7066597924d704d02a0193fafbfdf571ee0dfe414dc2f52896912bc32
+SIG: 44b0124663adb0c73aed49f73403461fcb19111b0ba17aa996566f477e37d524b0e1f107612fc52a7c767b181fbf4d629bddc08f30584dec6124c5d39d423102
+
+TST: 186
+SK:  738f1310a4e08f917a0a5c1fbaf4ef72f95ee62fcded50868a3daf98856a448d
+PK:  42272c2c8b08470ee5dd8af8849c01b7508d3a3c65b0330e695c841d5dccb2f5
+MSG: f0e7ef6782d04c6943b19eb66ff6226b736e3b0940c09bb126bfc4c4ca7a5e7016c286b7bfd73aa6a79a96031bc81cb5da68cec71a6a0d39780cbe6a0cd4774d3aa06a881610444a8c9d19102294e5f635187aa6f48d11912c7094b38833028d570cb110db60625bb1bdc37affa25ea3c8f8dbfc2514f4365c62b2989a66d27c80384e74ae5fba8c1c2af9c72c4971e64fa6a1dc2517b31ea57ccb0815a7fe2da0f146caa08431d25d151662d9d26e95229d0c62823664123c
+SIG: ce1e3577b6a21016b9dd0b517baa0ccb107bc199b8bbaef68f950c8ed58013c853b4d338eedc675079ab1390462ffefa6a959b043f8b5651c6ca375ce0b4a403
+
+TST: 187
+SK:  8841d22aded69c131ef5ee0a10ab0a9b77cb754ede8d257a5372726e2b499c6e
+PK:  715ecca63681bc6e9e31d18848902f4d96feaf43b95d008642903b1763bc9fb8
+MSG: 087ca6be2a950c024b3e7467fe00a7d364555d5dc6770f5ebd260642525bd3c0f965db36d7b229a57421eec64e4d991cdde59123034470553f4eb0be81ad2936c8ca26bcab4e5d79040e29798728601684a468323cf3baae4d948d0a1fd905effe16dc44642088df53f6388bc480edf4aa207d0ed161eda345712b4c00cb05fcf635ec2588785bfb8a27cdc28996a1db3e6787023393c075d83c9038fed7899c55fec307de3249c14bda49e8b895860942c36d640bb893779142
+SIG: bb2bab7003f1311be9b8c883fc4fd528adfd51a9c99db3dca8da0fca958da19a10eb22332667b1a0065d3dbc0d06269a1259b6a890484aa2143a52695f145b0a
+
+TST: 188
+SK:  c02135e7b65aac72f63c32bf5bef5b68c7f3b8ed56208e59e4752070e9d07095
+PK:  dcf600f244037a75203ae11ac316e8dbe9986f0dce23473939334bf5cea48b0d
+MSG: 86d9491350d2566e708ed356185d610c73465b2a5c7012919958af2cf76af995230d360de400b7137170dd0835f10fcbec224ee4e42c7d1cebb7f580fea8ed6223163bacdd1923a572cbb6dc26ca8b17ade68c6d2808c4ca1eca28eae9a145f68d4079d8d59d140e958228e7e99520e342dbd7457a9159740f48bdc27b93bdabeba465cbf0c8df5ef2c0f9386eebe656f5d749d5f9147f525266910d7b80396a90be5cc188a9a945f93e753fc99bafa18ee0a6dff79bf8484898ef
+SIG: dd5cbae479eb5e229574c21ec3bed911113a57a1916d3313457515d55cc5b6e6ebc52c93f821d13988dbba8df5096d55ff9c39e7f9d561cb58930c96a7a5d60b
+
+TST: 189
+SK:  154a47eba1b8c38362ea61faeb0c0ad7e61e412a3cba4688af0db2a487208b1c
+PK:  16de2c894a50cbd4ca90419a4ca64942cb14bd335c5d3f4a53e239c280bda725
+MSG: bf607e8b6e14d9c8acd96815af0c035ac73c4104c93786ccc1c9f859395dd781900320ebf356aa991cdc9f503fcee9f83675888a7d592002d2a54a573a96994b3fa865538c617ed8ad1ff62018288a674f449be0aab5222f74c4fd475ed6a8dfb27f45287b22b2b6c3bd15179f267d157d7d8a4159679be85b25c2bb2ba850aaed9ae3ae571be4f75836329cf36f412c1c80f1413b7661eab4a8e11b6024244fc62323ff02e38aceb1737bd474bf1e98015dbc788b027bbe217cf4e7
+SIG: f4b6eb1a8d950e887fd2f30f70a23b41871495bfa5b8a4ad3996cd9bf51eb742e07f4c4d2da4b01ab087367a50e2b65b3cef514e40d837540b8c89966485910f
+
+TST: 190
+SK:  d3028431ce2eef73bd940ab84ca29f13fb26436aa25e1b7bf26cb33f17fdf817
+PK:  63df203e2860bac4d352e722c1c91fe3776e1cbcae8553a4f19890260bf0e457
+MSG: 086335d61275d168eaac0540477f50d4b15f9e50b9be693921ed54a9941bc40643cda62e1d805d0250a81146bd5fe2d39e81444d21e2b21b031c111306cacbf52717f6fb4cd3416f1215f8dddcedd2f0096b0fcfa0a6cc2cde7a2bab7f1e32790b5361df3671424cc722f231bf71895bcdcb7b22ee074e8fb4a9678504e735366c172f07637b7a93149bb21f38883378a1db273fc23239e35337f9ce566d8ddf3b3133cad7f2ce81edb503ce1d27c5a657160b78dca9aeaea379be9c85
+SIG: ce9729a96c3ed28943b27839c73382ecd572960c1f9e90c5eff9dd499ff48f17d25edd1268effe41ee6a81ce48d84de513df9c41442621b2f5491e346be18c04
+
+TST: 191
+SK:  ee8985dc27504440a8758d4c53e4225215797a00cd8631d59bd93bc66f373d5e
+PK:  cd647bb065693d486589156a9fa261437534dc86f46f72d0a800399a7af010f7
+MSG: f2220485addfebce02a833aca33381d1df917ed609950ed24f85e3b02b2b994b4d939784e332f41064c8b4a2630ab36961742aa1cffdcb08c144eeaedeafd48b5dbe96bf24350e14fd68286bc08eeaef8bc6ad9e195d1484afcd30afa8ced4848126d56c81b43c27a5dbbdec1a50c11062ce21c61d860c25a862fbb75c3bd51c8dc07636668669bbf751eacaccb3b51d2c0d4140316cfce2eb18d2908cecd5a188679bc5f5de290f548e7ebc57d41b589a24ce88ee48d97e8d0c7c769960
+SIG: 5bd60ad5e9bad9932ca9c75f231a76889ae7a8b864b91d1fcba5c5d4bfa1d92838adb974842a0710779b3e3094044909e92c7cf046ce519f4c68e8f19ec03c02
+
+TST: 192
+SK:  80dfe2bf7387bad4654eb076f8dae9595163e40127f5df492dad7df04c7221c4
+PK:  d1783ceeb9cf8e4d07764c473fa4061b8274397103f2076d703249d758b8fbd5
+MSG: aa09d784bb09dc999931ebb4c00e424cefeca104818d8eaf0661f09728ad025ef47393210571f17404e9aa6d8cbd5fd88cd7dfb8e2e8a108c05de206f3408234a3b463dbe71a07d05587324524b7326ee79d3348ddbed7871b86fcb488031dc9ea93f6b8d7fda6239348a562444faf1e72d31af35443e9df53e762f3e56b48668f9784b3368ab278a48ef4546a26cfad0d0a5161698f26ee8d34fc2b3d6dfb93b009ac296f6afe487ee335eac9f02cfcae5fcbd1a16ba4e71be1b112562fc2
+SIG: 27279e3cdcb03ef557a5defc2f6c58128a6dc3f8b0385958014e709c1f61b0ae6b403576f0e454d5e4c64c173138ee4bbd5fe7b60d06c5abe23fe99ee3b46a00
+
+TST: 193
+SK:  da1f868542cd7cce7a5ca3fa3c24081b4d2344b21a157f0264a347132d19659d
+PK:  cb3a25a53f272ea813804468d6500e96a1eaf822705b7790a8ac3e98cc4e524b
+MSG: c6987ef380d5d0e74196443aaa3a32356cbc02636c5a4b6d62a8114b2111bc1abddd9e44b3672c18b58d4ef591af4562e020049f8e1274688e1f8e5296d2f9252e7fc84cd1d0c58e98f0f160530aa22c871eef652e71974ce91b4a65fc25fd09fa1b6c32086e98ec708d9abcb1d9cc8e1a089ed8db2206ee9570236ad69b3de6821862fd2c70cd83a32a68b0486229553d928de48d03a104e87381964abea76683976d527c84163a12eee0a55986cf1431e9c86cba8182ca94689bacd165fbce
+SIG: 75c517ade4f08d7746305743d1a776c3c55eb5eedfdfcb5eb1d5634a1bdaf7a4b8d24187d6c8850e3ced6567a03c4c59389a4cf47114ce5473160f230546e60d
+
+TST: 194
+SK:  f13daec0ef33ddd133c7d244d10fd27ddb23705280ff5f1815f0f656d836fe84
+PK:  2dc7f1367de672c51e005c74f876f982593996873acba079292734c209c2b111
+MSG: ec02ff1804b2b309af3158b66272a14a3aad83c41a719846f7088ca9792af575c78913c432759f0b9a748bdc5568496e41658cc1cdb8da6c91d07c3ec2f4af504249b996aa00c0071cdfa793f82d0ec5d267262f518fc029b88e20b6201fb9e05abd3f9524c5da2fa8978ff2efd48120cf00822d1bee90df816125d8edc0cfb5de66d16be63896a412a62b031b7118ac13fe2c9faa6b1a3342f9ccf7884166cf489a84de26b5ce5b21856a3af289bc6622c0aab9f2142d393f5d4b236779dbb066
+SIG: db771833f7fdbacdab2b5cc80eed50afdf13783b7fe5e903d5dbb4c2e535316a6eef4c34f004d2b9a4e2700bd6e2acdd564c3c80cc68a303f5fb091cb4340f0a
+
+TST: 195
+SK:  42dc16c57fb6f128945fa101e05bbf548ef7d97726b692fe404069cc57ccefa0
+PK:  0a1ba5df523996f954b34ddcfabad3f3dee21a5fa7a4ce322d216bd8ccaf438c
+MSG: f2714c23a3a6fc11ad15c980b7350fc84217877661188055ff750d82c49c5fef7bc8e6aac574a1b79a3f26d16969c0f406eeab3e9e12850a55709745e30dffa62a69dfb2b64b3c1bd2bc3586e26d4eea714d2a7b71cf79fb8ffbf2aaad00ca3e4f2b6f503cc1fef2eab3656fb44f8d62a8db8ab58f394693949eea57fafecf005f6ebf1287dba4d2d623c02ea171f567e526add20709ebcab962f83d98ef668ebd01ef20488b3665e3a446fbfb13d34050942c749bb2dffc766367fd452e68e5b0c6
+SIG: c75977e83bcfe9df7292a860ed972555b5c24416fd4b7ee3285388fa5b1447608e4a347813cfe093512a7651e422e9867db7b97c0b0867f0b8c7b7f4f02c310d
+
+TST: 196
+SK:  90b455c6bb9cec83e137357065339d030525d0ea7f5b923a2d5972c3c12aa37b
+PK:  5cef038c16bfa4b4c923a0fe70cd7f25c8bc837fdf5a7efb9d95f21b96be925a
+MSG: c62cfdb9d21eee6be47f30727aaee51f0703789a431d32228533350217a93a18900669c95956f3f2ae90dc745a71e18340d058d16b4c6fe33b64af8dad973fe5dc02e8520705c7a8bb3ccbe1838c6c249337f9b6a4c0e1f8a4e5d103196fa79998923d0422e9d079a72cc2a8f86d659031a607d4cca0b947b3abeeeef64c28da420d05de665a5510fe55f77598ecad7faa0ac284800b53829394c4ae90be66678ff04ab46da265ae06402d8c83cad84d61a051de0260559888e779f74b72a5d71c132f
+SIG: c9345eec2c4a0aec732386494a69a3fce8b8a1be366bbed1659f131fe97cc037fb1b7c1b68b0f3023945d20090a0cd2c1553a47faec4d66fd816ce121168f309
+
+TST: 197
+SK:  dc185c2ba0b378dfe5dda510c32feff535ca2e8a02434b326e0158bc878e8848
+PK:  33d6cc05a434e419280d5864a1af209a2c676814b70f72f8141ac7e0573ee63e
+MSG: e276b11912cca5a84bba650c172aef3a4d5f91ac722913bb891a3ab0424ab07ea709cb8bba3a3d11f82f51c2af0162a82f7219ce27b35a30507d536a930817e40f85a22a5a432b94d192c3c8911777cfdb7fe937a67502770d6d75753d3ae88229e08f1ed23b4328d862ac61863c063ea9848f8ab96a0213d7b936c48fe754836c98487859d199b3d940392716a1d569e6c0cb1ba918932cf88525e256c8abb11aaf0b454655d5db55713cebba287ae202651ac872bfc80feaa7e00d47c0be38e658f7c5
+SIG: f1e44514d2ecbcc8d1a7e84bf584ce731835e9894f88974f098d456b60718f575ef4d8062f2182504250cf83bb2af2a79b1f58a6a97bd98da467132d7bec2f05
+
+TST: 198
+SK:  90721c43bc366f24bf4e8c993e138024682f1029dba35abeb0d60c7fa710021c
+PK:  7c63a2f13b7b220a0bb752e3800753b8b6b32669378ce131bb77a9a8d230e9ae
+MSG: 651c9617cac958c7edd4a5f3fedfb83dc971abfbb69a31e898cca8472ef068034a6d2376ee0e72d0a9bfee275796c3795adac8ebe1d12b66ec268f6b75fa3941154f99e223faf2cbab5b92e2b3ba7b79be7700ef9dba69253cce5356b0c4e74703cfcafdb5546850b46232675c90c02d5e426d33d60cebf0c7930182379dbb007f536163c8ddbbd3157bb2da62340133f00ae2682ec6baa6416b5a01521cc10e04695295f2e5b94c05f00383ffe954830797f6df823172532f98165fe314ab325929af8385
+SIG: d2064a6d6c99c6c3f152d2d435f24e34b5459b082ef11e944a77ff54ddf9862737ecb2ac8d54207d36c51ad41f36490a111ba80e126bfecb09def6accbdf880e
+
+TST: 199
+SK:  9cec246758e412e7378b4579eafe9fac5a25d5405f9270b5d7e543414ec3d5da
+PK:  975a9e6a152caebb2f9dd0deb76dd922b6dc77055dda03fbae9e7c685d073aa1
+MSG: 17ec9bd47add6ccfbd787af0d9013e9cc979aaf850e09426d3b28edfd71296eb31ff8b21c5fe7be050f536324c3ec48850e0b508a36bb4cb7e754b327183a1b394d88a7941d1ce8dac62a5d8291874d78485e51f29ed05865a206e52ecb12c5d107d4ff96f25d3c5d181d2c4ba6463600db1cca32857fcf597cbdfb2fda2708a8aba281b43c3d28c4a4e7983361509f61a1074e6f0ad6101c7b567ee4078e9839c47f46531b729ff0efeef7c9d1a8d833d9c0f42812a34187c3a778c165c09d6459c9c7ceaa2
+SIG: 9bad1e3b1279ef658f4d071644c63ae2b7a780357e9dc426f1650ec0634dfc520f8eda9dc8f10aa7324c5942d2347ff8802bd90e95fcec313352cdae64f32a04
+
+TST: 200
+SK:  d1403f63202e080525843bde255eeb6b6783c1caae9d6ed00ba60805bed1941f
+PK:  238aea3ad6d6f27783e70516bbfcca4770366b50ed0fe6a4e966b53af121a721
+MSG: c4f17d442fba4ca0df8dc1d0628d7d7f36b60b5758d7c13b80b8f97a62124d96a23b279565495a8accab5997115b13a4ba220a73957eb7930520acbbfb6f54cf68726b6450c6ffa9470b055ea262914e2bc612633f1ac3d0618a23dff188a733d76bcbcc460f52ab61e19938f9c8caaa792c208d1f6c754728905fda51d881a347a53da744d3baadc0a76c474c558680269095f9084a74471d5c09ffc29141b5bfaf4954dfacbca663d037b17ebf9559882233e5ca5a8bf75cca4fc9c5a4109f32e145f3853b17
+SIG: 8e60e73c063816795e29f5d64ece1159f1b5d5021a6f8f655e261a4d0026f5b94ff2923250499d995298480512e4126276aa4a226d015a95827b3ce692e23302
+
+TST: 201
+SK:  bdf6bdc31ab0b5313784483abeca6ea5e9cdc68f81b21f350d09c3907bb9b6a1
+PK:  03627712b755e5069fb9ab8f9e899724029a7f268af9398821eeec9360c9285b
+MSG: 90a66aafa5642a98e79f0d88147080167b11e4466518f195cddd8940d12ee4918d31a6d4cb77d0bf5af29983bbe5085610a79daf0c75a78ccbcffbbdab2189c394ae24e265bd8c55fd3f4098e1b175577549518e7a4dcf7452086dd1278dd58ea4c0aa690e917951ef39fcff60cbfa1e90910bab5374928d4722f702bf5ad6028ffda6541fa5ba1a3779ec78b0a95fe3850c748b6c8f42f330ec79541a52a1cf57db72df4f92ce7f748aeef1af33bc5ae0a82c89dff216f23aec168a7dbb510aa632daabcc971b3f
+SIG: 38fac603ed246f833f1c0fd4585698b0a71305eff0d14a0049b3cef073bd036dd451b3dabadaaeaea2aeaf83d395746f4e86866ada971cbe482edb0419332f0e
+
+TST: 202
+SK:  57b3b14ace1cd0cd603e6328bd219ee7d9d094487fa668f28aeec02b43c909a7
+PK:  24e6b6395f97ea0e237186d469b71923d2113adf403beeeb4a2d27909aaf3eda
+MSG: b2e0dedd802eed996dbd5836bf8688b0d1201bf5442ff9bbd351aeefe1a0c21fea2b5c9fe5edee47e921099b05aedaa80367c1ce08821d783a5b64cf059c0f4335083986a5a6ecff8c84fd40e0ba5dd5e5d2f01112a84ce5cf8e0db78beb182d9139c0b0f3e0060a3fa73869e96423f170df9af1cb9c35566d87dff542223f6d439bdb54729d366aff637b0f36a5d14b15d612bd03076cc4d04c1f25b3ba84e0d1fe474e5718d1a17d5a488465662ee4c3f664b4c9274b649d78cea4e85243f3713239048a908ce3e1
+SIG: fc79fdc6d090887a61e43c6b9187b657d2e4d9cbafd6e7caeb7ebdea842825b78fb949d2c49a0cf38b6c73296d82c8ddeb1fe2d40aaddd7964da68acf8c66f0e
+
+TST: 203
+SK:  018a2c3deea50ab506751f9c2adaadfd9e2192121609931684eb265e193e7f89
+PK:  af410bdddefc644ef12c9899ff71b9e1d0dfa3d69d8c2cd676c1916b34591cfd
+MSG: cf7813efac12ad1c7c7322ccbe54aa0e9a8ba4fd4345b06e4ce7a35c8b1cd5e3f7f0688533849ba2cf4c75b6f20926a1194a72df0e1b1b34456a2133112d006722fe811d5e40c4121159ded88990c0ac2bfd34f35af4f07cc402e9a381a675d03fec7ec438c4ad9d929aec8f242def023c993c9e8ba18c7428e88fde68a4711e506d7969f63c8e0bc83ff0de4e1336106c05e09d5922400e8a81bf54885667899785882b70f20dd8fb1e75f5855b765a256da4341bf23ea0ffa18aadda381816946001045669c8d04df0
+SIG: 7a44e6a31932dee6dc2d8394e29a6551d13e6c6ffdfa218fa5b998668d8439db5e05379fbfa0da5b563ed966435ae2c54e3ad16e1a9fca1f5a157a080704ab03
+
+TST: 204
+SK:  bea445e9b6d3f21235912cd6c42ec0577297ca20a10357880c2b846dd8e2cc77
+PK:  024174966221699ea4b0a37e517ff9b16598ae4d4e83bfa3ca50bc616841f595
+MSG: 4743c7c099ab815927b3674d0054b6de59af2811abc2cf7fde08f62929185adc238fadd5e75ae3ba0036ff565a79405b424f6552331e2789d9709ac1ecbd839aa1e91c854817597958cc4bd91d07377507c2c8d3c006cfeb6c0a6c5a50eee115e21153dd198ea0a3aff62b7075d5a461788783f050e659c572963d7a59e5afaa2b9c501f43c6ac08ab4797c4566d22b93cdf65a99a2a1d638e79f72b5f4631fe5e9e5f968f6db7a1880df51d8febc14942672f8ea6fc3a72814a44d66d148420a69000f68c330de5b80fc6
+SIG: 6964b9c5903e74e99328acef036558eecd3369150a52e2cbad4bbb97d461b3dfc6b3e8455813a4f4bdca46302e02e683ecea1820171c538e54c3de6c954aa407
+
+TST: 205
+SK:  6447540ed7be0a11c2a8de793d83c6e244983db18d78ec9d75f1729c92e0fdf1
+PK:  391212c8edc4d334a5bec860ef0f5ebb5ec44e8bb51c0f6741998959b2b379fc
+MSG: a4381c7638c48799e9b5c43f67fc3aa3cbb5ec4234f37e70ccccced1627a57683d1e53f4e0883d8b462bf83f1308630368c89b491533ddb8c9a5b9e8155002fdd581a9a5be0e430b9086a6beac4720210f87b14e862d97e5cc69286786a7586723f231ef0e3e1b932dbba3a18a0cb221cb07f80e6a8e1300056c13e702b23bfb3250ec7cc864d5c7ec5786240709c56024ea6be5f7b15a4fa5555e39a744a1dc557df5b948db220b3d5745746691dacb4421641cdcc12e7ec0450293f19ec57b09cff135847aabe446a61332
+SIG: 3ab5f88e2f7276b5b6583dffba5639993a905dbf9b88ceeaaaae3335800e4a5f10f83da6d6225a8dbe99ae80075009dd508786b3975113db478e14ba101bee0f
+
+TST: 206
+SK:  0c587a811add88b994458c3c808ac4e3a83afab26d4cff5c961b9df0b5c83344
+PK:  06783b0cdcc5028c5638bd748f0bc76f7e94d1aa2015ca948738a3500460aca0
+MSG: f56dc6b76076325b2126ed11d1f09decef9d15c31d0e90cdb1a27e089cc56329f6ec3f665eb6739ec5678b3f37ee1fb37deb9e240092b7a88fd25525acd55e294eb1046f9b1b69a847eb9ceb7b1593b9f6978ef618c15de4e059ecc3bfda3297a19c2df202adf72155cf21eabd03948df15198e8a68b0884f93ad5e36eb0983cca30e45a8b4b5fb8136fdea8a3341dd7877540a557debf7530cc33aeeef6271c3f0af6d09787e815f2f1dd25ce4d2fd09ffa9f53081b469c500da4d44180c04eb1869329cbf2d823187e831c24
+SIG: 33b4f4274f20008a721d1e8d054a2b4e95327e38bb07b33c4bee7e1ce020a442fb2627eda3b7ac93cd3ab0b12b99935a1a9233111604da4acffb5315b907120b
+
+TST: 207
+SK:  66cf401a2142fcf4a8018046cf4140bca18d76ef6266e7a024757df172a5d653
+PK:  67d48dfd23743cc2ca40e4dfd6b8cc5d84be82dd2b1120cc476e6af6f25ecc98
+MSG: daa8efb3fd41f12fbc55bd60464157a26d718632d882aedb6bf98e47dd2337879e0b46452e062e6dfbff3e7bca7289e4ef6b3f41d4b03bdc2c842afe97f3029883ed45f6054dde9690649abb2b8dc28f5fe8cecf80fc1ea411bfc40bbf4fd20b218cf47ea8ee118d4d5aefa5c1bfa08a8fb1b30d6de0977cd15e50292c501f2e71ce2740ff828b8432da5a594bab5223760b64792ed3a69dd75e2829234943656513df1a17a2a067a9a8eaa64e19569f46939d34b99271ae50a47d7dbca3620c81255b0e1fd1f3cec851f1b11b35
+SIG: d6b0e80e60bc1b29ab8f74808fc460847795ccb887bac0ecaa8e135297a85097712b24b0a1fbaf7a67c5d530a47d0643fc8702c059d215fb112dbe475e5bca0d
+
+TST: 208
+SK:  5dbf885aa598e895571f5f65090b72323e9d70b0f58110687afbbc383afedcac
+PK:  fa17eba76e3bc3ea6dab3a5b120dc5ecb9ae6f00138f7d36dda9268bc4722174
+MSG: 1e0b6cf15ce03337179c02d65408df5be9200c3782b6004af94ea4decb257999d6fdff301d11d00c98c372fac0d026cb56dfefe3def7eb99ac68d6968e17124d8446f53e8d2d3dd890d37a23c7e0b83a484b3c93bddf6c118e0281959d27bd87d37e843d5785f4a40771398494e6c4322fbb675c1d479321032148f7fe52564ddf7ae7ac269d0cd2e552fec589aeae0fb93fe3eeaef0856096cf4f6b3497e7235cc8494d810a0b46c5eac87f187e505bb7764f8045c9541983f7b025698009a23d9df0bd1a473cbee4cf5e9488ecbc
+SIG: e1429dab2e42cd035b7fc602efd6baf94706f16eaf2f8b5fed329239e875605fb172f5dd9ae2bc2eb42eb474567e292f5206e82e694bca0d6d433b867634cb0d
+
+TST: 209
+SK:  84b3aedd4797a565c351de7dfa0700b9ff7c4d7291c8808d8a8ae505cdd22590
+PK:  d7ad72caa7c22209ec4678d11d5590a6cb28a07117fe5aef57b50751583201a5
+MSG: 532567ffa53b5c0fcd29c39499d2e78ecd20e63123499240e775088b394dc65c8baaa0fe8f6aa7e70181f9e10add8b4a8beb0b2ec38a43309f100cd4be91c6f48e79dc0aee93a15c9403773b354a8d42ed48d8f276230fa6de5ada501ee0a653b4458f0ecf6d5b3c33e2141c662f6ea055f741e54586917d2e0c4eb2b56621f9665fef3246f0bd800b533e3bc615c4021f8d0e2ad233a11e7736c493acc31faee76a097dc40db9efc22446eacf1cc18f51fd10236a2f942d0a53c3ce209108b5938c0a9e536b89ef0ad6b405a10f22c3
+SIG: 9220f0edaaaee1b876350dbe9266061767b86296c351d4cac99d07cd612c6efb24f8f9b0b975f95c42c5b6afedc892f87efedd39d5160294c27658bdcf42850b
+
+TST: 210
+SK:  6950bfcf480b98ea18a2d5ae5ba6e7668f4c283ff2711357740ffe32cf25819a
+PK:  8e4c6f233f7b86321c9d6799bac28aafcd2503d7aa0a7bded8722727fbbcaeb8
+MSG: a401b922aba57ee0c6ac1c8f1b48296a8562eef137526893886a08306e2203667788618b939864467a31f16edce152a42c25546b640ea8bed189a4f89886a37f106911eae1f50081bf795e70c6504437d2a80cb839479ecbb87c129bcc5fe31d716ef978c206d7f08a793466594f4d75e215bb6374596f8e7d00eea724780943e89bd3863c951bbd24efee23c97c2c797c7fafbf8f2c8b43f37a5f881129a09573fa7a034a285e80dc4ba4bc9564a4dcedeb33167e0b30c5a00b9a109a2231cfa0012b29b2b3450b892eccef0808e503f8
+SIG: 94de5df7a25ecd70205d40bc9499fc7cd7136568060a419a93be6e318664bb6dfce60e2d4e633f7ec148fe4f834ed277c1fec4c4e2a86f44c4589c817888db00
+
+TST: 211
+SK:  61b260f5b848b271ef48e5a56d297432d89f2ab85bd538fa668870d0560220e5
+PK:  6086fe8735f399f1af2e395e0fdfb5629ebcb04b6ed4a54a9e47052c6e8191d4
+MSG: 2826295d79945f675476bc4d45ef800d80b1f0398e4be60e3de4571ed108df989f032de6c2345d9948d677927ea0b8cf1a5ca36fd5f23c25dc0d2ab5bd565a54af46fd97d338d770e3a7b47efb54c07a1664707771eb4e37d9d70ba779251dcdcd3bf6d1248adec53f787259c4d594d5fd4ced8e3db7621d4965d48298178124931a3d0cd269b2d53b7cd261b96d370c5d9693c8ad133ed58945ee3540e10625d924aeba9bdafc656100aab276fa996b1db477bf85ea559081d5b4c7307dc1595654aca82f7b6d2ddaf7357c15a4d7d8b908
+SIG: 9828fec8ff5cf85a98f450770b5bdb4b80daca44379d8f53c91c348e22df64ac48f2b6e2a7b3b642bc8193a194316229e69447ed241cd423d83b6fe7b2d44b00
+
+TST: 212
+SK:  936dc1cef6a310747f350088055a39aa762d9a4b52c8c8e4c682794380c2725c
+PK:  03b31800412df4d56f1532c05828c0b72528a67a781bef4c06c1fb6ff2ce324b
+MSG: eb58fe86c4ef349c29ae6fb04f10850e38c6823dbe64a09a5bf1e0ce600d394efa6fb96ed6a8f2c9d4bec05e6a5ebd5a1bf4d0c51db934e57b79e5c6a879d975197dbb10475f65c7f8a8c6a77a420384b5062a2740f1401740ee0f5e043aad7a2a2b4260c5d907f705edaf65b0e375dfc7b00bd660db6147f2ebe870a0ee18dc2ba3c92b0b76fae2b90932cdb6c149e46f3feecf4c26f0441f3a9e006678aecff8ccaecaeda73a18a68ac988b62e83a9bb5188aede38df77a9a164abbdd9d58e52a6caf7222389f198e85fbf966236dcdbd4c1
+SIG: 3f994b8ef528f6421c6a6a22e977ade5cee887263de38b719acd12d469bfd8c3f68e7ac07d2fae80a2092778df0b463537ad3a0551997a3d5b51f832d9c8230b
+
+TST: 213
+SK:  f89eed09dec551361fa46f375973d4fbfa5c5c12f1b5e5abf45cfa05ff31a340
+PK:  3e0efdca3919fa10d4a849cef1de428851bd08efd248594fd89cdeb9deee43b0
+MSG: 4cf9773da05fd322fc147be900ef5cf256c88afdad4b08c230dfc8981fb69f476f7d45ef7c9006bc10032ba53436ac22843e0d76289cf68f9818fa64031d4b40955059aa69110915889f5e22732a1343912581ab3b11a3bae7a471359508596575f888160beef966e5708f0e3147eacfcec1caa3ef240c5e0a14c186546c8eeb64658350b1affc0cfd2ac213af670afca7bbc9dddd28a465b586e69c388cd73478d68efb322bdf86d9213011e711b2b95fefa7bb9b5939761706aa7121024906420bddf1d8800a4338d938fa137cf27e9ffc51c6
+SIG: 897e6f2797c3f326d2cdb1d2673d360631f063304580ff5b4eb43d39ad6851834c9cf891d9f0905bf8de075f7635dfca601adc0f14e7b2c76f7571bfa468ed0c
+
+TST: 214
+SK:  400796ef60c5cf4084dee1801c4a1975e482e70aef961cd42e2fd5a3fa1a0fbe
+PK:  f47da38128f2d012cc5797571d479c83e7d8a3409802f9a7d976c27067cbbe43
+MSG: c473325e785b27df4471eefb9ebebd6461d570800181100ff36caf3c38f67c1921b157ec8e6126f955aebd90ea3fe5385f8042cd704b27cc1d6978c0e2a296695f5ef97b7c2e16ae4ff4d063c688d7f46e964e1f0a00503f357345977683d6e4c3423d56bdb6ce864b6987e085e83e70c7c1a14e0e413f592a72a71e017d505b64c24f1a1a6b813e064e6e0cf8bd4571d0ff2f267a6a13e0cd430463b6ca3b88f0cd40b0fb83d5bedf6f7d47e170e87d0a750093693eda232a6daf98125727b9588ecb894ae373bae3a445a106306469a4c2cd77ff
+SIG: 84d3aa3f361844396754d80d9fa05b8b2fa4abf3a0f36b639bee9cfb5c8530a3a9cc34677f92a913c41e800f2e8041f7666d07ed85f16a57d817b1241fc5ee04
+
+TST: 215
+SK:  6703a6232c5e2e65e0ab3b92e2aaf9f5fbd33fb46988047d6f4d0ff5387fa029
+PK:  047cffca8b7b11ac6eacc0eaa0c5b73c75b9c637956973af9d97b2dd5b605d6f
+MSG: a26b30a769197932a3a62854968d760151612366778dc994576a2e0e0355496b46200e506948a0d102b6651b2e7334ca6c6eaef8bca44b425970a0b37d6bde0da9d3c1b9f51cbb25bc335cd6fa928a74f2c0dc2c6e99d37a12863a474d4df43aad35415ffcaa24d8c29f914572ab2abec3892db49e679c5ea220c2f519a7d033ac1a2c5a467869e30eda3d2635ca863431473f958d552bdc5582352c290d0ce4fa9cfd0ad42799c227ec90b7c9e5db9f5a7b6d569212eed94d323326805f2b3a0010d6c11eb4107c8283037652f50dc067b6dc81f4db
+SIG: cae96879e5b603be866609d4a053bfa12a51378e99b2a2812e4789267d8f32f473243f8af74b9be73f47dea50f0d165ebf49458b73e53d88580c191a182d1904
+
+TST: 216
+SK:  e0e72f8f178633626733bcbda2ad2a50e653890f15359b6c22fc7345ad333109
+PK:  d13cee540d84b5667d516fe7ec7239bf8da91546ee791f84edd8ffcf3a083e76
+MSG: 791fd613c1095292c8a4a2c86b47ae026155b8465b607dbb416477ef79a297c9d7758ce34af9dcbf1c68474f30909fbe74b7ba429632f2403aad832b486b72c23054ad42f7653a9ddb456cc791f348886a7ae5dcec7c0ba815f7a93a10fe331e903b970f7b5028be49d14bc5620d63792672b98b9488c67ae16646693e112047f0ac8921ff561c92dd0596d32df0a6e507ac1b07de516c98428d570a37db9bcd7c7e61c6948ab3fe91250dd1d5bd671275df9a972f22c2ba36804747aec1ea2416c1f41ab87befde31629b2d43317ce41cda03626286c0
+SIG: 14552171b95245ac0f0e5a6e7a2f541721068db650c6dada04c28cab7c49195f6436712144cb31913c562e30c39d8a8549fb64ffea81c7445143b5f23286da05
+
+TST: 217
+SK:  544dafd9960d829756c6d4b3eadd44375fe78051876bf978a381b0decaaa8096
+PK:  ae4f6425c1b67ccb77f9aacfea28eaef769c8cacee035205cdcd787e8d07629d
+MSG: 447fe7344cad1fae09d6a7d05f09d503c1b3d3d5dfa584810c35bc41e4955693706154e2d751b2f1b525e1a14547ba7f8b232088a6fc922702d93a11cd82949c27bed645dc351fb4c1242cf41d01575412e792aed214531d94fd66e03dd32e972fd77f6947a353e1ae5e00f5a6ca77992472f096b6e7475fe534e913a77bcb0d681fdfb3a7a0dcb56d274df4aa109d4a8a37794a9276f50006696ff12ca4d0254039df0fb3f72a960da05c9872f2e33ee81d1cf7a6f48bbce0aa18c7c0f06ba55e67689e0af587b500eab79cc7f9640bca104b7fbf31f08e
+SIG: a2ae117c8de4ca6d6fe75e466023bd550c26fedd3e74ca13adb625f272e175f14d5df550ace7d82288efefabf96311a123bee23889ad3711bff2b8087946bf0e
+
+TST: 218
+SK:  bfbcd867027a199978d53e359d70318fc78c7cc7bb5c7996ba797c8554f3f0f0
+PK:  7c5ae3bab9201199dfbe74b7d1ec157125bdbaa4520f501da3f248579dc6c22d
+MSG: 117fae13e78777b6219f020214c1b87c57046d1c09ce82ee2b5629898d9b0de74a15cfe99f80548ba913d7036c56285a4cba493b52d2cb70d6365ace3da12b1f34a2778af36ef52ab82ede04cacaf2793f5f89831e3b205a9ee4c1d6fbdab4ba4d9fae65dd79a5fe76b4b39a3092cc7148d211e85ee82ab463d34dcee9061d9c21ded2051bbd50b413f0e21a0e48d1ffa8dcae240b3495be25d93151b57aa271ab99aa708ca28080cab4804fcefa929f5f1ef3f4c6c0fbfb40bef7ea1b509b36ba1260323512379d7bc3fdbb5d3faac9b00e21f12ea1ca2e29
+SIG: e48615b65633e61993b0aaa1fafb74b9629c384fd592bd735fa1f62c5cad11291fcd8c2e91a50bfe0b03b43502fff3a5c382b9c2821907efc34da5ba054af00e
+
+TST: 219
+SK:  df2df8a9d66d5638cdee09324e7b10f8ed29ab91387e3147b7dc03f7cd800508
+PK:  5c042e157fb7fb12d4d4fef2847141ecfb57c1253e14eaf3004d6513f52fe625
+MSG: 21576615c9346a63dccf0c50ecbd7c6d72ad452cfed43ea73202cc7a98576056b9664b54622905a1e7221720730ac685d3bd3977ec3959d446bfa941e725b6fe16afe5432c4b4bdee7aa0fd8030948ed6fcba7c0bdb40c2e517da97456e74e1f93d5ed676de0f4a8b0aea449404bd15b6da79dc1b813965fe5572410d76f5b5eac663050570311dc9842b6fbf8806aec03151715cacf7f21802e8bf5e98a89c0d7d0d098b73c6efc09962e36b4e030c1a64b5d349f5f2042c74428671e4a2c7fea0caee2422d85c4fcddfed32213859a69955d4e3ebb7e1b2022
+SIG: 9a1074531ed43d07bffc7f2b6c13b8838fc75cba02c7d1ec7ba38bca3cef20dc9badf3a3064a2c93b1842441420b6a8d421a960d70dfb7c70eec295f21f83f0a
+
+TST: 220
+SK:  e8ee065f9907f1efa2daecb23a0425f353094da02bc2c931f0a587efc0d13de1
+PK:  c72651b7fb7ac0337a172977496fd7f2a72aea889385835e563c6b6053a32dc1
+MSG: a2f0c1373473a305d8f1d99138b06b9a9694ffaa8a88222de9f729bee1305175dfb17001cc77f67b6d40c90c1a28fb226c11286db4a13e45e69211242bcdd01cb6e2c454e76c0cab881b4d2d9d3ab100a5d61d1725d866e4fdb66d93d77f5b308693b9b5a333e57fa25d1e5d2e38df6e4e9ec84159bbee1ffea926836a0101c91483bd5bc88a6f1cc4d4e7f008ad08453a0123429dd335781c7cbf8d685a8999ed1177607004a13c4cb5ea4908c542607d3f2cd6690cf1f2a7455bbd38f538f07a103964317efbcee37eb46931c027cf153ef86e43d78281ebd710
+SIG: a510dff42d4559a19a7bf0fe0bea53d3e1f22dfa6be55039895e12a5d07da5f2e37713ccb2eb216011628f6983f871fee286e66fff4be7582c961a1ed7568404
+
+TST: 221
+SK:  c72e67d8c3fec004ff618718a9099eb8ad7b06ff3b8c542a7e8b9847313475e1
+PK:  4eb002d3cceb188c6658fec51cb479a65264ac555c75cdc2249cf1ce3defc16d
+MSG: a8f34135c0132ec95b64b0cbf51d66900143370406791fbb55f2b8ca953cc74a46e08b002fa2da21b951b8871f7a29bc6d38790afc66a329c397d9f9250bae0e30ae3426e08d8ead0179a3b313c908839192f289a3f3b6e960b4c5cebef0a09daa9c7a15c19d4ebc6fc2ac3cd02232e832b234edd7965d687bfeb758f70fa7963841b7859bb97c971bd557bc8769524ac4c6eeb3579793334b522d176bc62f86b4d5c0d4017036d2b6bd4e4384416ef8263139691a8606170d73c93d6417dcc1a08a537c9ed4400471a46f52907b46b10a8b6889dbb4647a8bbc7149
+SIG: 2d7bab8ebda7fca5bb3c25f51dc51b73e6ff6a3bb1b52acc7811a7d2595cd6fdaf730494418e2f57efdc5617b066fd7b6207680d94fb8c43d3d4740b41cb6901
+
+TST: 222
+SK:  696450b557ec3c94cf1af1326475634aa81def3814ff30a02ba7f2044b59c0fe
+PK:  8584773c566b0eed3f43281705b575a434e47d6cf6b251b89803fef53534cb29
+MSG: cc257829f30a5f90dfdbc247d42e388738b76c41ef8a82a5e0225ddf1e386d77080b3b9df86c54b85cdf2c32f367aba0c3b6bf888a5a6903529b6aeb4d5407a10180149114130228fc4356ccf366b77be89796a9e71a0c693f31e584a4f143097ba370363b67b2f2e2fd8d6fe8b4e8dbf0d7dcc1a8360041158aa2aff7e2a325b8e518f193a28bae05e3d52b26621af402026d7f250e86dcee301a58b631eadf4527e958f02a61587f0bb516cefac009fe51052fff53336dbd94e7266d3b43caba8a1b38e5d871c2a24a4c412fff3f7a9a52a8ab23bac9791b2b5a669a
+SIG: ce8b0a5779f4f5f401e84d65927a0c28df829e95d09bfa97111b8700078ff894cf7277e34a716144d55306fc9e2f64cd287583cc8003be0e8faf26af7640140e
+
+TST: 223
+SK:  a8dd35f054fb6ff6f0ab094a0d3d1c262832181df35ccd5192545ebd6a9cf529
+PK:  ca412338d3814b886d964b71925e1aabb3ffd07834dbe7dc512568882b53e4a3
+MSG: 55a7ad9132d63ac161e7adb132b9189fdd84c361c1e4f5419a6df73df4d7aeb29a8dc4bf01490d4f484e2d12077517f5fc7ad0bdeda20a6cb0227942290b08c3fe33ab9b2135bc38a6579a54bd982f7d1417ce867117aea918dbd3dd476e7eb5b5d3c3e48a864a2f942a31501aa2b29b53b80513c95d6a411844f0dedf16a29ac267d331e53bdc2539bfcf32dc9b5d640f1231e2cafb0ae94bb5189426863364262efb47b5b5ccdbbc93324216a799b6f50d3704f15ed59af6cc7d910cf062d1be632dca5df213d487d8564f2b2bd7d818bba27c364013d92d7f72625462
+SIG: fa709fbc8382af83d11812618dfaca452eab83e4c53fe9e5858467d07b6767e17975c1e06393d6dde15a34d9473d1cf4d6d8c2d57394520080fac4e43448be07
+
+TST: 224
+SK:  ae1d2c6b171be24c2e413d364dcda97fa476aaf9123d3366b0be03a142fe6e7d
+PK:  d437f57542c681dd543487408ec7a44bd42a5fd545ce2f4c8297d67bb0b3aa7b
+MSG: 9e6c2fc76e30f17cd8b498845da44f22d55bec150c6130b411c6339d14b39969ab1033be687569a991a06f70b2a8a6931a777b0e4be6723cd75e5aa7532813ef50b3d37271640fa2fb287c0355257641ea935c851c0b6ac68be72c88dfc5856fb53543fb377b0dbf64808afcc4274aa456855ad28f61267a419bc72166b9ca73cd3bb79bf7dd259baa75911440974b68e8ba95a78cbbe1cb6ad807a33a1cce2f406ff7bcbd058b44a311b38ab4d4e61416c4a74d883d6a6a794abd9cf1c039028bf1b20e3d4990aae86f32bf06cd8349a7a884cce0165e36a0640e987b9d51
+SIG: 909008f3fcfff43988aee1314b15b1822caaa8dab120bd452af494e08335b44a94c313c4b145eadd5166eaac034e29b7e6ac7941d5961fc49d260e1c4820b00e
+
+TST: 225
+SK:  0265a7944baccfebf417b87ae1e6df2ff2a544ffb58225a08e092be03f026097
+PK:  63d327615ea0139be0740b618aff1acfa818d4b0c2cfeaf0da93cdd5245fb5a9
+MSG: 874ed712a2c41c26a2d9527c55233fde0a4ffb86af8e8a1dd0a820502c5a26932bf87ee0de72a8874ef2eebf83384d443f7a5f46a1233b4fb514a2469981824894f325bf86aa0fe1217153d40f3556c43a8ea9269444e149fb70e9415ae0766c565d93d1d6368f9a23a0ad76f9a09dbf79634aa97178677734d04ef1a5b3f87ce1ee9fc5a9ac4e7a72c9d7d31ec89e28a845d2e1103c15d6410ce3c723b0cc2209f698aa9fa288bbbecfd9e5f89cdcb09d3c215feb47a58b71ea70e2abead67f1b08ea6f561fb93ef05232eedabfc1c7702ab039bc465cf57e207f1093fc8208
+SIG: b6c445b7eddca5935c61708d44ea5906bd19cc54224eae3c8e46ce99f5cbbd341f26623938f5fe04070b1b02e71fbb7c78a90c0dda66cb143fab02e6a0bae306
+
+TST: 226
+SK:  6bce4dfd53bfa5506f2f554d2d994a0dc40cafcdec7e1be050006e5c5a4b38a1
+PK:  c890023728d8397070291771e65e034d34d4aae5e247653e4ff4c074591da702
+MSG: 3239190747ee33d40bf870ac9ad49d88ee320f63c05257e8ab2c60306597ce76d1f1e792ab6a65caa544fbec20892fd4960594f31b3763ef07d4982eae4a2dbf3377dcc1e3f95e46ed39b7f0222f04bb5c3b434c8f9f310de9f122a29f8241e81e206549ae628d2b8ad768972c98847c1188ad04c835356378bef79cd126869405b129fdbdc3bc489cbd1399505dadef7617b5be5da173d3e80e5838c99e349276242729e0219bd7476ae5c4f81a12878fb483a6c0e9b0df2962eb0bf00157782cf768a1b71c010169ee8522def0024ad7e45775a290639c53aaf48198c42de75c
+SIG: 99ae6782ff27646c27f61e23636ae1881521cfa5ed256f70bce7ce00b68280ce8e0c82aa765afb8b5a1ff2fe42c57441e458e443dc8b123477ae33d884888c0b
+
+TST: 227
+SK:  17861a8d4154acd4fa9c8fc947c1886c11290be222872ff4f8cd25939e4d1361
+PK:  43773f4449065eaebaf8937baf758560b0c4d2de46977839b3b873d5d7d5fd8f
+MSG: 184df5ea3215ebe180390b0ff042ba2381155a038dc732f76a01c7e70f82d1ccc9de9a0596b3fee447209c992684f643df21f4cf9d179262790e8623e42472dc351997e6da189c07e1e8882c07f86c6337ec0113912cf92215c8de1982b8fc57bfabc55a3e8736f73610429d97feb51d794f505d0c5a0b3abd48ef7f55a628f90b8567a1c15ea9d190d7bf4ec2bc9334ada6cb92808dfc2064836fcfa46b96fd7a5d6f4b054dab09b73595feb89ed005b9ec9d3188121de69696d64e7c7bbdfc1c469faf148c38a7785970afe1acd06a92c99478fe44974e3bb2095e4467e9b2e996
+SIG: a5ee024ccdbdd4c21a24709ec53dccb7ee17626dd00a093d0884f5b45c4c9d1691840151c33c8aa07b69b34e16f61647ebe793ae4daa70cff48e6ab42ffdbc00
+
+TST: 228
+SK:  0a84baa54f11cf17090fec61f3f9401508a3a03887aca1a7939394b1ee40a925
+PK:  309a73c62d23d740f2e93c18587ac15e7ec480d25ac0794e10f8cd461cc2b130
+MSG: fe70017b14678b0d3ad03e183d6f53314378379ab3da65b3511257b3d54086e86f2031139021391af9d72085ff7c3dc8c1e2d91e53333855423d0f785e2cc5f8b7799fcf1b70e6becb788e53e9020f2995ddb0c383a1f81038fc3d543ce0a38c9c288a9bc4077f4277dcc6c5642263fcfe19688005a603f57675d2434f3ed1f46d32f14eaeb073e83ee7086da2fb67659d3fb68c62320b7727b3b8ea006576bc2c7e6b5f1ecefa8b92e70c92c88951d0c12d91de801c38b7ca5a0a04b4c3429aba86386e96e06afd20d4c5c2fe2b9b4273eb05201a79273abdbeb37ed1830d226b6bdb
+SIG: 4d870bd53af8f13f214d9934ec903ac48284092cd9b162a44ccec851fa942de715ccda07b7991d712723e7a4d5b4f0374ab85ac3867e0b53ebc46b530f9fed05
+
+TST: 229
+SK:  38379423dafdbf25e19d7231bddd80b4cefcfe2aed932584dfa0cc3c9f9232de
+PK:  597e81dcee9448b77de6829e7921c8a390535d89a0849430aed66364ee140d8b
+MSG: 36125ca66668802906237e63a2fe5ae610f11a7cf92520d19e6690a3adfafd5d07a784bc1a0e185273d11d340d5eff901597dedf450c4699d43f3fb168d557f6c9c03077c3cdc370d34832ccdf2a8e3d75796490ed0242899d25ddf44bfc66f329cf4c45168703c31bc9202d890f3969ffd3ac35a12818dca751ceb8808fe81efa26a5e0d200c5ec1d94a5097ea74b6498fe288f30c48d727e9d3d35c8e12d85420702556f2861484ffd09b4f12265cc9abafeb82cf590028895a7d050ff57ccf5f28022d016ab4094b062e48b66fd36d1e19626e5215efa40fb7e3b7062f81e954830c9
+SIG: d8b50a88aed6f2a96d082213adf8b2519f6a0bbd30dd3cb0f3fd3ce1c643fc029946cd43462ed22513f1d65fca24bde3818166baa86daa798792afafe0c1a10a
+
+TST: 230
+SK:  f925d274aaf1fe1a21656237385e97f7783e78090c5d4217fece7057c80f426d
+PK:  3b0fc370be3a4b19a88ab998c59504ffb59a87606338e673df5b3fab4d9bfb8d
+MSG: 143caafa5f62b13e43dffa49d420fa99f771b1926d40d6cb2bbb427f27b6c266eb3deb2d8bbbd47b8214ad40251cb1907ad65eb94193e54ad85c6700b4189e80f1cc0154c63ed151a8bbbd30e01637ca58e70aa3ee52ef75d0873078a405014f786eb2d77b7f4422f927823e475e05b24245f9068a67f14f4f3cfb1eb30bfede7b3262230ced9e31361db19636b2c12fdf1b9c14510acd5bc18c0ddf7635e003503e6f71e1c365cdfb4c65ee75b4de0694af87076374d631e6c4b8e240fa51dab5e1f80ca2a06c49f42ea09e0475defb184d9cde9f58f959e64092aac8f2027e468126f2fb
+SIG: 79549a317d10a0be322a94a151ad11e77efc4836cc8006a85081273d7602a638963a9caf19c3edf1e25fad1e9d68701a71dea727da6a5c5bcac9339589224b05
+
+TST: 231
+SK:  971f806be6f07d41be8830ff8dae704b08638ad6cff722d8432538127b769625
+PK:  af6ac98dce2078a6c73f6097bab63f205caf6953afa284d042bd50a4fce96cb4
+MSG: 013455d049aa54ed995fbd94e6369955495395e4438822259b1060e9a34779042a1a69211f6ea2077399dd234806ba0b353cd79a57e1c49b250ab27106dcde576ecfa115eae461febb12d2da25ffcf17b715f8d95c2f0c425d5a81f700115b70d49e1cfe49fcaa14fa205e28ec85247f1a6e7128bf3bb3060dc08464bda6538540d0ac472093e5a0720fde2f3dc4788e0e9b0dbfe2a2b5f1a0f3f80de984025b15c65af77f671e1c5e2840444de5c7eda025e6dc1a3ff16e26cc54cdeed56be73f9b01ab2b1bc16c8ef58a5b76dd47287807e5c50f0d7c0a5b8120dfde645a012c5cf11491bc
+SIG: 2037a0a7674b84ff27d0b22f62b4bac65e2dc0f5fdc899feb7800f25c29981dee641c5a50f8b9410970b49d2d53658c89ee16961dccf5391a6918f2a84eada0b
+
+TST: 232
+SK:  2bb0652f8fff6901991148c68a3267877271006ae9589149bb206850cdf52fb0
+PK:  c03b77be983e74a234c1986496b292e139992eb7529e70b3afad7ae4fdcf8a66
+MSG: b923ca67e396d8656fa3dbce8289a38bd3c128cefb30efc1862bb944b4507805419824ce2b83d690ef4cf107492817143bf64c024989af1a7d2e1f5ac97874f86bb0d3773ff840f514d9a1394a3959b011d3a6b816a3fae5de17b2a9ff349863d27fbbb50cca734108751000d6358ca0647a93eb49e2e7af06287d48f2c09d5c1c73e4d8f77ea2bcaa7356795b26728719bed5ffdb821578bd5d66bf92edaf8b238b2bbd7d1e2c30a787f901a33d0a76669a9c3c7f2b552ccb8349c7ded5e1a46170cf28e359e2fdd54b05a562f528c68a56974df82d466637c8e53246a7217e4386801e0e3266
+SIG: 4e158deaaec3d88941296af2d27341012b0241d4e0f46e435e375c9875e89f5e32c057b527bc3411af096a77bfceb45b983efe455e3f03155d6bc7b0acc8e60c
+
+TST: 233
+SK:  db9b812cb3c7c03b977f487d3d65ccd9cd2f3dee11602067dbfb72b589ff3f79
+PK:  ffa038ad8c3b378ce75d65844d08e3d6a92d194a1b7862e9d9720d20679b2944
+MSG: a70092c7697cd4a209567c38ba7fb71aa8f15e5827a20876923943fd6adc659c9867ac6f58a61dc7cec3d362411682000c1a9ad1295eb8b70f242d86b5865eb76b87e3f2c6941d2612ee3bcde8f19765566733152ef54e95690943285f78b375f4036585d4739deedeef6d946db61ca458ef4f650da963c385e29dfdee415fe495845f55197a870f8cdeb5a010ba6bbb32bf1a588cc774d4890184c4b2924a5b8073313bce226585f1adfc229c90bc6cc9d212e62f05d33bedac961d77cf8c2620e451de817f8c1bb16a2c59ff804b635a73a8cf8c181b3f9401c3b643d18a2f706ea9cae47071a6
+SIG: a628a77421b2abab576eed35d2ee3d14561b21fa14a6e2fac263c3eadd79f2fc0669f9429b910b8422b4b29ac026a42e98d181be3507c5ed7c748a1fdcf1d807
+
+TST: 234
+SK:  ce379bbe2fa8abcba51c7a7543de5b7180771b3c44bc6b41892e7b88979bab90
+PK:  7f3cff89f41babf4fa64cba33a5bb17f413bbf2a1e112b50a8e9b1f821d849bf
+MSG: 001a74f095c814d3beed67a8d15fc18efe235dc3f6457812a4039b7a46fe9a0e9de81a7a4e5fbab5ebe9e1e4801bd11b45c9f7ad0636a09bff42164be5749a04c02f0ab61f0ecfdfef799b827da6a274c8d3b39f2e3805a6791287eedb2314d3f842b558b9b489afe1ed37bbbcfc5e60a431d5ac60b39e946d903d6bf6b140e12c7e07f9ed7ac46a3999c6245c8ab1bdb21879a317a3dcd257a5c4f349b7f59e4e43d62d9f1cd16f518f1ca6cad37e2cb20f2598c4134291c6b8a98aae5247e26eefb76aa38c9c8231c17e9dbf271cec80fba5b4a834bd9be81ea841637aa9cdd4c4bf26d7ad24ca3c
+SIG: da98dfb189385b2c853b6cf375738046a8f27ef27974abcecea1db02989b951fe433a6ce1e225b3fa82032fe060a7d3f6c183fd1157f791a064b407650571600
+
+TST: 235
+SK:  2b2ee809d647023e7b77fc541f44875a35fa941d37f7c5b21fd34934d2391935
+PK:  2c29d53e1bf2c7879d73d20ba88ca07a0b216d7f6d05d93663a65c3d9e10633a
+MSG: c4147d64ebfda41a1be5977262958104e940c3876bcd5b6956acfdec32c660914d62623c210663cb2cbe6249d7f5274991c60e950e8e2809049953c69581d2469f4fe982c7434fedd9d4e00ae08896d62cc1fb984dd233150cc2483e159cff4097df8c036bb633003abbfbe18c8fa79b5a22270838123fc9be39b8892c80384a385028c1a81ec58c8f21060e78afd2c04bfd2d30ca3977c6edad518cc1e2004cdc14bf3d15f5f528e5af277fa182275870e5c012f5f82fb1afd04edde4578ddd2160a1a3dbc050e80bdd811bc88ead79bf93f010cd0fd4433d0bc348dacfd0947cceda62bfa49711d013
+SIG: 12d90685775572c9eabc9be2574ca9ae66f0e652e578b21736cd6e654f7c6b1545883d56bf760ccfc3cf87544e0004c798061257e130030cb997a788369a9a05
+
+TST: 236
+SK:  4ea18d6b4af8053b885ec188be48deb86ffb2a69a4cec86637bbd7b41b807c46
+PK:  e5986059976233ed77382c3d9959f34e317962696553e86ed1e5902c4bedd167
+MSG: e9c89a1a1119373206ce40ede3b89a82f89462a1dee9e789e9845eec21f571c0faefd430ad338e4a72c047a39a4259580387fb9aacaddc36a2b51e7b60a87ca1321ff806794cd6dd4549a4df45c2dae3e539c4d7d06b6e6e9f466ffca2fa4978ce3dc792e44a6283880cd138a75a226f985da41ffdc0e32a5a85c85fe9a43ae78fcfe57f4dd7540a6dd3924a49ab39eb69950d421151d96b1e4fd3935890f634cd52a73a755f5c2fb72f9cd5a2e67ea930915e133b47cf6b7c10a9d889c6af6b5f1f4f51094d27fbba228ac2268b344027fd49e426343cc0134399b4b510aaea50234df42c37fa1c4f4d0e
+SIG: 27570c002a487d000ca3928b83cb4319722c46dfb4cca260de790ec0e3c1932688f87362952818b54f51bc7aeeb263f960bc0da8964bf312ef93e81f06c80b04
+
+TST: 237
+SK:  fc1b75d17d3807217351d2aa40d9b04f525b89ed3f5fcdb311bec2aec5cb7ece
+PK:  55e484e774a4392a9d6eeff835a8fbb232cf6276a89c74fc0d1bb2045a8b21be
+MSG: d031bd11da308097e3beb6ffdb2600ee6a193ca6d8324501c972b1a25166fa7a369f5bc882ea45612cf02580254d21b40b0363237e835dae2656c1b7f4736e88be53d6b119c07f5729bbd82f67de03588322879243c5990a7e61f56907b24171a57cbb0bbefba2316277af9326f9cbf3538bcbf6780be41825a2ca774b41bdb1cd5c608851ec2339eb2f4feeddaa891a6326b29d97d7fbf311e3bb749c5d4c058dcc14f452f9334991e271c16d6508c818633927f429804ca7a38170f1b9f6bd73ed675e11e8c0d321fac912730b4ba2f7c428534adcaa4dad314c55807e6c642d494c6b2f0e8cd129775cc0
+SIG: 9a68d151fea3909893359e60b96b68b2a3e2946f2b47b875398a1e39eb01463d35eae7d976f833a762b51f2726ee0dccad5ce3600564fd9dd58c23807fdffd05
+
+TST: 238
+SK:  0d0bf4d42ef810b179eb841771de6dbde76361caf894e42a14b1e09787ea3e06
+PK:  7171510b43fc17efa80b15e320b1b0a408332542e0d36e4ab9a649cd941b5aed
+MSG: 8e2179975d0a8e5a69fe875a3cb1e79aec49c3853e30dd0320fe3ebfb638b82f89ad1643036b37e56e0b55e0a9e22a4e283d7a27485ce9102db6787d6628b77913e10896774e495c26e8bab26e7f9a94d29aaa36aec9c26ad3f50e5d8c0b7698bb5f01b876d0d65fcf5e9e32cd7b89829ed05b0b8f63a93858985bc9569fce429fd37a211abed650f585c3b55900443b6c5d6e8a48ba67deeed07b76e969fc88430fce2709c0bb5ce926ab7f44e0cd79f4ec359ef76748883fcc3d026edd06c8b9cba54b990d30aa41f1448a10893fb0539280c599d42361433a34cdafd8ebdd92efb9c38a36daf4c74060c696
+SIG: 24446bdf03416a4d08614466fb851db50e91a623cacd1b0b35660f3cf933200e15308708da3499a5ad25f0f0306b7942762e20a765b7ca9b901c750b3a95320a
+
+TST: 239
+SK:  57b5194d26abe4ab2116c0f03d23dbe116d48825a25e77d64648b43692ae25bf
+PK:  499c02dbad2a4eab3b6ff1aba3944b91c3f273a382c548a6f3a19c83f0a86724
+MSG: b4813c9d13215fe9f63a78ff7ac95173eb810b4613f0f48d6876b2bd3b2c72bc7d98cb1ac32bc41ca47f09896f79204ecfb8264ce8f3c3e76dc124da8ddc6e0dfc1e13b5a529f20c82613fb9a82e5f5d77326a861faedabc7325c59af33dae6744025e649774fc4f79134bf9f6e3d5875dd91bc8a14cc36a66283d01d8d108c13327eca53057ba50bf210c19f139de6494982646198a1246c271b0a368c10aab95cd8961235d742df4545be68bd010dc0db23b673e623609e420ee76b1056c520f9ce8fbe8ee1863df97d17b7174636c3a2b612295091948810d1d4b8a5843760a2887dc55ef512af041ec54fad3
+SIG: 4c7345960c8fd48a7dead71dbd61908468efa865a135568c8f9ca0055483468617a7e335840f57c6cd8f2c9805cd47a9d7cdfde53da8ef4f1adbb6f698aaf100
+
+TST: 240
+SK:  068d27b21e2acfcc19c3e9673dd44142d98aacae894930e20ca067439e749a79
+PK:  e22ddd396f955bb90e284776aa76e921e50699d0ca8914a9b7b841eb5ff47d6d
+MSG: 1c6815423d1a2c5ebe8828d1646527c17b2006e547f016b5350f010d79b13df4fb8c6ed57ba9c26c3cb0e0a64178b650a3ea5444a4fad5b20a3eb8caa702634011cf7892a0727b6e8150b0770429a37a8a0bb3a7edb891a7c90240bc0360b14e6dd770a990b31b31f33ddbf653988f82742e5eec31b27368eb0e4f1ecf4d676f49214a520d1e5b2bbb59ac2e13267e07a0cbacbed9f94d7473ed697828b0928fcc616ee02e51fcd8db4d8f7533b7b139a05e06f9e0eae32993e3025aef0590b3fbb4292a3ac40765e8584ead00266acdcbdde1457a03b7d57bd5c9e64fb06b64a50f35f0a1ec34b6ddbde767b96ffd
+SIG: 0c173c488ad001cbb9c43d7b30a7c071a2fdb08cf7f37daf71d7ae7128dc0d43f0f095b2929c54b773ed4a1f0bf0dc4f364f0601e8d5ae062f5b78c05bfbc702
+
+TST: 241
+SK:  a34d52563159e0723e9f3fd133bd96e20adae623f8c798013bc36b441489bdc2
+PK:  1fb658e645de6d3efdb083a73fbd592fcd4b800e03c7bd681aeae6576bfbbe2f
+MSG: 1d215f85c089f35f307a746c66c7c1e41d6ba37730d759e6e5622d6c6a198e40f63d37873b715df7518b3c6bb5e95a467726b97c9a0f8f5dfcdbfd1e0de357661ddeab555042b945fd899fad6d382d7917da9e12dfbda0d69900b3975165a73d0ac9de01fd3048b8fe5f0b90be67e03dc22f653a0a13eb4b0b753f3f3bbf787369ebd8bf5e00eb78bf0b3515a91e68b1d5fc6920bf4f4259f8a730efc7f1016d501ef6fb7cb8366fc8e716cfa50ea8b203cca1a316707e0b0fc57eafce82d62f7ff3ae04ac8fd041b55b19a352a69e6d4b79d0e650175168e34fa3358eac816cecf2c8dd1bf2a589113e91bb818f91f8
+SIG: 5fab5a7140d47873684305aa6353d3862f5fc13e54a40c9563cceac8f74008c6c445631fa864e0f1c345b5954f80056aeba25662b78827b5e8e3a9437813720f
+
+TST: 242
+SK:  58dfe768bf52118494b29975154cf452bd9746dc7de1d6bcd18ee6a05acfd858
+PK:  0f1476c6cc2a1b4764af75805e77341f14a0d8b09c6a5b2ea287fd517c3fa6b9
+MSG: 609794201c4f6faf488790d61dbff3f41b328c5b0695cbe9aa8a136d72b4977b21b500f216e9f32168ada8c13bff25327647e30d8a244d74d88303abc90b7f71aa07ca04d17bc8a0167d6e63fb88baa1dab81d50f1e91f46f5af77f2e8408b826336a35052efffdf4af79596af1bb2259f83c1bc109cfdc3dd50fd96d310f27ea4c6c7690f21815ea92bd79389680cfe3ed40c80181190688d24222d9a1ed52ce6a16b41dbd9107eb6d2e3594e4494d75dd7c089e3b26ffd00d1003c92c4c39ae5382ef9291491a880ca4ec3ac2b86e66719b92b6f7cea2cb0bbb1cf624d0d1abeae556e5f73909dd546277037ec972fd4
+SIG: 977137a38af44f4b262abff7e07282433c58926d562fbc6180bde6cd9497861fb6d955cf383d999fa1037b8b1754ce888c9ffc1560a451d0e9db8d74d2940604
+
+TST: 243
+SK:  5a63ef9bd7dbf0e89fef155983659e8a0a6ca002bc42fad5a45af8e0281923f4
+PK:  e632f4dc994231cc1790c21afadaa977a589b0eb0da19fcb2792911b15ecf8af
+MSG: 796bc8361c6e8eec39838b24f53971e820f82361e0510eb4def1db2512387d6bf35bbdfa318879209435d6887b1410b3ebc1455f91f985e0fab1ce1c505c455576bca03539d048ad3a0ed1f11c73bac6809e2ea147975bee27c65261aca117df0fae7008e2c3c130bec5533ab89351c2140c9d1a62bdf688629787f954e1c610cbb75edb86209d7c357cd06ef41931dd5dfd1c7d407fa4ee1ef29393beab5713173802cce2d56229cfa76b601662c4d9a84a4936c52abb1981378b717eb55cb604a68d34f03b219f32226ca0e669348a2d8d2453930eb6e9c2bf66fa4e92c75136e148cdb034130d3f646382e1c71579ac70
+SIG: 75461f99650c0368058113a15ba16bd2337b2e633da38112878c4834fac9ba2e307c866c02af79bea33659614cbb4465c57ec3effd4c478ae38a34a05cf1ed07
+
+TST: 244
+SK:  8b2f06141e401163f90f674b04dc90dcb6dd3386419339662ecb0dffadf2500b
+PK:  54da934a659119198553fd4566b660d8d610adc3290cb84829c894148cf3f67e
+MSG: 1deb25d43458690323a7d26a26695090993474f467c6fde5ddb34da945be3cea2f6b75652ae21cbc4fd22763a1b45583e1c3e88bbb5fea2049b7336c91159988c01526824ca3bef16b362b9202b8b9754185bd61bea8f539aadf4a1ab135fbc31d2a8e33178073106cbbc02d4cd0d3c8feaa8eb733084356251795afbd78ac3c4f8a3ba19aed755c646f35569c7a6c675b6d6918e834969aca03f71a2e72ccb17003bb75b62e852aaf58b3baea89bcd64a32eb14a6b9e10de48971e53d0e9ac99a78f42de0382ef0e80ed3cfa343f35e4a9983b9aeed986d3a57f47e5e46d40e9d677302809a2d37e4ec011f051b4d031ed600
+SIG: d68e3750dc56432397401c98ff1529db9ed48fea246dd4ed383ec74c1a463aeb784c87b1fda8bbce970fc97aa9807ddbe95d41fb022ea68c1e311654fa1da207
+
+TST: 245
+SK:  dc649fbb1bee0a44814d6d9e9080d5d90c1fc173ab5fefed826a74723a774e0a
+PK:  0214c89f3867ad2e8870e50f8c2a6254986d9c220e3338411300cd9c6404d4b1
+MSG: 328700a8ae581c1edc4e2c00c78bf4606097f9bd75aade205a243c5fd7434d6222da937e2881a2e3c574356d4d5679301da99e11cf749c27921c8caa2ab2a564d87c5df8ecf1a72b680184824f6986022e3fc98bd2a21c3455abf1154954fb30c89882947b02f35af7b1bfad05237d242e2b74832fc536196f2e59d1acd0c1db6f1943d0f6043bbd6a769083ed66ba0e05a50feb0acf72b6c16ba9af039afb7fe2a4aaeb4d06181c5a1878689e67a3f5d0ad39e794d6239a7e0a12ce820c5be60fd5f1dd79702f49d02b79755fe873f5785c72f74625cd7e2428262597d31482c2c0508801fd96319d61b91ba253a5e722f414cf
+SIG: 0e0c5e4e184375da4ef7e2a2e4888050cd84e2fe21d08e84a852db2be3fbc372c472de0954dcd1dc11aec493c569f40fc6f77f03ee524fb06ec40faa1d6cc10f
+
+TST: 246
+SK:  39b8062da43e64e1676765d62c7fb8e0a99c4fd417d6f7e3319bb13044205f3b
+PK:  6227cefe88ea4fb27b37b5f797778bd72fdafeadccd9aeb67ad437ce08fba6a8
+MSG: 740af679e3069fad059fa4825fa41c59fbd484aa649303c27c4f7a94711c5b713b2a6b8987859e2271a6a71eb0b4a15abde4f5168f6cb9dbdc6a27a2a13d52c9720896a1f4ce3a5345ee793b6cc3ad80d7d58163d5455b9cbd073e2b7adbff95590c7172271bd91fefdbd01657ee1750651036cdc3560b444ca2184bf4f3ea89fc973aab6fb4a8ee5704bbe5a71c99fa3b5ef0d0396249758297699ae202b819690dc7ac4692770346907845e2210d5363adeec03f0fc7761b7e0ec0fea1bcf6b04fc54b3e4c40d19b8fa649ac8479e8f80730c0c94e9f4a1ad506f2bcab0c49540f6decaa77b3d657dc38a02b28a977ece482545a
+SIG: c5f626490c0ef4e1efc3edeb0cbc3f7de267057fb7b6eb8f0c813584965bc5c421feedf54241cae001ec6d5e25c9b1fba0385e5dbd95a06ec1d8ae519144960d
+
+TST: 247
+SK:  52f4675d8ccd0eb909df0a516648db26fa033ba41d43fc3845896d456e14265f
+PK:  f39e7dafc97b0a84dcbf7fa14a9403ee1fa92b85e5a7e5d05f031b44ddf1f794
+MSG: 74427110857cb4af0a3342c2b52997bce1a0db6405c74e9651c5b85979acb071e567fe70412c4e0d8c9fa421914f6a62f2ae420b7b2f4cf80c90574221222288b65867eaa66e7e0a0557a26c549f9a7a4e70838ba4074b4cd7a9d758b378b88dd49441df802a444dcbc30624933b59922f33c20f019fe78ee24b8fba79a682f388505ac9c97f4eb87c611880026b4c23306b865173f5d716abc6cd9a9906db3430136f754129c443b20c42be2fbcbcd44034d714f58a4ba8e756607a02b608ef49648f2ad0cea99e7ab30a8dd7814004f725f49301d7b304dcda625c296d928cb581736ab739c86b469241a8259351fd37b4780a9993
+SIG: 4bf668827a720af68898a06ea7b44545a34ca896ecf311feea47e0686d911fadaa03118997153c65361fea15de9bb891b8909872045508ffad0cd9eab21a9702
+
+TST: 248
+SK:  bad73c9fda4ceb9da6c701c2a6e2efc0467afa0a74f8750c52cf1fd4c8e7489a
+PK:  bb0f027a9035376e1aa3206c3d774475e351f5767ef86ef48a72c037c24cce62
+MSG: 74b966cb780771aee63d734df3756702d1d5fdeddf32136c6358b836318a4f984fe71e7716adddbd649eba44cd4282e0055d8c1ed2d35123d66e5a98f1c0838ded563b9a20eb8007538fc7b0713e7e485e3c28f6ebc421a29dce2524db7f29205761036ada62e5b0b7d5b7f294ff17f338232fa5fd42b6f7253304092d848f50735248595da0f7ef28e568e9916bfc56d7ed0d811b59d5d891ae43e1b198071306bf525c678c6343998005fbb7869d1c40f8cac807fe2ef03f3d5b933f58978ef2906fccf7444a2936e63d928c690926c9c994ed3d666263e956fdfea27764bc5f74125bc46bc102dd3e5ff93b5e123e4b38bdef697e15
+SIG: 197d6b6cc88a98c06dfca0c01225edfe38a0b2289f29f8a44ec0816a952d585e2d59b5b08de100c0606296ccf5e92a99e093623144b8b22db87d929225546005
+
+TST: 249
+SK:  707327a431dba77639b3966b2bc095f8eedf57f7a200e3b0077ce420389c92fe
+PK:  ee2496910864189fdaa3c7757eb3cda9ab1e70fc9e7f71a38a0bfc845931c95a
+MSG: 32ef31b64eee700fca2ab21a267f8d9d3bdc689c7538fe959bf713fa995db2c0ad36dde430a8417d437b72c74e26dbe31d93701d4617fe51825cff7a544fc9f44e4345e14b4b11e15f26ffc2af8035f3f970e4dda44c0ebc0363c2b56fde218663bf78839092538fc2f39153d4eb29da0c1a08aa966601cc68ca96e993b01b173a261b2ef327650382f568fe944855b0f4fd9d15e752ac74dcfd37b3786fffcef23339c21e9270dce8891dd5eeeba9608fdc7b6fbcc99fa1b5903daa0968e1b691d19d06f215ded047ef9d76610f5de220f5041b313faf9e96c9fd7db54b5225726af435f9cbd9fd87ab40ce8f2c6940b55f0faae87850ca
+SIG: fb99029feca387a5d765961e361d7172b98b7e0f11290bb1e5b57b51bc2123d0bce29020392a4fec9ae6a72c4c386cea1857cb8f9c50aa9a76d7f1687fcf2900
+
+TST: 250
+SK:  6aa5c9f008f990473ba4a6286a416614026661f11e1a24efa81ac35852d1d070
+PK:  605ac9b4dbdd5033d6c828bfafa93c0039440aa11ca724ae834043e07bd032d5
+MSG: b5165d3963f6e6f9ea5657e9f07ff3a321eb338f9a8c3d3c42306b2b278978b31c623a631be3b04c41edfdeddf538e1b765bc8785401c1af29d0467a64411c497395d755dca03ae3272f4bc1fb1918dcc1ed6f04d6498404a8ce1409d447f570a4359522cc54629202ebe507ab693843141bd5ea0573b20f321a483ff383a46897f5926fe0b8afc25572707b63eeed283532928a4144196497942c572ac547605139256b0aa0eaf04db1a256012ed453b173ee19ad6e9b1af3f45ff3044a641f8c8eb0ac7bb45abbded47286b2a069d3908694ee06f2fbd0ef605a7911026ea9ea3c4913f38c04d8b69565a7027867ab3092d05f4cfb18fc7c
+SIG: 9756303b90655e935251032ab19cfc95ca1c2a2c3ea28b033bd47066cbd4c7d8982a8b9886f1b9cd02e88a65564da8dcc34f308ba9f10144ba469c2efa49e004
+
+TST: 251
+SK:  8efb8b79742be21e6d31de678bc81450ba8621082cd6f0003e22861e2291c481
+PK:  33381e356c4fd386a3f7b969afd9f5c00d2067b698b3f1f00f3784202d3084cf
+MSG: 6b750325d3a0f08a147700b51a9b3725571094818ed69d1f761013eb86f323f73c49f5e439877c2783b336d1f1a674ef3e431fc1ae0180082df5fca69f848139fe6ab6739a0592ebd6d4705c7f0136b22189a11d60d4d3c9bc80fe7d7c00952d5742f9c0c2121fe792df133f221db991fc960ee64b9d32e0178e542bce8efa8d03ac8026cd77ba8bf0b24215b9faed2eaec920e925d5ec46fff6bde725e91c8280e4ada232a5433ae9680ebb53eb55553147c93370574854896154514299c093219a111dca4e637ad5001338c6d4d5ee9098c65832f7af835bcb622128423036c79a5737738a7539f8d4a6b8b221b56d1401aeb74d4571bc009d
+SIG: 923005cb4848402aa8f9d5da74030b009444924c214ad600ddbab4c153a6ff022b53cf6364cd7ee99bef34fe144da964edfc38a0ba633312650ebf0e55a06009
+
+TST: 252
+SK:  ed046d688b2b0a1bc3daf2119dd321a607b16d2a2d1d963add1209c665b5ccba
+PK:  8734f1ffcbd71cfde290017ea6253e580d59e65b541b46521f5e5ec1451eaec6
+MSG: b9cc90fd8de2a141f95116db3b04be83e98522597ec2174964245180b9a473767d6d470a217db5ff5a1ab777e1e28a0b16975e2bacb873020444b47ed8326421b90ebb503688f090c11b3b13617c5c5052c297a41e2893775e34d59ada49d994c0e4a9f5220e9f0315a67705a3ec08af0dc724b5cf67ff34fada8ba7109ed2b5a8907bb403fb1a838b4b059f18c792d7bfec05dee0c9cbbf1753409d7db3aceaf47b4c61398497b0eca6c1f8ac08a7ea1eb9c40bc4e92e888212f7d9ee14fdb73158160944ff9bcdfef1a7469cc70f9474e5f24dfffea585f09eaaab4be2afebbe8e6cf86d35680dc5d1b92913e848256ec736316fd0a2142063b0
+SIG: 721bfd4776cfba13330fd37269e979c1d7b6ce54a51b82f456e137378e582f192a12089da5aba76a7b161813dce56b72892a35330c94f7ff21d09cf09e553504
+
+TST: 253
+SK:  76ac8e570a39b3a0232c45497537fb2155acec3617865ed1df210f00b49d1b8d
+PK:  312a3ad899ae6a25507ae6e4524e10b63a6e7ae53d9cffd39cf28521d93533d6
+MSG: 53ced9db2b479e59d3ed643f7cc3784c24b8bd4c63206c72e23fa850028899a41ce1a8bdc003f12b7c29972c9a08bcd231fe0e1a0fef0bafbfa4e0e027d72004075ba37d490eb9964e783bb98f9e503e9c1fd3d23fb0017cc7c7a9f86d171f041e2355d8c5e6229d34c7eeacb6358cf3060d5d265bae2004a558878659a30dfed5f2ec788b4e14397b5d00c29db5d4ebf16639a8df292a3d24f6983cbca760d903e976f5b698642ba1fed49e79c38f4bb3946efccc9d6aefad336d558f78e4f205422e10384a4e531e75807efb389d2af4cab43825fb87f196a9080769fe7585782970a6918affe10d20d629b705845597418d699de3f1de854f94bd
+SIG: cf03f525913c44303b2f80079393c21c1158146ecf99636f5d97adfdd9f35839804c23804cbf1e553cfd4b73f689a9143aec298f8276e1e4ee0891f1ba75de04
+
+TST: 254
+SK:  f64a66ba0f0819f3001416c220bf52d860130a19764aa8ab38d15b2aa75ac022
+PK:  8125253cd337e00d45b45079b585349561e5f542a81f6d2fcfd985c10feab2af
+MSG: 8072862ed0ab35921db5ec2cba8e6aedb0441fdf47491006c01e6456ad70fae3c4152dcfbfdbb8f0fddec5e96b12bf67989ba96793f4861a11b63909ce8d19b8ca64a544b31ce051fbc88e062806d9965cbd2967b01614e86b532fbf59843218dc9c19c80315f044731719371092a3da38878bc4cf77de972e860466b8fc45e465dc3d0ebf94bdea60ef0b9891ced41b997b11b31ee4167db60c9cfc8b85beacfe223cc1829213774085d7c06d2b2e632cc21cd9660df47c4fa918bdd596ddf622dcb652642b67527ba8ed15a819a8e21f48d7ee70247f5200e37c259dffd17eec8c232f970cb03182fe3964132993f6ecb7c4db18ccef390c9eb3639e
+SIG: 4de6f5250822d7c9d5bb98582500b5c085f541ebdc450ed1acaf83684827ed1dc77147aae4b19e14a7dc5bbe1f1e4f5771d8a6e4f2351739afb08c806d558701
+
+TST: 255
+SK:  8439b1d60aa48460135eb1002cc112792995079a77e6e8ab020b9abaca8920b4
+PK:  eadc3e0c5bddbc3052c3b2f8b0a94566c2b2c879ed17034ac0e6a45f2b3e32d2
+MSG: 5419f6d24eb46635d4a7f8eab803cfd0d04de092afbd86f2a6961a8d1eb8c0d197ba55ee08c991822a5aa702bae0337abd5ca7faa15e1f1ae369946e9b81216c0f5fc22bbd4433c3de93c5caa2741683bbd0e1a78df28dda19174101876334d40339659f021ae766162c6cc5421b79cf9d5c090ed4af07ec84493035bd0b2421b533684295bbe76a70fec596ef8c89c5c9dda3c33b7735d2d2f20b28f1a5402e72d04ba291dd59f14af08adf56eeb086d769c6bec3451891372345fd6bd02dcf95e803af0353150e182e323aaf683e036d9a135d2e6f98cb4d327e2ce7d54247f3592ed067b4ce7627174f996f28165c9c11f07e5ee9cee63851c6b68ea2
+SIG: 62da81e16440821b593b6ee6540e15d1aea75d23e0a1bbfedc808c9548f87e8bbf36915a39a74716f645cca5714d170af907576d4f3705e543d2adddc5ff2303
+
+TST: 256
+SK:  3a046397f0afc072bc7f907c74d38fd1b9afdf27e14a3534768b0dd2df3a1c22
+PK:  99cd70ef3be342493393872f54c47deaa081021892d11a3268f3145ed4f3abe5
+MSG: f08ddef46cc6c34179820c9861375172fddf774f8dc3f7d64aa432da8e5fae644c0a8a9e6908517d505debd612868ac6daf95cd7e1699750022ccd4b88dbae2bbf73546ee4b835d319a842dae8b9ed683323f31e5cc57919bc9dbe3bcfffb2ada48072697ff4a7d310c91adbca81faf26a0eb7bb0c404ac9d8dfec63e9c64e2f420c07d323b7c0dc3b73507283aeb1cee51db4e1a83a692c7c1ea398f6f30940fab85e2138d4b85aa4e231e5424f5b064ed026f0ccb99d1c85a9eb15f5934a11359d411cf94ae8ffa3361a224f46bab852d184a248b4c31fe3a7e7f5134c051031a9f328a7be4a7cbbb1d8d863a400fd2d58daa44f1b9d8e9ddf961ce6322f
+SIG: 5024ce60257965687080c5b1fc7d1301c32aa6fcc835497d9cb23a74a6ca2724f55353c1b757827ca5440c9ef8f8c1050913e20aabec35c497b56041b5deb209
+
+TST: 257
+SK:  124f7416a80453e4cf1cd7b5e050a9761418258bf7d27beb7f23238c4540be2d
+PK:  0da34ab173990150df7399b6bcddba93c6dbcbf4d176941cb5071e8734c5dc92
+MSG: 9dcb9873ff054db11d0a9b19de6885ffba7f0e681cf7fb8f6cd950c48328d1f919ca46054eeee6c9e57843ebdda7b24bc3503c4d612abb1a314f39f58221d2b54dc755acca7969740e7fa8b1a9523b8c7379fd395253f4e6cd054ee24b75613c3581d49e19246a7b3be1cecb334be44f3d626fe3b7b269e628d44580c20636eba2642f2744b959e65757d0ee601843f188e95d17253fef567068a5405a3a9e677fea3d7d55f7ead19a3f30c5f985671b55fa120cb9d05f471b6e1e8d779a2c803a19e6d0d7cd507887ed647c2a95483f933991ed45ae301a2b0e954a5703d248c78810aa0b199cc2bebb2f1d71cc40487dbd42eee0f745f7d285685b1fb31b15
+SIG: b0572104aa69e529e3465a6fd28f404a4ec20276a993b1725eb8c5f650b4a216f1871b24e368cc46cd1ee0174cda1b5e4ae2200aa9fc44522d975a9c51814908
+
+TST: 258
+SK:  25d13b3837601b07a975693e5a33d5337c34c1127fe4c27490612aaf7f642e9a
+PK:  3a07cd68ee2692d51cfad1a80e7763b18a043c74f4e1b01edc55ba9a9e07795a
+MSG: 115b3220b45ca8f36c7ff5b53887d47e669b78dac13b98cc7aaca5c2e19fce81ec8617ca410e11c9a9118a668453b329ffb718eaec739172f0a849a0848192a5bdea18ab4f60d8d1a0d338952d77b2cc13efe83c76e8dd58803b1d8b3c9729ef102b20835b7de872bef3010f15a4caddf07cf7bdd222d84b174bc21527cffb1b7ffde81e281d30cb7bce25ea3dffb6ea1fbb06cb70569a95ed1a07e97ca42de70aa218159efd608fa9b0896e0b58518a322f251d133e58c8fc1428ab0a170ed845c75fb403f1ffb97d2d2a6d4f277911d326c1cabbb8516cbc17908ab81ff8d79af44611ea1d05879c1ec81d06936e0f4a0aef6d5748e181d30ec25236597a973d
+SIG: 20cbf08392fea6a99cf446a95c199caa0c0f9813cc217b8d228e2ed90bab95ea92cd73ac95834764d33e42243c80a7603491c8d3e49ac715fd8a5b9e4789bb03
+
+TST: 259
+SK:  7b3a76decaea60c41e95b05877a7da82064c27278c8d7df5f0bb95f0ad2d0435
+PK:  f80db5c28721b1c611bd87eb145a98bbf383b068045df2458d1a6fda099f7fc2
+MSG: 375fadaedd9cac49b64e1574028046069f4c83654c8a7011abdb64db16b47fa311798172f9072217b0a6a43e5df6ffcc1154bcec1c68e1d35ec05880d012ce76e4cebf301bb2ec983d00b4a0540c937ff1c6df9441c61bdb3be8e0c7c11a35d49b6f55c381269a0e768efbd453447fe48b75ac39646ca82eca7d149304423491871c10dbcfc5973a57fab8371c30cbc4e90becc0b67152226ee177b4ff368ec879b391eb95e36dcbb07b2c16ba395545d4529f727b1a11ef65d120976b7ccc86af4bd204cb9489c921e43ba5e850cfe59899f1c1ec4aa5c92b6dac6914b1952b53dcb540b409231381568987bb2236bc40895df3f17eab7c0274f2244f958612e88e
+SIG: 2cd26fb3c4f7440a72affe93564f6f6559adb15cc7a2ba10879fb7d67e47d4ebd02fe4823698a5fbd4a907fd69184c255a170e5f1747fce968102dc219b50d02
+
+TST: 260
+SK:  5ff8d4052608eb033a5e94b603ce384d8452f60a26498b9112567f3410c18666
+PK:  c4900de24d9af2482763109926af7c481380fabcda9440c1a53ea1cdc27e6568
+MSG: 138c60557c2e9008afc03d45bec71f961149a0835926751c8ff3935c7d652d83e1b0b1da7d5bbe0b8e171a4e49aae06fd8a9deff78dcde4d25b1aa899998a0f99e1df6f9337a3ea2f24b76c317a7014db4e5283191795a70d8821d217846490f958701d39dc2c8ce47d928938874d87b3558989bc77af820979a351eef9594aa5b94f3341eded4ea20b08c3e7c5610d43267818dfac0a87ddf527fbce8512bbf85b66c9bb5d62f0fe84048f23b19604a5c8d82b1f25a8da02731feb2ecae489b8475f7bd326ddf1a08189e46c08cf50538c2a363e2f4eb2c01a204c7ffbc0b981adc0fd997aafdf2a222ee84c309f6e95ec7de4fa85d4768d5c003165028225e22e09e
+SIG: b737d4e5be27deb6d87729c636dff7a406c013f313c38cf683fe14f75a3b3005d9535d7e5815c8f8b37c51d6927111c979f7d9d81a347aa9cc09ed4e6c18e90f
+
+TST: 261
+SK:  eedefc1757e3a7e5ed3946dbedc396a362f683d2c51b0b9f60765d4bfc5134de
+PK:  a9872bc2192fc02b189ceed403ab9f270a032a835fdebfaf1c9d6934ed8304bc
+MSG: b194db73f994cbdc3cbe630ba72c47c2249bc0592ab547942b1d1b882b44f5b3855e568bdddf92ef05022d88fcfc294e76b64a00e9c74355373763e49a4ebc47243d48a9ad588994a518f80f8615c2b31da587a53e529d435a8697350dfcde02d20cce7d5eeefe3f5ab2aac601259cda38538a1b8301f9832e75ab90f8a932f267eac181003965d5266f206180c6c380ece803577ccb46176bf607159486f24259747e2ca6fb1912db7b78a973b2846387c1208030ee1f400d0c5b5e8bde9635ae55638ba17c734de8638bb85dfcd76629a7f9f40d6ab954d55bf8575fc9c9a595097e0893db5a7b8a6c455ecbd3d22d725e19de2941f467f9eb93d66a0e2bbdbf92ed1c
+SIG: d5bea8ea9a5fe9ed6d2bf839930c0c6cd5039e988f551fdedb5437e1c1af0ed7b3897c035711c3c51926be8d1b32024d5cd582f5f8369ad84d18b12502652f07
+
+TST: 262
+SK:  09d22bbaa5956cfacbbf9fd5510975128686c40c6ea96b89ef4c0f0c649bcd7f
+PK:  e559ea8acbdc61b6709a7d83ae15849a6c78b203923dd0a299239ee4886930ba
+MSG: 1c26a0f3a1a5b2d7d5b297af8a6a689d7c62a25267e197d23becd2f2b816c4de92fbdaffb941c3fc8db7a84335a84cfbc92cb3ac806ed58df16b6b8e119a48df4f27c71e931a5938e7d002734885e13a258a15b6e1136efba72f1d096b689f7618f49c968063e8f991fa0b55601e430eee13492a1b09413eb23813591a7a9f070cc396ca9d1facdd4f4ce37c40f7245f55035e10fad6b85b5f01a1daacc0df94069f7de8f6467f96d1fb98648e8a0520a8cd723c98e9dc2dd4b2934d8228f0ae1a415bd3a7cda38d7a9983ce1af6f8c970a2a591635fe12b917536ef815eaf1a3138d70ce70a794264d7c986d9ee3290445f15a9248f2765271e5a992196ae331abd4164bf
+SIG: e65275c4328a70ad62408ed7fb1728be87a73a814fee8ebd94f2665c71bc66ab0c1b07a600b30bc081a74c536857c20610384be268d9af3e3ecddd3eb0c14c0c
+
+TST: 263
+SK:  77826ed351a3f09254ae5692885d774cb3f24410a4809fd90f8a00da9aee9903
+PK:  3eac8f41ee73e6ef136821f7957a1c27e15638d0e3916e6caac6fb7beb7bcfb0
+MSG: 1ff06c0b3999cecb1900a47d267beafbb35d93d14cb2c8925e3e3fe5d967586925ee4baa41998edd0103205810aad5c0bbdc77874476810246d13089a64db576424fae0bed9664a42a491147d1ee3b9c3b1ba4875be15462392540f9978d9a4630ba4c525499751a45efc299ec7d73b17f9ad275ee71a687e72690d7320242d2dc2bd4d5c5cf0f17a465185dcf60f8efff53903f20b0c2ab2192d44368f2f2fb36048af071f7aa857b14ad1d11461205bebe17e02be2e3ccb6092821885c4e0d4811be3f45b1fea088453e022432f562562b43a355cb56270cedb6c2c42dbf9be850e77192fdc65cfd36834be988dbe9a93e2518c138b090fb9da827cb1c91c8fe52fe7c57f7
+SIG: 977adccdb829b40bbd8e53856a783db346a39dff62041a2972d29009f1c9ff81b8ad54cb901e497c1d3021b50b6c69ee73558fd7be05d625f5727f9af2ce8702
+
+TST: 264
+SK:  99a99531c3cd6e3e9c900a9eeb26267e72f09d11b651a897ebb79be016f64c6e
+PK:  9bf9f8b48a2728e02608fc19899d219656839d1cc1e9a8984df674ec26662f41
+MSG: 7a89c0c1952fdc4298dcaea854efc134656be147e9e8e82fc9a449059d80570f75676b81c4a94f76a968200cdeb0988c73f59afc72ad4c3103e19fe63b7e95e140b5cb2efc7b97a6ffbb6c298ddace3be6d2ed3d598b8bdf0c2fe6c97602142a76e978514c196c1b9a88efdc1925fc506155cff9a2f21ab634e2b93e96928a5d8f7ce4cb7326d9689469242ba9c6a01b77496badef87578f5a17284e900a72df141c6199b0e71ab5da4375037617ec6196d4f4e23ae2916a72d0fce796022305ac9fbbbbe4705b340e42b78e1c02bb1001860cdcaf71ed89255dd56cc0b31c59d4596dcef84e22234be562bd801e94111d83a78064c90f9d82fce91f68abb03c73b6bd8d7e02d4
+SIG: 0e89da5d949cf2bf40c7e17c2d0f9ceabc88a092eb4d49cfbfeab7c8bff43245c67b9e2e92f9bcb9b34b3fcf8b01fa2ea7a9649f814c3aa98b3dd04540c31d09
+
+TST: 265
+SK:  aa58403e763bac405db065eb11eb6be3e3b6cf00ec4a222b52bff4b6e3d156ac
+PK:  167f9b9a4665f93f5d7d3016ace6fbd13420b2e51e72bde59eedf26993b66cae
+MSG: 3baa0998ff02b32b90b51f9a840c7b5c5870cfb1810a9b0f77b55909d47ad335147a991c29fbebfc592e9307175c1964129a2d5efc6215807453bcd726969781222bcad1c99a49748b9ee667c4d0c82889e2f50064c115dbd8fb483d72ab0ccadf76bddb2dc727dbc3fa5c4624c283d8921c8aa4425110dcdd69c05e5ed59b359625eeaaec1e27eafe9d9a5ce736c3f9c527ea547818b9bca6811be4cc15058a6f5b683303b80c90c94a83b8b15869713a66b1e0f656331b286d1ef7698834ab3e138417aad6bb3ab3bd9fc78761a482dfc654f3f8628c8d9fc16018898f1641e8622bd272e38d41706cb9cebe6ee5e173576bf61bb1188cf2f39c62220bba88fcb4de4898b25b04
+SIG: 64b598ca5b8f9ae742e46ee0d8c1aaf31458b50c25d267a677e44be5b755f14d51801a30399bfcc38d14071aa0ae93da825a581ab6c20725a0a910b4735dfa0b
+
+TST: 266
+SK:  1044ee3708c0b0e909a8cb2ba2cd0af8d28a5de01d962e826087fb232df7b2d2
+PK:  46d241ea0c702c1889d44655824629b67284d4e644a48fa45455d27ac5f62529
+MSG: b8a445455fb66e17e3143d35204c9ea93474eebeef93963ee5c1d377ca217acd4ca63e5755da08fbffdbd4352bf165193896c8d6f76bb4cd3bc2d3a476a4e320824a1210ce74d0014d747f111eec310c5c89ed4d0850e811f80a8bb28dcaf6f411df83e2c1dfd90c4ad23561454eb5d756b63b4ea7f37dc5d466c16ef70d11190c4f5316fe2aa8597440e88bbebaeb35ea5f04f07b0339264158ef909ad5163bfc248cd724133e274f812695f290e57176a96b9393d07bb310299f5d2a6b6dd1dabcb51bf29c5afa7ebb0701c6c84767ac137793091fe0ed6e47d780628a32c84f83e00e9c16742a523ecb63c24f4a338ed299a06194924f44c5a5d3c937ff9b0945982ad24a2d1c79
+SIG: 7d6bed7f87d090abe013c31e1203903bac9c93445d06c7b53d31d15f970d88647a7ed2c3a63050ba19d68043aadd18bd861de1ac4715b8e828b2b16f8a92b001
+
+TST: 267
+SK:  95dd1a5e658fa6c8d42507b3e5b8edb5baeca62deb00fc5d4dca8e1ab5835e59
+PK:  3a5323dd1e07f323bb6d83e9c2db92a29f62e2e003ee0deacd7e2e4e030d8d27
+MSG: 9b7afd48c474604c26367531556840c388668b0f3840063dfc9869ad5b901274b931293d04f3c8e8f7f8eab815a641d7c351284e8bb0437ac551bb29438964e6a7c7ba772344b333f9eda5a77568c8931ddcaf21e32e07b10bf4820fb859bcf87b81c4bff426f24a4d468f2e9aeda8f17d939709970db11df76247e98a39eb8b38f5949f349f2ae05ab48c018517c48fa0205dc7f1566453e105e48c52eb455c0c40802f797b3eefb1e2f3b1f84315aed5b0711c6499a691b74b91f12ef70f76c4c05c1aa1a993e2f3e528ab343dd2368162f4036a61a13a88045dcdefa85d68532275bcf5b8f5f00efdea999a95783175d9ee95a925d48a544934d8c6b262225b6ebea35415dd44df1f
+SIG: d02a7523dcbd29576ba809b531037774df41734a41175813119c6a6a788cd9b8ad780865678667699ae66d010919a966a051c08163df67a977ee6e220d0dc30f
+
+TST: 268
+SK:  1abc0b9aa01dc57ca53efe7380962b1a88d50a964f5cd98640982c74393f2926
+PK:  8d4fd14394d7c1405700306983fbf76ea9f171b15a6b56612a1feb1cbdae5dd5
+MSG: da2dd940d5e1db6e80bf7e2b782e7e745cd4fd252e981517975887dd05ac77ed837d082961575efedf301fdf24b70718b991b8d92bdd2e6bee17c8aa4bc694a727bcfc78fd85195c42caf883a2c38d161cadd79cfda9a39110e1264d30bd4c5c4a5876777f233b071b1b0b408935f0468954cc744af8063b004ede56cd981c4dd5608abffeaec9e58f3fafaa671467804b7fa2558f4f95174201f183d80a5914065fed53115b41ebc338f78df050053b8a4e75ea7c6fdc354dad27bfd8a2e66fcd7ae2f587d24be0d4a33da30a220e51bc05fa4e412b959fd95d89ea6ec0162516c096a9433a9e7cf599c928bd5305c2173bf7493ed0c1c603cd03f082cce44237a79ffd8be9a672c2ebaa
+SIG: f738af2d3e290b3d23d9aff7414bfc5ffa47235dc053687a8ba5c8541b8511f781566cdaa130e0677db55fa8be9d81a092cb58923a8628494d2f62d95c167100
+
+TST: 269
+SK:  cbffce2c9bd3e23e406e5f66e632dcfa726654d29a955cec983173235fa359d0
+PK:  49653edd64a55f7cd40eaf3f8e72eb96dbcdee398f34817f2c95867949710b14
+MSG: 1ffde6826e4f0c24a7961f191e74cc0bbc928e3f1aec3efab32765c2501cbc1620e7ee6f61fccfb00cfca9fb98143b529bcc8c3d0fdf89ee7c342f101815fabf7deaf9f302a288fe175826d590d99ee6fd92da74f9596b783c0e7d47d711a32f39ea4165e5212431441b498c6b70db3b09d1f4e4a14a6bae39da5088bb85b3285ce9df2f90681af2c74dece439aeb91e1c1b0712eddbee8d72569828f37cb720c509d02aec476070484e9b16ec7179947ac96caf0e1be8b6b74f372d7235fe6e3999df733bccd482dfe2e631f56b582667dce5e3121763adfacf3b18cf2095f7394dee4927fc2bea6b5824d90cd59e854ec5872b4551b02efaba5ad54a9b7a8f6de5d7cda5825b325b076ded
+SIG: e7ced4fa2a7dff73f1068bbad0ec9a1109043c97a62effa148876f0969ed4dc608e28bce797af3b82532c94dec4d6811b7f563679129facf17bb73d69375eb05
+
+TST: 270
+SK:  9f91231497484cab39b9e20f861181d397908577bbb2968242d071bca4813ffb
+PK:  8824bc6cd6a6f15a5f41668f2b3bae8fc4967383078d08b51d6d1b2b93a1071f
+MSG: 21d4fbc98163c3fb6e09f775c2ab7b18b18792340bafedacb49605622e3c08aa3b2b8d0e0902f361aa1c0f652e2732b10a0c5c6a05098996b588267cc8951a78b5d431e7222bbb508eeef1b5e8b8d01d3991e18dddc6ca8d222ef177ce62938d1810eecf06f4738b28f440946ccad2a12e39d38611bed3a39f93419a179ec2b1b52d5fe5c80c23b84d8803755f5146092cc199b4bdcea5bcf2037bd53ff6346694155f027d8ce2baffe30a5666596c00783aaeade9c77fc8637942ece017d6484c2899b1918d3a480bd5157678d4772d271f9b99768ee1bcc46b2489ae87cd030f47d1333c7672cb902cb4f5fe746e853de57940ba2264d3e629644d653a5b7af78ce64a993f36250f8cb7cb45
+SIG: 0a1c706dd8a13077ab18386c65fa97cf9dfc43542d1846ecbddeb7b3c93f3c66f3ccd0447aacdd4dad8fbf736c4ff9dbdb62bfc14d8883e385bce9bac56a350c
+
+TST: 271
+SK:  1e2bd5487c5f5ced461f604dccb4e78eb91608f0b821f5afc4e3e534f7960392
+PK:  ef825475cf2051a2017ae532f077d96774347d2767ea7b45f9c1b860ab993506
+MSG: 1dbbbb13cdad88854b809ceded273343d306a8deabf3ff02c9cec6f002b8e9e10ef5d1b0f5711f33267aa91c171b61e960f740457b81d751a473f44f750a080cab80af7ccca7dffcfac9ee4c39dc85cbdf51259ccd3470d9bad3ad30f4ee5dbd4fac6bd5c6c4df7311a470044695a7e1a7e18572207588afa57eebcd4d575b6d424457ee92465ce1863e3c677cf875fdb98d4078ebe7144260807052577144cb8e0359aa42ad155d79dae3deb99c4632c191c799cbfe587d954787068d663bdfc0fab1334f1876bf498c4db5c53db7b0204ed5a521c62f09eaca8d0189f3b394143f29c421cb5c8d07bd751baf4cbe3bf4be1701df4b2207dfb2904d84f4dbda51cba576d5a5bb16efe698edd608
+SIG: 4d33c96a2e3a5db7391adf65c1cc3565fe76eeafd0b5c7abb0b492a0b51e1fa33639946a243b2ddef357552298ce0aa95eac6fbfe660988271877eb2a7da1806
+
+TST: 272
+SK:  f78db14d6d1a643dd7735baf2635321244e7ec8ca72c5c38c98c809db9cb5a55
+PK:  5414f75f52f3864afb0c79c2c5c1d06b4bce400fbddf17fe9cfb2a8bac47a0dd
+MSG: 05caf1b8edc3b173fbc1ed29b95e2bf06d814ba2407d4b31c728d04ec273d25394423ac7d4fff2ca36ee90273093c756e2bd13c96d4a3dc7f5be1759fcd328eb66c5882b58fa4588e5b2a3713a4154a2340d0b06ad019601b0e028e497f898256b028af95cd8168df5e58a57cd1ebfc0a0c91ced61dbb480aca7df8dca91eb16e98007cd2cd1a2045b0e4477d12d5a4072f365426567c9d61577f3485c8f46605e7f475ef04a3948f60dba8c5508d14bfddb9b11dd044ef2d84c16b9a9038d8e78eda43b91297df35f4361a383b41d49677a687d5b344ad1ab0fc73017b3bebf32306fb3fd7b3d5071f3ab5f6e49aa15540cad6503bea7784cf9421801ce1385839893362a97fae121300d6783af0f
+SIG: d7cbd4181f67712007b7f0e18452e0a024464d9dc9b5ff9cf669d1b91169d7573262f83336b97c861bfab3fcf669223ce8caf319f21d23f1fa331a2d89b6ca0b
+
+TST: 273
+SK:  7dfa328e90a1b849c219e3da832df9ed77448234f0d89ea5d17a3d64e7883daf
+PK:  e30ce6fd5f5800389a70cd117364f59945afb180f229927360b06b4835f8dc91
+MSG: e5e495d663f47236714532687a24308f942ca9c33e088f7f106a5a723518cacbbef4a68c939a6950b2dc2589f82d354e575272d42b1383d315ab8a20aa0cdc9d4df678ab3b26612b5dca66e71f9f3fa7d9e731dc481e2bc7127cea3b6203ca6cd8162e90886a73dc46c83ddefc4b9e2d53d29dd387c624e08bd8d53be928a40a9aa8ae8b1c8d0fb6a7bd6dce5f62315b7a2181f627f256bbe7e2a95bf464e6132204c174209629840235b2c39913301a4b40325d118d384bc7ac028cd4f12702e161191b149e4209058a55122bbb8b22b24683ba4f8e2e6ccfc08dc8c8b1bcfb6d60bd8f062196933df319ab16906d085730eba1720d4b02c67daf38cce6aba38e25d68ef95b2f521913a1d77d5eb650
+SIG: 1c61d53b872f8cde598609682c79f6c5df007c513a71cfb3a06dcb82d85c4b00ccc40b00e59f595393088b4cd0432855c67a207da71f87e72c409b3e50279507
+
+TST: 274
+SK:  6ce13d3c2ec71fed83131a69d5d030314ab49e6565ef68163fff09ac5d9b47e7
+PK:  9c7b1118fab91e0e7b192a23d95fb877cb7936cc6c8a330592f48e6784edc292
+MSG: 10bbc311eb2a765e0167ff37618ff70e13f02d7b0617ae4ac06befbbe149c972a994f680ca4dc9a92ec7efa53997fad356b9ff4ebdee629541d1f4dea62ed0d2494f9ccfdf07a9310491f61c4b3e2700b4a3c668d678329a38c2eff9d8cba431fb959e7f7655bd0fbd77d53bbbc2eb8dc51dd718ed98728a181686be122b844d3da331e329d3959b5923f7734325a021026e2754e17a15108be801465ad958dbcf21df890cfe5d5b883ca43c61cedccbdb58b849ea75374f1e918e803e577a5dc7a1c17936eccfcd3481bd2b1eb075b83237ca6f3c07c19e9af9731267be82d4898eee96ebc900d48b059d51b0dd415b1c890660a88d25f5c5f35d8e45e523e0ce3336923ab43670e35c5057d56c758876
+SIG: 608b2bf6f6da05c2ac5bbfd795a2ac32c79c74153f9431dea59768ff4c225e3b693b645a506766b860850ee97ea43032b05b69e56767e8eb9d1918df9afba805
+
+TST: 275
+SK:  d45ee69a5f1a7cfdd0343f8770d1c6bc026f067a70dbe839a86f2aa068c33f81
+PK:  fc8d9fb0e4f34793090755e0328096e01e281ea351b8d95cd9116e131a5ca54e
+MSG: eb5ed8ab79cbfe61c25981b9d1d6b70f10b60194b4161fe17d11aff1767994aa0813e9ece2f4c5d531b99e8adf1888c30a63893eb451aaf55acd5a52ad8c401faa88d6eacf3e49470566114fd0c6a274e9544846b0ae9bfa124d7951eb26715e19253ff7edc8a70965776f23ce46031e034a200723ba3d11e11d353d7e7cd84aede267ff64bed418cb9f28c61cd0f63b6ce2ecae14b20bc6bdaed8c428bad18be4b7d66338364acd8042a8256f258a69969b8d3ca2eab3aea3706e5f21c3b1efcc254a824bb4e7ea7aba8827c8eb82786c665aa973821931ff990a63fd34a74a6d8c22a882b0b935152ccb36fcc76f4eca65d67c8680942f75dfad073439c0916065e83877f7ba209303f33548d9e40d4a6b
+SIG: 156c51c5f915d89b8d1400350f8f217a5c02e2629ede9f4a30b6e71d1ea7a953cc6db31ba5c778c269920b649fb4221c6d38cf2cea2a7de3ad423e04faaa0607
+
+TST: 276
+SK:  8a76eaab3a21ec5a975c8b9e197a989e8e030899eb45d78968d0fb697b92e46d
+PK:  2d9c813d2d81e2730b0d17d8512bb8b5d33f436cabaa13e141ca1cb785014344
+MSG: c6c78f2e2080461aed9f12b4f77c989b19716780fab60e6ecb9793b4bc7ed69e5f70fa6bdba16e9bd3194969eea6665abfd630deeefa3d717b6d254dd24bc97dde21f0f29f9ed34b8bd7a013380f4f82c984fdbd95af9805b744bcd952c5a71fbb57d11f411c18cc30bc3594f7ad8228cb6099394a1b6b0a818581bdf93cce58f3a4a23e55db3e69ca9d60cfb3a907fb68329e2ffb6c65f1e828d28127109c9e9fb70160f2ef82a2ee9f9bd170c51e13fd3fc1866b22c79fe6d5101217979dbe2724dcad8a9bc69acc42c112dc697bd271eea550e9e50406bfd28245b83b8f012d34db6dbdd55ae6e575745c153d6e7534901027eadc2fcc33a5287ddbca6d3aeab8972294dc6c712b9942547277340e7ad19e
+SIG: fceecca4b014fecd90b921b0fa3b15aeaa4e62caa1fb22729c70269232c33cef0d0aeea66432c128afb9a3646bc7f03a12774da8758398c2a0dcce0bbbf6740a
+
+TST: 277
+SK:  18a8f93648cdcf47133630af1e11c0ceea3de07327314c96580df775597d7a9c
+PK:  2912f41ab4c87e3937a03331802cba87716b4eea14b9fba6f546d0ac2c0973df
+MSG: 592093ac7cd671d6070b0027edac1fb015cc205d78bb603f378eb9f8aa388ca830db3cb23420c7e852db0b55241eb88a02cc627aa94143be439aab4bf2634757470406e842f20eb10f0700e3c2da364f588a8000f23850c12ce976f326d2df1bac13e95020b412b175bf74bd7ebbacf3ae55c0daebb5c010bf804feee1d7d49fae050bea55996f53cfe1f15a0cf20727db4ee311c260bad9682d7b965e27a9491f471d4a473aff646c7d424d5a0bdcbb8a0233f4b3060dd04c98ec98dfd05ec7247884e2d8e152d4ae52b3d5865d9efd6706a60e088e1e7c9f624510abc7a2045a2c7a7588e2535e73191dd5cf05421563f556a13e8236670343cd5ba4d466e245c4ee3b5a41e70c9a0f5e6ea2c559ebe61ba81e
+SIG: 3b77394cd69f8b45d00cfe3a79a7900628a56518b379ed8a11581fc3a376e5d66807df11e70904f696c741d21d139310fa1b89a93bdc4d2c3997991f5220ee00
+
+TST: 278
+SK:  206cd2b8114aae188d81862ccec4cb92c4ef5fc78c24435a19f9ed9b8a22f47e
+PK:  97a67ac2811f529456df532737d76bed7e387da83bd55459372fdfb27ffacff3
+MSG: 480c4800f68c79f5dfc0c3666c0ac429b30fe0c5fe848750db2171380b80c8e9fec0a054b16d08674cefe2f64ec28bb6b0596b35235575f189bee259aca766c222ac0a46cf2af75774da4e34a0b54fc2ac49ec8bedf4887cd9b7be4fdb7f686902ddfab04627e26ea2dc3d97d62a4b1546180218ed8fa113334819b5275cc54afdee44309008596507971675e6d8b8a8edec4718f2d4bd735213cbbd18791faa8054174907a7ac17d7143a4757e493beeec4849d0b836f18bb2b3c9016f25af47fb96199251720549f15d149503d41095e25f26209daac39154485c3ded7cb1a8c3e83a52f5a06ec09cf83df00726b7968f64c0cbae299512fb438560f04b3b644346f938ac8e90486614cd844b54eae078bf678b3
+SIG: 73a40d9da08fb98ea25b67e721557a1a51225294d316b53149af895fa4d63cb4a3f56f688566ef6da42fd2941dffa06d497aa902165d50213a6214116299a90c
+
+TST: 279
+SK:  59b144a708abec972729a04a6c13f0ea020b4ed4a48298023a568958c21215ec
+PK:  c4f4720092ed6179a082ae4d6145df3771786efca9bd9bb79c9f6667d2cb56b3
+MSG: 3857bd260b8aad9d073f06765d37fe893a3f53e23de866ddac33495a39ad33ee9e9d5c22502bc1c4b5470d0e3f3a585223fe4cb93cc4ad2b5ba6d78826a53fc0253dc580a2018cc9ff1cfedbd3ac0b53292deefbc14e589acf496cb5f7670130fdbb6cf38d208953c015a0474675b724bd109f7cb89c33016751fe7aa785d099d09ab20dd5258cd764ac8daf343ce4790ead0863af43121aa527a37a11628f47869668f8eac00d80b6bf9906663d7a2899c1cb678cd7b3eb3bc80226b8b13b6e46877f38f07c3d9c86d3368baac4a6f6b93ccebcec9811474b6a6a4da5c3a5966571eed05edcc0e3fe7cd15915c91f44eee8c149ae451f375518a79fb600a971a39b9433dfa19f91931b1932275747c262eedcbd27f1
+SIG: 1a80850fcbd6e643c6ba8eb684dbef7df015159228daedcf0604709186054db185aa7baacb09d6caad01638eff8e468735a60124de0c5376e94340e541a98007
+
+TST: 280
+SK:  8d1621eeab83270de857335c665bbf5726e3722225fd016e23bf90ab47aeec3d
+PK:  becdbc024dae6a94ed4e29c80f2aff796aed8feb2c1b3790a8c72d7b048a2c61
+MSG: 97facddc82cccccf788c31b3305e93eba956f89613e6e53542b043267fee544c2b0a8ae8886a31b9d321a63c27623baefea840b2a8af5b2330193ffb5baf873c335528afeae2160163c851c5a2e58154a1b0569c2d1366c0710437623b0e08c686e54fc279ed4c45f3e856868375f78224c777b13d75de10d79173552425d15a561904155f2117b2f14713eb0b04648a3bdeb3302167d1973e788a06cb00d48ccb269fa71af8ba68eae55dbbfd9594d5c2b4dc13ae0321718561acdf67dc8cfcc25bc46bb66e096a1941d9335207d3f7d11e8904904fabe3a50a3883e7078047df252f38b67cd28a6ac45c7d7a1d2a1de8d45747cf09301e01cdafd0cd99a6e91b704d509fce692fbdef2f71a5ce0b35bc15c65f876824
+SIG: e08d6caa5f39327d6e6652ed74dd1a37844b979f5cce747a606f5679f4898bbb7643df7e931b54a2b40ebdefe83003f61ca0f11112f023c6a3e8cc18cafe5f0d
+
+TST: 281
+SK:  f2735d50ee3a9a65b58c8acf551663e98809ec406f73e3e7f4e73bc4ea923874
+PK:  df48a5b94a07af3c2c99b8388762243233c850dc175317d602638e5b86ab49ed
+MSG: ae31e94e7197e4e4d0239348025ed6681e513ce1a6e0aa0e5b979373912150ef113e50ef0569c483f7568c4bbc4703c5dacaa80a0de4e738383fa1f10d6d4071a31b99e6485143972316c86522e37c6887a1c307b29b0dd6f9f1b438310af9d8d7346fb41f9b2dd2e80b14c45eb87d4ed48e37a5260b52257b3e99787a13c55392ba930c08e0240e960def0c29b8550745cf149dee53a5d174ec065d2d6677dee1fc42057062c34e27ea5dbcdb861b9f670c6032c7846cec8e87a7c9520e27967b0186ee71b77ed6d029bbdd70949cec4a709329fa37fee002490cc1bc4c2df6f763f9858f33d750c5b505a67e237063c0486f9456d3c620d9ac7c98f1381de0effe41c18259504a150d68a6a28b0a3eea803b855315c9e0
+SIG: 6942a7696417efaa591b95e11f02d763bef5279b932a8e2a7cbb9f583695c14ce5cc556bec66799b33cb592da4df2735f9eef2c3ceca4362164b6cc93da4e105
+
+TST: 282
+SK:  cad9d21a01c7e1d15df2fbd79c516eb8c3401e9fe28467cc7b21679d4e331a3d
+PK:  a7b55c15d6790b40536fcae5ad2892cd66b18689f499c1fdeea66d4a7df39424
+MSG: 70702bf19c919f9836defd7b846fd9992d8b7eb2e106aeb71e60a31b4ea25a41b212dc7de7c91cbd613d58d0595db833cfe7e50584f25569602c7744fa675d156d0f63cd2b7c089c8a00686a437169826a12dc485b38c068a8007142e5163747011a07a415683622ab1e23ce577c732ba14f401fbc3043e0693a9205c19a92298a3d9b08fb7afafae0a9f016bc750ee631a5f5da5db6f9ba2692c74caaaeb4d097e90e3c02d2e3a7fb3aa000040b7c17b74564e646bea16bad611ebc0859a3828804ab4f5cfba417d254515ca3620a3ad683c46ca6267bb49539bb30e369087e67438e9489562750dccba3aa0b1b0a6c267032d20c2adb75e68df1123b5259bfe4eac6cadca6778138a37318adb30e8d669f3bc9692cc74b68
+SIG: 31927d01db9f2472f4df6f63c18ebd83c2b1aaf88d580e848854df8cba6395d3da7bd6bb9edc1fce1c7d7e1360558fcddfa93915be076efb8ea2dc5ea7b20d0a
+
+TST: 283
+SK:  d9be842255e9a16b0a51a8674218cee7cd9a8bdf343508397f4ddb05f3fa0082
+PK:  7931bc6dfa3324943aab183d1285515919399ffe0b710677f0915d3a5be51e92
+MSG: ac6c55b134663e41f02a6dcb8549eaa1c013f59658d81d812f95b74009513723671945e1324f90f8a3f971369181b587bab45665f788d663ab78140c5a22c1c18d4afedc7448a748afe5bf2387003c1d65ab18482ef98922b470da80ad14c944951ce4aed37390cce79a8e01b24c7dfc1141c0eca2c7f773ed4b11806a34615513486e4ee11af08078a1b4054cf9880298608dd9b3faa1a242a452fe511604b3102c313d14cc27c6f0f8471d94555317eaa264cdf52c69e18f461e47903d21298716b172ee9cb178f08ff2d3c9c162121c2ed21d8734b2f0630d399146cbf76e028a143f2bf7bb50af0f57b9ba8021d264b00c6662f84c86cb6d5952b3d241f7dc3e700c96616cbcfb0d0e753ffd5d21ee320e65e97e25cb8609
+SIG: c93845658c9560d2c0e28f282adbd4652bafd3bb2edec17c94878f7b94d3c77afec906ed292a8dfbf5f8e7c118e8f2ca33dda7909d9b695b8ff5a1c0e97ac807
+
+TST: 284
+SK:  cfc48cc6f65811fe7d7bba85d1cd84858fd6f7edd638f4f552363ee7685f69ca
+PK:  d29c10694c5e8e3f3447ed78d34dbd74a2b301373ba871b5850c333dff7bf8d0
+MSG: 8e7defb9d16d036bd642cf226e32773e605361c5ec4b951255788db0a042c63e5a4367d61524f10e6258991325a39ab6b03612260c3fe3df20b34202d34395bd4ed40bd61373df781a4c8bcfbd15301060f07437732333d8e49736322dee6b22438e787d8856b70c26ec57d6dade9c3c28e27220c5670e393544ed095937298dc3adc73865f777e90037bdef834716476d78f4e6cb4961a4c68a8a836338a9f5da179c4d5e93c3f70dd35eec709653dd8de37996b12056d4eefcb4b6b3c13ba984d832275c4386ebf4a8ff7f078be3d428c1e0d9b162381f06a5b7bb12704003d91f25d1d8fd43626ce70fff59d2927768a76bf7f9ef76ff95489f38edcd1c9e9b8a8b0ef66c32805776d5ae9fbd84a7af4fa6563ec70ac5733a44
+SIG: 80c5d51e96d1cac8efd3459825e79c1e9f65af701d1d29e1f95b036707113b77984b7b3350f04077333c957f8fbc7d9b040c362651417b9899027cd33edb1103
+
+TST: 285
+SK:  15c9f7c4d84a5a479041952e6a8cac24e76fd2d275c197e6b521929b43ba6c5d
+PK:  8633c1829d29091df71fd5c0ef640572e4b64974cd097dbebbcddeba041647c0
+MSG: 11730dd45dda80d84d080d92e9bddaeea6878e4a0b3b512d9ea733808e1cef51d49048d6c78116a4bde3c64aceaa52beca86b331ab59e9185c70286a02bb5dd04f5c7f4e9c7e445e77458565f159c783dfd4d976a910e937789d2141d416ed3a7f608d26737a86b20b624e3c36af18d25c7d59b8d7427ec6c4d3d438d7ae0949dd7d748c1ffd6f28e8285d440422d22a3761202e9584f5cdb3504547aa4b685730c982cba213de08020a5e4e46a95fac4b481bea0b630abd030ddd335a20fe2cf7094aef4813956991913c6821f4b5410df4f133fe63e22c08092a0a65972722a27ae42011a807c327b417237c540114eecb9f0e96cda5dcf0246f1d2717f49b9cea9dc6a3da9b396f0270529226f5dcba6499918a6c289fe055fec8
+SIG: 1e36bea5a583767ebd80306cab233155b7b42814b43473cf45cdc5039c939744a9694b87220daf4ccd29f25cea405e7c08db2ef17f3f034dbb49cff60283e306
+
+TST: 286
+SK:  6d2d0d823f294746b9a5512e14e73c1d855b5e4bca65fe817729810cc5ef840d
+PK:  1b6480a6a90dfb472984855cef6f1ab31eb7b3f13c8ac00fa556d20b53e5ae17
+MSG: 8772721f72eaf7f73040c068a7c3753bffca7dc2d0930c6525f425e6005c25cd4c0ff5095c9c61a5d8a1967b8c86010c884e509e6b1670f79046e22979ebd354734090d3ada21435c1f8254f7b5222cd5564f064e977640366449f4e5008f870f9c4840565bf4fb5f574c9774ba2568e71a9ccd82ffc59b694f26e7de4ce2e3fd880a0eef387931333ede00dcb065e6d0f79591a2aa956df1948a265cb95750d8a233b15c288a05487c515663f93e740fb1570fbe4bd80c68e8d9297345a8a01cdbd88f4a39bed9c5ef09f144bce5de568bf3733bc53b2039a29cb3e194501adc1c10e86383aac8b0f85c67a6689bbe1470a392476313439ca88d98c021c0eaec25fb2f9a160ce5c786170be0238fb8785dd33bfa9059a6c3702d0de05
+SIG: b515f49eb32ad478692df88f07b7802c6e0e5327aa08a6366e4cb1d1e26f9e65fc81abebe2215d649100f27598273a412b624e842d8130403797e57dec975a0a
+
+TST: 287
+SK:  c0cf799af7395bf27bafa36cab437045e39c903bf807548319ce44f287494fbb
+PK:  afbf550ca290c905bdd92fc8831ebe3dfeb6daae4f56005253cc50951e50edc2
+MSG: dbe65780e968de9e40ffb57cf59a60fd93b3f9a5e7d8ed5180adbc578ca1bc48bd9fb60a1324c9c2c1141479a0dcf0f1d07e84936526df42333c0d773e3fed9e4038de5b95ad905c92cbe040487bf55e10e1edb429a0ecc4e0e8d00a988a9cd53e2eb372f4fc4cd9537b269ba3a23cefbc8df6476e75434b81d93e8891bf417c82e363f3e4abf80a4f73aca84ac7df6337f536d63d939d92cba64be742221116069ef251abba0b00af01718bb580ddbeb79973ef10a68b4d0fa023d6ebd3079d6b32a1aa20a21e9202f27590c3f0c0cc253073c3f822aac459d39f50758b70c00710a3c98438416508522e512adaa0afd503a7ceb04fb94a4a932ce80cd5a7f11bb861263f58e5749d542a110de7c7689dfcb0c51afa9d54a58ff89f3f67
+SIG: 5bba01a4c7b25542d06912de70aa1e220423fdf8338a9e693395cb6f0dc1fbfd018e3c77e50aef90a9080f30f1f5792b2431078fe6e3e00464245e17cd8dc107
+
+TST: 288
+SK:  cdaa50e8527dc7a50fb37e28fa8b9568c37e8567e0b499997b9aed676180c3b0
+PK:  7c56e164510268c182b423747904f1d3a5809330f6e1b29266ec46e73be1550f
+MSG: 94fcfbaaa303dece7b908f874cc5f095061f1754bb35780db666b63ab8290811bf1c521a7f8f785ea270dfb39d0d6ed95ab71955a11ffaeaa268e081ff3e4f2425b41880a987151e678e89111350942d820c3eec36212426663be175e5286b4ad1cc804e3e3a03b9fa3e82838ebbc2615a645f2ca1468ac4a1cdbe523761e83f4381b0c8550ae5e8c8cd1fda57191436e27cb883bc64be86a9dc6110ef3401d88a7debd1b701d9c257a6826cf01e9e2922e3ae577f2834275fb0ecda80ed8cf1801e0bc5e01e26a77c48bdf46a5c4894d22ab53e741827e24bed5f0750ffad05e53f1d5e61dfd316b191d9797ef713131a8b430abe3fac5f3c4a2ca021878b15adc8c5f542114260e687a9d199d230c4e0d3fc696993b59ccfa3ffa9d8d2fb
+SIG: 137bd10a50ef609384fe668768fb871de741ca0f53ff8477d7ebfa90aafd5e2681fdf1b89250463c15db8e17a58825fe9427de089c34de13cd07bba18d4aa40d
+
+TST: 289
+SK:  0fdea9bee6288f947e0adbdda4dfb2baa03891af25024a5e138ac77984d00507
+PK:  70abd86430d7e8d63209c8b373ec4e4b79e989e6725facefbade3c7574d23cd0
+MSG: cf72c1a180a2bc37d8478d9a7a39acf03bf2a50790f7902f81121222d31d3ec916f4f24cef9d7c41dc021b0e8487bb892e47305e54520303e89b30b263dac4a9ba375d46c40fcf400535c959d2b746a7fc970cf65b472e84b5f1d0ebadcfa1aed6fc47facce16a366a3b1d6e516813c1960975f8f2b43042fb4eeaabe63c6f65db45ddb7db888a19a9d7ba6ca479fcd70c5d1e970f12c14f4d24fb7e2f357bd3a94aa1b868ccc0847f2eef21853e253bafbf07c4e6176a1ef077167841ebbe5629337157f39f75c71d21e7e96c51a1b16fa8dc60f0b1279fcda2641fc8591e3c492f15bf83caf1d95b2cd91332f1b4202fe72862ca2ea2ef92c11db831d82f8fc3d41fe29a76c211a758e2f71bd89d2c6610f201429f348d56e10e3b7af53e27
+SIG: 80c42dd5df03b285a86ac95ce6669f786a978a813a9d7b8c6a23de76fbd09bdb66c5dd1cc9f1a176cba388d5051764a32fa27f0028ba4898068bd01a3ee17208
+
+TST: 290
+SK:  03d5e466f8298ab5438a30976d1322a7215a642dd5fb4c3f8519409a7522f092
+PK:  4b3ed4db080e2a452e16912c14504424920a60975604e4f379258d1c8b193d6f
+MSG: 1b47b70013cb53e1f8f4971e0f39563ce87edbc2cedd99e5a35585df8b00a852f7b9c97c7e4a5465fc5605ae8c5c36570a99201a7ad6031287ef0c7b2ba6e57b056d0fc8d6ca43bf6cbdab098934b403197b525d22d45e6b29c78f8d6183e41ffe197dae25ba22b06669ae05badd7e1da6932a7d054cbab3f54e5146223ad8671231bc16fe62679bd2817a6b80e653998c4949f81ff53b6173163e11da3e6d3c76d84c713225b4173d6bf06a85b6988a48be4359cb515503ca563f4353f8e7d45e4d94462c89a04a00f1b3b0ca6422d5db029c507d464834a20c78a713661d84edffc496d69282619894437b4487954cbea2aa7261e6a62b6851154a5d25fb6b4f09c59473d385ce03e91ba865eab66c58c0abb0b7a78e4be927e55460ccd70d82
+SIG: 6d7e4658f26f337c98e03f13542e2f39440ff7bf8d88f3f6dfa4d64948cd96b79051492fc28f65f2cc0d23a0c4d5e2307bb1c47e11e53b371f091b69f80dbd05
+
+TST: 291
+SK:  76cc18a1dafffa100586c06a7b40f79c35fe558c339c2999a5f43875cfade03e
+PK:  4b9da8d2f137dc6c857a99a5998dd89dd5f05971a21e8c776670eb47bc1270a5
+MSG: 4522b1d82373f7a318221e7e57617503ddf44fd53997522a1d963c85b708d0b245de372ad52ec7f54f6213d271f7c91d5a1d36d134db389df0b081a06bc0c7a4875f724092793172c9115641c6d054f1d992e0fae4df58695f0ea3449d7a4b3a8857e19803fe49b6d52c9ff3746a574a2756956579f9fb809a0edec92c55e95ffefa3d05f165822f464a21999f29691f6744ac5a3ee49017880645e837edebfd2e0f24997f041145a72e2376ada283186ca2b836362977195baee30a3acc81b243f3ee376a2c4764c783667a4b1177e7951d3e3c7be4f1bd7ae8c60fd5fb0fd91f0c1c14d0d2327e8f20d92c0dfcc53870e9d99fdbf9dd9a17e882509ae7baa8653e39edc8ee569000d624cb93a0754a798d1f811f6a0ef5501a17bcf25fd0f91626
+SIG: db74751c66e6b1866044dd9ae99f19e6334f179e79d8b8e0c8cd71d22cefb9eab7e3e7a9c2da225f2a9d93a313d1cbf1b7fe2597b8d702bf3017a6a6bc7b7b06
+
+TST: 292
+SK:  71ad980d58ad8e7d33306689358936a372d5190b24ec7f9bde749cb81150efda
+PK:  fd35a75fe5abc20104691a24a4659440b55aeaea902ac3be274af27aa8312869
+MSG: e87ae073ff5dcc5485a19940e4e3ff263a0618a9025ad4032dfb36d171ce881f71c18a49210eb45819806142e2f00db3041835bf2c3bccf1dba02b8b5a5bdaf8fea316c0623dd48a564ec166f037d587c8c01684e5e5c0ba9dba4d23b49a0309244e282a51408622edb05704747e0cdeec976893777071098972c113a8ab639c31f1613233ee460eea8a8c10e1e6e152214529878cf1adaeaf78cf19bac71361815bf57955498fab4f0f2b7586c86f9f4c2ddf8972f9b9e0eb636d84bcc14385b2d038be55a963702efe225a50bdd0c4da92a2a6a09100ea04a211d396458dceb4487116837d139eb0f122538ed3986ad0af4da2dffc89f3269ca88538086e691e5beae9581e7c63d8e612da2c47f74dde1d94951eadb0df60c3897d2a3095c506093b
+SIG: 81670b1029e481e9ff3c171f05c16861c846ee79cdf2e21e3bf952bcfac97565f2b1dcedf69d2e7eb35caf5662e8bc671fbb96756a63a596264d1b7f4af97e06
+
+TST: 293
+SK:  61594e24e75f996b4fb6b3e563f6a4f9915cfa65ddb199b01fed7f8ed7824ecb
+PK:  8627d2141579cd2521aa076800ac354b9e3a47d71cedc8547434268225e33005
+MSG: bc01b08c7caa236100a012a726477d0ec389dbfadac73d5106424c5d1f3d1cef1695cfd93a7062ec8bf1067047854920162f651357bedf1cd5a92ec29bdb5dff716e8f6025515a9549ba36cdc35ced7c5c0c368e6cd92f2f10ae146a20728c374bba509641ce88cb42fff0cedfd9fd67f310f9d01a3f3690eb21db17bce67ae35c4cd24c209f09f044759d8d5a7d248e2bd966524ba8c0c28974726b43bd05de843433cc400598922974623d9acbfdc761c4c04375a952ce54caffaa96acff6d9dc278742af476e1865cb8c20d13d1c1900863bca231e44c6b0d47cb41d510f7958f48f304d03da033484a3e1f273faf6983375b7d3be03d8a0a002def6365beb2fa8ccf1a94987adcd33d0da1177fc5159b6e56d004301e921dbc12ec0a73f413cf2c48
+SIG: 6302b3ff2710be306c92b9aae30d23c3d4beff394e63201e6ad11713345c4fcb5cc8d3dd10adfb82bb11a189ce7ec3e4222727624fc17881c14788d2710e1608
+
+TST: 294
+SK:  54e6bbfbf8c06ff2c066318c2ebf03d506547bf43c2d7a5d4df305a3032b7138
+PK:  3b71aa1def666d9188f403f82ed30454aba5bc9f470f6eb988da187c92523284
+MSG: 0318d7cb4805af9821dd3f914b0e076fea04a7d2db3a59a00affead3325a2be40c1f87f53276a8552604f228b976e288b9be906a7bd25b2ffab8a8af5d0f6e08786fd034e2fe1eb7ee033979860dd1e5327287e9e615f5dc5a960f17026b56842fc8d44cad002edc8501cfb956001502e4ddc81a7700d9c0be88eb4aaa64a6cbc39de82f13c11086de1a4270d3af97284bac1caef1d3edaa1071666bd83b2ede3962d98b9d93497ddfd8e97dab3089950cf30ed11db77ad1437a0af5889d8efc44e612420e3907267df3acff4bd3fb6e8ca5badf8e72f9de39528653058524456a81da5f84982afac34bef5f71e91f8f90938a6f5f1f287716de56a0946d261e87bc775ce189e41a77baede7320a3c608fc971e55d0a773c4d848d428637f11b4e4460390c
+SIG: 3df4d09079f830e3f982283681ba37b50f3c73de2c5d22a291358ebb1fb854e510f63f9a48e9fff7fd8311302ea3e969394e6d49c9e3182054942f6a744cee03
+
+TST: 295
+SK:  6862061be0de9dfd998118204b2b98db3ce7d7e819dbc10794af0ab2b06e8434
+PK:  9c5f7c2265dde1b25e4f27ec71580d52dc89f2c3a712bc1ad5d6d69e711e08d4
+MSG: 1740dde8434a0d689925679b0c180300cdbd0cf6a89ad8fde34653316cee4c571a4105c9e9e0284238fef2c38a09157c5db94340571b390adfb69ff4c0dc5053253a679d42cc1f1bf1ff429229ea0a5044c6f79564e0dd287f53f015b83187d9ad27d91039af062c437b1575a0eab6aeb8aa0d27b27665d6dea9041ff9963a3118b3298a8544e3fd69ac6877e3e4052fe4422bf03560b2c57ec531ee8b5ff53c28dbde35bb45c35077636e6f841b59d7eb77bc7791b6093858a3a80a3aa6d778dbf53db9d06119c50b71c791c0495c576d1b59d396873ed871485352c8299a359da5ee9d7f36ed1455f89851a30851bea719685aecd08f25562609dd106630735277e1d6519bb1687de8b8c68b9671452edbb3491da264cdfa0017c512d2769759cb925fb664
+SIG: 965edb34e8ab8bc3204a3201d22186372de4242600297cfdb57aa1df074ec50ddf10105e9d4c89a266c34db7772aa94cba946429e68ba62bf9a0ac90f5f05b02
+
+TST: 296
+SK:  b2250bbcb268d2477c8312b1900fd99982baa29a68974fbf8778a1228dc97550
+PK:  44aa8df1181674b05ade980f7eddbaf3bd7422a920287cb2d2db59a063eebf74
+MSG: 7ef0ae1336a6fab37f99da5fa7d0dec7409c072623ead84f241d53d0596b461705fb1b3c537d36b89e8960febb4cdc0d427ce2fc1be58dbbce151e35acd8b6ace40a19822914a4bd8c4af632f136418ac49b184d55193ebcc32d0d798709b1a8fe294fba8a1fe72d976b4400d4a393242311b0f8cc994e89475b0038ae5d8914938e8f6e87c6f50b9d656c45d7b14231efed97f3c90668913670bf5be2efd5c270c7cbaf01e8572e9800978dfe2e10a2fc0440b855629bf9cd409ea941cb69226cac771b15ea77c0326848806ff8d2e201e6e26cd5f45430dadcff8f59c321c1c9c6a29b94882935447d3e6c2e8804b1161576bdf0320fe53c307d9cde426077a7677cde3c1bc83e18e60a0c4ee6dccd877c213a8e4cca640ee04929804570ae1f96157c04357a
+SIG: f2b8d92ed51ebd1000bf9dd3411a9fa9e7aee54c4c86e24ad0f9ad5c55643a12d680019ca03f216bd4bd32c9ce1cd8a528c3ffaa5d5b1dc91a4be56f0e2c5e06
+
+TST: 297
+SK:  b809361f55cfe8137fbda880fc62cbe44c216e141893346302b336045de21878
+PK:  fd23e42ff06644ead347abcc1b3e03b0e88593b61254981dd8ae59454e61b3e0
+MSG: 17ace197d083aaf1726f53e5ef81b5a8c09222f260ee5f1f5404ab78d900d489688449b843bad3c498aac6d80b4639b76e6e81c55276a6f9c7cecd70b71aaaf2018ef76c0e30154aae86a5c86d4e8d0e4ec68cc427060bd56514f7238086bbef5bfca1f5671b18041838fd013572443dba48fbdd95ca740b0daa4327164a1e34677249708f77bd793e7caa6638b5dc9fbe6f0dfd4120209097209c93cedfaf21b6bf59ca6e99e6209639444f0e827bbcc0a61c3a237ca22a283213223ab658e712c7556238d3a5fe31722d65f5706ef6d64d73232d3043220f14e5cfd3c2c83a83d68e20274b6f96b29de040cec8475030b6a8a87d29808dd381795c3d22acf5dc193b720d95a752d9f123c209ffba004e48dd06dd8c9e172bc9e087d80bc5216c0b0b6e77031241
+SIG: b5b5950d3772d2eef88e1b0f5df5ffae2f2103885e71446d346fbb5daef94967a6b7b6e4be885110065876c665b7812de46ad31ec3bfcbeaee13ed0c1e0b300e
+
+TST: 298
+SK:  eeef8074c2eb9a1cee2f2d3bb05325546a9fb7cbe44b599461fc5885f5fd9cac
+PK:  9b892941a0573b7a1673ef480f081168d9b7496a81f9177dc427ca1f84cbbf7d
+MSG: 9ae39feade905affcbedd2e72a6f2429b3d1108e5bc1a9dbaf490a6299bccd94acc413adacc918b14afa85c78bc168cc00740c3da0e08183915f79b7fe3868ce2a7e886b32ad45009805bfb81b8c07b3b1022420c0f009b889d7fc22fd1997ae34198438ca94778575122fcaaf96e6502c33a75a129a2d0dbb073d93820d9c96683db318990be3fef4cafc890afbd9b1504c7439a08a065e7814ee4f9b6f57ee16baed3f0e3aa35dd23d3528a458919ad77048b4e2e6172346be249a50af02bc6c853304c208ae0ba02771262a0d8a465f71fa0635e53eb2ef0a847d56a0bcd7dd3fe077c92bcdca3069a4a682a2859928315ce3eb445c6072a71492ee82e172a20be0b648b756e6c775376f0c7c3df8e64288089c2f81ce9593c6e08bb1cc1b27fcbd392fc7952c55
+SIG: 6f7101984fd6892e2144b7d45619830caeb6713bfab4eebbe217c5becd249bd9d752eb76e9fa995e7c71ff7df86bb260cdda173ff5deec6af204b7dde011de09
+
+TST: 299
+SK:  61faeb15f857f6557862c8b8c7ef41f80545520996fcc1127b8c2491822201ae
+PK:  60a290c0fc425a0874673d94f9bb1400f9dacde9954f9f5b05dd48ab747a3950
+MSG: 253b566eccb563bd6e480c69739b8e372519a3437254e0e5029cac86c71638f2df2a6cf9e56db2569934deba90db75547e3671747df64d6f2aaf3c110fa67a7094ccbe4cc5355f0d43235136ee26dbe37f4225d3bbfe245595280585fb548f894e86c516102580291fa7a02859557fb98eb588870828b0990ae9d74f3831da58946bc7a5ce1ba498b4e8be8989a3b50d7e8789f56b8b4fecbc2a33bfa3ef591a0fbcd932fa93e19f3a812ae5e4e3b4b242be7705a5874af73be310b0058266a378f23c1348524715b0ccc18d6634b23636c316ba6a1dd2fd5092c06716a717b54d0eb9fc7f636f85bbf225a2cf035b4b7cfddd75351682c0576c6b3ba5a1c0b25ec594e7709dd09a0079772ff3acc67fb6c1b37bb3742b726e77e80561d9ab73160b73362581da5b9c7f
+SIG: 31f90f50b2dc705f1d92f12ca9975d76f1b2826ada3cc185b0ed6c83860777bd8c489b59855a91f64839d49ba467985abb376c47a4908b271b8f77c58d01fd04
+
+TST: 300
+SK:  e6b9cd4da07cb34f30391cf68f0d87c7cfcf68f810ffa40f9739c95deb037f71
+PK:  569ede0f04630b43a04c5a66b6a5636b766c75965984a7477e15491960fdd864
+MSG: 69def0523afda696f8448f9c1143abc26533e68695a090df0d9e43d0c0eff43583e6f709d2043c815fbb3f96ba2b0dc3be6fecad5dd38148788e4a0385a9fe7a921fcb8ccee0e4d3aed4bc3d216d84b414f9580b02820c03d92e675e685c4b5851f363bb4df97b417c3fd90022eeafa20dfbe82964f2ff073d255758fbe567c76b2c35e2b09f8a8d7afa32c6f5ad01bc3ebf6e210606db038ecb6820ce1ea4dd529fc1adfbc2a138565ac6d0f4a4109bdd47b8aa6ef4b8bede454680d1dbdb75fe1eb2e548d5de7cb6d792fef3aa0d8480a6030b30f104d7e76b58e9f476ebf2cc832923b50c50c111c3515fc518852323426ca778a596d3195da8585d8c3aa92083313a6e6585b70c98b185b472798a61cde77e62ec272f14b0d9eb4f22f9c7c05817da6fdefe7879a584
+SIG: 1e375c94bd809ca0cdd02f89ecec4e437732dd20a0a84b254eae889d8070e682d113b0be22e41e6cdc3be877680e7eeb7f0995e6622dc0b434fb0949dd994b0c
+
+TST: 301
+SK:  4d9044f17b5a0977dc5aa9916a924300a244a1ef7f060277ad4978351ea64291
+PK:  ab9c0692a606b2567c19c30f9faa3b4cfe72fb237077767b76d3b2ae1490a6d4
+MSG: 7c8c7189af67327af1c6dd2c30e975f190e3b38d008b4585167e0d450740d46734587f6d208784245cc5cb062a2a277f17ebb2746f9bdf4a8237ca479ab0a430177e19ed7dd3622576b14cdc08282214fe5ee4d76b43c16ac90864c51be8aed45d7b980df7917f290fdf795846465f27fcb7e5730637944f0577c92f32375e995bc0cda9d7196f2c0c1ac8b80d12a0439963ebd2254c347703575816e7964c13d44d629280c312ea265344de38f3b18d9150f8f924afb44b6bfb9eda513d59e65e2ef18666e6c2a21c4018665befe92cae581d3cb14e23e97d830002cb90931ae0210068af394ebe351be5b817f3674bfbf40049030e4fe505d34a1d502a2c50d8e638e926c230676b7edefb6bec77b1c0ce609325287ba5fdd7a9976987bd07fc6a4344956ebf818f08586c
+SIG: 6fa48aea4d5b9af65af964cdb709443a11fa84f7d44acddab16e04a6fcefb27ae33c05b36da13c23de517d6e6ac574a03ea630ba4fbb958131129aa7f1354c01
+
+TST: 302
+SK:  75ad76bb4c0c229a5adc79e444b13f88a96459862c8cf0ba498d0c996af94a7a
+PK:  f074dd2b9c1c309105ec951bb5812a91ddb54023b3809ab379c56af0461af617
+MSG: 0ca8c1c74128d74e9d0a7bf8964291d074917f2f9920efb911520567642a50a615abcbd00aed4abbfef1a983cce333e1d0df3e6404fb9043c6803914cd5fffbc66a0790c7878a24089a571f895662a1d18be3f01ff97fb3323334b6f5baf96551448e4090d033c464294d09133b151d5b5c6321b50e2241de0ef6f882889ccf4ad3540d5a1e3f7548fb13be71c16516606e79d0449c2a08e5dc23148843c84e97ed24069161c8e75208f33e95b3e10d1d49a2faef9d986ab62809f62ad39c7cc871f375a4f5a6faf104d7e11b890cfb0589902685216ec07cb8e8e9e7a7c43635e23212b69ca3b7ed54f0b97949e3d9a6662f8e4b3ab09cd495294c331c047d86ee785ff658bcd7fcf9c480605ce05e810068d60fc9b26b5f063eb9000d2657a5094284ac80f1375d0b66d6f5f
+SIG: 0c4643a8be6dc22f4beb6bcc70c6172ec7608378653cb4e99f3ae795eadf4e982a297609ca7938f5df632b095628cb75062d3d51fc0f3323bfa7b22ec4d47205
+
+TST: 303
+SK:  adc6e9b2e103b62c24ad4346410e83a1a0bd253e4abf77911850c6d9666e09f9
+PK:  fce316e33c910821beeddd634bedc58ee57999a76ece384605283b99b543b78b
+MSG: 8cccd98ebbf2439ffdfac41687638faa444e1ca4b63d13e898eaa8355492f28813ab813fd01510e112be106b2045d30f63335d248904d521de181abac03e3d2cb2d16c44b3b012a0c51f9901aef9056c724d7a2c6b2acb0a07555940e4c6e21154890611adeb6489f461d3e5ecd1af5a4d2b0adaf41747436eb414757a8fe4775674e3c6e5de4569d6fc6c788e10905eba32c270a393e6f721a765294e2ac99a9b6e534d3df08d1db97d602ac3195cb0b77f5bd4acaf737fadd6991f0688abc74918047574eac28289739a664e0e0e20574a2c25fde49d14539db1cedd4a9204a70acff0a62c8f25cd768ffab15c4db316840a4d1bc92e212670be07c5bdcf537590607dfbbbb4d9f98b89da0b4df7d88f3eca4814d16bfa20c8d2fa94f9f259f2ee2d3a83c9e4171b1a262c4b99
+SIG: cb017d6d2682c9854366259aa35f30d491cfaa930998c297dbddc6aded5b3d401cf76d80d8a2764de131718b6e0c481d7196bc72579716b0c0f6ff053e68c50c
+
+TST: 304
+SK:  37fc1beda4060b6c57883ddba0776c2bcf5ac28a651326021cca97723730fbb0
+PK:  7bd7bf1c99dc82e06f08bb454d8fb288a57927e07ff1b12af15ee2c12fbb6b3d
+MSG: 3dfcac0265a024a83cb932674489a163aac314bf3d969f27596e451733b99deba5eeb779210baf95bf545a1ae6b8a915860693ee890f939320e06a844483d18c6a1bcd03c638bb7d1fe2a82eb448a311b1302ea6428f54a39f45a4d560be1557a2b254c45c137f45cc68356836e21bed0b7f73a518ce09db0be393927c339bf2a4b5987539404ce650284de12e3b553b262efe23848332ccfdc35e791a0ab43f139c71ed0fcb2d173bb377ee46b1a9dca9277e77df855f2830251e31e26acd86763c8d7eac22c882fc174f2b5e75ca6ad1ade03f942bb2a13bf541906159158c68363c7480c5b27a99320f8283a2699d4369c071c50dbd90b7792e4772efbc0b195bce84cc4dcfff7072a48968db69f9feddd0f9ced659eb5db7167f35f988cec114887dcbfdf27d02d300b3e1abec
+SIG: a01dd65fada27039f168b123419d8abfbda48c572ece24fda06e1a5ec31e084f4ee1cbf9961e88ed51e189fcb7f5f235de1e5b28d08f2bfca190b0f019ecc207
+
+TST: 305
+SK:  8d42f4ddd2bbd2b827b0a0d31d8f758ebd13a1b9b3712228948ca610bb8858e5
+PK:  b7354898794f9db0a8af6eeafcdbdf011d3fbef0212ad938a4a4ad27ab16ebbf
+MSG: e3a2bebc0496d8974a8f4061880369314ed9e440c1b77e26fe5071ce694ffd2136db0c4d5e880e6000083a75c90d3cf72b9cf5a2b1a9002c2701a2ff59b0699a8f42d79dd8a5fb71a8125453d91fb80080a3f0a16584282f17ec7dfdc2e5c69c4d9bdf484d55944dae273f211cfb76ad37da45871365439af35eea1fbecd4ca679b59b5e01bacf49c7f4e5efaa406ba1daeb085482af5ded89dc6885ffbe3d14d2931b83897e28ad06e5564e2789baea81bd932aa279fe8e324b9a8ef111c2abe2f137d4bb50d8ab76cebc0bd982a23919751ad4d49e88eb14173d3310289a872317e4a451e88d54320891870f15b2d53324430877a9fb5b49bb929f211c5b89764dd9c3a595a1451e9f85a238540002566e53a99ed1e6ddc9b4853f455edb4cf1980d56bbdc1313a36e76ea9cbb048a
+SIG: 70764be39c6dca0f067abe1eca490fda951fd4e9499695266e270b9b05eae706ca8d1ca6a92d7c488ec6ad8ba11457a42a5e31702a9c2bce892dc40535c09f01
+
+TST: 306
+SK:  b62de5a1acfe4ca2d1f0c132afcbdae66fb29a02f297fbc2407fadbbf2454200
+PK:  b63b2d0bf355f7b6d0bac07403411c40afbbb2f707503b3fc2cee8a1c7d0a838
+MSG: e659e51d7b193c4b8e2b3ed73a9d7557ed2bab6153883ab723592f730a914567142b3fa435db3219f83a542dc7a4bd805af666ea865b853146f8e3a9fe870711f90d12b0693492af2a1edf99a16458f781f1266ec437a5296a822ca9d69ce844b5c59097a2a56f3eb8fd273a636116db774300922d45b744657a692f5e8bfbcb06d2422818aeb51e7cda68acfbeda16e7c79580dcccde24e8e3d601b16e063b43a6d0d1407552f7504f5be19882e4ffe32344f5f473e73a8f6ed37b0d8d9e5e0a0dc9828395bcbd8f3a4e3124869249d058be0e045de0b1e12b1c83ba0aa227c95b82bf742c3eac0152b33e6d19be8b33a35bf705daab10622a90aed022ea6e439ed50a9308437929924ba3ab111ad0caa6feb0a6eb165824ebdb0866571efc07e5222ed8686b14d9270bf76b945d52014
+SIG: 5cdb00e98de73eab480be42f8a8a6163809a0d37101b6a5a4eed6a0c92030d09a5562c729080ce6f6594c8fafb1f594772db7a90a9e7da15896e82f70569390d
+
+TST: 307
+SK:  9732059d7bf0200f5f30412430336be4ef1e3cae62938ad08729ce3ba714cfd4
+PK:  0de8425f5e30b2b8aebb8072009a30cf0411c3c8238f4e4208760c56c33e434f
+MSG: 1a13e7ab603b48eb896fe17173fb31950b0dcd5a35ffdbe1371c7a5bfba593317589d9652d88797729180b8d0e515abfe6548f160421e537d5c94aef2b34c7ebb097420003bc0f361b423e7e14630a803c118202540049f68c9cf46fae0368d162e400d77bb4523cf6c753b975c245bc99ed2f413a9d06c2da6ce0cc0987b6406b809e8eb319033d2de9131dee3b1b7b5c95d653ced8fccf998da1768511eca4d3c5f735adab96503b3551803e4922635095ef811be4c08a6cbac917cbe6cd91a4ae5a330ccec0e8e815371217a3de62f2d2d61466219833f33447132f4d43350c58cbaf422475edb128c56d80a495726b1fdbc56551eb72d0f4fec26ba8bff5eed6774b85039a5292834b5d1cc1b09ba0a3954d29323673f5e71276a12ac4c579355bf1ecca48e6a716b9fcecdc565c51b9
+SIG: fba1749b641dd4df34664bc43c00468c7d75e84afad72de473fd1e9c87da15ea604fc2549a1a867fa80850e9c2a59cd99053886760a8d9764b84dd672676720d
+
+TST: 308
+SK:  9c7f6f379e3857007e2ac6324cbbced57ac9eee4477813f83a81fc8cefa964d5
+PK:  a54ba396d687634d3eccf41c5782494f5f10a521a1e5d388523d80eeba5b0b2b
+MSG: 3f2d3072fe7383e541551ea9abdbaeae6a464ae6b9f0ba786a441b2d08da5bcada3c5424dc6931d6b39523e2de0a0c2e4e6b5b8cda925e5eac938416a2c51bf13d49531d7ec7114b1c82feaf90f3f87591e397d02702f8ec1b30d99f5be7d2203e4fe4db2ea47e7b4589d8ac506248d7347466edbc96ea32bf3a6ea7502dd60c9e84902715ab2c6ca68f5b00e1d909d83aa6ab662d8aea870ecd861fec69f2eec0ae677d2995b0ed688faa8ef78244e0d1195697b07122ceaa11f5a6ea58fbdfa2e2ec2df9d18693ae96d47127556e91f0864982c13419b04a63f208e730d26951882aefe001bca3408bd9862748c6cc876c28cac3bb2eb3395818c2091e0fbd7a0b4468c6b0d00cd008c11c3c3ad01080a1f5a40ae2e4b0c3a071efc8e1d1ba6ace6d4df0ff19829b0c680b3aeb759177ed34
+SIG: 65685f9ca5982e15a22ba3c83a0348348482dfae57cea178f0780c057baebe4af632f984540a26019a7fb34253c9ece7ff308ada233ce0686347ab5b21ce570b
+
+TST: 309
+SK:  a478f35abb73727b6be6ee5e56eec323c9517882fd6919360ebbbf5d5cb8b83a
+PK:  7a6e266a54d135dda0009ccda8a94a4712ae5cb14761e8436e97c4b7814d8e8c
+MSG: 0173a34050b43748061ff8f5a3d7c43b6360847786e8bb75e536fb47b645b214f221ba24d83d28bc025024663e534f90f6e83a93d8bddeda2cd8808155652a908c437c2db6f3ed4912f57ca5b97928a73be964af59df4439854bb006fc295a87b7b72239c7fadfec40715509d98579daadfb8d524b4cec6620705efd4104c297144aea722974e12c5ecee5391ef2d93ac2b124e4ac496147c8b70363585d7078ccc53e2ae593350bc25548a0542526ab00afe477a0f4b27397c72bc74a8a8ab156e62b8bb47c3fbb4b34913e459687476bf33142c614702107ffe2cc01e25fa30275e1e2e63cea9168e4a47c02de097d4d853b27675c5bb330b94a974ead85e2bdee8ee17cbb5653346658df2f91f6bd739491dd71988b3a976a3e2e7a9d137410f4acba9feb5f11798c9a43b6adce14365a7c6d
+SIG: 9d16fd40b9f8dd9b4a1a8c6d703b9fccbb940b1e0ae77a5970374af0cf726f4479fd30d7dff5cf53494d9a296ab6b9e46ea6c136b4db2c71c21b97c1c8254d0a
+
+TST: 310
+SK:  ffe825148c0959b3a68de86ad8e8af7fa5e078f363dc124213c90020da0c9089
+PK:  139152a0bd22962dd919ae3e0b1620e03c033c2ad0a3979ec6bcd1705e23d598
+MSG: f125780d0cd088530f0c87b70bd42ebab56adb5ad4345f929ae5deae07fb55322153a8f023d38843bf5d6a93fe993eee71bc2ee563b25a50918f03efdb5dbf7269add69ded3e66953895620d9b6cf46ba2348f8d66d7f092235e378c1e3edfebeb78084bc8dea013f9933aae14a041948276d01f1cb5834b0e590e13d931d19292bb1d8041ff2fe2e1171a2e0b9a059821d0924dde7f3b1bb59813f5e3c63520aafb8801ba62c7097d4d8cf437a568a7f0087c6ea0fce6e568c4883f1cd12c749d06a6feb278f1086a8b04769921f78a9959062ab06f98ee80c2c7854ffa760f86a89ee1a51266053d195e61bb1dbd18dd89ff394e408ace0f641a395d56118ea72b7d8adf78b1655ecece7e8250e8a3a91cb8fca0d9ce0baf8980a387c5ed4318663280e5b4531f3187c47eaea7c329728ddd0e40
+SIG: fe4e89ee31786c0a3d3de3649bb93f0b8aef1caf5a832ec5e4067810705adddf539b8f4e05ad08cf3479e45b42c96528f6d59a4625703ddbf15b63093965d80d
+
+TST: 311
+SK:  49aff421a7cd12722aa84c48c1fb1c5f8d9e277d0a99ecbc9348c3aaa74be422
+PK:  88d2c26266f493bc67578ca0b1f51160cf0fdb6a09a906db9faa686f11f8208d
+MSG: 70a1ac144b75fda75586a79c36fd39cce5f5cae2e6375852d3b62a9630336a293ea6d2ac6e5b57da21ef364a595bb0750f5bf4d2b320676423870e4b8e0869601f16680619048c4ede276da69f205a70176e25ea04bd089763e709ba343fc8831e52044eabf9441e6997f8ba1aeb9ef0f491170667a7f5fc9627cbd0551b76be27283a4b0c5f667846688226a115ee8020df08042b19b59fe551316a6cb6916860b9ecd74154b4051038a17352372ec14d3c957d2ef50ff786189a8aeb9c08f45eeb5eb8b040339974aa9798c425d7becb228c447a6d0b3cef271893e0f7076e223a7e87c6a3d270a033bc97a4565edce0aa91ffc3f7801775a6f29b230245bd71fa034353de372395d1bfcbdebba081330f7c076be99c2cf4867f15b78d52f46fc7391c9cb95e5d64643baffe72a8e3a650667fbb3e
+SIG: 749181284df05dbe5974b91782a1a76ea08642cb0f0c98db586c575c210cdc8b651bd34b757ae38e4b6be9465235bd0eca430e26c3eede561c6e824dfa200e0a
+
+TST: 312
+SK:  703a6e2b62d0090c61d8659b6a963e03c9d62c1b38f7d70e5f9ff05590cd0360
+PK:  370c21de6ef2fab534ada999869c90bc9b92ccbf249b79d39d95441d1ede210a
+MSG: d42a1756e84df4b4e9773f86f7674a2cd78e71e40aa8f644e6702dfbc2c2c5ca90fc242e9cb0099cc8f2c2d3136baafc0ff695482fdacdef9f565610b6e1900722f435c6385b35e9f6c436ca037e03f64e2233dffa58db3b91cc1daa0bb0c54c8a43e469d2cff7fa2bf8f5d1d877931089c82ed89aba42f2ee2b86e445cfd09f4cd78b35191bf467e784eef75dc987e046d37d4d4e8e9bbe14af80d03a1f40898384b9d3279fac9c57fd9c7eecbe19a5acc15033b84e07fd0e409bdbd5a57f65641183a6c0a8ec426d1f1d223166ff0a1900b2e92b7d85835d019d17775e5093ccd126f90f63cb7d15cbeb531324219cd64ded6714b21a65371af07210dfdf0e4e58ddc7d59f4cfa65c421d814ee2c9bf6dbf64873d579b09ee5dcedd733063e039ac9a5f9ca4c2525a4cc8e984da7185e2d64fad81c8a
+SIG: e5fd64da028800c6ceed068a5e596f1621c70a8cb138b31b32647eb4b07bd2ecc5942c18844f367033f67398e314ba2c7ccf299c069787777025d845f2aad60e
+
+TST: 313
+SK:  76849c188e3edd0ff5f8fb874dc0456645518445e41a7d6833e616c3c48c9868
+PK:  d670e2ea07db60c22ab79a93ebf49d22a6245ee3af07b3be584eda694c37729e
+MSG: 1eccb0bc8eca3ab5bee68c5f8caa34536766c705f50827db7ac375d4fe30b58ffb7e2fe490cc71a8ff86c006d6174d05793ab8a55dd51b06de417bc0ac452cdc7cfb0bb00362b6765d20db23eb1848027064a1d9091d3b10ed776f28b76768bdfc08f0bc511f76faeba76cfc4cb5c83dc9ebe8a8d79edca923eccd524009cafedc90e3ad87d1392e1fccf4e60ccab95dc0ab54bf44245a007a96d46634b1b2965b829c3d7daa765972b54a7b365b6f34d77d7176acd8d894f6b417091b6c00edb7a4e81379988bfcecb692e9c3c4310a7e240e5c1063cde113f22a684a50a112ff47d3898812efb92637072b86163ad89316d221195acbfad0a03a1fbc2d967fe83f84c8459fccd490b9c5b3e55d27e9484e943c417f2128d73701da28f49fd3683f33a39cdee234bd305b9491e2f3eb621be3dd1dbbb31b
+SIG: 7141399d51daa6eb4519bf3f01b233920fa908fefa612f0cd7d5af8a9a3c44190e3f6384a8d14d37c97030ef5018cf8aee8aeb1569a73d84862a59b7df72fe09
+
+TST: 314
+SK:  83ae48ad70da0bb3cdf87481ee2c0c8571c2ca986712f8bc2329e9a3e33383c5
+PK:  b785309000df95f5a04f7d89c4113301057adaeeb29bcd28d99371b537bba2f6
+MSG: b7521d3f71c679fa7037fe7488a641f6b97c49454acc8e36b903d8f9ebb54d89cb56efd19e04ba6a7c8f48a7d3ec9decd3f1cd0faf6e978118e6adce9c6c6be63c6a6a1ae21651828479a46bc9a0f7943040f940a0d470c8e577c5d575cb53c1bf3ab1feb050dcb6fef0ba4447f299fdb9f27ecb0714ecfefd74bad7b122a462c24a209848a03389074578c5bdc36396d809b0f14018da64917e6bf87ef405c8f3e333ff9c3baf6339667620794bb4743f0514b5de7d7fdd947a7e3501ee88efad159e33a1072fbb99c7c71e9d13a502d5a07c4f817eeb7f0c5319aa41a96d5ff4f15a73c29b571fe211090e172c8db518624612a5c371a9d7cef6de35ebef96e88e1a78af3bd5dd35251ab54d73718f3e70d2d59021531dc73184f0fc69c2e92965844ec27c1c02af5e9a3469de355db2256e0ec2a4eba30a
+SIG: 43332351d3fb7b45fcf37c607d442ea80dbda2cb69c2884f424e65ea3a331ed8472d4368405cb736b2d6685ad782e239fe833ed789a2923185166f608342ee05
+
+TST: 315
+SK:  39e56a65623a0aebade0da12ce1df378bc924073f73a549effaebc465d1a78e2
+PK:  83da8ad50bad09eb3e94c725df3cc3a119736adc859ca1a10503f48ff2fec596
+MSG: a96dc2ea3fa1351492a4619d9194681f8ec400a97158244482653838ccb7e156a82d564368f83a6ee1be46bc34b817200e8464c3d12b5ef2c50b19565b881c4c3d4563fb947eb47c3ee9c1ee7853269874455bfacba305f307d1ac5309eeae5c07fa5c4d428edbc8b9528c4415243a9ef580aff8fcfb12000a71fceee89de97f90279529bcc822ed3cb34c82ba5fec15f4945663636d67b5feceacc31d25f98aea07f7800d5a1034251cb91dd0963ec2c1a54773a4d96c18357f8d101de58e932f8c6cdde8e3cfcef5a7443fdba7b78320403c0196844724a612183e34bdd808ce7b958861ca37115730eaede1fd0baabe976efefd0365fdf926776c536f47ff80de5c18291bb7e9f1b913ffd1d94468b789752fae6ca897c0cca53ef1e731d00c8bdbe8929ea6b1dce1f31a20688d37b0f3a2b4153b306bdba1
+SIG: 398e8260011f57d8ac8c58d5457bc652c7414aaf6fb2f426b7899056605c0afc28392423b2b571f5e6c3c7f6d60245e53ebd03bdc5ad3c1ad8738cb32214d00f
+
+TST: 316
+SK:  4b9921852f409a323ae38175e8d76a211fc4d9c654178eea3baa7a767a6fda06
+PK:  4c723e436b6bd97f44af52503b21cc50d5f6ad6cfc8288345dde8054e995582e
+MSG: 3f33d8fb83e68741090a37bedd745cf141aaaed8c92ffa742a52561777885805ace14246ab98a8cb598c9ce3de9b29bae5fa04b1cf828de11aff80a7ef8a3a38aede4f3c3563a25d049badcad5ed7e47fdbba6e111307eebe9ef4906bc989728b76e84afe808e6653b271e21104aa665f1898dd2aab23090e22b4e344a2616fbd8ee4ad8ed8108395eba817fbd14fec5c17dcf56b8220856b2b833e091407d5089b35ddf34b86ff7dc9fde52b21ef12176ef3370b7f3a0a8cb1b058a51aefff3d279d80f51a68bfb592587b45c5c63a7e4d625b887de486a118316c3b6a238575f92ac5b1c94c3f5dbbd96686000d6d39cccd558d420e4d447a8cbc4bc7b8c6a03af0f0034fb3518d93800f0f713e4b13732e16ada51801d7e559cf839d1058f64955698311399345416850dddcc5601a684fd09e6afd3944f5e19
+SIG: cbf1f1642df950eb71fd09590d34c265922c58bd8026bba3fc0e594a6bb1f2b90da3dc1d5f6b6d5b405a896d1dbb71b8685c4dfc444acaffe65ab8331789f507
+
+TST: 317
+SK:  1bff652a2c8309a393ac11da3aa97fb078bb284ed5e1b8ccc983652ef8556cd0
+PK:  aaabdc091fc3682354201744e9b73fd2a6cfb281914bf2c70ec3dc1dec7216b0
+MSG: 48d02698a97bdcb3ef078dcfcf5750005f1702d300e7e89bc436e381113401f852b8b4acff60ffbd4ab46d202168d98b8735e79cb350e35b070ff6bdcafd954b551969b6b1a70c9131ebd40d96140291d8d2b091540a8b18d8e5465915c25dbc6b5c9a687942533c372c8b4e95a953677169b950edd3464375cd43132ff9bd541ee22bd418ce23195f65d8b289f633ec8d71e1a801b06c3c827f627e723d2199100ce73e8e4a4440e778317a474910793b47b10ffb55db7f281c7d7a033bd80048b82673b87cf95e99422ba628688f3c971890ca15d12f572fa1977a17307069da304ead3026eb01042668890d17008cd1e92c46cbe9c857e7193de3aba3911e4f86fe0a1698ab7cdb9251a8424b2848b96ad81ea239d365fdea92ea5c0473d0a6bb1e371356bdfad2d0350336d3e1947c936fd0c25195445011731b
+SIG: 93c9c33493fc64172d51e16a0a1cd729a0d99e3cb864e89a42987f39dd8cd26545fdfe37581911e803677da4c55b0a683ddf62b728f8f30685ae58f628ebe609
+
+TST: 318
+SK:  002fdd1f7641793ab064bb7aa848f762e7ec6e332ffc26eeacda141ae33b1783
+PK:  77d1d8ebacd13f4e2f8a40e28c4a63bc9ce3bfb69716334bcb28a33eb134086c
+MSG: 5ac1dfc324f43e6cb79a87ab0470fa857b51fb944982e19074ca44b1e40082c1d07b92efa7ea55ad42b7c027e0b9e33756d95a2c1796a7c2066811dc41858377d4b835c1688d638884cd2ad8970b74c1a54aadd27064163928a77988b24403aa85af82ceab6b728e554761af7175aeb99215b7421e4474c04d213e01ff03e3529b11077cdf28964b8c49c5649e3a46fa0a09dcd59dcad58b9b922a83210acd5e65065531400234f5e40cddcf9804968e3e9ac6f5c44af65001e158067fc3a660502d13fa8874fa93332138d9606bc41b4cee7edc39d753dae12a873941bb357f7e92a4498847d6605456cb8c0b425a47d7d3ca37e54e903a41e6450a35ebe5237c6f0c1bbbc1fd71fb7cd893d189850295c199b7d88af26bc8548975fda1099ffefee42a52f3428ddff35e0173d3339562507ac5d2c45bbd2c19cfe89b
+SIG: 0df3aa0d0999ad3dc580378f52d152700d5b3b057f56a66f92112e441e1cb9123c66f18712c87efe22d2573777296241216904d7cdd7d5ea433928bd2872fa0c
+
+TST: 319
+SK:  25b0f0bb3dcb422a6f3c6c220eaadb11dbfe489c2d455b276cefe8cba057f9f3
+PK:  fe03c9c4394adc74b13f47654bead8bc855958b4194fdab2097ac1b157933c05
+MSG: 54d99f969efa8870fc20fa9a962bb372619c324439728af3139c2a07e8c1b29c1e4eedc2d40ba722f63ce37670362af6f5202add668c4fb4d62fa8bacbc7d07ff3bd38c15a01064259cc34134861632967460541a99b8d5182bf59347b5a59879aa3b091a1f3e04135bd6301be5226d4895e5e9c2b15e48e5ecdf44129e6122853a606fc118466fa720b5ab165635c3bde04d74289274fa03547accbde780e1fa0bf2c56f8436a53e73878a424a29aa9de385dba419ae6a5d12e004276152b58d325b302400a55333c38cde4908ae1d0121cbeca950809c543314277c1485e68d9f9c0a962d1b1e0dda1d4a52b56f8308a80b92acc9f4ebc3ed45d91a129da8675621af676703def3b84113183b2e3a8c56157f243f13980f3d1756fea7668c91503d35c839a2120c79ec954fb546d7b542f987289534ffdef62d47fd5ec
+SIG: da50d5242bf51c3951780cafd926d67bdf5640d5d3bb08433831d56e48e2592a1c375968bb4d2fbea56145abf2d82991363b1565fa1effe214011a686e39950e
+
+TST: 320
+SK:  bf5ba5d6a49dd5ef7b4d5d7d3e4ecc505c01f6ccee4c54b5ef7b40af6a454140
+PK:  1be034f813017b900d8990af45fad5b5214b573bd303ef7a75ef4b8c5c5b9842
+MSG: 16152c2e037b1c0d3219ced8e0674aee6b57834b55106c5344625322da638ecea2fc9a424a05ee9512d48fcf75dd8bd4691b3c10c28ec98ee1afa5b863d1c36795ed18105db3a9aabd9d2b4c1747adbaf1a56ffcc0c533c1c0faef331cdb79d961fa39f880a1b8b1164741822efb15a7259a465bef212855751fab66a897bfa211abe0ea2f2e1cd8a11d80e142cde1263eec267a3138ae1fcf4099db0ab53d64f336f4bcd7a363f6db112c0a2453051a0006f813aaf4ae948a2090619374fa58052409c28ef76225687df3cb2d1b0bfb43b09f47f1232f790e6d8dea759e57942099f4c4bd3390f28afc2098244961465c643fc8b29766af2bcbc5440b86e83608cfc937be98bb4827fd5e6b689adc2e26513db531076a6564396255a09975b7034dac06461b255642e3a7ed75fa9fc265011f5f6250382a84ac268d63ba64
+SIG: 279cace6fdaf3945e3837df474b28646143747632bede93e7a66f5ca291d2c24978512ca0cb8827c8c322685bd605503a5ec94dbae61bbdcae1e49650602bc07
+
+TST: 321
+SK:  65de297b70cbe80980500af0561a24db50001000125f4490366d8300d3128592
+PK:  ba8e2ad929bdcea538741042b57f2067d3153707a453770db9f3c4ca75504d24
+MSG: 131d8f4c2c94b153565b86592e770c987a443461b39aa2408b29e213ab057affc598b583739d6603a83fef0afc514721db0e76f9bd1b72b98c565cc8881af5747c0ba6f58c53dd2377da6c0d3aa805620cc4e75d52aabcba1f9b2849e08bd1b6b92e6f06615b814519606a02dc65a8609f5b29e9c2af5a894f7116ef28cfd1e7b76b64061732f7a5a3f8aa4c2e569e627a3f9749aa597be49d6b94436c352dd5fa7b83c92d2610faa32095ca302152d91a3c9776750e758ee8e9e402c6f5385eaa5df23850e54beb1be437a416c7115ed6aa6de13b55482532787e0bee34b83f3084406765635497c931b62a0518f1fbc2b891dc7262c7c6b67eda594fa530d74c9329bad5be94c287fbcde53aa80272b83322613d9368e5904076fdbcc88b2c0e59c10b02c448e00d1b3e7a9c9640feffb9523a8a60e1d83f04a4b8df69153b
+SIG: 7a9b736b01cc92a3349f1a3c32dbd91959825394ff443c567405e899c8185ce8fad9500e1fce89d95a6253c00477435acf04bff993de1b00495def0834ee1f07
+
+TST: 322
+SK:  0826e7333324e7ec8c764292f6015d4670e9b8d7c4a89e8d909e8ef435d18d15
+PK:  ffb2348ca8a018058be71d1512f376f91e8b0d552581254e107602217395e662
+MSG: 7f9e3e2f03c9df3d21b990f5a4af8295734afe783accc34fb1e9b8e95a0fd837af7e05c13cda0de8fadac9205265a0792b52563bdc2fee766348befcc56b88bbb95f154414fb186ec436aa62ea6fcabb11c017a9d2d15f67e595980e04c9313bc94fbc8c1134c2f40332bc7e311ac1ce11b505f8572ada7fbe196fba822d9a914492fa7185e9f3bea4687200a524c673a1cdf87eb3a140dcdb6a8875613488a2b00adf7175341c1c257635fa1a53a3e21d60c228399eea0991f112c60f653d7148e2c5ceb98f940831f070db1084d79156cc82c46bc9b8e884f3fa81be2da4cdda46bcaa24cc461f76ee647bb0f0f8c15ac5daa795b945e6f85bb310362e48d8095c782c61c52b481b4b002ad06ea74b8d306eff71abf21db710a8913cbe48332be0a0b3f31e0c7a6eba85ce33f357c7aeccd30bfb1a6574408b66fe404d31c3c5
+SIG: 4bac7fabec8724d81ab09ae130874d70b5213492104372f601ae5abb10532799373c4dad215876441f474e2c006be37c3c8f5f6f017d0870414fd276a8f42808
+
+TST: 323
+SK:  00ad6227977b5f38ccda994d928bba9086d2daeb013f8690db986648b90c1d45
+PK:  91a4ea005752b92cbebf99a8a5cbecd240ae3f016c44ad141b2e57ddc773dc8e
+MSG: cb5bc5b98b2efce43543e91df041e0dbb53ed8f67bf0f197c52b2211e7a45e2e1ec818c1a80e10abf6a43535f5b79d974d8ae28a2295c0a6521763b607d5103c6aef3b2786bd5afd7563695660684337bc3090739fb1cd53a9d644139b6d4caec75bda7f2521fbfe676ab45b98cb317aa7ca79fc54a3d7c578466a6aa64e434e923465a7f211aa0c61681bb8486e90206a25250d3fdae6fb03299721e99e2a914910d91760089b5d281e131e6c836bc2de08f7e02c48d323c647e9536c00ec1039201c0362618c7d47aa8e7b9715ffc439987ae1d31154a6198c5aa11c128f4082f556c99baf103ecadc3b2f3b2ec5b469623bc03a53caf3814b16300aedbda538d676d1f607102639db2a62c446707ce6469bd873a0468225be88b0aef5d4020459b94b32fe2b0133e92e7ba54dd2a5397ed85f966ab39ed0730cca8e7dacb8a336
+SIG: dc501db79fd782bc88cae792557d5d273f9ba560c7d90037fe84ac879d684f612a77452c4443e95c07b8be192c35769b17bbdfca42280de796d92119d833670d
+
+TST: 324
+SK:  1521c6dbd6f724de73eaf7b56264f01035c04e01c1f3eb3cbe83efd26c439ada
+PK:  2f61a26ffb68ba4f6e141529dc2617e8531c7151404808093b4fa7fedaea255d
+MSG: 3e3c7c490788e4b1d42f5cbcae3a9930bf617ebdff447f7be2ac2ba7cd5bcfc015760963e6fe5b956fb7cdb35bd5a17f5429ca664f437f08753a741c2bc8692b71a9115c582a25b2f74d329854d60b7817c079b3523aaff8793c2f72fff8cd10592c54e738df1d6452fb72da131c6731ea5c953c62ea177ac1f4735e5154477387109afae15f3ed6eeb08606e28c81d4386f03b9376924b6ef8d221ee29547f82a7ede48e1dc17723e3d42171eeaf96ac84bedc2a01dd86f4d085734fd69f91b5263e439083ff0318536adff4147308e3aafd1b58bb74f6fb0214a46fdcd3524f18df5a719ce57319e791b4ea606b499bfa57a60e707f94e18f1fed22f91bc79e6364a843f9cbf93825c465e9cae9072bc9d3ec4471f21ab2f7e99a633f587aac3db78ae9666a89a18008dd61d60218554411a65740ffd1ae3adc06595e3b7876407b6
+SIG: a817ed23ec398a128601c1832dc6af7643bf3a5f517bcc579450fdb4759028f4966164125f6ebd0d6bf86ff298a39c766d0c21fdb0cbfdf81cd0eb1f03cd8a08
+
+TST: 325
+SK:  17e5f0a8f34751babc5c723ecf339306992f39ea065ac140fcbc397d2dd32c4b
+PK:  4f1e23cc0f2f69c88ef9162ab5f8c59fb3b8ab2096b77e782c63c07c8c4f2b60
+MSG: c0fad790024019bd6fc08a7a92f5f2ac35cf6432e2eaa53d482f6e1204935336cb3ae65a63c24d0ec6539a10ee18760f2f520537774cdec6e96b55536011daa8f8bcb9cdaf6df5b34648448ac7d7cb7c6bd80d67fbf330f8765297766046a925ab52411d1604c3ed6a85173040125658a32cf4c854ef2813df2be6f3830e5eee5a6163a83ca8849f612991a31e9f88028e50bf8535e11755fad029d94cf25959f6695d09c1ba4315d40f7cf51b3f8166d02faba7511ecd8b1dded5f10cd6843455cff707ed225396c61d0820d20ada70d0c3619ff679422061c9f7c76e97d5a37af61fd62212d2dafc647ebbb979e61d9070ec03609a07f5fc57d119ae64b7a6ef92a5afae660a30ed48d702cc3128c633b4f19060a0578101729ee979f790f45bdbb5fe1a8a62f01a61a31d61af07030450fa0417323e9407bc76e73130e7c69d62e6a7
+SIG: efe2cb63fe7b4fc98946dc82fb6998e741ed9ce6b9c1a93bb45bc0a7d8396d7405282b43fe363ba5b23589f8e1fae130e157ce888cd72d053d0cc19d257a4300
+
+TST: 326
+SK:  0cd7aa7d605e44d5ffb97966b2cb93c189e4c5a85db87fad7ab8d62463c59b59
+PK:  4889855fe4116b4913927f47f2273bf559c3b394a983631a25ae597033185e46
+MSG: 28a55dda6cd0844b6577c9d6da073a4dc35cbc98ac158ab54cf88fd20cc87e83c4bba2d74d82ce0f4854ec4db513de400465aaa5eee790bc84f16337072d3a91cde40d6e0df1ba0cc0645f5d5cbbb642381d7b9e211d25267a8acf77d1edb69c3a630f5b133d24f046a81bf22ff03b31d8447e12c3f7b77114a70cbd20bbd08b0b3827a6bbcf90409e344447a7fbc59bdd97d729071f8d71dcc33e6ef2cbab1d411edf13734db1dd9703276f5eb2d6aa2cb8952dd6712bfae809ce08c3aa502b8135713fac0a9c25b1d45b6a5831e02421bba65b81a596efa24b0576bd1dc7fdfb49be762875e81bd540722bc06140b9aa2ef7b84a801e41ded68d4546ac4873d9e7ced649b64fadaf0b5c4b6eb8d036315233f4326ca01e03393050cd027c24f67303fb846bd2c6b3dba06bed0d59a36289d24bd648f7db0b3a81346612593e3ddd18c557
+SIG: bf9115fd3d02706e398d4bf3b02a82674ff3041508fd39d29f867e501634b9261f516a794f98738d7c7013a3f2f858ffdd08047fb6bf3dddfb4b4f4cbeef3003
+
+TST: 327
+SK:  33371d9e892f9875052ac8e325ba505e7477c1ace24ba7822643d43d0acef3de
+PK:  35929bded27c249c87d8b8d82f59260a575327b546c3a167c69f5992d5b8e006
+MSG: 27a32efba28204be59b7ff5fe488ca158a91d5986091ecc4458b49e090dd37cbfede7c0f46186fabcbdff78d2844155808efffd873ed9c9261526e04e4f7050b8d7bd267a0fe3d5a449378d54a4febbd2f26824338e2aaaf35a32ff0f62504bda5c2e44abc63159f336cf25e6bb40ddb7d8825dff18fd51fc01951eaedcd33707007e1203ca58b4f7d242f8166a907e099932c001bfb1ec9a61e0ef2da4e8446af208201315d69681710d425d2400c387d7b9df321a4aec602b9c656c3e2310bff8756d18b802134b15604f4edc111149a9879e31241dd34f702f4c349617b13529769a772f5e52a89c098e0dca5920667893a250061b17991626eb9319298685be46b6a8b68422444fa5a36bcf3a687e2eccb9322c87dc80165da898930850b98fc863cada1aa99c6d61c451b9ccf4874c7f0e75b0a0c602f044812c71765adaf02025395b0
+SIG: 985ca446ddc007827cc8f2852cbd8115ef8c5975e9d7ce96d74dfed859aa14a4c15254006bea5e08359efe2625d715e0897ee5a16f151203be5010418637de05
+
+TST: 328
+SK:  beedb8073df58f8c1bffbdbd77ec7decb2c82a9babecefc0331507bdc2c2a7e7
+PK:  b27e908b805e296fc30d2e474b060cd50c0f6f520b3671712183bd89d4e733e9
+MSG: 35ca57f0f915e5209d54ea4b871ffb585354df1b4a4a1796fbe4d6227d3e1aba5171ed0391a79e83e24d82fdafd15c17b28bf6c94d618c74d65264e58faaacd2902872fdd0efa22e8d2d7ce8e3b8197f0c3615b0a385235fa9fd8e4564ee6e6b1650b4cfb94d872c805c32d4f3a18f966461d3adbb605fa525884f8eb197627396ba4d995d78ac02948a0eaabb58519b9a8e2e7985cd1de2c71d8918d96a0168660ce17cddf364e3ec0d4bd90f2104751a1927ee1d23f3e7a69840ed040b00e5f6e4866ec58813149cc382aebf6162608c79574d553f47230e924a0ef1ebf55d8e1a52abb62a2d7ac86027c7c03cc83fa1949da29e2f3037ab986fd2fffe650e3149babae5a50b1ee9696f3babec72e29697c82422814d272085500fd837fe3c7a973ef4c169af12dd7f02700620bb045bdbf84623f326350570b3cadbc9aea4200b28287e17ab
+SIG: 8c890cccadc7760e1e82e43c44b3dc0b685a48b479ae13cc0a6b0557d0fb1cbabba63d2a96843412ea8d36c50acbf52b92cfb2dce49dc48af6ddcf8ee47a8608
+
+TST: 329
+SK:  9184ef618816832592bc8eb35f4ffd4ff98dfbf7776c90f2aad212ce7e03351e
+PK:  687b7726010d9bde2c90e573cd2a2a702ff28c4a2af70afc7315c94d575601e5
+MSG: 729eb7e54a9d00c58617af18c345b8dc6e5b4e0f57de2f3c02e54a2ec8f1425ec2e240775b5ab0c10f84ac8bafda4584f7e21c655faecd8030a98906bd68398f26b5d58d92b6cf045e9bd9743c74c9a342ec61ce57f37b981eac4d8bf034608866e985bb68686a68b4a2af88b992a2a6d2dc8ce88bfb0a36cf28bbab7024abfa2bea53313b66c906f4f7cf66970f540095bd0104aa4924dd82e15413c22679f847e48cd0c7ec1f677e005fec0177fbd5c559fc39add613991fbaeae4d24d39d309ef74647f8192cc4c62d0642028c76a1b951f6bc9639deb91ecc08be6043f2109705a42c7eae712649d91d96ccbbfb63d8d0dd6dd112160f61361ecdc6793929ca9aef9ab56944a6fa4a7df1e279eaf58ce8323a9cf62c94279fff7440fbc936baa61489c999330badcb9fc0e184bc5093f330cbb242f71fb378738fea10511dd438364d7f76bcc
+SIG: b3c24e75132c563475422d5ea412b5c1e8e6e5ea1c08ead1393c412da134c9a1638284ea7e2ca032fe3d3e32a9066a8c8839903f6ef46e966bb5e492d8c2aa00
+
+TST: 330
+SK:  354e13152ee1fe748a1252204c6527bdc1b1eb2eb53678150e6359924708d812
+PK:  d45ff6c5fb83e7bb9669aa8960deb7dbc665c988439b6c9ef672c6811dc8bcf6
+MSG: 8e5fccf66b1ba6169cb685733d9d0e0190361c90bcab95c163285a97fe356d2bdcde3c9380268805a384d063da09ccd9969cc3ff7431e60a8e9f869cd62faa0e356151b280bc526e577c2c538c9a724dc48bf88b70321d7e1eeedb3c4af706748c942e67bdabdb41bec2977b1523069e31e29b76300288f88a51b384b80cc2526f1679340ddec3881f5cd28b0378d9cd0a812b68dd3f68f7a23e1b54bee7466ac765cf38df04d67441dfa498c4bffc52045fa6d2dbcdbfa33dfaa77644ffccef0decdb6790c70a0d734ec287cc338cb5a909c0055189301169c4f7702c05c0911a27b16ef9ed934fa6a0ca7b13e413523422535647968030edc40cd73e7d6b345b7581f438316d68e3cd292b846d3f4f7c4862bc7e6b3fb89a27f6f60cd7db2e34ec9aae1013fe37acff8ad888cb9a593ef5e621eae5186c58b31dcfde22870e336d33f440f6b8d49a
+SIG: de2b46e65f3decef34332e500f2e11306fbdcf1be85a1c1ee68ba3045dcec2c7be608d22927da1f44c0e2083ae622cf3c29d893887994efcfa2ca594f5051f03
+
+TST: 331
+SK:  7ff62d4b3c4d99d342d4bb401d726b21e99f4ef592149fc311b68761f5567ff6
+PK:  7fdfdb9eca29d3f01d9486d7e112ce03aa37b91326a4283b9c03999c5eda099a
+MSG: 99c44c796572a4823fc6c3807730839173774c05dbfc1492ed0d00509a95a1de37274b3135ed0456a1718e576597dc13f2a2ab37a45c06cbb4a2d22afad4d5f3d90ab3d8da4dcdaa06d44f2219088401c5dceee26055c4782f78d7d63a380608e1bef89eeef338c2f0897da106fafce2fb2ebc5db669c7c172c9cfe77d3109d239fe5d005c8ee751511b5a88317c729b0d8b70b52f6bd3cda2fe865c77f36e4f1b635f336e036bd718bec90ee78a802811510c4058c1ba364017253aa842922e1dd7d7a0f0fc9c69e43fc4eaeffaaf1ae5fa5d2d73b43079617baba030923fe5b13d2c1c4fe6fac3f2db74e2020a734b6121a0302fce820ba0580ce6135348fdf0632e0008df03ee112168f5cfa0037a26a1f69b1f1317edf2a3ab367455a77e00691215d7aa3133c2159d3da2b134cf04f0defbf07a6064011e64dd14d4f8f064356655428804c2771a
+SIG: 058f79927fbf6178724815c7b11c63baaa90bcc15d7272be082f8a9141861c816433055f6cf6491424853f9ec78bb91ace913a93411b4e5ed58bc4ba5715c60a
+
+TST: 332
+SK:  6cabadd03f8a2e6ebab96a74f80e18164e4d1b6baa678f5a82e25604af989aaf
+PK:  2a4a3179564194e00100c18bc35351d8b135bbae5b32b28fce1d7b6766ca4b32
+MSG: 279f78cf3b9ccfc6e1b01e1a82f50ed172e9a8e1e702bb15661dd7dc3a456ff7a7a7fdfb081db3867079630c7f70fd753292ec60ecbf50632e9aa45b996505c66e6dc3c6ae892e21b6a8705e4bbae8f16a3378554b31fdb0139dcd15c96a8a7e4b88756a86d18db5dc74fd7691197dd88e2c7d5df52b049344cdc477c9cd7e89eda99ccfb1d00814d0152b9654df3279372ca5f18b1c946f2894a76b079ddb1c3cd61fbb969aeec9193a6b88fb7d136c07f9821e5c1074b4e93bcaf6fa14d0d1d7e1707589d77ec1337206e53a1f06cc26672ff95c13d5ff444766931ba30a0afdcdadd2098e9c41fd87a3f23cd16dbb0efbf8092ce33e327f42610990e1cee6cb8e54951aa081e69765ae4009aeed758e768de50c23d9a22b4a06dc4d19fc8cbd0cdef4c983461755d0a3b5d6a9c12253e09568339ff7e5f78c5fdf7ec89f9186a621a8c0eed11b67022e
+SIG: 4e65c6c1d493045e8a9250e397c1d1d30ffed24db66a8961aa458f8f0fcb760c39fe8657d7ab8f84000b96d519717cff71f926522c1efec7f8b2624eae55f60c
+
+TST: 333
+SK:  0fa0c32c3ae34be51b92f91945405981a8e202488558a8e220c288c7d6a5532d
+PK:  d6aee62bd91fc9453635ffcc02b2f38dcab13285140380580ccdff0865df0492
+MSG: 53f44be0e5997ff07264cb64ba1359e2801def8755e64a2362bddaf597e672d021d34fface6d97e0f2b1f6ae625fd33d3c4f6e9ff7d0c73f1da8defb23f324975e921bb2473258177a16612567edf7d5760f3f3e3a6d26aaabc5fde4e2043f73fa70f128020933b1ba3b6bd69498e9503ea670f1ed880d3651f2e4c59e79cabc86e9b703394294112d5d8e213c317423b525a6df70106a9d658a262028b5f45100cb77d1150d8fe461eed434f241015f3276ad7b09a291b4a7f35e3c30051cbf13b1d4a7fa0c81a50f939e7c49673afdc87883c9e3e61f5a1df03755470fda74bf23ea88676b258a97a280d5f90b52b714b596035bae08c8d0fe6d94f8949559b1f27d7116cf59dd3cfbf18202a09c13f5c4fbc8d97225492887d32870c2297e34debd9876d6d01ac27a16b088b079079f2b20feb02537cda314c43cb2dca371b9df37ed11ec97e1a7a6993a
+SIG: 7e9ab85ee94fe4b35dcb545329a0ef25923de5c9dc23e7df1a7e77ab0dcfb89e03f4e785ca6429cb2b0df50da6230f733f00f33a45c4e576cd40bdb84f1ae001
+
+TST: 334
+SK:  7b06f88026fa86f39fce2426f67cc5996bedd0cfc4b5ebb1b5e3edbb47e080aa
+PK:  3f1469ee6a2e7867e2e9012d402cf5a4861497c01df879a1deb1c539830b58de
+MSG: 71175d4e21721297d9176d817f4e785d9600d923f987fe0b26fd79d33a5ea5d1e818b71f0f92b8c73afddabdcc27f6d16e26aafa874cfd77a00e06c36b041487582bb933760f88b419127345776ea418f83522254fed33819bc5c95f8f8404cc144ebf1486c88515409d3433aaf519d9920f5256e629419e9a95580a35b069b8d25533dfcbc98ad36404a951808e01378c03266326d120046975fde07daef3266caacd821c1403499d7fdf17c033c8d8c3f28f162b5f09dfdaca06285f00c6cb986dfdf5151aa6639608b5b13e78d65a4368585b16138754fbd113835a686cd066c2b89bb0953c24d50e77bf0fc457c1e0fcf5d44da8db9a88f062be3b688d5cdcff1d1c00e81ec9d413882295b341fee8fa427dc109adeb5f284eec202f1bef115bf96b1782d3ccdeb682b69bf92d170c007d5df80e1ed962f677dc24a145a1e4e829e8dec0104e5f78365944
+SIG: 42f133e34e3eb7032a133ed781537ec62e44a5ce8381e5e0bf9e13a914a4b2c757811d6d3b1e86672424ea4230d10f7c610abb7069e61e319b4066a2bd7bc900
+
+TST: 335
+SK:  c3f5e149968a24f4de9119531975f443015ccca305d7119ed4749e8bf6d94fc7
+PK:  39aaccdb948a4038538a4588322f806bb129b5876c4bec51271afe4f49690045
+MSG: c46370e37f2e0cadcf93402f1f0cb048f52881ba750b7a43f56ab11ce348732fb57e7f9aaf8dfcbe455e14e983c248d026a27e7f148d5db5a53f94635702b895127771047a876d14107386c5e0ff8933345bbd7a936d990d33efa28c2ec4e4864ffd2ff576f7c88f954cfc1c459e883bb712dae3cdf6632066f1f4d13a509615b3360cadc5a307f23e52a51b40a6feebe0b18d0e9ee4e348f33cd81a8def222f6a59b12861d335bd9af85cc004be46f1d3a424f4870ae9dc587e5a4ade136b9370649348c33ac3bf1febeebffea37085ed59cac9d9e696470b234609e9a10a9d431ff91e69cb5135fd117ff58a36539744ebe70cea6973c00c7a4d57b62f4a7136d731b8e46ff18ec0ed69070031905075d8541d568cfce6eeb76242b7819a7b6a93552111bb88f165527cfa6966d39fcbe0a7dea008e39c7a3e577ab307cd1d0ea326833d52654e172955f3fcd4
+SIG: 5fa2b531677b00b85b0a313cbd479f55f4ab3ec5cfce5e454d2b74176ccc3399c899f9d6b51ed4c1e76185ac9fe730c4b4014044f7041185bc3c85722eb2ea02
+
+TST: 336
+SK:  42305c9302f45ea6f87e26e2208fd94b3c4ad037b1b6c83cf6677aa1096a013c
+PK:  3b97b1f11ce45ba46ffbb25b76bfc5ad7b77f90cc69ed76115dea4029469d587
+MSG: d110828d449198d675e74e8e39439fd15e75bf2cc1f430abfb245836885bafc420f754b89d2fbbf6dd3490792e7a4f766073cfe3b302d089831ace869e2730fde45c2121ec3ef217aa9c43fa7cc7e9ed0a01ad9f1d2fc3613638ca9fc193c98b37455bf5dbf8f38b64708dfdca6c21f0975f1017c5da5f6434bda9f033cec2a631ab50318e017b170b240bf01eb8b36c7e1cb59e7736ac34444208132a8f59e4f313d65d849c6a4fdf13e20ecaee3823e589a171b39b2489497b06e6ff58c2c9f1dc5d3aa3bd10e6443e22d42d07b783f79fd43a46e1cde314b663a95f7246dea131fcd46d1dc333c5454f86b2c4e2e424dea405cc2230d4dcd39a2eab2f92845cf6a7994192063f1202749ef52dcb96f2b79ed6a98118ca0b99ba2285490860eb4c61ab78b9ddc6acc7ad883fa5e96f9d029171223abf7573e36230e0a81f6c1311151473ee264f4b842e923dcb3b
+SIG: 18d05e5d01668e83f40fa3bbee28b388acf318d1b0b5ad668c672f345c8eda14c2f884cd2a9039459ce0810bc5b580fe70d3964a43edb49e73a6ff914bbf040c
+
+TST: 337
+SK:  c57a43dcd7bab8516009546918d71ad459b7345efdca8d4f19929875c839d722
+PK:  2083b444236b9ab31d4e00c89d55c6260fee71ac1a47c4b5ba227404d382b82d
+MSG: a4f6d9c281cf81a28a0b9e77499aa24bde96cc1264374491c008294ee0af6f6e4bbb686396f59068d358e30fe9992db0c6f16680a1c71e27a4a907ac607d39bdc3258c7956482fb37996f4beb3e5051b8148019a1c256e2ee999ebc8ce64c54e07fedb4fbd8953ebd93b7d69ce5a0082edd6209d12d3619b4fd2eae916461f72a4ce727157251a19209bbff9fbdbd289436f3fcacc6b4e1318521a47839cba4b14f7d7a21e7b5d6b6a753d5804afcd2b1eb7779b92abab8afa8aa4fa51caec0b85dcd0fc2a0676036d3f56630a831ffeb502861dd89161c708a9c006c73c930ce5b94756426ff18aa112fb4eb9a68500b48d4eedbd4167b6ffd0a11d49443a173ce9d949436748fc0634f06bb08b8f3423f4463dba7b4d199b64df578117f0a2645f0b2a1e2ada27d286f76733f25b82ed1d48a5c3898d4ad621e50ed9060daad40a39532e4d1bf162ce36804d5d4e2d
+SIG: 1edef9bc036971f1fa88edf45393c802e6c1a1631c8a06871a09a320821dce40beca97e53a0361a955a4c6d60b8ca8e400c81340911ccb4f56284041cdbb1804
+
+TST: 338
+SK:  2dddb6b8fd04fa90ece1a709f8418f2e5d0c9c43afe7cfce19e6ad15a73476f7
+PK:  8059de6a7c4776489ecc2e7d707ffce30285bf30a23f78d72db49cfd6ed0d492
+MSG: 474baa590a4cd72d5424e51d8257b3d44325bc4c5063a0033c86ebbe99ed7212184c19944d082a115379dd4cece973faa0bca6485bd25f3744a719e70aa0291e1b5a96e637c140616a98263357c76b6eb0083fe51414e386870d0fdc7dd9abe4ff6fb5bbf1e7b15dac3e08e2615f655c3104ceb32a4cc2c9e9c43cf282d346ac253ccc46b635ae040973b49735720ffb890469a567c5824e0c00d7ccd5509a718092a906461c4d6163eaf422418f5fc6e009fc3f529ac61a2f89bb8e0ed45d940c4c2331ff8d8e1d6d58d417d8fc2656a02e8701aee75aed918724eebe4a2cf4744c5c401e217023df68a6f6a0228bd05a679a697d8de7036b9ed269090d3c65486afb91e27954eb15b964665ede7ad008f12fb3a9d0e69c13b4254f43819e0818a4195f68b8a38ae81f3fcb1879c95ab4cd0ffc38e381089260cca967ace5a085b457ab5eb363852101377570f9ac9e38
+SIG: c634ea7bf72e895a2e796e2834201415b8b45e05e045559284eb9052c0e84f62a5a9f0c9764f7576788c7228b19ef517c195497325a48a9344b147c12fd75509
+
+TST: 339
+SK:  5547f1004baedfce5cfc0850b05302374aad24f6163994ecd751df3af3c10620
+PK:  7ce620787385ee1951ac49a77352ee0d6f8c5cd47df74e9e3216a6324fc7cf7f
+MSG: a6c17eeb5b8066c2cd9a89667317a945a0c7c96996e77ae854c509c6cd0631e922ad04503af87a3c4628adafed7600d071c078a22e7f64bda08a362b38b26ca15006d38acf532d0dedea4177a2d33f06956d80e963848ec791b2762fa99449b4f1a1ed9b3f2580be3ac7d7f52fb14421d6222ba76f807750c6cbb0b16f0895fc73d9dfc587e1a9e5d1e58375fbab705b8f0c1fd7df8b3ad446f2f08459e7ed1af59556fbc966dc249c1cf604f3e677c8a09d4363608774bf3811bef0642748c55c516c7a580fa3499050acb30eed870d0d91174cb623e98c3ad121cf81f04e57d49b008424a98a31eeaaf5f38e000f903d48d215ed52f862d636a5a73607de85760167267efe30f8a26ebc5aa0c09f5b258d3361ca69d1d7ee07b59648179ab2170ec50c07f6616f216872529421a6334a4a1ed3d2671ef47bc9a92afb58314e832db8a9003408a0487503fe4f67770dd4b6
+SIG: 29df3ad589009c667baa5e72dabb4e53cb7876de4e7efe5cc21ead7fa878db57f97c1103ddb39a861eb88653c1d4ec3b4306e4584b47b8bc90423119e7e4af00
+
+TST: 340
+SK:  3dd7203c237aefe9e38a201ff341490179905f9f100828da18fcbe58768b5760
+PK:  f067d7b2ff3a957e8373a7d42ef0832bcda84ebf287249a184a212a94c99ea5b
+MSG: db28ed31ac04b0c2decee7a6b24fc9a082cc262ca7ccf2a247d6372ec3e9120ecedb4542ea593fea30335c5ab9dd318a3b4fd5834299cf3f53d9ef46137b273c390ec3c26a0b4470d0d94b77d82cae4b24587837b167bb7f8166710baeb3ee70af797316cb7d05fa57e468ae3f0bd449404d8528808b41fcca62f5e0a2aa5d8f3acab008cc5f6e5ab02777bdcde87f0a10ef06a4bb37fe02c94815cf76bfb8f5cdd865cc26dcb5cf492edfd547b535e2e6a6d8540956dcba62cfea19a9474406e934337e454270e01036ac45793b6b8aceda187a08d56a2ce4e98f42ea375b101a6b9fcb4231d171aa463eeb43586a4b82a387bcddaf71a80fd5c1f7292efc2bd8e70c11eaa817106061b6c461c4883d613cc06c7e2a03f73d90fc55cdc07265eefd36be72270383d6c676cae37c93691f1ae3d927b3a1cd963e4229757ae5231eea73a9f71515628305410ac2593b325cc631
+SIG: 4c036935a96abc0d050d907bedbe9946fb97439f039c742e051ccf09add7df44d17da98c2ca01bdc2424da1e4debf347f8fff48ac8030d2cc07f9575c044be04
+
+TST: 341
+SK:  282775df9ebbd7c5a65f3a2b096e36ee64a8f8ea719da77758739e4e7476111d
+PK:  a2b49646033a13937cad6b0e914e3cec54989c252ca5643d076555d8c55e56e0
+MSG: 14cc50c2973ea9d0187a73f71cb9f1ce07e739e049ec2b27e6613c10c26b73a2a966e01ac3be8b505aeaad1485c1c2a3c6c2b00f81b9e5f927b73bfd498601a7622e8544837aad02e72bf72196dc246902e58af253ad7e025e3666d3bfc46b5b02f0eb4a37c9554992abc8651de12fd813177379bb0ce172cd8aaf937f979642bc2ed7c7a430cb14c3cd3101b9f6b91ee3f542acdf017f8c2116297f4564768f4db95dad8a9bcdc8da4d8fb13ef6e2da0b1316d3c8c2f3ed836b35fe2fd33effb409e3bc1b0f85225d2a1de3bfc2d20563946475c4d7ca9fddbaf59ad8f8961d287ae7dd803e7af1fa612329b1bdc04e225600ae731bc01ae0925aed62ac50d46086f3646cf47b072f0d3b044b36f85cec729a8bb2b92883ca4dfb34a8ee8a0273b31af50982bb6131bfa11d55504b1f6f1a0a00438ca26d8ab4f48bcddc9d5a38851abede4151d5b70d720732a00abea2c8b979
+SIG: 15763973859402907d8dcb86adc24a2a168ba3abf2246173d6348afed51ef60b0c0edeff4e10bcef4c6e5778c8bc1f5e9ee0237373445b455155d23de127a202
+
+TST: 342
+SK:  4730a5cf9772d7d6665ba787bea4c95252e6ecd63ec62390547bf100c0a46375
+PK:  f9f094f7cc1d40f1926b5b22dce465784468b20ab349bc6d4fdf78d0042bbc5b
+MSG: e7476d2e668420e1b0fadfbaa54286fa7fa890a87b8280e26078152295e1e6e55d1241435cc430a8693bb10cde4643f59cbfcc256f45f5090c909a14c7fc49d37bfc25af11e8f4c83f4c32d4aabf43b20fa382bb6622a1848f8ffc4dff3408bb4ec7c67a35b4cdaee5e279c0fc0a66093a9f36a60fdd65e6334a804e845c8530b6fda363b5640337d027243ccfb3c177f43e717896e46ead7f72ca06aa0ff1e77247121baf48be9a445f729ca1390fc46151cbd33fcbd7373f27a6ba55c92cbf6945b09b44b9a4e5800d403070ae66048997b2197f02181a097e563f9b9acc841139258a258bc610d3bd891637356b2edc8c184c35c65af91aaf7b1c16d74a5f5f862548139254ecf550631d5f8849afdb5b64cf366ff2633a93f3a18c39b5150245fb5f33c9e4e2d94af6963a70b88f9e7e519f8fa2a0f2e3749de883d0e6f052a949d0fc7153a8693f6d801d7352eb2f7a465c0e
+SIG: 552c7347bdfe131646ce0932d82a36d2c1b76d7c30ee890e0592e19f9d18b9a56f48d7a9b68c017da6b550c943af4a907baf317e419fbbc96f6cf4bfad42de00
+
+TST: 343
+SK:  2770aadd1d123e9547832dfb2a837eba089179ef4f23abc4a53f2a714e423ee2
+PK:  3c5fbb07530dd3a20ff35a500e3708926310fed8a899690232b42c15bd86e5dc
+MSG: a5cc2055eba3cf6f0c6332c1f2ab5854870913b03ff7093bc94f335add44332231d9869f027d82efd5f1227144ab56e3222dc3ddccf062d9c1b0c1024d9b416dfa3ee8a7027923003465e0ffaefb75b9f29dc6bcf213adc5e318fd8ba93a7aa5bfb495de9d7c5e1a196cd3a2d7721f8ba785aa9052a1811c7fcc8f93932765059cab9c9b718945895ef26f3ac048d4cabf91a9e6aa83ac14d43156827837914eb763a23cba53f60f150f4b70203ec1833ff105849457a8da7327661fb23a554164e05fcf0146b10674964be6f6aa0acc94c41ad57180e5180d199bd9102f55d740e81789b15671bbd0670e6de5d97e1ae626d8a0ebc32c8fd9d24737274e47d2dd5941a272e72a598928ad109cde937bf248d57f5d2942983c51e2a89f8f054d5c48dfad8fcf1ffa97f7de6a3a43ca15fc6720efaec69f0836d84223f9776d111ec2bbc69b2dfd58be8ca12c072164b718cd7c246d64
+SIG: f267715e9a84c7314f2d5869ef4ab8d2149a13f7e8e1c728c423906293b49ce6283454dd1c7b04741df2eabedc4d6ab1397dc95a679df04d2c17d66c79bb7601
+
+TST: 344
+SK:  4fdab7c1600e70114b11f533242376af7614b4d5da046ac4bedea21d8a361598
+PK:  a25c9a94d6e4ecd95a4bd6805f762eb1c457a8d45d243238b1839cbba8f441cc
+MSG: da405890d11a872c119dab5efcbff61e931f38eccca457edc626d3ea29ed4fe3154fafec1444da74343c06ad90ac9d17b511bcb73bb49d90bafb7c7ea800bd58411df1275c3cae71b700a5dab491a4261678587956aa4a219e1ac6dd3fb2cb8c46197218e726dc7ed234526a6b01c0d72cb93ab3f4f38a08e5940b3f61a72ad2789a0532000fac1d2d2e3ad632ac8b62bb3ff5b99d53597bf4d44b19674924df9b3db3d0253f74627ccab30031c85e291c58b5fa9167522a46746fc307036745d4f9817786e5d300e6c5d503125fea01dec3e3fedbf3861ca2627a0518fb2b24e5a7a014178719e9b345f7b249ce3a413280c8deb674f59a25be92a8ab6400c7c52b0728ae34e22b2ec200c1cbaba2ccd8af29249d17af60c36007a722fc80258a7bebab1cdaad7462a8b7588c2f7e27c6d07afcf60117fed11bd6859e75e3b4fcee3981881e95dd116827dd4b369af069d3c8f2676f8a
+SIG: 5075c090cfbeb6b01802af7f4da5aa4f434d5ee2f3530eebb75c85e08621f83edc08aa96693894a4277633ba81e19e9e55af5c495daa5e1a6f8cbb79c01c7207
+
+TST: 345
+SK:  264504604e70d72dc4474dbb34913e9c0f806dfe18c7879a41762a9e4390ec61
+PK:  eb2b518ce7dc71c91f3665581651fd03af84c46bf1fed2433222353bc7ec511d
+MSG: 901d70e67ed242f2ec1dda813d4c052cfb31fd00cfe5446bf3b93fdb950f952d94ef9c99d1c264a6b13c3554a264beb97ed20e6b5d66ad84db5d8f1de35c496f947a23270954051f8e4dbe0d3ef9ab3003dd47b859356cecb81c50affa68c15dadb5f864d5e1bb4d3bada6f3aba1c83c438d79a94bfb50b43879e9cef08a2bfb22fad943dbf7683779746e31c486f01fd644905048b112ee258042153f46d1c7772a0624bcd6941e9062cfda75dc8712533f4057335c298038cbca29ebdb560a295a88339692808eb3481fd9735ea414f620c143b2133f57bb64e44778a8ca70918202d157426102e1dfc0a8f7b1ae487b74f02792633154dfe74caa1b7088fda22fa8b9bc354c585f1567706e2955493870f54169e0d7691159df43897961d24a852ea970c514948f3b48f71ee586e72ec78db820f253e08db84f6f312c4333bd0b732fe75883507783e9a1fd4fbab8e5870f9bf7ad58aa
+SIG: eea439a00f7e459b402b835150a779eed171ab971bd1b58dcc7f9386dadd583de8dc69e267121dde41f0f9493d450b16219cdf3c22f09482ce402fe17ca49e08
+
+TST: 346
+SK:  2ca7447a3668b748b1fd3d52d2080d30e34d397bb2846caf8f659ac168788ca5
+PK:  ab331cd40a31d0173c0c8c1c17002532807bf89e3edb6d34c2dd8294632b9fbc
+MSG: a82bcd9424bffda0f2f5e9eae17835dbe468f61b785aab82934737a91c5f602cb7c617cdffe87cad726a4972e15a7b8ee147f062d2a5a4d89706b571fa8aa2b95981c78abeaaae86203fa2c0e07297406ea8c27111a86dbe1d5a7c3b7ae930904d9890f6d4abebd1412a73ad5feea64acf065d3e63b5cbe20cf20bbd2d8b94f9053ed5f66633482530124446605918de66455e8cf4b101a127233c4e27d5d55bf95bd3195d0340d43531fc75faf8dded5275bf89750de838fd10c31745be4ca41fa871cb0f9b016706a1a7e3c44bb90ac7a8ad51e272389292fd6c98ad7a069e76e3f5f3e0cc770b9e9b35a765d0d93712d7cdabd17e5d01dd8183af4ad9365db0a0fa41381fce60a081df1c5ab0f8c18f95a7a8b582dfff7f149ea579df0623b33b7508f0c663f01e3a2dcd9dfbee51cc615220fdaffdab51bdae42cb9f7fa9e3b7c69cc8ada5ccd642529ba514fdc54fcf2720b8f5d08b95
+SIG: f93ada15ae9cd2b54f26f86f0c28392aed5eb6b6b44d01a4e33a54e7da37c38e8d53366f73fd85be642e4ec81236d163f0d025e76c8bbdd65d43df49f09c1f01
+
+TST: 347
+SK:  494ea9bcce26885b7d17d1fc114448f239f0ce46e5f247b4c999fa8629692472
+PK:  6901e5efae57536ba5fdd96b59657359065f25d391a1aa8cdc0d38bb5d53c139
+MSG: 3badbfa5f5a8aa2cce0a60e686cdce654d24452f98fd54872e7395b39464380a0e185557ea134d095730864f4254d3dd946970c10c804fcc0899dfa024205be0f80b1c75449523324fe6a0751e47b4ff4822b8c33e9eaf1d1d96e0de3d4acd89696b7fcc03d49f92f82b9725700b350db1a87615369545561b8599f5ea920a310a8bafc0e8d7468cbf6f3820e943594afdd5166e4e3309dddd7694ef67e694f34fc62724ff96ac3364176f34e8a02b4cf569db5b8f77d58512aedabf0bcd1c2df12db3a9473f948c5c3243309aae46c49efd088b60f31a8a72ad7e5a35acc5d89fa66807eb5d3ba9cdf08d4753cb85089ee36f5c96b432b6928352afad58012225d6157f9e3611426df921b6d1d8374628a63031e9ffb90e42ffbba021f174f68503155430152c9155dc98ffa26c4fab065e1f8e4622c2f28a8cb043110b617441140f8e20adc16f799d1d5096b1f50532be5042d21b81ea46c7
+SIG: 548a093a680361b7dc56f14503b55eeec3b3f4fd4ca99d6aedce0830f7f4ae2f7328539b34c48fc9760922333dae9c7c017e7db73b8faa6c06be05e347992b06
+
+TST: 348
+SK:  00d735ebaee75dd579a40dfd82508274d01a1572df99b811d5b01190d82192e4
+PK:  ba02517c0fdd3e2614b3f7bf99ed9b492b80edf0495d230f881730ea45bc17c4
+MSG: 59c0b69af95d074c88fdc8f063bfdc31b5f4a9bc9cecdffa8128e01e7c1937dde5eb0570b51b7b5d0a67a3555b4cdce2bca7a31a4fe8e1d03ab32b4035e6dadbf1532059ee01d3d9a7633a0e706a1154cab22a07cd74c06a3cb601244cf3cf35a35c3100ba47f31372a2da65dcff0d7a80a1055d8aa99212e899aad7f02e949e6fee4d3c9cefa85069eaff1f6ad06fc300c871ab82b2bedb934d20875c2a263242cdb7f9be192a8710b24c7ea98d43daec8baa5553c678a38f0e0adf7d3ff2dcc799a1dbad6eab1c3d9458a9db922f02e75cfab9d65c7336dae71895d5bb15cac203f2b38b9996c410f8655ad22d3c091c20b7f926d45e780128f19747462abc5c58932fbb9e0bc62d53868802f1b083f183b8a1f9434986d5cf97c04e2f3e145730cba98779c7fed0cab1c05d5e4653c6c3f6736260bc78ee4372862ffe9e90371d762c7432781f35ced884a4baca05653ef25f25a6f3d5628308
+SIG: dcdc54611937d2bd06cacd9818b3be15ce7425427a75f50d197a337a3b8ba6714ef48866f243bd5ac7415e914517a2c1c5a953f432b99db0e620d64f74eb8505
+
+TST: 349
+SK:  8c34b905440b61911d1d8137c53d46a1a76d4609af973e18eb4c5709295627bb
+PK:  b69a8b2fdf5c20e734c2ffb294bc8ae1011d664f11afe7fbc471925cf72fa99d
+MSG: 30b57a389b48a0beb1a48432bff6b314bded79c4a1763a5acb57cea1bfb4c6d016cf090f5bd05bbd114e33ae7c17782dfa264f46c45f8c599c603016fe9ff05b6b5a99e92fe713a4cd5c41b292ed2bb2e9cf33a440542e821ec82cbf665c3f02e3dc337d7fdb58e31b27cb2954541468814698510df18c85c81fad12db11ec6b966f4930da5646b991db97445097da30dab61cda53a41083cb96add19de6c5eec323bca9d3530e38c00b35af7360077601be6ac97f3030f930a27b90fe8b6911bae389065adc15e1882300e2a003274d23182d5efd5ba4b9130c07bd5c65fecb8b5cb7eb38836b318befdfd77de4d6ca0181f77ae5740891683225f549dd8426145c97c5818c319f7ab2d868e1a41ceab64c085116069897bf2ca3667652406155ed0646431b6de1ccc03b4279ae4d326679265dce82048e7298e1f87fcec0768ac0f5d8ff84f7210be54d411af8edea7217f4e59413121e148c60da
+SIG: 3e0b72073dc9375eedcca6c4fc1cd315938a050c92716bd2284f4629a962beec0b7d7cf16ab923d58f5b90d3901a8e5c75c8f17dab9998e007d8c49511973d0e
+
+TST: 350
+SK:  77a83e18c9f000eeff7deeac959ecba2206c0aa39d2f0e2aed5729482a7a0229
+PK:  62b1b316135596bfbca6037ed847c61fb7f09fa36ce90abb7789b86f768b59dd
+MSG: f3d5fa2acaefd858f1df26e03059cdcbc2468ad74afc993d0db9c4cde4113f8d55c7da71d38ba06520531c61fddb5f33d5f0353be2376e580711be45c0a30b1fa01b55e228c6fa35e3f95b67909fc7df3fd464d93d661a926f9d11f7550c17fbcc3496526e8f10e0c8916677b2be5b319b688f21e81aaa9482e5c93e64ce8c437b9c1e14fefed70a3fee568811dc31cadab3d5b220254465336dc4d97a3bd096b5e065e0cfbe82849e2c1905aca486533f0da7a61f1e9a55b8e2a83262deeb59f2b13d3a8aef5700845b83b25ae2183c0ddac0ce42f8d25674cb0d0d220a6de7c1858bb07d59a3372344d944602aa451d2b937db0fe6feca0beba81721fc361ea7509e2b6d397e1c191b56f54ab436d0d27ab4c061bd661ad1a4452387e8735754d07fa7ef4d4548b172582425b299046e6301b5ba6b914418f149cf722e10bde2e0d41700f12c8429fc897b7819da92292240cd45565458c9a7b29c12
+SIG: 1eaad8420ac12c99ac1ff4476678e3cbbe94da6a797f174664d5ee0f641433fb1e7cb2f5613e10805df8654cd8e0d45d96230932bc7f20b04eae836435134309
+
+TST: 351
+SK:  73b03373ef1fd849005ecd6270dd9906f19f4439e40376cdbc520902bc976812
+PK:  663719e08ba3ba1666f6069a3f54991866b18cc6be41991b02eb3026ff9e155f
+MSG: d5c2deaba795c30aba321bc7de6996f0d90e4d05c747fb4dae8f3451895def6e16e72f38eace756f36635f8fb0b72a3a0c1f54663817a94d4fd346f835ab0e657f001a6f2cecb86d0825bd02639254f7f7f38ca99dbb86c64a633f73baf933aae3563281f4005e2d0e7cec9fbde8e588a957e211068be65b3d3d35bf4e8d5bb3478333df9ced9b2abaf48697994a145e9321499fc5ee560f4fbb6849e1ae8eb3d1de0083a21a03f6a6b28176f0130d3895e50e75e3d7d0947a7bc2c5b9ff69895d27791442ba8d0f2180712b567f712ea912f3b0d92c19342e0106ff1d87b46ad33af300b90855ba9769d366e79425d98e4de19905a04577707cbe625b84691781cd26bf62260b4a8bd605f77af6f970e1b3a112e8918344bd0d8d2e41dfd2ce9895b0246e50887aa3a577ff73be4b6ae60feb0ca36f6a5f8171ed209e5c566529c0940d9b4bd744ccee56e54a9a0c6e4da520dd315c2872b02db563703e
+SIG: a40abe98fc69da8a1ff9ff5c2cca93632e975980ee8b82c3c376022d6524ab736d01b072f2b681b5f1cd3ea067012ed6d074e949c42327a366caa9e4750a3c08
+
+TST: 352
+SK:  eab179e41ed5c889ffe6aabdc054faf1307c395e46e313e17a14fe01023ffa30
+PK:  86f34746d3f7a01ddbe322f1aca56d22856d38733a3a6900bb08e776450ec803
+MSG: 971095cebe5031530224387c5c31966e389b8566390054cf45264b44e18964b7be52c33c4ffb259af16283438fa15dd66bc7791b7533ef10cb0beab524a6437626f4cc74512851adcc2fb129055a482c61107383fb7c5241831d5551634eef0dc0b8f9053a00971aa8fa1ae0898e4b481b6707e97c0f942040b339d92fc17bbade74675af243d8b2dafb15b1db55d12415b85f3037291930ab61600ba3431f8eb425be4491614728af101e81c091f348bc5ffd1bde6ae6cad5c15b3aa7358078cc4effb54a86e7f0e0c55e4cfe0a54605ed443fdf2aaba016585da617e77341d52889d75dd540d39fe8b7993ed705cfddea0cb0d5a731d6bfcdb816afaff47e963eedebdf241af5593353d6d401a34f029a8cdeb1904cc2caa4f9635cc2ba6b7b1a29da625ffc383be2f5a8f1fa4f39b2d4b4f4c2d8838ce258a04d4a120493fdf07f68c0ffd1c16b768a35c55fea2cac696b5c20efc10865cde8a64627dcd
+SIG: 143cb28027c2f82e375e5f340e7fe6e60ce7bd51000b49c74168af85e26ed2ed630ed2672090164cc54b052da694ebdd21a21b3053f4dcfd7895ea5f6c8aa80d
+
+TST: 353
+SK:  fbf146ebd51075570ec51ac410ae9f391db75b610ada6362b4dbd949656cfb66
+PK:  be7c2f5b21d746c8ea3245ce6f268e9da74e00fa85c9c475260c68fa1af6361f
+MSG: cd7ad4f17fcff73acc402dc102d09079b29aaf2a0f4b27cf6beeb1e2b23d19ab47deb3ae1becd68861ea279c46691738f4fff47c43047c4f8b56b6bbcc3fde0723d44120dcd307a6310dc4f366b8f3cd52db19b8266a487f7872391c45fe0d3248a7abf2c20022d3769547f683067dcc363cd22fd7cda3cadc15804056f0e2aa2b795008c598be7a961805e6df291ba3041c47ff5640275f46e6ae82092d21abcbcfba11e730216008822de3ce462400596da79f7ae5d1df8389112ad98868fa94fb0546bfe6a67aa8d28c4d32072d2eadd6256255f18c2382e662dfa922a680e06a43622c4871d27d1807f7b2703070c83db8dd929c06038b2183cb8e2b9ec4c778d7ecf9e9ffac77fa7737b055feac2e7982aeeec0b72f1bbca2424e1a844bbac79cb2e7400f81dc449d0560b521a7c16bb4167e6696586058a9b8ed2e5116690b77f2a17e5c0b16a83dcbd2e24552293e258b32ba7f844944379342698627
+SIG: 6768006fe0f201b217dd10eb05d4b82adcfeb2ecfc8373c3308f4150394811eb60491881a2e53d1289d96478e18a64c34b2a19832cdccfd96a2e4a0c469fdc0b
+
+TST: 354
+SK:  dff0eb6b426dea2fd33c1d3fc24df9b31b486facb7edb8502954a3e8da99d9fd
+PK:  c245085ece69fb9aa560d0c27fdb634f7a840d41d8463660fbe82483b0f3cc3a
+MSG: e7c9e313d86160f4c74aa0ae07369ee22b27f81b3f69097affae28dae48483fb52a5c062306b59610f5cdbff6332b1960cd6f2b8f7b41578c20f0bc9637a0fdfc739d61f699a573f1c1a0b49294506cf4487965e5bb07bbf81803cb3d5cb3829c66c4bee7fc800ede216150934d277dea50edb097b992f11bb669fdf140bf6ae9fec46c3ea32f888fde9d154ea84f01c51265a7d3fef6eefc1ccdbffd1e2c897f05546a3b1ca11d9517cd667c660ec3960f7a8e5e80202a78d3a388b92f5c1dee14ae6acf8e17c841c9557c35a2eeced6e6af6372148e483ccd06c8fe344924e1019fb91cbf7941b9a176a073415867210670410c5dbd0ac4a50e6c0a509ddfdc555f60d696d41c77db8e6c84d5181f872755e64a721b061fcd68c463db4d32c9e01ea501267de22879d7fc12c8ca0379edb45abaa6e64dda2af6d40ccf24fbebad7b5a8d3e52007945ecd3ddc1e3efeb522581ac80e98c863ba0c590a3ed95cd1
+SIG: 6b48b10f545ddb7a89cd5829f4e5b20146cf6bc96e550d06f65de8bdae7ccdded26cd630f86c9266bccf88e924033e04f83a54f8290d7f734cf8673cca8f9703
+
+TST: 355
+SK:  9f32958c7679b90fd5036056a75ec2eb2f56ec1effc7c012461dc89a3a167420
+PK:  1d7269dcb6d1f584e662d4ce251de0aba290ef78b97d448afb1e5333f1976d26
+MSG: a56ba86c71360504087e745c41627092ad6b49a71e9daa5640e1044bf04d4f071ad728779e95d1e2460584e6f0773545da82d4814c9189a120f12f3e3819813e5b240d0f26436f70ee353b4d20cea54a1460b5b8f1008d6f95f3aa2d8f1e908fced50d624e3a096938b9353854b96da463a2798a5a312ec790842c10c446e3350c764bf5c972593b9987bf23256daa8894d47f22e85b97607e66fc08a12c789c4746080368d321bb9015a1155b65523ad8e99bb989b44eac756b0734acd7c6357c70b59743246d1652d91b0f9896965141345b9945cf34980452f3502974edb76b9c785fb0f4395266b055f3b5db8aab68e9d7102a1cd9ee3d142504f0e88b282e603a738e051d98de05d1fcc65b5f7e99c4111cc0aec489abd0ecad311bfc13e7d1653b9c31e81c998037f959d5cd980835aa0e0b09bcbed634391151da02bc01a36c9a5800afb984163a7bb815edbc0226eda0595c724ca9b3f8a71178f0d20a5a
+SIG: 9881a5763bdb259a3fefbba3d957162d6c70b804fa94ab613406a6ec42505b8789465ca1a9a33e1895988842270c55e5bdd5483f6b17b31781b593507a6c1808
+
+TST: 356
+SK:  f86d6f766f88b00717b7d6327eb26cf3ceeba5385184426f9cfd8295e2421ff2
+PK:  cb1d250504754183704dbe21c323d66f9f9011758f6d8dab6f597b199662145b
+MSG: da8423a6b7a18f20aa1f90ed2331b17b24067c40175bc25d8109e21d87ac00528eb3b2f66a2b52dc7ef2f8cecb75c76099cfa23db8da897043ba1cce31e2dfea46075f5e073203eaeb3d62c84c107b6dab33a14eaf149aa61850c15f5a58d88a15aba9196f9e495e8dbecbcf7e8444f5dd72a08a099d7f6209990b562974ea829ef11d29a920e3a799d0d92cb50d50f817631ab09de97c31e9a05f4d78d649fcd93a83752078ab3bb0e16c564d4fb07ca923c0374ba5bf1eea7e73668e135031feafcbb47cbc2ae30ec16a39b9c337e0a62eecdd80c0b7a04924ac3972da4fa9299c14b5a53d37b08bf02268b3bac9ea9355090eeb04ad87bee0593ba4e4443dda38a97afbf2db9952df63f178f3b4c52bcc132be8d9e26881213abdeb7e1c44c4061548909f0520f0dd7520fc408ea28c2cebc0f53063a2d30570e05350e52b390dd9b67662984847be9ad9b4cd50b069ffd29dd9c62ef14701f8d012a4a70c8431cc
+SIG: ec61c0b292203a8f1d87235ede92b74723c8d23408423773ae50b1e9bc4464e03e446da9dce4c39f6dd159bea26c009ed00120bc36d4a247dc0d24bcefcc110c
+
+TST: 357
+SK:  a5b34cefab9479df8389d7e6f6c146aa8affb0bec837f78af64624a145cc344e
+PK:  7b0f4f24d9972bc6fe83826c52716ad1e0d7d19f123858cb3e99fa636ac9631a
+MSG: e21e98af6c2bac70557eb0e864da2c2b4d6c0a39a059d3477251f6178a39676f4749e7fbea623f148a43a8b0fe0610506fa658abd2f5fa39198f2636b724db22d1aebc2ab07b2b6dbffdee8cece81e1af1493ec1964e16bf86ab258ca0feb77e3c8717e44038abe152c14be15660bf93b2d48d92c4ed7074d2494210621bcf204fba88c654d5ffe01e1a53d08f70bb237089dc807216ff6a85dbec3102237d42590778acf6c1dc566d5a2bb9a63bc21c329c272e5965baeeb0fe891de3cc8cbfa8e541a8881df68942e7ff8dc656bd08575f6aaf924a176d663b1a1f43574d11768c701b269561e55438dbebfd443d2115cb933d1cde4a915b54c325c27f499ef02bd012ff1f9a36390922887600fe712bcdc23eb5974a305372ad52951f83f0e58cc49e289841621917f1fcb0235147240dae4cf3b99b6ac6d8de94efe7c4436714508bcd0114c56068ff1b7c16d51bd906437874d6549ab5d8087896872ec8a09d7412
+SIG: 2fbd899d72b6d39e4f45b8b62cbbd5f3c0acb1ad8540913fa585877e91ccfef7bee50a4b0f9fedf5cc1e0d1953ad399c8389a93391e1b7c929af6d6f3b796c08
+
+TST: 358
+SK:  ad75c9ce299c4d59393367d77a4c9f8df8dcec765c6dbd25b527fb7669913604
+PK:  b9910548fe6312a119c9993eebcfb9dc90030ffb0e4de2b7ccd23cbeb4fef71b
+MSG: 62fc5ab67deb1fee9ab6cca3b88a1df1e589f0fd4a88f4aa7738948761fe84372c5b18e4655220c1d84d52acad32e229a5c756c20fc62fe4b4b4e5fd7077ae4ed5397aa796f2307ceedb6505b39297856f4aeb5e70938e36ee24a0ac7d9868306f6b53910623b7dc89a6672ad738576ed5d88831dd338321c8902bc2061f65e94d452fdfa0dc665cefb92308e52301bd4627006b363d06b775a395914d8c863e95a00d6893f3376134c429f56478145e4456f7a12d65bb2b8965d728cb2ddbb708f7125c237095a92195d92fa727a372f3545ae701f3808fee802c8967a76e8a940e55fb2d810bfb47ada156f0eda1829b159cf05c7f36cf3847d7b21de84c3dc0fe658347f79396a01139a508b60022db1c0e5aeef47e445e66f783e62c96597bdb16f209c08a9132c7573136170ee3ebf24261265a89fb4f10333375e20b33ab7403464f5249461c6853c5fddb9f58af816892910393a7077b799fdc3489720998feea86
+SIG: 6b7ef27bcfbf2b714985033764fccff555e3f5bc44610d6c8c62117cb3831a07f4a8bddb0eaed1d46b0289b15de1aa4dcc17d71be96a09e66ba4dc4627c78705
+
+TST: 359
+SK:  1ced574529b9b416977e92eb39448a8717cac2934a243a5c44fb44b73ccc16da
+PK:  85e167d5f062fee82014f3c8b1beaed8eefb2c22d8649c424b86b21b11eb8bda
+MSG: 1b3b953cce6d15303c61ca707609f70e7250f6c0deba56a8ce522b5986689651cdb848b842b2229661b8eeabfb8570749ed6c2b10a8fbf515053b5ea7d7a9228349e4646f9505e198029fec9ce0f38e4e0ca73625842d64caf8ced070a6e29c743586aa3db6d82993ac71fd38b783162d8fe04ffd0fa5cbc381d0e219c91937df6c973912fc02fda5377312468274c4bee6dca7f79c8b544861ed5babcf5c50e1473491be01708ac7c9ff58f1e40f855497ce9d7cc47b9410f2edd00f6496740243b8d03b2f5fa742b9c630867f77ac42f2b62c14e5ebddc7b647a05fff43670745f2851eff4909f5d27d57ae87f61e965ee60fdf97724c59267f2610b7ad5de919856d64d7c212659ce8656149b6a6d29d8f92b312be50b6e2a431d36ae022b00a6fe360e3af65432899c43be0427e36d21cfec81f21aa53b33db5ed2c37da8f96ac3e7dc67a1de37546cf7de1008c7e1adbe0f34fa7eb2434d94e6a13f4cf86a98d497622f
+SIG: e0303aefe08a77738dcc657afbb9b835ed279613a53c73fdc5ddbfb350e5cff4d6c9bb43dc07c95bf4e23b64c40f8804c7169952e3c8d59a7197241bfed0740f
+
+TST: 360
+SK:  f0790d93e2d3b84f61ef4c807147aba410e415e72b71b0d61d01026fed99da3d
+PK:  efdf649fb033cf328e0b287796f8a25e9c6e2e871b33c2c21a4028a8a25a4b28
+MSG: 7973e9f32d74805992eb65da0d637335e50eff0ce68ea2d1f3a02de704492b9cfbe7e7ba96fdb42bb821a513d73fc60402e92c855deaed73ffeaf70952029062c833e14ec1b14f144e2207f6a0e727e5a7e3cbab27d5972970f69518a15b093e740cc0ce11bf5248f0826b8a98bde8bf2c7082c97aff158d08371118c89021cc3974ae8f76d86673c3f824b62c79c4b41f40eaa8943738f03300f68cbe175468eb235a9ff0e6537f8714e97e8f08ca444e41191063b5fabd156e85dcf66606b81dad4a95065584b3e0658c20a706eaf4a0777da4d2e0cd2a0fca60109c2b4403db3f03cd4781c1fbb0272202bcb11687808c50cb98f64b7f3fd3d43333bb5a061b9e377090abb1e0a885cb26b73c163e63ff6451ff2f4ec8249c7e152bd03973a1e964e2b5b235281a938399a112a24529e383a560dc50bb1b622ad74ef35658dcb10ffe022568ac3ffae5b465a8ed7643e8561b352ee9944a35d882c712b187788a0abae5a22f
+SIG: 08773a6a78762cbb1e25fcbb29139941bdf16f4e09a1fa08fc701f32f933edd74c0ae983c12a0a5b020b6bcf44bb719dde8ed0781a8298265640e1608c98b301
+
+TST: 361
+SK:  4cb9df7ce6fae9d62ba09e8eb70e4c969bdeafcb5ec7d7024326e6603b0621bf
+PK:  018069dd0eb44055a35cd8c77c37ca9fb1ad2417271385e134b2f4e81f52033c
+MSG: 14627d6ea0e7895460759476dc74c42800ceef994327518151490d9df23067914e44788a12768ccb25471b9c3ba9d14fb436dcba38429b3a0456877763c49175d0e082683e07a9058f3685c6279307b2303d1221b9c29793d8a4877f6df51587384dadf751c5f7bfbd207d519622c37b51ceeee2c20d8269f8cb88d3fe43d6d434d5bbd0e203c1532d97ba552147227496c87f67b50bb76193add0144df1c176657585408362ca2ed04ad62acf1c25e341dfd1498d85b4b1349a8b0b9b02c43523c55853419bfed37d5a2cdf17dfbf1a3bd7759d6ae180f9d27dcd9a8933e29a7c0a30771eea7c2e0fa242925d2336dce585629057d844323964f6d3d11ff0b3f829a3be8c9f0468a6823d8e70ab5a2da21e15fa8b041a29812222e9c30b2bd9a12d1fdee6f87876e8ce81009637a8bb2236129a47ca74289ee4aad429ffe29f47430241ca8cc3848b7200fd6e1470651a9a0a6f72c9033e831df051408a6260f65cbaf6e012b18e
+SIG: e33c07836c537d6bfbd0f4592d6e35b163499ba78dc7ffcec565d04f9a7db781943e29e6ce76763e9baddf57437fd9c6b03239a6e6850e4502a356c2e12c3705
+
+TST: 362
+SK:  a136e009d53e5ef59d0946bc175663a86bc0fcd29eadd95cfc9d266037b1e4fb
+PK:  9c1806ec0454f58314eb8397d64287dee386640d8491aba364607688841715a0
+MSG: a49d1c3d49e13c2eda56868a8824aa9f8d2bf72f21955ebafd07b3bdc8e924de20936cee513d8a64a47173a3bd659eff1accff8244b26aae1a0c27fa891bf4d85e8fb1b76a6cab1e7f74c89ee07bb40d714326f09b3fd40632fad208ea816f9072028c14b5b54ecc1c5b7fc809e7e0786e2f11495e76017eb62aa4563f3d00ee84348d9838cd17649f6929a6d206f60e6fc82e0c3464b27e0e6abd22f4469bdfd4cb54f77e329b80f71bf42129ec13c9dfe192adfaa42ee3ddeeda385816fbad5f411938c63b560f4ecd94534be7d98725cd94c99ce492f0f069ba0ec08f877a7812ef27ae19d7a77be63f66bcf8d6cf3a1a61fc9cfef104c7462a21ca7f03afb5bb1ac8c75124b554e8d044b810d95ff8c9dd09a34484d8c4b6c95f95c3c22823f52ce844293724d5259191f1ba0929e2acdbb8b9a7a8adf0c52e78acdfdf057b0985881afbed4dbebdebbdae0a2b63bd4e90f96afdcbbd78f506309f9bdb650013cb73faed73904e
+SIG: bc094ba91c115dee15d753361a75f3f03d6af45c92157e95dbe8d32194b6c5ce72b9dc66f73df12dca0b639f3e791d478616a1f8d7359a42c8eae0dda16b1606
+
+TST: 363
+SK:  ff0f1c57dd884fbeea6e2917282b79ba67f8a6851267b9f4636dafda33bd2b5b
+PK:  fef6378ad12a7c252fa6eb742b05064b41530ff019dc680ab544c027ea2836e7
+MSG: 522a5e5eff5b5e98fad6878a9d72df6eb318622610a1e1a48183f5590ecef5a6df671b28be91c88cdf7ae2881147fe6c37c28b43f64cf981c455c59e765ce94e1b6491631deaeef6d1da9ebca88643c77f83eae2cfdd2d97f604fe45081d1be5c4ae2d875996b8b6fecd707d3fa219a93ba0488e55247b405e330cfb97d31a1361c9b2084bdb13fb0c058925db8c3c649c9a3e937b533cc6310fa3b16126fb3cc9bb2b35c5c8300015488a30fadca3c8871fa70dfdc7055bf8e631f20c9b2528311e324a7c4edd5462079f3441c9ecf55fa999e731372344fdc0d413e417aaa001a1b2d3d9bc000fec1b02bd7a88a812d9d8a66f9464764c070c93041eefb17ce74eff6d4aff75f0cbf6a789a9ecde74abe33130fca0da853aa7c3313ada3f0ae2f595c6796a93685e729dd18a669d6381825ab3f36a391e7525b2a807a52fa5ec2a030a8cf3b77337ac41fceb580e845eed655a48b547238c2e8137c92f8c27e585caad3106eee3814a
+SIG: d5008486726cce330a29dd7e4d7474d735798201afd1206feb869a112e5b43523c06976761be3cf9b2716378273c94f93572a7d2b8982634e0755c632b449008
+
+TST: 364
+SK:  0bc6af64de5709d3dbc28f7ef6d3fe28b6de529f08f5857ccb910695de454f56
+PK:  fb491fc900237bdc7e9a119f27150cd911935cd3628749ff40ef41f3955bc8ac
+MSG: ac7886e4f4172a22c95e8eea37437b375d72accedcee6cc6e816763301a2d8ef4d6f31a2c1d635818b7026a395ce0dafd71c5180893af76b7ea056c972d680eca01dcbdbae6b26f1c5f33fc988b824fbbe00cacc316469a3bae07aa7c8885af7f65f42e75cef94dbb9aab4825143c85070e7716b7612f64ef0b0166011d23eb5654aa098b02d8d71e57c8fa17bff2fe97dc8193177eadc09fb192d80aa92afa98720d4614817ff3c39d3acce18906fa3de09618931d0d7a60c4429cbfa20cf165c947929ac293ae6c06e7e8f25f1264291e3e1c98f5d93e6ecc2389bc60dbbf4a621b132c552a99c95d26d8d1af61138b570a0de4b497ebe8051c7273a98e6e7876d0b327503af3cb2cc4091ce1925cb2f2957f4ec56ee90f8a09dd57d6e83067a356a4cfe65b1b7a4465da2ab133b0efb5e7d4dbb811bcbbde712afbf0f7dd3f326222284b8c74eac7ad6257fa8c632b7da2559a6266e91e0ef90dbb0aa968f75376b693fcaa5da342221
+SIG: dbc7134d1cd6b0813b53352714b6df939498e91cf37c324337d9c088a1b998347d26185b430900412929e4f63e910379fc42e355a4e98f6fee27dafad1957206
+
+TST: 365
+SK:  2f5e83bd5b412e71ae3e9084cd369efcc79bf6037c4b174dfd6a11fb0f5da218
+PK:  a22a6da29a5ef6240c49d8896e3a0f1a4281a266c77d383ee6f9d25ffacbb872
+MSG: b766273f060ef3b2ae3340454a391b426bc2e97264f8674553eb00dd6ecfdd59b611d8d662929fec710d0e462020e12cdbf9c1ec8858e85671acf8b7b14424ce92079d7d801e2ad9acac036bc8d2dfaa72aa839bff30c0aa7e414a882c00b645ff9d31bcf5a54382def4d0142efa4f06e823257ff132ee968cdc6738c53f53b84c8df76e9f78dd5056cf3d4d5a80a8f84e3edec48520f2cb4583e708539355ef7aa86fb5a0e87a94dcf14f30a2cca568f139d9ce59eaf459a5c5916cc8f20b26aaf6c7c029379aedb05a07fe585ccac60307c1f58ca9f859157d06d06baa394aace79d51b8cb38cfa2598141e245624e5ab9b9d68731173348905315bf1a5ad61d1e8adaeb810e4e8a86d7c13537b0be860ab2ed35b73399b8808aa91d750f77943f8a8b7e89fdb50728aa3dbbd8a41a6e00756f438c9b9e9d55872df5a9068add8a972b7e43edad9ced2237ca1367be4b7cdb66a54ea12eef129471158610eaf28f99f7f686557dcdf644ea
+SIG: 9f80922bc8db32d0cc43f9936affebe7b2bc35a5d82277cd187b5d50dc7fc4c4832fffa34e9543806b485c04548e7c75429425e14d55d91fc1052efd8667430b
+
+TST: 366
+SK:  722a2da50e42c11a61c9afac7be1a2fed2267d650f8f7d8e5bc706b807c1b91d
+PK:  fd0b964562f823721e649c3fedb432a76f91e0aead7c61d35f95ed7726d78589
+MSG: 173e8bb885e1f9081404acac999041d2ecfcb73f945e0db36e631d7cd1ab999eb717f34bf07874bf3d34e2530eb6085f4a9f88ae1b0f7d80f221456a8e9a8890b91a50192deaaacc0a1a615a87841e2c5a9e057957af6e48e78cc86198e32e7aa24dcf6cffa329bc72606d65b11682c8ba736cce22a05785df1146331e41609cf9ca711cf464958297138b58a9073f3bbf06ad8a85d135de66652104d88b49d27ad41e59bcc44c7fab68f53f0502e293ffcabaaf755927dfdffbfde3b35c080b5de4c8b785f4da64ef357bc0d1466a6a96560c3c4f3e3c0b563a003f5f95f237171bce1a001771a04ede7cdd9b8ca770fd36ef90e9fe0000a8d7685fd153cc7282de95920a8f8f0898d00bf0c6c933fe5bb9653ff146c4e2acd1a2e0c23c1244844dacf8652716302c2032f9c114679ed26b3ee3ab4a7b18bc4e3071f0977db57cd0ac68c0727a09b4f125fb64af2850b26c8a484263334e2da902d744737044e79ab1cf5b2f93a022b63d40cd
+SIG: c2695a57172aaa31bd0890f231ca8eeec0287a87172669a899ad0891cea4c47579b50420e791cdec8c182c8a0e8dde21b2480b0cfd8111e28e5603347a352d04
+
+TST: 367
+SK:  5fe9c3960ed5bd374cc94d42357e6a24dc7e3060788f726365defacf13cd12da
+PK:  0ce7b155c8b20ebdaacdc2aa23627e34b1f9ace980650a2530c7607d04814eb4
+MSG: c9490d83d9c3a9370f06c91af001685a02fe49b5ca667733fff189eee853ec1667a6c1b6c787e9244812d2d532866ab74dfc870d6f14033b6bcd39852a3900f8f08cd95a74cb8cbe02b8b8b51e993a06adfebd7fc9854ae5d29f4df9642871d0c5e470d903cfbcbd5adb3275628f28a80bf8c0f0376687dae673bf7a8547e80d4a9855ae2572fc2b205dc8a198016ddc9b50995f5b39f368f540504a551803d6dd5f874828e5541ded052894d9e2dc5e6aa351087e790c0dd5d9c4decb217e4db81c98a184b264e6daeac0f11e074cae2bfc899f54b419c65dcc22664a915fbfffac35cee0f286eb7b144933db933e16c4bcb650d537722489de236373fd8d65fc86118b6def37ca4608bc6ce927b65436ffda7f02bfbf88b045ae7d2c2b45a0b30c8f2a04df953221088c555fe9a5df260982a3d64df194ee952fa9a98c31b96493db6180d13d67c36716f95f8c0bd7a039ad990667ca34a83ac1a18c37dd7c7736aa6b9b6fc2b1ac0ce119ef77
+SIG: 379f9c54c413af0d192e9bc736b29da9d521e7ba7841d309f9bcc1e742ec4308fe9f7ba51e0b22aed487cb4aa3913b9bebfb3aacd38f4039f9bbbebe1ad80002
+
+TST: 368
+SK:  ec2fa541ac14b414149c3825eaa7001b795aa1957d4040dda92573904afa7ee4
+PK:  71b363b2408404d7beecdef1e1f511bb6084658b532f7ea63d4e3f5f01c61d31
+MSG: 2749fc7c4a729e0e0ad71b5b74eb9f9c534ebd02ffc9df4374d813bdd1ae4eb87f1350d5fdc563934515771763e6c33b50e64e0cd114573031d2186b6eca4fc802cddc7cc51d92a61345a17f6ac38cc74d84707a5156be9202dee3444652e79bae7f0d31bd17567961f65dd01a8e4bee38331938ce4b2b550691b99a4bc3c072d186df4b3344a5c8fbfbb9fd2f355f6107e410c3d0c798b68d3fb9c6f7ab5fe27e70871e86767698fe35b77ead4e435a9402cc9ed6a2657b059be0a21003c048bbf5e0ebd93cbb2e71e923cf5c728d1758cd817ad74b454a887126d653b95a7f25e5293b768c9fc5a9c35a2372e3741bc90fd66301427b10824bb4b1e9110bfba84c21a40eb8fed4497e91dc3ffd0438c514c0a8cb4cac6ad0256bf11d5aa7a9c7c00b669b015b0bf81425a21413e2ffb6edc0bd78e385c44fd74558e511c2c25fee1fec18d3990b8690300fa711e93d9854668f0187065e76e7113ae763c30ddd86720b5546a6c3c6f1c43bc67b14
+SIG: 84d18d56f964e3776759bba92c510c2b6d574555c3cddade212da90374554991e7d77e278d63e34693e1958078cc3685f8c41c1f5342e351899638ef61211401
+
+TST: 369
+SK:  6132692a5ef27bf476b1e991e6c431a8c764f1aebd470282db3321bb7cb09c20
+PK:  7a2d166184f9e5f73bea454486b041ceb5fc2314a7bd59cb718e79f0ec989d84
+MSG: a9c0861665d8c2de06f9301da70afb27b3024b744c6b38b24259294c97b1d1cb4f0dcf7575a8ed454e2f0980f50313a77363415183fe9677a9eb1e06cb6d34a467cb7b0758d6f55c564b5ba15603e202b18856d89e72a23ab07d8853ff77da7aff1caebd7959f2c710ef31f5078a9f2cdae92641a1cc5f74d0c143ec42afbaa5f378a9e10d5bf74587fa5f49c156233247dafd3929acde888dc684337e40cdc5932e7eb73ffcc90b85c0ad460416691aefbd7efd07b657c350946a0e366b37a6c8089aba5c5fe3bbca064afbe9d47fbc83914af1cb43c2b2efa98e0a43be32ba823202001def36817251b65f9b0506cef6683642a46ed612f8ca81ee97bb04d317b517343ade2b77126d1f02a87b7604c8653b6748cf5488fa6d43df809faa19e69292d38c5d397dd8e20c7af7c5334ec977f5010a0f7cb5b89479ca06db4d12627f067d6c42186a6b1f8742f36ae709ba720e3cd898116666d81b190b9b9d2a72202cb690a03f3310429a71dc048cde
+SIG: eb677f3347e1a1ea929efdf62bf9105a6c8f4993033b4f6d03cb0dbf9c742b270704e383ab7c0676bdb1ad0ce9b16673083c9602ec10ae1dd98e8748b336440b
+
+TST: 370
+SK:  f219b2101164aa9723bde3a7346f68a35061c01f9782072580ba32df903ba891
+PK:  f66b920d5aa1a6085495a1480539beba01ffe60e6a6388d1b2e8eda23355810e
+MSG: 015577d3e4a0ec1ab25930106343ff35ab4f1e0a8a2d844aadbb70e5fc5348ccb679c2295c51d702aaae7f6273ce70297b26cb7a253a3db94332e86a15b4a64491232791f7a8b082ee2834af30400e804647a532e9c454d2a0a7320130ab6d4d860073a34667ac25b7e5e2747ba9f5c94594fb68377ae260369c40713b4e32f23195bf91d3d7f1a2719bf408aad8d8a347b112e84b118817cb06513344021763035272a7db728a0ccdaa949c61715d0764140b3e8c01d20ff1593c7f2d55c4e82a1c0cb1ea58442bf80a741bca91f58ab0581b498ee9fe3c92ca654148ef75313543d1aff382befe1a93b02190ce0102175158e2071d02bacad8dbe9fb940fcb610c105ad52c80feb1ec4e524f4c0ec7983e9ce696fa4fcf4bf0514b8f0432b17d5448fc426fea2b01ac7b26c2aed769927534da22576fc1bba726e9d65be01b59f60a648ace2fc3e5e275789fa637cbbd84be3d6ac24457a6292cd656c7b569a52ffea7916b8d04b4f4a75be7ac95142f
+SIG: 17f0127ca3bafa5f4ee959cd60f772be87a0034961517e39a0a1d0f4b9e26db1336e60c82b352c4cbacdbbd11771c3774f8cc5a1a795d6e4f4ebd51def36770b
+
+TST: 371
+SK:  fc180035aec0f5ede7bda93bf77ade7a81ed06de07ee2e3aa8576be81608610a
+PK:  4f215e948cae243ee3143b80282ad792c780d2a6b75060ca1d290ca1a8e3151f
+MSG: b5e8b01625664b222339e0f05f93a990ba48b56ae65439a17520932df011721e284dbe36f98631c066510098a68d7b692a3863e99d58db76ca5667c8043cb10bd7abbaf506529fbb23a5166be038affdb9a234c4f4fcf43bddd6b8d2ce772dd653ed115c095e232b269dd4888d2368cb1c66be29dd383fca67f66765b296564e37555f0c0e484504c591f006ea8533a12583ad2e48318ff6f324ecaf804b1bae04aa896743e67ef61ca383d58e42acfc6410de30776e3ba262373b9e1441943955101a4e768231ad9c6529eff6118dde5df02f94b8d6df2d99f27863b517243a579e7aaff311ea3a0282e47ca876fabc2280fce7adc984dd0b30885b1650f1471dfcb0522d49fec7d042f32a93bc368f076006ea01ec1c7412bf66f62dc88de2c0b74701a5614e855e9fa728fb1f1171385f96afbde70dea02e9aa94dc21848c26302b50ae91f9693a1864e4e095ae03cdc22ad28a0eb7db596779246712fab5f5da327efec3e79612de0a6ccaa536759b8e
+SIG: a43a71c3a19c35660dae6f31a254b8c0ea3593fc8fca74d13640012b9e9473d4afe070db01e7fb399bf4ca6070e062180011285a67dd6858b761e46c6bd32004
+
+TST: 372
+SK:  a2836a65427912122d25dcdfc99d7046fe9b53d5c1bb23617f11890e94ca93ed
+PK:  8c12bda214c8abb2286acffbf8112425040aab9f4d8bb7870b98da0159e882f1
+MSG: 813d6061c56eae0ff53041c0244aa5e29e13ec0f3fb428d4beb8a99e04bca8c41bddb0db945f487efe38f2fc14a628fafa2462f860e4e34250eb4e93f139ab1b74a2614519e41ee2403be427930ab8bc82ec89ceafb60905bd4ddbbd13bdb19654314fc92373140b962e2258e038d71b9ec66b84ef8319e03551cb707e747f6c40ad476fbefdce71f3a7b67a1af1869bc6440686e7e0855e4f369d1d88b8099fba54714678627bba1aff41e7707bc97eddf890b0c08dce3e9800d24c6f61092ce28d481b5dea5c096c55d72f8946009131fb968e2bc8a054d825adab76740dcf0d758c8bf54ff38659e71b32bfe2e615aaabb0f5293085649cf60b9847bc62011ce3878af628984a5840a4ad5dae3702db367da0f8a165fed0517eb5c442b0145330241b97eeca733ba6688b9c129a61cd1236aff0e27bcf98c28b0fbeea55a3d7c7193d644b2749f986bd46af8938e8faaeafbd9cec3612ab005bd7c3eeafe9a31279ca6102560666ba16136ff1452f850adb
+SIG: e6a9a6b436559a4320c45c0c2c4a2aedecb90d416d52c82680ac7330d062aebef3e9ac9f2c5ffa455c9be113013a2b282e5600fd306435ada83b1e48ba2a3605
+
+TST: 373
+SK:  f051af426d0c3282fafc8bf912ade1c24211a95ad200e1eef549320e1cb1a252
+PK:  fa87955e0ea13dde49d83dc22e63a2bdf1076725c2cc7f93c76511f28e7944f2
+MSG: b48d9f84762b3bcc66e96d76a616fa8fe8e01695251f47cfc1b7b17d60dc9f90d576ef64ee7d388504e2c9079638165a889696471c989a876f8f13b63b58d531fea4dd1229fc631668a047bfae2da281feae1b6de3ebe280abe0a82ee00fbfdc22ce2d10e06a0492ff1404dfc094c40b203bf55721dd787ed4e91d5517aaf58d3bdd35d44a65ae6ba75619b339b650518cefcc17493de27a3b5d41788f87edbde72610f181bf06e208e0eb7cdfe881d91a2d6cc77aa19c0fcf330fedb44675d800eb8cff9505d8887544a503cbe373c4847b19e8f3995726efd6649858595c57ccaf0cbc9eb25de83ba046bc9f1838ac7b8953dd81b81ac0f68d0e9338cb55402552afb6bc16949351b926d151a82efc695e8d7da0dd55099366789718ccbf36030bd2c3c109399be26cdb8b9e2a155f3b2cb1bfa71ab69a23625a4ac118fe91cb2c19788cf52a71d730d576b421d96982a51a2991daec440cda7e6cc3282b8312714278b819bfe2387eb96aa91d40173034f428
+SIG: b8f713578a64466719aceb432fce302a87cf066bf3e102a350616921a840964bfc7e685d8fd17455ac3eb4861edcb8979d35e3a4bd82a078cd707721d733400e
+
+TST: 374
+SK:  a103e92672c65f81ea5da1fff1a4038788479e941d503a756f4a755201a57c1d
+PK:  ee63a5b69641217acbaf3339da829ec071b9931e5987153514d30140837a7af4
+MSG: b1984e9eec085d524c1eb3b95c89c84ae085be5dc65c326e19025e1210a1d50edbbba5d1370cf15d68d687eb113233e0fba50f9433c7d358773950c67931db8296bbcbecec888e87e71a2f7579fad2fa162b85fb97473c456b9a5ce2956676969c7bf4c45679085b62f2c224fc7f458794273f6d12c5f3e0d06951824d1cca3e2f904559ed28e2868b366d79d94dc98667b9b5924268f3e39b1291e5abe4a758f77019dacbb22bd8196e0a83a5677658836e96ca5635055a1e63d65d036a68d87ac2fd283fdda390319909c5cc7680368848873d597f298e0c6172308030ffd452bb1363617b316ed7cd949a165dc8abb53f991aef3f3e9502c5dfe4756b7c6bfdfe89f5e00febdd6afb0402818f11cf8d1d5864fe9da1b86e39aa935831506cf2400ea7ed75bd9533b23e202fe875d7d9638c89d11cb2d6e6021ae6bd27c7754810d35cd3a61494f27b16fc794e2cd2f0d3453ada933865db78c579571f8fc5c5c6be8eaffce6a852e5b3b1c524c49313d427abcb
+SIG: 2aa2035c2ce5b5e6ae161e168f3ad0d6592bcf2c4a049d3ed342fceb56be9c7cb372027573ae0178e8878ebefca7b030327b8aad41857de58cb78e1a00cbac05
+
+TST: 375
+SK:  d47c1b4b9e50cbb71fd07d096d91d87213d44b024373044761c4822f9d9df880
+PK:  f4e1cb86c8ca2cfee43e58594a8778436d3ea519704e00c1bbe48bbb1c9454f8
+MSG: 88d7009d51de3d337eef0f215ea66ab830ec5a9e6823761c3b92ad93ea341db92ece67f4ef4ceb84194ae6926c3d014b2d59781f02e0b32f9a611222cb9a5850c6957cb8079ae64e0832a1f05e5d1a3c572f9d08f1437f76bb3b83b52967c3d48c3576848891c9658d4959eb80656d26cdba0810037c8a18318ff122f8aa8985c773cb317efa2f557f1c3896bcb162df5d87681bb787e7813aa2dea3b0c564d646a92861f444ca1407efbac3d12432cbb70a1d0eaffb11741d3718fedee2b83036189a6fc45a52f74fa487c18fd264a7945f6c9e44b011f5d86613f1939b19f4f4fdf53234057be3f005ad64eebf3c8ffb58cb40956c4336df01d4424b706a0e561d601708d12485e21bcb6d799d8d1d044b400064ec0944501406e70253947006cabbdb2dd6bd8cee4497653d9113a44d4de9b68d4c526fca0b9b0c18fe50fb917fdd9a914fb816108a73a6b3fff9e654e69c9cfe02b05c6c1b9d15c4e65cf31018b8100d784633ee1888eee3572aafa6f189ea22d0
+SIG: 627e7ca7e34ed6331d62b9541c1ea9a9292be7b0a65d805e266b5122272a82db7d765acc7e2a290d685804922f91ed04a3c382c03ff21a1768f584413c4e5f00
+
+TST: 376
+SK:  fc0c32c5eb6c71ea08dc2b300cbcef18fdde3ea20f68f21733237b4ddaab900e
+PK:  47c37d8a080857eb8777a6c0a9a5c927303faf5c320953b5de48e462e12d0062
+MSG: a7b1e2db6bdd96b3d51475603537a76b42b04d7ebd24fe515a887658e4a352e22109335639a59e2534811f4753b70209d0e4698e9d926088826c14689681ea00fa3a2fcaa0047ced3ef287e6172502b215e56497614d86b4cb26bcd77a2e172509360ee58893d01c0d0fb4d4abfe4dbd8d2a2f54190fa2f731c1ceac6829c3ddc9bfb2ffd70c57ba0c2b22d2326fbfe7390db8809f73547ff47b86c36f2bf7454e678c4f1c0fa870bd0e30bbf3278ec8d0c5e9b64aff0af64babc19b70f4cf9a41cb8f95d3cde24f456ba3571c8f021d38e591dec05cb5d1ca7b48f9da4bd734b069a9fd106500c1f408ab7fe8e4a6e6f3ed64da0ed24b01e33df8475f95fa9ed71d04dd30b3cd823755a3401bf5afae10ee7e18ec6fe637c3793fd434b48d7145130447e00299101052558b506554ec9c399f62941c3f414cbc352caa345b930adecfaddac91ee53d1451a65e06201026325de07c931f69bba868a7c87ee23c604ec6794332917dfe2c5b69669b659706917f71eddf96
+SIG: 6887c6e2b98a82af5ee3dfa7ca2cb25d9c10745620a82956acba85cb57c8ec24279fa42f092359a1b6bbeafba050f14b6288209e6ef7bc1e0a2b872c1138f305
+
+TST: 377
+SK:  a8d73d639a23cc6a967ef31bcabb5d063e53e1eab8fcc7cab9bc3a17fde9c2f8
+PK:  8daa9f4c8b1a44691bf44521f2f7ca45dc7fc61f6a4ce6f98faa41c2a74977d1
+MSG: fd1fac3d53313b11acd29f5a83ac11896dab2530fa47865b2295c0d99dd67c36ed8e5fa549150c794c5549efb5c1d69114d5d607b23285b7212afaab57846a54ae67b9e880e07b6586607cecf6d4eed516a3a75511fe367d88eb871e6d71b7d6aa1367a01421b1088fc2d75e44954b73625c52da8a3a183c60be9da6050f59a453caa53520593671728d431877bfaac913a765fb6a56b75290b2a8aaac34afb9217ba1b0d5850ba0fdabf80969def0feee794ceb60614e3368e63ef20e4c32d341ec9b0328ea9fe139207ed7a626ff08943b415233db7cfcc845c9b63121d4ed52ec3748ab6a1f36b2103c7dc7e9303acea4ba8af7a3e07184fb491e891ede84f0dc41cadc3973028e879acd2031afc29a16092868e2c7f539fc1b792edab195a25ab9830661346b39ef53915de4af52c421eaf172e9da76a08c283a52df907f705d7e8599c5baae0c2af380c1bb46f93484a03f28374324b278992b50b7afa02552cafa503f034f8d866e9b720271dd68ccb685a85fffd1
+SIG: c4dcef1a2453939b364b340250c3129431431d5ba3f47670ab07ce680c69bf28b678627c76a6360fc40dc109aa7dea371b825e46134f624572182acf3957e70f
+
+TST: 378
+SK:  79c7dcb7d59a8df6b2b2ba0413059d89680995c20e916da01b8f067dc60cdeb4
+PK:  298743c73918bd556b28f8d4824a09b814752a7aeae7ee04875c53f4d6b108d9
+MSG: 5fe202f5b33b7788810d2508a13b3114d69b8596e6eacda05a04a2eb597fa3279c208b5a5b65daacb699f144e1d660e78e139b578331abec5c3c35334454f03e832c8d6e2984df5d450ecb5d33582a78808a9c78f26ebcd1244ef52e3fa6dca115c1f0cb56e38eae0e5b39f5fd863dffd0b2fb5b958f2d739db312fc667a17b031c4c9f8c5a2ad577984cc4146c437580efd2152173fe0d5782cc2ae9831a8d9a04177256018ff7631e0b0d8a99cb28f008b320421e27a74c31359188663456d85e098c1ebd281701097b6ae5a871e5ccc02058a501416cb91c12cef5be6f1914370e563f1a1b2aa41f4b8ee84cd32a1d509e529787d14a445438d807ecd620e2fa26de0da6426864784d4a28f54103e609283b99ee9b2b699c980bbb7882c3ea68ddc90802ac232f2c8e84291987bf3c5240921b59cfa214969317673d0be7f34b1ca0e15ea73c7175401ce550be106b49e62f8db68695e740e0f3a3556a19f3c8e6b91ac1cc23e863fcd0f0d9eb7047aa631e0d2eb9bcc6b
+SIG: 7b7cbe44c771e4371bae13b0722babcc1064155732962f407cba2acd35381d42210bece822f4681121fd4dab745a1f3077922fba1a78045b712902baccac660e
+
+TST: 379
+SK:  b9ced0412593fefed95e94ac965e5b23ff9d4b0e797db02bf497994d3b793e60
+PK:  c1629a723189959337f5535201e5d395ba0a03ea8c17660d0f8b6f6e6404bb12
+MSG: 555bb39c1899d57cabe428064c2d925f5fc4cf7059b95fb89a8e9e3a7e426c6c922d9e4d76984ea2383cabb4f2befd89c1f20eaa8a00dbe787cfa70ae2ae6aa90331cbbe580fa5a02184ed05e6c8e89d576af28aeeaf7c4e2500f358a00971a0a75920e854849bf332142975404f598c32e96982043d992bcd1a4fe819bb5634ad03467afc4ce05073f88ba1ba4ae8653a04665cf3f71690fe13343885bc5ebc0e5e62d882f43b7c68900ac9438bf4a81ce90169ec129ee63e2c675a1a5a67e27cc798c48cc23f51078f463b3b7cc14e3bcfd2e9b82c75240934cbdc50c4308f282f193122995606f40135100a291c55afdf8934eb8b61d81421674124dec3b88f9a73110a9e616f5b826b9d343f3ac0e9d7bdf4fd8b648b40f0098b3897a3a1cd65a64570059b8bc5c6743883074c88623c1f5a88c58969e21c692aca236833d3470b3eb09815e1138e9d0650c390eee977422193b00918be8a97cc6199b451b05b5730d1d13358cf74610678f7ac7f7895cc2efc456e03873b
+SIG: f1b797ded8a6942b12626848340fb719fcddafd98f33e2992d357bfdd35933c7ac561e5b2f939464338c5666854ca885c4d046eb2c54e48a1b5ed266ad34de05
+
+TST: 380
+SK:  81da168f02d46bb87cda845da43f8a6cba2c016878d6f49c6f061a60f155a04a
+PK:  aff86e98093ca4c71b1b804c5fe451cfdf868250dea30345fa4b89bb09b6a53b
+MSG: 6bc6726a34a64aae76ab08c92b179e54ff5d2e65eb2c6c659ae8703cc245cbc2cf45a12b22c468ae61fd9a6627ad0626c9b1e5af412cb483eaee1db11b29f0a510c13e38020e09ae0eee762537a3e9d1a0c7b033d097fdc1f4f82629a9de9ef38da1cf96a940357d5f2e0e7e8dbc29db728a1e6aad876e5e053113d06420272b87cf0c40dfe03a544de96c7aea13ba0029b57b48d99dcc6a650492d78c4cdd1b28e1a115a7e3e7a7cb21333d4ff80858dfb67782c16354b8716596560d7d8e389eb15a052a0bf5d16eb54fb3e4973ad4984e72a187f5347d5b262c32b1647e42b6a53837096cc78c2a05ce1c6e12493a03f1a667584cb97f4fcd57ee944c65b7eed25f7ae0f3f6cede173fdfacf5af1db143730d18096664914ba4cfc6966f392022781c66a9417ca2680b51f63e4fba424ecfdbc6a2f01787d0e7484f8a8ab390aeaa6d1f7ed325d82feaa1692a4984fae43da87329b045da8f0a4f56b695aa935de152ce0385153720979a2b7006d405fcb0fba09e23b85fd19b
+SIG: 4aaca947e3f22cc8b8588ee030ace8f6b5f5711c2974f20cc18c3b655b07a5bc1366b59a1708032d12cae01ab794f8cbcc1a330874a75035db1d69422d2fc00c
+
+TST: 381
+SK:  af2e60da0f29bb1614fc3f193cc353331986b73f3f9a0aec9421b9473d6a4b6a
+PK:  c8bfe2835822199c6127b806fabeef0cb9ff59f3c81ff0cb89c556f55106af6a
+MSG: 7dbb77b88bda94f344416a06b096566c6e8b393931a8243a6cab75c361fde7dc536aec40cded83296a89e8c3bef7d787cfc49401a7b9183f138d5000619ff073c05e2f841d6008358f10a2da7dcfac3d4d70c20d2ec34c7b6d5cd1a734d6bbb11c5fd8d2bce32ac810ef82b4188aa8ea3cfc3032233dc0e2600e9db6e18bc22b10044a31c15baceaf5554de89d2a3466807f244414d080ff2963956c6e83c8e144ed0066088b476ddcb564403447d9159f9089aba2b4d5575c4d8ae66fc8690e7349ed40832e6369c024563ec493bfcc0fc9ac787ac841397fe133167283d80c42f006a99d39e82979da3fa9334bd9ede0d14b41b7466bcebbe8171bc804a645d3723274a1b92bf82fd993358744de92441903d436fd47f23d40052a3829367f202f0553b5e49b76c5e03fa6ce7c3cf5eeb21de967bec4dd355925384ebf96697e823762bac4d43a767c241a4cef724a970d00ff3a8ab3b83eed840075c74e90f306e330013260962161e9d0910de183622ce9a6b8d5144280550fc7
+SIG: 50f9f941a8da9f6240f76d2fa3b06dd6b2292ed32d1c05218097d34d8a19dfe553f76ae3c6b4a2ed20852128461540decf418f52d38e64037eec7771bd1afe00
+
+TST: 382
+SK:  605f90b53d8e4a3b48b97d745439f2a0807d83b8502e8e2979f03e8d376ac9fe
+PK:  aa3fae4cfa6f6bfd14ba0afa36dcb1a2656f36541ad6b3e67f1794b06360a62f
+MSG: 3bcdcac292ac9519024aaecee2b3e999ff5d3445e9f1eb60940f06b91275b6c5db2722ed4d82fe89605226530f3e6b0737b308cde8956184944f388a80042f6cba274c0f7d1192a0a96b0da6e2d6a61b76518fbee555773a414590a928b4cd545fccf58172f35857120eb96e75c5c8ac9ae3add367d51d34ac403446360ec10f553ea9f14fb2b8b78cba18c3e506b2f04097063a43b2d36431cce02caf11c5a4db8c821752e52985d5af1bfbf4c61572e3fadae3ad424acd81662ea5837a1143b9669391d7b9cfe230cffb3a7bb03f6591c25a4f01c0d2d4aca3e74db1997d3739c851f0327db919ff6e77f6c8a20fdd3e1594e92d01901ab9aef194fc893e70d78c8ae0f480001a515d4f9923ae6278e8927237d05db23e984c92a683882f57b1f1882a74a193ab6912ff241b9ffa662a0d47f29205f084dbde845baaeb5dd36ae6439a437642fa763b57e8dbe84e55813f0151e97e5b9de768b234b8db15c496d4bfcfa1388788972bb50ce030bc6e0ccf4fa7d00d343782f6ba8de0
+SIG: dd0212e63288cbe14a4569b4d891da3c7f92727c5e7f9a801cf9d6827085e7095b669d7d45f882ca5f0745dccd24d87a57181320191e5b7a47c3f7f2dccbd707
+
+TST: 383
+SK:  9e2c3d189838f4dd52ef0832886874c5ca493983ddadc07cbc570af2ee9d6209
+PK:  f68d3b81e73557ee1f08bd2d3f46a4718256a0f3cd8d2e03eb8fe882aab65c69
+MSG: 19485f5238ba82eadf5eff14ca75cd42e5d56fea69d5718cfb5b1d40d760899b450e66884558f3f25b7c3de9afc4738d7ac09da5dd4689bbfac07836f5e0be432b1ddcf1b1a075bc9815d0debc865d90bd5a0c5f5604d9b46ace816c57694ecc3d40d8f84df0ede2bc4d577775a027f725de0816f563fa88f88e077720ebb6ac02574604819824db7474d4d0b22cd1bc05768e0fb867ca1c1a7b90b34ab7a41afc66957266ac0c915934aaf31c0cf6927a4f03f23285e6f24afd5813849bb08c203ac2d0336dcbf80d77f6cf7120edfbcdf181db107ec8e00f32449c1d3f5c049a92694b4ea2c6ebe5e2b0f64b5ae50ad3374d246b3270057e724a27cf263b633ab65ecb7f5c266b8007618b10ac9ac83db0febc04fd863d9661ab6e58494766f71b9a867c5a7a4555f667c1af2e54588f162a41ce756407cc4161d607b6e0682980934caa1bef036f7330d9eef01ecc553583fee5994e533a46ca916f60f8b961ae01d20f7abf0df6141b604de733c636b42018cd5f1d1ef4f84cee40fc
+SIG: 38a31b6b465084738262a26c065fe5d9e2886bf9dd35cde05df9bad0cc7db401c750aa19e66090bce25a3c721201e60502c8c10454346648af065eab0ee7d80f
+
+TST: 384
+SK:  31010d1d67eb616348e84792b92d5dc128553cb52f6368159fe7b816cd0e7c37
+PK:  266543d96787ca901fcff06e6e434491ae0970880a5a187d535edb19db5cabeb
+MSG: 39f89a5e7aa530b5463d498f8035b9909d55da527cdbd4de6d228379f089e608a9207a2c5b9c42051a60c8ca3fb97a1c06cd747d9d0739970ceb88ce526f971140ea2ec21f090ba075bf8975faa508b1cc10efa494dc172e6d3d3f3f75dc8e0e96f05c0cccb2f96e911cfa7a2c82c9845018bb1f9d75f82e3dfe1139347b2ac058b014ac93760c90f5567ab5c4eba04b49fb09ddadd305be511dfe05c96ebc86fd67b5d0ab57d85f4fe5e2f0fa9d88a68f0f6b6bc8bb944eb3c0b17557e55d5ea187d922a42813e69057c9b6a7f75e49921b7079e58f8a63719ee3e1ad10cf0e8a70c4f1540218b70494bd029ee02ff9727a7d85d377919ec4051479b70f7cd6767723fe42c1c7899c2b7c1f702dd6b4d13b672d488f34a0e969db79cc2cb2524a948a8de4c5b623ecd90d6e82d97033c125637d1cd8c84803d8fbc012846ffe484f6c02149258f9462fa1e99c307dd0062fe0b6f11eee40c2629ef7c0f6a5107259ea5b9ffb6f29f12c32f7b5228cabc986ab66450af9dcc3da09d0e0b9a4
+SIG: 7b1eb677c3e5e6a8b4ba69fcb7f6b1870e42a8d58958a35c674e2db82107481c4c7b37f0f689d39d9f51e181b17b1108c15a3e27b29df3a4315dcc4faf122205
+
+TST: 385
+SK:  8ff2398cd51f51d4c2c57869a2218b8486822031f400729f4ac4d5909c48bafe
+PK:  a5a88704b68677be3d16c3dc0052cfee6e2b30e08609059d4cba52c6d96061fb
+MSG: 993953e47a341188bc592942e1557af29546e4e9368e2f1a5ee9806e2baf66b6190191fc5d2b7e47de37ff054fb2bbb1f031684ada5d607adda3d65433122fa904e0456faa84109bbc517f8ad39660876382adcfed0f7620cf1164622eacd91eb37a8596462ebe9ebe26bdc1e32cc34ad46fb1cea420e73c31215408e6d35425f44a829b132f631a3f6dd4b873a000667e19eb22fffd5903aaa7d4c8fdf21953c3c6178f5f8cb2aa6bff92894ead835888df060a3c9043026e0e2cef275497e7d105df3b644a98f26bf00105c99413ee0af8851954d65ceb8d79ad3071b8bb87f0b19743d2556ffd9819830b6eebf7ecc7e045661f43570ce9fdbbe2d252406fa90d04236f222c429ec16b1287224ada1a532161ae8b481bcab8d47afb3ed0445b3060fd6759179856f4085c1e585fd7c1409799af693cf427bd1d3dc10b5ae3447a8d2a18dc3a12a6860b22175dd5eb53a0950432e2d7aefece8af0ade3d8567743de43690f2d253723c5d7e48bd30d2937593701cecde9154b7665cb611d7d
+SIG: 417a647829c92898e520ff5311daa0a139cd8fffcb25a18e6d9b50cb52cbc35424c39ebbb5d5ac6a6d63f1f53c4df212f7025a8aaef8e36493c874c3ce341a0e
+
+TST: 386
+SK:  ef816c8f5ec34ef41f68831d90cd29e52de8973782d003ee4edada2ada2691d6
+PK:  47f9b363a88a45053a05bb72160852bfe8f7dfefc2f37283de346752caf092cc
+MSG: 9593c35cdec535bebb6965da68eab0b646bffcfbd04883bc4cef90d5d01f018c63c9b0ddfb3cef5e786284d5218caaaf060e9288952f16301ed8a4c1bcee256356a0c8bda359fbaa2782b10c86d18e20f7a0ec99b27a0b4dbefc0a262a3bf68fe81444dcae5f693eb0f16e6ee03f8fcbf3a3398146d20ec4d2657761fd0320fee7ea703c49a6a543bc9bba911e7925038710e8c36552d476d6027f58b2c52ba51ad65ea4f039c78f96b889102bb4bdd69b68e9c3d45b5176a2d82b0b95dc321016370dae30c3936515db0464c41774301c74e42d89b8bf4b9c19ed554b12febac0f60ddb3219ccc5603531dbf2eb5f293425d72ccefa0c7f144aba89347b296be87ff18994b4a0c70c930f059303b5dd4c8fe1e6bbc3cd68c6c0d84246dc6e6140a2abd1780b13f1594a6019d1778b7cbb3a3e3a34bfae7297f0b3edc376941c32352a4be314b84a9d8d6d7f1f38a0ad3798020aa2a331a402be9c704484744a730cbdedcb904b6fde708fbd14bfdc29efd461d1d0b5825de0bc79422b69a2722f
+SIG: 65c5d10ea7bfdbb38d55364a9968f82b548224dff3363b2ddcf585163dea27dc63b0563eb1a8dfbee951d3c9b33fcd6bbf0921c3abb21786b229069bd9ca000a
+
+TST: 387
+SK:  45eb0c4dfafa2a7690ef579c095456ceedcd32f0b6144d0c380f87fb744a0b1f
+PK:  fc85632c98384b5f9682aed9cd664cf1f48e588be2d568e5c734494df4c712b8
+MSG: 6f66d847405a03d7bd6f8d2897dbdf04e76d7df2d9470a4996b7dd6db88500f8f4f83e960e219a2486e24545add13614550414d827c41a9b08318daf01b15214c64a4266cbf8a5717ada3e62c26729073e16ddbd66f2d520e1e09935de05e4db11c396d477010aec66aafb762e69238d0b9e76b452454bf9e451e76ac79e6990d41b932bc32917093783c91bc9cf0bbe3b514070a1e692ff34fd06b66ea11f39e10af933ee96d8e9b677cb03737e7964eeaa725f121207f9c1b26a96c616df7cb7caef47bda901368ff2ea586e422e65bf21a691bdd2c13e67fff58cfbfed81782049dafa0f727df88623f2f7e8f262daf939542a187b8720a9b6b2b09890e54876b28a43874abbe3bfa981f8138b772c5d51736885f86acac2215a0b010dfc2c6b150845d4f8296252586a3e115f303c3d8a582e20fd2d43f6c446e5d00280ec179823b7fb4c1b0feb94eb4ef1707f5184e3b52461a7562d1f307cb751cdbbf6eae49ffae91862358e74e9548822b8a049fec6bf4c7a99cabbe09206577b657e31f
+SIG: 55851de8e1092f78944f6c6dd95bf07e2dbc8df7f57ad576829b978e3af58a7a8e94ed4dccbc0182467edf0bad4bae7ca84aa9a0c17c61a9e0ddff1d7525d704
+
+TST: 388
+SK:  709d2e199006f5369a7a0bdd34e74dc784be33880ea3c5dd10ed5c94451e7972
+PK:  06f989202ba2cbc9c150be611262aca00c45f012f89fbaf89f8ceccba0b1934a
+MSG: 62f003140fa09e0387d187a0ff96c4563df9f4e28c2282c0183ac3eede1312354921f780fca5361d3068d29949630b7530cd5914ace0468d014b6f53d839b82e38817dbf2d8392c3ce3424eab86a24d804c7acb1ce7acfe0a1cda4393924283105da4a7741196e027550047f85b7a0a01d454124efc0e299f0ef9ad14350543053482261528baa56e65999ac802c00a336267c635106b26403c19f391d53bd82861d6d48a4380b3043aa91d649536881204eccb0de20d43e5a3755b7f600916eccae42a0c9053b462d9417a13d67d778264a896e8eaf90baf66d29e5438a716781123a89fa9b8beef91d965af2f4a1a5bd5d2e2aaf46d5c94b7709cdd38d05feee4bfb76a359077c16bc4be9116e69001271cda565bc19bf47d4f986bd9c0d184cd8a3520ca1bdb4b505aaf7cb4ec9f94789779d30714e79116dd5019d59b28b17dad96f4e2155ad9c61274addc6b638109504e9ed19f4eda5377762648c4098224e3391043e4c2ad591654c9e7f974efdf0b0504b6fa5f646cecf44cd372412372505
+SIG: 629bf97b0c78ee6a9c8759fbea28224e27abbb6cbe4dea5bb797e6e0fe80c913f953e3a9b623352d13acf4ce6250fb029a1e198d72bd5e7402e60e9e48ca3501
+
+TST: 389
+SK:  5151617421aadc9c95a442b45e7ff6de06a2c733b85bd789fbad414ee3c91add
+PK:  14941d559761b30ab0a86d47e0f7d1896b33784527c80af41cb84810cbff9dbf
+MSG: 216e9d40bcdc3b2650188d121c9f8ef29e914facd022fe01b90ed11225f2eb93538e5fcee5ab8045e9199aa76a16bdd0616805660e247fecd7e22821b69b1f8e8a58ac3fb85691d75d5957a1daf53ff9ee6476d7c4bc541e6ad38e3a34ea90fc52a48b9399f92d17c9bb0d7fc3104c55d0efb4ea5b831ff9490b3f79f4d9d699594b741566f2b50a8fc78cc403fa40f5abb6638a32f449a8b3ef029c402f46931ad2bd3e8e683108714c989ae21689e9c444b9f55b81119bb5035bcf73e97ce43a2218c7bc3e430d1e814f34dee057265d3194b9f43875d8381f525f78576e64ce692584faa30fb743a12d1b77614d2e10a6b856b52be27cdb630ba1f0d3a6f8ea9844542e584ea0a2777527d0c52aca949aacda45ad83d16d5c83d663adb79cad6f3e39e990fe282a14c353aa2379d7f06adab74cea021b8983a57f1d0cf703292eb05ece89c53f3a1265610e0c1ea8ddd444d1ffd6bc3d03f0a6e4d0df5c5b8dc1f95d9f5558b118afe6bea0f6c2931363f03ab34e757d49364174f658efbbf38dc177
+SIG: fae4773b334460c77bf01ec6366c4fe61c0cab57d8a4b03909c619e11ee3461c13fa21576f63870e423dd04181e4a7013a7524f246fe33853c674162a7815104
+
+TST: 390
+SK:  38bed445556de74482bf5fec0506f9af330b151e50d4774dfe8591d7b7e0276b
+PK:  4c0f9c49a42f4047bfe6885551c5e4b856cf771a67af3f89dbf602f9db9220f3
+MSG: 0ff0031df0beeff3710c6b763f9b8ec81719bfa1528ce46519adf3d3412d93fb188fd497d5d17091c0f0345960dd0eb0c09fc4005173665d4d97f95c13828bc76b3492b87a4b64253c8b5fa47aa75fa3b86d5abeea8de5959a602289136f60a69b309e773b2255cde19ed2a2e199c33db11c16ade08a319750b851d92c692924fc9859be523431cbe78ec092db1129210ebbeaa7c2a2c000eeb105ca0301a48f3e45fdfb15b275cbab83ca5c99d737a585320e9e3b317179bd86467fa9694fcdb2ac6ad36ed7144843dbc34e423d35afd7d8972a1c43c199a191abd6ceba4936d395c995a3eb13cb057f88a9dc9490fe98845ee5d26a89fb642a2a516dc3056c54d3637213363a8628a42a395d942b954a89e8ef7a744d8ae5adac88c616efaa90e2077205a60baffede5c87bb14dead306229495f698f3e490616966b1636387d0d86183f945b24a9dcfccf4d36722cd12ebb6bd8e78325752afa2b1abd13c4bdbcadd170869136826242acfb721de5ff27ba8aa0c018b225ed3404803ce9fa2d508d8944
+SIG: f702d0d463282fc7fd5f8f9029b89c626cafd83450c3bb9dd8f6589f0c4b4b71f649ea212e5e33487c59c168ea3ad83150f1fcdfe8c53eba65adc2023c25830f
+
+TST: 391
+SK:  055460b32dd04d7f4b2311a89807e073fd556565a4771857d882794130a2fe5d
+PK:  260f8fed4bba30b9e12ad8523fbb6f57f0a7a882550061f1da46fbd8ea442221
+MSG: 7407f96ee3e79c69d36ce1f64e4f188655ea68b947e7e2be97b05ebc6d4439e950276ef3f0e6a03dd48b24f66929b49c1580eb468807e1e7a25eb9b94da340c53f984f8b81603efb61047bf3f14b686d9798003d2f68589a79ebfad54409c71c90ff67c11fbd76cc72c2d145f458e42f88b75d250eadcafe66bf37ffc837b62ff006685b7f85a9d875fc078c82e61fe35d1922527a551dab62f9e477499146bad912203e664c417c3679c02d872abac0032f8cc77f77bfe54d3326fdee9276a48ea4eb251350406882d08c830e7649fe6854558a7513ab2d8d2ac3e5ced8a808d2aee454779edabd1aa63bb19f718f470bdc8451cd9b294941e3497063b1e39b6ca184562fe838cbfeee922de24ddfcf9882c5e615b11bf904817fbd647139db80b4e8feb37f11e1852d7e876db9cb63c94d7ee34192f7200b5bc77a0311ae43b806ebd4c2896c53f58f7ebc1625cb20d7107ef9db0da28788523de991ef6c5866b18d8de83a954d3281e06dbf27c4f2382e08cd0e0f6ebae3f961b77fce5a95a9b0621b756f
+SIG: 23f4f1627fbabd7891d7d8489631c7231d22de71864e262ab4da84ea8a13a60feac4dcfb1812f1200444b775f121d7266d755ce9b6a9ad796559c0a26b516d02
+
+TST: 392
+SK:  e9f6d31b936942c526e0f9ec4f5a7ac25fa789e0c434bcd9199d720c743c84c4
+PK:  32126d26e28231c5b585b13f43a01c6fe542946b07d3a91e57d281523f5cb45c
+MSG: e88133f3d17642d5c22779a85316ba0df34c792b4efee49ed7dd93ca3322ef47c72e5b2e4595c77800434b60719adf54e4c1a34c89fa1e27ee8d35a0921f9755ac4a77a6c1684ea0f5c8ee5f759ce59bfe8315800a67aa6c64ddfaac92eabe6c2c613779784b3affafcc620f2a6dc5cb8d8dc7d74aa4d79494678494e5e6394c433c14809ff40c9a592d0d694a81103b44531e1f48bc13965d15af8bf3340488f8cd58f09ae1a6616bf85ac9de7e0c6696aa2f1bec15e17a44da4a84edb4ec6d77247788ba0de3ae12a155cbedc0da2f568eef0b75a877ea5b0c2c0d4bf2c61d468a46faadfaece35fc263a9be9987f4f7f78f05c707784378c7b8f7daf9ac3a122aad39a1677966da9ef286c9e062c4f439ad0bddea26e54b2f7388e238b2a64928450d34564c5a447e7afbbedd1085f1f24c11ae084322d1a32cf8aa473941f00d56b1618213cab3900aa606463d9f800e926f9f42d4b082d8c5ec3a4a025b45f9aadc8bcbd17091b3da49e9453dc55e89b5b5fe6b31f5eddad10b6601572568d8e205d3251a
+SIG: 7e3b1c4c716c808e90b974458915f3b2239c42077119fe270788fae520578bd7da6488044132e1bef23e3b23c34d9c1862744f28fcaecda6cac0fd72b93b6a0f
+
+TST: 393
+SK:  6bf4caaabb96854a38a572f4ce6c7838f7e750118c73f2723582618e2307f838
+PK:  08126373d056f00e54b8d43d77c35f5f919833e90d8aafd6c8246d27917ad091
+MSG: 4776e9d60085481fa537bf295bdabd8b1cf632a8cd40bce6bd325c129f977000e88468ebf2dc158ac0f207212db00fb60b8ec8bae229372e9a6b01530a7ed1bc9d389ec8913f59030d5b54af56ae1ccc28f37cc96a8e53204e92a677766adfaada99b0281f867f61ac9ff7d972ee3ed427d72faae75d4aec01b5ffc37061b6f0f7e5714c4cf30d5b731b0746065f19e4c8922dde642f80fe24a3c8dcb2e5f1c266e2af6c37decf55a2baa54f0d5cf0839370c3e0b4e77a4f36bbb3162014933a4a4ebcae8c60961ac6dcf134f30828d31402ae74e7e8513c9d2ad8ee46b7a9d53a1f87ebfce04f461bded1749b6fc4c4f25793525692d7a0e426c84e06082cc3e6abb51368370cbb106c7a0897f66d92c9739cff9f2706d6a2980ecea3ac4945f0f47e656bd9637777e853d2a839104327dc049ebc34f049d6c2f80eca99db7b418424acef752260d2d427949323997cd9617edf50d441d0088b1d47912e35cf542315265829f383f45860d3b45e735bb2f8586dcf58db4f2acfb4a68853a96eed7b89769d365613
+SIG: d2113f80d6cf928486a250a679d6e74b35ea9d26061fa94d769e1a8fbfa0a734227f55537e4ebff59336db141cf5d6d482a0711f1e9fc72ff70956a11b4fb909
+
+TST: 394
+SK:  5d9585736ab209b0abe8bf74aca4eea4f6d1650b532550a223e044580f8e20de
+PK:  e77729edfd2144b2b12078765417fa21f1594f09b269e9b6706802b4f3bdfe85
+MSG: 08693591e6c58a5ead9c85fe8ec58508f81a3467636c2d34fcc1f466e5c6dafdc37c35cbee35589c6997e2b15448132744e5a1e131bb49bf5c2563f87ead3efe01e88cbf24cc1769c78cdfc167e378215b15859c7a28ece70e188fa330267d3fc57b4ace6c1520ec67875067fd33be86f4a1967afb3eb164c797cf28d8072aa69d82afa38374f8e5797c4c28471b7d69f5b9c7b4acdbc19f3c5c5d400808a982a47837aed1b3841d69890eeb31494e10e3e513d12d0ca686c7ce651778092703fef0dcc0214077dfb361251bdea4364dd41b97bceb0fb1475a50e4708f47f7878c74401e9771cc3fceace89169981aa77250850090d181d8358ebba65e290acb0352bece8c579832a601551816d1c05621ccbbee0fbe39ea2f195393199e69c234c2fb1c37e474840860ce609161fcfce2869574be0d38f95e20f4f8725247b9627b46e834905101ac12b934cbf87cb2d190d2f51490a82c4e810eddb81f956a9f36bda497bca506a49ee9cd47fda5b7f2b884a3648cadd12ab61898ada46ecc970f81dc9f876845db
+SIG: e7b08e1d5809fdd8529443d65ada5dd655ea55b5415a011393be7071676486d358e8d2a460ebe075b0e701b24c9e3ab5f2b033592d4de3b7f37fd541f6920909
+
+TST: 395
+SK:  60b142f165114143ca30a604fef51c686436aa1b9afdb266b3e398ccb3c4d855
+PK:  eaf6c5a76ca99bf7306498888c3b7a1feae98bf8988d7f2e1547f8f53a4528aa
+MSG: 1815dee1173b78264720d35b7cc2454a000a65fff214e2473e20bc83f3ecde9c04c1e0696ce6e55519dd2a75ce0464bf601adc381e793ecb9f8ce7ab87b6ca2a3e410f639069451978d14873d3390fab8623969713c3dfcd58d86d124073761ee09a652a48767f9646cb726ac454ac9a1bc5faed3026b703982bc2b1e0758210e1d62519230eb2b2f4a486bc55168560c4363df5ff5adfda11ac7ef51b18196c94337c07aef117990f770c0f1e8c0f88eb6ffc40e8ed7c3a80a632db1e7f63b63096e2ac49e57792b31143e2f4faabceae66b27471681c36fc1139007f9b548cdc6e3b8fbbdaba7a8adb843431238bb461ba24f6e09f62c72d6377b4048cb0134c25a5411a20bfcfc13e48d80e36bfb0da7e0185d33f1928636e15dee0e5df8992a16572b13ea8f7cf85cae32d529f66e8f6d2fb2ad0bbfe7199169b2567ba00c781b20a48e1d70df9fa3119cd7e5bbe58884b0b51218940fa815f85625fa203471cee8084780eb0b9356f9f3d4f6df740301d707ef1ffb3519e3f90b8064b98e70f375d071426881718
+SIG: a621f084ea1a36ef812a9755c9afbb53dadaae6b3a53fa8344ca40d3612a268a35fed0fd398ab75bcd639c547937c94155ab1a7a3467dd4bfddfacab1655e908
+
+TST: 396
+SK:  734ba47033c6140232dd4a7a14f1a7743eefe9070bad9662491630cc9d28c1f3
+PK:  2fa5df3026d60742e2aff6b57842c7126846c8a7bbe9266efa7b3f2398c357ea
+MSG: 5d3c659810c3fea52a6df3861e5cdc5b703cc1cef48558c61d8c51d0edea5a1479cfe5063d82ded9ca681e5748887c40ecfb9e1a9a8b7f8509d10776461c3923399693a78189089178d5aabd15f8c846642be47d6d4caf13824edcefb809868fa72ddf035c4de8ef0a9c832264f66f012761ce6955bc3c416e93e29188025ebbb13a553258c1d7c499c9a4aeb10bb36f61d1bb4cec5ae55d175722b9a9696df881951e35200b9653cf6ed4b3d15de087a9d1c319fce8582156bebf3fc91e0e610ff7a15308fd1d2c6069fbbb2947d3110731d245ae2963014bd76dea42db125cecc493c8e9091a76646577729aed4966fce9699fe12e367d665df9e95a9193e1133e143af92f82b66ac7764e5033178690521809a7107d8ae9b88e0ed1f35b1719901b930ad0e1cbce7fb30267b1155204f605f525e49de2988ea7f74be8815177fd976a1bcc126d9c9c135c5b4276d38019c34aefb7a0220f7f5aeff380aed627b070c2c9e21533bb35c08e394c85ae25e6862942599c65dbae5977a584a88180e0c8c71e5a8409e04ef7
+SIG: 9bd074d1d0bd28001baf7d2d4e82435df08c4264d8cbb1c381183c2f01223f79f94923ca178cac75564e16c7f56079088f7ed885de4d509fbc78f438fba3f607
+
+TST: 397
+SK:  45e34d0ef4c196fa6d572b6b1774b5218f7c3291304c13500df7070d90e8039e
+PK:  13a7304dff423359177abafa5e6508d26769ca99cf8af45c383f3ff634406003
+MSG: 3d9ed5c64b75e135df2f5e85300d90f21b363935e2817556fc9311751ba7535477dec8356ec385efb82b414062f35bb6d3edeafde305f9900a25e9813c9ee0237d46409650cdcdb5dfa2301a8e2647f8d3819d86f7b7e3070d33440f82c4054b1ab5edebeb27f95b3c4c6fdd468f21600f03b3494da200bab9293c38d02fc44048e52ff5fd0f7217a04d4ce912a180d1628f368280b6892672e8ff98d4629ac28b60c02a301e6c6026c1b9e9ef21cf0392df225008d5a0e0284b282631ad1710f811615697066c98296519948a7cfed5aeeb454ee7a61cc271bd3d499be17df09d3a0e790ee6b9bd99e1b919bed4a063b8d1a34f1afd2e952b9dfefd770969c8b2fc37977abb0fee6317253a23ecc97578168973334c8f91763ab97f29c49baeee7b35f3ae7f5cd3a4a6e697ef255a3c2ec0c752a3396f69f663ca1fc2b332dfe6c0faf78afe9c68d99571e8e896c5093085e9863a27648a9e58f3a9a84cbbfe2b41ca3633dd5cf6e82cb77cecacad8d78b353f48db42d99c36bcad170ea9e98abb2788c33a3c706268f3631
+SIG: b42c1f925f4baccd129efb109db354aca31c6898f4f451294749a26a6da1677bd3a5c04119e35f47319f20cfdfc08bb4528b21009e00bd41ebc0f46863bed10b
+
+TST: 398
+SK:  888ce2ecceda9ca2b948ac1443c2aedd7595aacf36edaf27255bde7a6991dcc0
+PK:  016e572b4f98417c6ee297abd784ea48226ff4fbf0050a5ade8806e7046d3ba3
+MSG: 5c801a8e664e7660760a25a5e1431a62159fc3f3aa713780ae7cbce23b8564782799bf2be4817ee2921965bab7e1d44833824c1628d42dcee3e46ae42b2816d0a432a1ab0bd21fcf30adb63d8dd76569544343d0035c760522ca68bea72c404edda1e9095ec90f3325681c6de0f4c12d1afbcba2c7871a1b1e1f19c35b0bed9ec2a87c043d36d819396bd5d099e1aa090391297c733f65a8c5d2120c67635316fab25b4d4847a45fc3f76f2e2426dbee4629975062fce14e2189dba27fb1ded2453f001debfaa899c11660612d2ce2ad2f762ea5dee7e71e58adcdcefa79e8e8b27fc4ccf89aabf176b5d34f82dd15d889f9f087dc9ae8a42a72f3b83583616e170637cd1adf38aa6551cbacca3602bdc7ae210c4a446b3af8db2720e549bbedb8bed215ae00f19da29d8fb0b642d27b2d88575f0ee84f3d129eb774d20f537a1c0fdcf717bdebcfe47f8331a341864346fa6a1c6bbfd178819e387a0d5499a68e81cc9f82ad39e31e4dfe71952d5ea5cc8052a3ceed1751f59dc7ecc9742fad144e18dda8d0582e74e39ca8c4
+SIG: 99d83f148a236ebbef1cad88cb3c7694f4986c9250e21c3603a0d941bff199cf77d6ce99efdb20533188d68ad133de033a1fb3468abb706d2b8b4fbac08dfe03
+
+TST: 399
+SK:  617390857dc10cdf82b5c94261f58ce2d44aa2f57d298f08a2d6c74d28147daf
+PK:  89e0c3e0a0f130d1916e0e3849b7286fa2e3ac4c17bd1f716ee5a72f0257fb8d
+MSG: 1fd9e7453eaffd7c9b54055622dde170dd58b71cb945de75351d5fceb1f536bde25158f03786155f953dc207a1708f90d95b15aca0aee3097fdcaae85e4ab1c2cdb705c53e6c2ed21a994b304a75caf2ce4fc7d61f561e74e297397e2cde5cc69056940343aa81375d0af18d17d2f34c0a71dcf1de3c4fc488a14c5fa6b3337a3174b1da7958fb00bd5955148221427c60dba04117c80d2488656dbd5343de891287b50ef4df9825eda76b4977f3acd4ab6d3102fa56878306cd76561491bcfdaa1da567e677f7f03bae5dbf4426c3c4a6c3d082f9178b2efdd2bd49eee97ef4dcf3f0f51bbdeffe5ae6601e28019518f827f02e51f6679b8715978bec3e69d577156dd719959371baf034219fbbd17a2369a8541490f6a02013e33e74f4769be37aefa4defb6bfb3f351c2a261482c2fbec49f85f8445456e8f5a474030cd72d095ef6a622030e1e43a0c5debb034731d2f5e8e4ba3990f077d0c162649d1fa3ea4fe1e81d74aa849e21b059d966cbad4c493ca10bafe7a69243e3c0a6ebfd13d697906303392ba65d4fe06b6a5
+SIG: 63e90a6afbbbb0ee696bfb56efd679d68a9851a8947640a97f41f68edfeadd216ed8698e2e43c820c9044caa7adaab5b76762b681831a9f760476a8443c43c06
+
+TST: 400
+SK:  877d017436369ec2453fed46e977d6acc3a7be60d31395ad6e7ea9e07480e4c9
+PK:  4e65422fed334a55e8b673893eba7c181dd724dda002817b0bae28acdc3f7fc0
+MSG: 4ed3f5bdbd41d0e3b0a8a7fc3752eea496d6141678cbfe06757f61e1a168d761b6da83052f7994950d24626f004fbe9b8c9562e0c955fb3b5c08fd2d3d258393a349030c8e156205b40483038be1959f1cba490a87fe13899e4f3752063b68fe3e1c5071f7db0002f01494b4a3ee2e07992bdd200db4316629ee8a95ca347f0b28d6402a6da8b53e6b32581c3691e11ae9b6e0f0494894e649a92d03eb49c4d6833fa1f54f8dcd91d06936a6e62d491e2cea46dd07d9f02d3254b850bc9749f258a61ad3b9cc24b03287331b85a24143aaf8fcccac5f18bfc72dec75c0233516aa6e4589c78c665a186ed902091df97b0d04e83a2d74d789891aea2cacf813fffb5efaf78dbcd7af54ef55c77b1c4c8ace9e9278adc23d76c779d64b3bbbd1fb33b09836ea64a71e4711e89e8da0f709213342176ae22c6e7852c3973b60d9f98889b442aa48d7bfdfdef64c36c586c4fb2ad2e27ebe479f6d722f069fd6106b0d08975d5f721547c3b9c52f9fc5f45bb45b5b632188e80626518a79056bdc4ee1d2be6c6542a21fadea92c6dfb776
+SIG: 7688f3f2401eacaf2dd88e170ff1c4d7e94822a77f6b550b569e82152bbbb434057e01230b05ce58ee1dee5226b5c7cdbe5a8ade3b9465f59aed74145d14330c
+
+TST: 401
+SK:  4f0b3607d70b0f2698327ef4f1982c5b4b94be78f50c76f43bd642f1f0ede39b
+PK:  942b43089fd031cec0f99e5e550d65307fb6c3e793449fb390ff730fffd7c74b
+MSG: 9f700a1d2560f69d9bc105bc83bff539e4258c0248602013a959b978a19cc273280d90c0178089578b50518e06ad1eab790ffe710c63d78887a95569144f3e58a8837f93dd516fcddd22bc97a7f14411d424b2e8e9aa7c280119ad94ce92533fc7fea6c66248644ac3e1beef2553a6f61e91b9379b0fe0c68b40681455b311f40df0c97f53fc954242c375e7708d61bad9f51296247274fa01a7328fa5009d9995f501ae8683552b11a49d2638116723b1319450a90138d278cd9512b80ca5792ed16c683bef92ec87884c9f07f137dc47a13146e511065c2e1b4b80efde88ae12e29431beb7aee365c16d80506b99afa6a1406edb061766875832dba473e519dd7018f402eb1bb3014b7cee4f02e980b1b17127e7d25dfe0c168c5344f1c90044f827707dca03070e4c43cc460047ff62870f075f34591816e4d07ee302e7b2c2ca9255a35e8adec03530e86a13b1bdfa1498813098f9ba59f8187abcafe21ba09d7c4aaa1ad10a2f28334ab53996147c2459c01b6a10839e0301123d91a35ced7af89afbac7d9cf8ac9a38ceebef83
+SIG: f396a11f2f03c61439684f79001bd4f346a348dcf1d3beb2d3bfe33ea73a5ad4eb97506acfbffb784e77548189cd599f8ccf17355dde80e75024ef2a78d5fa03
+
+TST: 402
+SK:  b8a0010c784d8d002a31da11d022d30188a4197a1d5f14ea4c0dab29a2e40668
+PK:  8bdc63e50bede13c91a41e4b4b7857b9e553f484e3c1ec167dc04c281ea86622
+MSG: 5c6ccb298be216808b811e56d972f456b69ad39594eee354701ca6b3e38d1f41a359e5512af98a3a0873265fe5191f4f2ecaf66bee75a3ac0b71a4ddf2a759ebdddbd88a6a1c6fd0fcf7d7cb92a84e3307b4a4f98c710abf4f553dee74f652d2ac64bc30f72bf4354ef7e806a19071a051bcfcfb27e37fddd41eceaec1758e94695c670ef4c5a5902178329db9585c65ef0fa3cd62449bb20b1f13aecfdd1c6cf78c51f568ce9fb85259aad05b38c6b485f6b86076928ddb4e2036f45e7b9c6a7ff24ae1776030e2576825019ab463ebf7103a33072033eacbb5b503f53266afb82f9b2454b8dc057d84f30d9d2cb7c3a31a7dbdfba5b8e49231c231396c47ca042c8e48a1a5e3ec9afe4020595390f9990dfb874e0825ae9ae5e752af63af6fd3e787e75e8d8dc4c66302277ac01b30a18a56cb82c8a7ebdc915b7153255a1fedc492e49660262bb249780d173e1fd20d18c4f6b0b69aa2eca024bf3c80d7d5962cc4a129a7943b27f33cc799a36045541275a2cdb92a40e485ba8b737a04b43d29c3e25f76cb3d93a6b94461f88f5696
+SIG: b3f6cf4c0e0f9074ff2c2c47e163202f1e9d6ee117cf757633e4abe74423aa70008ada1509ec1dc117c1c230e9b23786f3d0f29b73aa284536e9580106a8a70c
+
+TST: 403
+SK:  efc86cbe40363abfbb2a4b1fcce5fd6084da96e7e814de71aadf9a618f303625
+PK:  22f295cee727d28d2b9317153e7d9412da1065c1b16ae2a251dd1fb431c62b01
+MSG: 9e4fa45dc026710f6bef4ed0f07c544b0bb0d88fa79e7177d8448bc209d71cfe9743c10af0c9937d72e1819e5b531d661c58c63141ce8662c8839e664db79e16c54d113abb02a75bdf11b3453d071825bc415741e99483546b8e1e6819de53017092e4ef871f1ca0d3508f937828a4667db11ffff9416eebb94bf9b84d654603094834a99ca70b90f562a86823624dfe9cb2f9e88c173f13464d4ce255f222db50dd63ab42465734e75295c064b64cc3f15e6237e37f33d615f7c243e4ba308960cfd4393402525500bb7902970b3931d48b35666a2d4d2ab08fa12af366a004346c9dd93d39fb1b7340f104e51fedbb533605b5ff39cf6d59513f12856dcfa198d793b0fc875cdea0741f1455746d8a19c3e9d928f0021b01c25131811e48c3c75c6f41422a8810c6c81f35b454eeae8cd17cf3f2e6f0bcd9f290984f496578623ab8e2738d2d10840eb91d101cb4a23722b72e3dd185440c3b9f44d46a393a34c187a20d610bb698c50531741efe96323512329800772a408065a7ef8e4e4105eb1f5bf6d3fd6b217fd836d89f53b96f45
+SIG: f8818310228ca76111524ce94bfcb0246ea63508cee9306592b2f77548edefcf76bd1454508ea715042cec169cea5115ab54235cb1097b10702aa38378028e0c
+
+TST: 404
+SK:  33556c60de2f2c9a9303b99add378592060505f8e49861085a4b15f072a7ef28
+PK:  231ec8cd845859f69961275119dbe4f715e5ec5aa98bb8741675b3c2d0c89fee
+MSG: 96af540ea2b1923f5fd0aad321ac032070c2d65ba13d164e75c3469758fcf31bb31655cb3a721f9cb34be2c90c77eb65be37f606d32a917a4cb9a709ac0705229930ef6eb6fdb0fa3c0fd3a90ce171674ee3ed06354bafc3c7075467a57445b80385640447902be39262894b1f64fea58287dc322d19875972a7c8be91d31f021c70eb682fdf11a10f8f582a126e064794838c69fdf64f5b6e8ba59d48b4384f8e9fb5c087cc7738295cd32344ba3b697ee6b6a8b78ee7a9575c97972a4d1bb18486f9037a0f3c6f471a90f86498dbc0df5232c07e8c01b690bee75302992a7a36fb4437c25a8bf5e34cf7d5b55572c700a079848d381364f9946a91eb1603ff3de5ebdd523bd92564818e237a53e8f522deaa2c29b897e961586e100ed0fc0ad70d160934e694027e5c957920bc0546e901be39a84535597e1f280c222267abe97f41205d8171820dd2faafc0699419321a9160f69b99fd41180945b62d2dd105cc7bbe821d28605e098edfa8b2309aeb0534e756377f59937c67463fd87c8b92ab58119cf4ce6c665af572fbae1de4a2cc71
+SIG: e06a7a414457bbbef2bac3775ccad087dacb1fa4bf938894e8c929118e09e678dd19938bc88f43ed0f7d31cc6a0e602c4e4d1fee33d41e74a119fa2d1e4e340f
+
+TST: 405
+SK:  7a5c74314e1183334a4b6226b9a82d70fc2a124e3f87db6a2283ee05b68e34e0
+PK:  beae7d3dd97c67f6273bfaa066131fed8ace7f535fe6464e65791c7e5398576c
+MSG: 98bac6724755912992adc2a48b5442376f2d927997a040fb98efe544eb0c8e1866b9616e298d3360316ed976bd946a411fdd3a6b625c0c1a37af0f41cf6569a7884ab8467491a987df3ea7a0b7ebc4692569a34ce3a2ea3503495b2c02d49d7d7db579d13a82cf0cf7a9547a6eaebe68e7267d45a60b8d4772455228cca4036e282e1a1216f34cef7ea68f938270bdb04293c885d005f9f7e638a8b4ead2626c0945174ff2a3e2d6e15a4c0338c09e1260f0928ca9d3499824f3fedc4785da49c5c34a56855e241facc6347a399ddcac4399a8b158198c151461a3b189e58ec1f7efcf2ab2031fb17b6f035ba1f092e9eee2e92c2d6cc2032287f854b41e70fc61c8d11a2e4f0708f02eebd02e8c7e8c7b38a57bfa1a745f3a86c23909f6f89ab16ce7e1813c1d20147f31b4cf2ad0b606fb17e5ac1ab51ef4a7d8093cee9a655f471dc5b146bd1b93e540a3d3d3e2de8105911c10d6ab5ff79c2d06027f7a54561f2071414bd330a8785442251c810e232f83c367f0be7799a93f5238f7f17b5be829fd89123c04833af8b77e5a4363047ceca7
+SIG: c2ab1f6f5114a84f218502582c567b37a8bdbcdf6340fa4622873be89106f0a90b4829505f72129df0ab3d8513268774a34df3ad21ce254b464488addd6c9b04
+
+TST: 406
+SK:  da8006adc492ca5dc86c2959437a75deb6120ff787d2ecb9c20c30b52c26bc41
+PK:  ff113bf0aa58d546f2385d444ecb7888f8caba43a174a89fd6065f2b7dc17bf0
+MSG: 3eb4324dbc0149d2e7d6df632bb0cbe9a9f6dfa83e227fc07bde1b577b3611fb921c9f8313f068e6295d4913a8196be530f6a01f57c09c028491444b784720e909ea1fb69c1c1dd6304400327b7731b33cc46deb046cdab6ad1b53f1749a0c65cb9a7e376ffa02230f536584aea243c639103adbba764321649d7e0126f82e0b4fd9dcb86c731cbcc517f2016841e916bcd5fde871dc098cd913dc546284d1b2165c63e88f32a2789a500856371b50d22fb8c87d1a3caedcdfd01ee5f870a53c284181d632ec66d48b6bdd5646ac39c9e75338a520212062bc3466ef5c58765570b905f63a93d07f8f1baac3526b016da799f3e9e03a4f7f81355e0f7a76f30a42b807322051b71c626a7a296d75b9d9d1a23bcb13c9ef48a912dc057325d3bcfb3f9fadaf0c249b102aeb854aa3631e34f69ad90c2ab2ed33bacc40b9ed1037fae67cdf799d5a9b43785961127d62f8e0bc1589fd1a06fca2aea7cfc012cbf7b5b207ddc4e677d8ae4aec100045ce36c00b74d1d28250791236dc5dcc1ed313c8c246172666f75217437c6034acd64198cd96df2a
+SIG: 1f5375dcb3ad2baaff956d8554ecb424176be9a6eb9ea54e814e0a73df2a5d848ada26ba8e1805cd51c5e16950c1ff7d4d2764daa6f4c7502fb865cbe55aaf0b
+
+TST: 407
+SK:  a284e26b97e538839c808d45bde6f012a354454aef81caa8c55914624f2b7d66
+PK:  5ae46e34695efaf463a4208fc4e35b81f2c63593238a56f2444b850f058c3c5c
+MSG: 9ebfe910b50a5cb719d95b961e5905f00ec7943b55468ab5956692017645b366071f8fbb77eb49ec73ea7d64511405b90de22db98c3eae39c4039c7a133430e8010bdd39a00fd1a528b113dae149cfad3ae340da27dcc507782ecd8929237517afe7463eca2473c7acf6f7aa04efc9f266ae7b6d63bb8cc2a438b344827f0713d1f1736f0cbb65b99353f20355fa0230d4fa707328a8662654e83ad0530a10f9a69e17c099e1e2b5db18e5f6f1dceda5883e8cab79701a5e9089562ed153ad08c674f097c28e4d16633e092969a8f0bdac54527c0ee03bc200e5be612e3d1eabd87091101b4962afa07b310806992f373076d76a58185118137c9d26ee2cd4c618c18283dd19f0e7a089ee37305b6b9518a78d8098436ef62be7d699808acecf67939d61b3e02937cd8c5f1e746d4274334bc9c37fdcba234c166fd712893f3a040832ec5425e57d80f11ef9ca5fbcd6c147fbbf5e2fae746e0ddb605867e3bd050483c3cd1329abe57a60bf88898dc7e80ede0f4517de8fc807e888b621a00f663084ff94b99996628f3b11690a60f0918cb5c9a7ef
+SIG: bf110e2e9cecbc31fa3e0c2438cd1f4321f92cd287005a48528addf76cad8d88bb22719ef91b139562a1511838682674faa9ff7e7ade6c9d573f845036d18905
+
+TST: 408
+SK:  cc97a96301ceed0f922731b685bad8ad4f06207be340f5a44fd187f29903ec20
+PK:  eb563a7bce12db97f1891d0f610bebd55101a3125ca8dbb50b25a6b5050d3784
+MSG: b9ea3b3df7187ea415a3c335e0834e10f440915b2ad41c71f255d6950a4e9120e4d494fd9e672ce53206fdc417d865897b47ac1054e1ca1068195232d4297435e44e1224e66a912d9d7d182946ff5a9f085bb8ba19c54d16b586a9b30461b6773b93950311e1619886f5a5b3f111aaad094bae31c48f1941080968bd0277bb6fa92eebf324b192df5cc969516c78c7b2d12159b4d1c8eb03160c4cd1907f62ed4b854c569ecc481c08e636f44ed7c390e58b5937d2906b2817bc3769dad9da1b0f79391b55942063055da0d6f249a3e452baddaa032998d7f73398ccd0151bfc92c5e2fdfa9b14855e6b0d3746dce248e219672987252ec747df2747fd3fbd8b714c882d707ee302a904950c34754f85350e1aa3f8ea6293cf01f717cefb6b83a22126df5c4f5698aafd06a2244ad7d01f34017ca0ece6f21040048aba6ca4aeb04325b9402bcd43ab130a105788ac3d7b7da01ea9426dd0ea1933a8189933a6c0c6cd648ea316a7469a5fdc6e7c934d9186586097b55dd51ac487bb80ed11d4df8d33626bbce95e4f13bd49922f00c920223f4cbf93cb
+SIG: ffbdd3244181cdf6034f4a450fdd95dee4971a933f8be022bb0a4106aef39af3055b721881c9b54d1e99b9409096fbe6dc2c9966e3679964bd7ef4c808cabf01
+
+TST: 409
+SK:  679e3e34773abe4ae25cae7d07ccd0eb3b0ec0a35d570257d62570de58ea2516
+PK:  18acffce253b27259579ed9924f479cae312167bcd876edba88b5d1d73c43dbe
+MSG: fb2b648ebb16688244f78b2ee9a273599d56b6198900d438a9e99c191425c72bec4f235847e18e47f57c3cb396655f778921f908580e8e83c96c108b20dd416678021bca259b98518fabb2d3532e4851d9d52add2542c0cb3efa3857a17e512438bc0ec4762e2f9baba429c03e99bec4038e6b0ca42bff5b233b24c333b4caead2de374a87b2ab5d80d6e49e4456329d51ae973bc83d7862f3d315e514481b12854a9dfc09e7d14f0d022c0ba3022578eba8f874deba4aa8c833f2b132861d4d51e50fe9aa4b787bd2f051aac50c375390cbbcfba2002b80ad00cdc12980f8ba8bcb7064afc04d5c4682c1029b10a6d45fe6ecd704245faf598c4659597c5d68a192cc1cd4fa45e84b549e8e5e67daa879ae5a520a6b5550519876a562ac49c6db0aa76ec69bb64dd6b5e1a3af2e131e722e7cdd05be34b5fcc6259aa124ccf814cf5b500d176be28ebc40bb21f03e24ccc131e0f41daa1ca02e6b00c9c53fad1248614e940d4b237760ab7569a767b7515dd2d623e57a2841b7d2441cf43049e4698d2f9c9eae7b2910f6ad65edf9cb2bdbd9b29f606e0d
+SIG: 1a51022628ccbb88eae9b21773c3f830b7b6e5bc36c9903ce70fbcf459d6a1ed8a1dceff5b19269ebf5a6fd3d8958860f554461f0e9fc0e29af9b1fb1744a80b
+
+TST: 410
+SK:  9bfa60923a43ed0c24e2f12f5b86a0716329f93d4d8d3e06238002893278c19a
+PK:  fb1c00687781b55b893d6b2f4f49cf5f73d2903c316d1eee75991d983a1868c0
+MSG: a99028b0f4a3aa5e79abef6c0df4a783ef470f1a29ba51eba00f6214e840fe19e5b6dc6021ab599bb2ee3699576015d79a7939af823535b630e3938c723f6e0b9229d46bb3379acdba587c238567e3d89bc3bd3519b727fc694fff1118bf22c8bc8bc82c4df7f5ad38de05fe9f762999ecaa795f3ae630a9a316d26dce9f1568ffa3f22b0295214020b3d3f5337c149568192218132a90709279c01d23baefa669e1c4e42038173f1319c212da144f1c4ea4c52c005cbc0b5bc283e74483a0dca69279deb17ae5b29cfafa7d0063f4e1bc93537efd937e58a8aca737228f937ff2a741890e96c5725da11b45c413a9bbb4180a419987bbf046bfd346295d62f081c76daf2b0e1eb4f6712feebe6f0a92e358e7ddb85896507c340a01f68d1b0f085778b7c44b014aa6673e501796959a17a688db0959058488a7112572f23cf9cdb53b5eb4b45f5953ba0c0c690f86bd75e89a047bebaf847c1dfc345a4f3c7d3beec98b84b0219003e819f5c2adb45f8717903d1f5bd5d71914c56fcabc7a290f9c41699c95584d6a3a16340cb17baa1fc5e5467af7ac3221
+SIG: 55f202efb2a57be8b4e4fd894dcc11a4fc5f8276618ef5cd34a4495adb016a298e6480a35cfc53edb25ff1499fc532a33061cc01a250458aa5e4f7f16f51440d
+
+TST: 411
+SK:  6e3af45e66e22890c3f3c934f523a4d69427976e6e52625f8bad558993963219
+PK:  e097364e76ff9f2e1d167f6b20c1bc5830085e7ec993c138f8b1b2175637e741
+MSG: 5cfc2f4b559f8205b39102087617f4d86c7ce6cb251e5f89601dfc88ed28e8d7a670ec0087d2ea5d893021c7044da2899a22d776fe90170e51c203250690d37a294555e74af9234cbf1ad8f22cee8974828a0d09e9554b71ee3bcf880ab98325f706272194eb2e80c701d441b5f8668561b88849f827af703ab0954105fd3c54b3f6ec5493596d0e3bc67818048310c4a3e0c556bc80675f201f9bb9c6538a41d99aa40c886fc431467218d819c23e78498aed0613fa6f973e2211df9fb87f44116f3fe4c26d6cb2fa334c87f78c08ca8c9b9041d83a1230677e0af788598a42e44cfdf6964a4ee80e38402ba67c73a581e552baa2282425cb2ca17ca92edfbf98299102fba761b9b71a5452141bb9c18dd95febc2a782de9ceec08bd2ee3f7f0c1bd8946dba99cf9ea086abafd37c9ca60213f0de17c61ff9c391c9818ed5cd8571778b7dcc13224962386fb8ca14f861e99f3b18edac8a5f130f7bfcd45d045d0ff34c81572a512363d6530f93813e5fb10e9cb8338a7f93800491006f4463e89f0ed4530e5f12df674f598904780ad0812b1e3521fcd0f83e
+SIG: 26ba562e8a4065708207c25e239b780aee38794cf983a37acbb9d557a65ceed3c0da47d17f3e8b8f4eeb1b65a2c182ea6f29623b63bb0f1c72592683b126b901
+
+TST: 412
+SK:  5f1f271844d9ed5a6a6f209a21408daea470f6fd53ba6479d7407105b7de4d65
+PK:  6085d7fb5a9b2ed806c1fd30a2afde760961f7a36b48f4875246e615a2bd9928
+MSG: eed6b4475dc263bd2207fe9d41d48282b713f680f2e037384f18b4bf224347f5e4c4b060b808d412eaabcf733dc39a40c6bda0505ce71fa823bd1b1794847678dc034e7999c16369340bc60c64d09bb9187b2e326055a053f8e505ea4196861471622db0e46f0f8954d8a1f07332da4d8ac55712626009912f8a15a9cd63a74a03c92f246cb63cc73f92e51dad1bc9715b1ed3fe5f2e1b2959b9b71e0e37360eb29536cf797147fab10864d6146c36b82335a0ce931408479c7ede484ff73e2dbfffc6c9227e16d7a23f4d90f15584514c39594e17bfbb295de9d62adadb589dbbe0b06dc8dac5b3bf517b24c1837b39472a6dd38931ffbbff5b763638805b4e22321f7afe92cdf502fb63d109ddcd9e4051ad6f45598532be179523710851d3931e887d02c345c79c489fc106a4ae162f7df71ab90b751da7038a6df7616cfc11887e21068fb9e33be566402be504f3fc2742b881509bd4fe6a0fc722649883f8cb655598a15a1d4c229dd86b5caeb711a028defd431154bba46b48172a4d8cbd45bc90aaf874b6085fa284f5fed655ad6fa17d67b3b9a796fa3e
+SIG: 319bb4deb2178112241b3fb8f46e105c3b8e4ef721eb200d762ef363e2716f2a89f80b5b9e89970890a09892ad6a58808b477e943b3cfa77774a3645bc745f03
+
+TST: 413
+SK:  048ac9ec3ecb30a3b1bfda9b3b79a48c0793b490879e3c8a5e23ee2babcd9b7c
+PK:  946c186feafc3580a58ddd526ff229c04720250f4cf6bde0271eef9b12b1c3f3
+MSG: d68be8ef7b4c7a4289f2b18b16ade97f4e4fa16452976afb581693380cc54de38a07587f32e2d4549f26595fee2393bd062e9b00bae72498e4148c8b882a8840e15b585c82b5c0defb233518409916615deb3a55a5f84e6b3aab93844de3b1e4d86e09f889ac71c324eb12d0fbd861cc31229540e843a34f8d5be47c0ec0d23df43e06813fca309439904c167d1043c0dcd444b004be1ff27b7862b00eba9433b94b0fcdc67521da0c1d5358636c78f530431164dde20a1cf164f51e29b8e63eacdecc869b41392c667664d91680d9ac516af548f09e60564e814e36e0b563dbae55c627ffc14158a56d8eb3609e174381b21de4ba82344466dd577f4d1103c43c27fb83cb833d87afdf7412b4090909b1dde264daddce967f496bf6f17112bf351e417db5953b13b8f0fcccbf30f5bcf376861c12ef20eec89ed23cf384ee78dc6eb40fd5811a7b23927c13e7dc5da3a921b883a9b2b1155970fb0da7d2993dcdfd4343642a9d5a6347e43c193b5793e4453ac1537aa3d04dc9f774e840934881d78a39ba250438c507250eed2f6e07cc953f783d6b72b1cc619981
+SIG: 2ecf5b8a59a8e27d25890a2aa32f4a0673275d539b174afa7b2cebf2e76280dffc338ede85ac8f614039560e2806d9e1e3cf9cce2ceb7874ffe1a7e80cdef40b
+
+TST: 414
+SK:  2f057d20b1678531611f48f003b7d22eba5dbbd7e2dd41b7c79d09071f85e993
+PK:  620fc4eaa34d787df675ccbf7e893204828db92ead17a1165ac7fa1ab42719d8
+MSG: 6e35f6eaa2bfee06ea6f2b2f7ab15fa97c5180958af2e90af918adfb3db8323f447c7bf26dc534997c38b7fc977f642de288cdf253071cacf3564e3b8ed6dce57ddfba9ff783bad2e76df124828fc1031acfadf01a44d41b42161ad9060301c1af1928b9e5b73b9bd21cac60a842b504dc3cc311c522e3bb048bf221444f53ceb08e77e948590e94ed98f1b604cb9eadc93bbe7431c1149b23193ff93e8569f113e1684d8976ecae6f09e0103614be418a472ef55bb8890d72b341cdd7505b50a45522ab63ed791ce8f82feddd7a620a4f6fb1d2fb0ed0c4560d78446d83b3d1b1bb56b366d196020d0624b1fbdb75ce735dd43e8e8df163c44e236993dca341f5132d825d0a4e393a19d38f61e11e0cf392cb9b646ea23c58099824dd8d9fbe26a49e33b23df80607abf19715799c19acc722ed9bcf94a0c29ad24b78b0b035b3241c64cd86edeac810e66745694b5eb1625060edf2d949de0d34f522df2dc60ae694a193f3b82c1d6f83a0cbb840f46c49a3d7d1cf06deaf96c64f8f9e17bd9ad512ae6309c486d9e2a78dceeca473a0421dd1b643c78754271b53ce
+SIG: 30df7b0b1c04fb1efa3517e928d6d57c2ca0d07f4e04ffb1f08b4792c5937dd271ccabdc00dce850afe50af5990f224e8420a681d95f9f7f515afec102efd10e
+
+TST: 415
+SK:  3a3d27970fe2acb6951edd5ca90dda0fc6dd229c0a56df6eb11a9c54d242dbbf
+PK:  564f0dc3dc4720e68e44dd16711e049e6112000098fa62a1b98c288042f7c3bd
+MSG: 4374f61c2cd88a3b8972249bfa79b36ab69e3ed484cc60e5d9541fa7686cf4eed1210c5d0dcf42dd25972501909193ca76ae6eb7f471d8bd0d5fb5a6b431bc3de0e0318d50514524de87c4b83005dfb41245fb1af79b84a97b83d3cac7ad7a53364e2e9b21c97b769bdc57f0703116168380f3cc883689eb4a7fa3b26dbe12bc28f8c40381af64df4b5361d174cf75acbd46428740b0d1322d32bbe94845215966ae588777a8c05336e352306d49278d328e496db65e9ecf6ce6405ed1c893490bc48c13a134e1fb6e80debe6d32fce6ef74783c8d77980a441a26aeb4fd83cc855352cedc188f5279ce211f744a40b23ce7ff24437a1dd3373ec5b290da1f94f43a07a3ffea5b5f67b52c196185bce9e9a858257fcd7a8ebaf9040ed091face5a155aa447fa15e12122d25e8fc36eaee2137c7b3aa30b7e3ff6cc86b6dcb9eaf49c9576f0f462008439cb1a3aba013e897a0faf994cb7d59ede5774bb144774f73ca30e6414a7cc7c74b20c51a1404ddc419ef7624593e9bcfb37c0a762eab68faca5863443e16edb759dbc8788732b9e4f59c11192c3fcc872af55f32d
+SIG: 22eb8ea0507349b6a0ace25cf9180cb08e0357b04502905fbe69b4e21b2bd94e22cfbdb851ae716a5c253c70d5e2b24ea78f35bc213292543d94e14110b24106
+
+TST: 416
+SK:  06d498318da456242b9c3b9ab6d532a128fce044f53882682e9262149c165288
+PK:  413517aa63200a17173209a4b3e78ab9383cb4e39efd6794c46a2d13fafa99c0
+MSG: 3fe30ecd55077a6e50df54bb1bf1248bea4063e3fa755f65fcd1159ee046efd0eb5f2fbb38b5c00947c97dc879b36b9e536192286086d0dc12053610386174a7c56f22a85b73ff208c5944f393236c32415809da036e73cad8fc3c30378064a76afa930a3baae9aa357061a8c5e8e756a9cecf94b72df43facd88fa49cb4948c6368318a6b1e5cff52e587ecdfaefdb69081f28c2d13bf8eab81dbaa5e3728c4317fb793dd196bca0fe54a6c242cf26e2d129ba0d82a2c3a45bc8d1dfd6f54f8da4f5189c91ac214fdabf4c597381b2e5c40cc71fa7051cf2ea93906a37d57df12d5c7e5cd77c907e442566315bae51a2222d62e3f42d1767882637d66a1d5305ab4010a0e49c57def69dcea839e1b76a41135ba952cc424950e8d3aac19e1d93de7757c15ff9997b3d2a8613cd9a164781d1be331799fa6109cef614305a1958f62903c8c9ea0b23ba706d49c54baccc1e63cb4bf14785fc7b062a9800349bdb0bb927260b677b60f10e62c8780f3ebb5eb6ff0360263d457ab52fd1125c9ce046a95d89d287350c804cfd4ff2b2ddd18a9e13519f20b4d1e051af624640f
+SIG: 8250f76dc599c5128787e4f6d3da23173330ce3320dba959bd714cc8cc07c67945d63e75662c075e267460ab7bf561f24faae3b41dbf676899191e3b02b5af0a
+
+TST: 417
+SK:  8e8e1db5b1102e22a95c47af3661469f000a33f13b8b87b115d2452a411f6f39
+PK:  56d7b3169a95c22998ec937925bd7cad13cc65808cd5d34a6c4da870eaf32364
+MSG: b24634fbdd1b7661315d9dc153ba90d66a88622a4158f8bcff25ba9c29e65f297f8e60311800b7331b69fc20c9f85bb7c184bd4086b3a9f9a27102b62362bdb4fa5b201594250fc628fd2e0e0d1be03dcf818c6094c4c29121cb2bf6d908ed8aab427c3771c0c95f0ac1469a0810b603a470282e5980a60729197fe6c20ef681cd1b96932d2058f896ea7416422a7e541f224a5f04253080741c5d4e3eb039db6ba051b4ca5417ce8afdc70214ba4dcc85b623d11e681c6009aee4e6130a83edd0d2c99fb0647e11ede7301ae56b59904ef7025732cde038801ec7e8d90a9a1bba047fe628351b3b89d0bc5ae665a700891f09ebeec05591842adfcc25adc3c71c1ebc4a312e5471be67253b0e9428b0cae37645a0f7ecb89dd79fbd9be2875433667ae07d74a7983c4cea601e72e975c21df993e7fa22a9fabd45455d45e37031558e13a7a4f5f497ea78fb7399f8838c0fd5de4ebb66db290f43a4867d505309f1c1bc27e9fabcbba71302fc1204715ce3fcb0905bfa411c9d1c9ab4a39954e50b8e0cf736c10289563bdfa967553c36cd9e555bc8cc56be594847de9f26f9
+SIG: f6ee5e13cfaa362c8971d5a4a879a7e36966525ccd86c5a48cba08d913ece1a79c4cd146b8e9c65125fbadf17bac1cabcde8fd17cfd68fa1f9c44ea61c08a405
+
+TST: 418
+SK:  3884b8b79abfd3be6c13985eb859ab743f157cd9deb81b2fe97ea4d6173e46f5
+PK:  bd7fd9a8def13a542ed2f2fb048886885ba9b5ce59cb7019fb54667986eebc26
+MSG: 12adafe30eaf2b9c7203ca5d44b97ffed4bf6517a49988e4e676c8e314adbdbe23d8f2d3e2b081a7024fa525ab5aae26e60057c101e8f368d3addb9376c4682c1f4224d7f149a8474bb9a8f663ef210e9572ce829da388d8aae72a467141adc153473be3653baaa64b5b1e2e30683f6f06dac2784d5bbf0d082aab47305ed8a8efd0886ce63a179315225d1e4d4ffcf1f24ac2f464cf5ed3a8b6d3998454f1c02cdbf0a444ee2b59ddbe0a174a0d937fa62865088ac647499957d281c6949803a5fbdfdd0dd9e91b6976861f3c5f2126f39aac935be09f4b9715bd4f0d5c55df73a6b9f2c0ad26ce49d822bf85bfa2346f3165b03859a71c3d2a7b86db6e9f2e5d7b169a910eeb7ef38fbdfbbec43a9a25f04bc3acfd3b0691542ab6de9db6f03058f9584024f9918edecd90fbb85735d6dcec5bd593ae63e2cc96553599a310f8f2009ba95371196b4d5b80e7559637f22926778be5e1ccef5126e2443fa939c2a53dddb04961eefd34e538cd8d7f0bec2bff1ef0d3a4bdd358317637f42d595538c1122251a94e963d1f81e7b9aeb164f95da9a4ed7529b845ebc961b27b5c19
+SIG: f4206fcd34502441d54a73323f33a5dbb4c98557319f21246f260ffbbe5844886db567f4b63c47943dbb78fc35657d7c04d4feb042ff8536f672925c319efb09
+
+TST: 419
+SK:  ecd519f287ad395052b0b30deac341d2a9df13d6567c891c813a0c9ca52e871e
+PK:  8ee94c588e0b343585fc6748fd1b54b5770c64e9937a56357a48d44ae2f51824
+MSG: aa71be5f557e10c9fb5f091a3a274453947c07a0e25b26f9509224541dff76f4d96effd0d5a41d319bc9321a86667d55cf49432fb5c3e715388f3f106c9174b1610c8f3075d5931c290099385ce9249e235128e907c53390036fbf5da968f8d012336958de90c5e8e6b1016ad43fb57c8e288dafe14e90e64b63791e5cbe557e02df8ac9370642a71faf851075e5565f6f9a267f4f6b454ce4c5474810b804844dda38392939719793246aa47454b9b0e82e9803c09935d0027f3995cca9713069bb31027f7b2af12fe5feec7eeb06843d8296ec5682262a07dae747ed7bc821ec17018d899fd167b36a7e3773b427499d99dc583bbe4b429afa6a26593953f943e4673bdd0d2a844256131603cd0903256f334d4f8ec82de115b6ca5338c75c8baa44b4ba963c7c78510d8de9b2a5852f42f3463c685fb3a6da61a8e0892662d6a250fcaa6fef74d450fc457b9871d08bb5be3011294ac888fce215d535c3b1a43bb47efe3ad25da159191aed55195469c59093ffb24f65d60c4020bfbe647ff5db7ab8a01d5e487b0b1b64ef25da156db142e6ad872a4dc1ee9ba668465265379e
+SIG: e8f51be73fc4e0235aa153a2e1b354e9c5d2d33a11ae0e333478de1d8e6c4456d2e250824c3246ca0e8d6ae3e16677a97344144108c13b959e1daf51cf0fe501
+
+TST: 420
+SK:  193f3c630f0c855b529f34a44e944970f4a6972e6c3859359c2e0c8762ba9eaf
+PK:  3256f2c82e7c801201210140569faf18507e60338c2cc4118bb1ce605b0ebe61
+MSG: 98623f651698085bde02762e8c3321f14da1619b5c3f7c1a568e8c26ff0c62fdcc412475912eb8e8c4b0d30918b8ffeef3509315e58da359cdc2f26bebfb5703953be16b8f3beb1e54a1abee0aebe24e64dbe873402e156f37dfc168eaf8a114ce08a6795d3f64f5151e9a8b8275cc7b49a6b8d8a66b6d4b7632ef80740dc1c1b0a38d1a28f7c1b29fa44541c1aad354d4590c231dae687a2a8fed09e8c1ebbfcc38f347bf06d94577e49ad139f710ed8bb1fd07663c0320846fbb455ab837ef964ae7d4eceea45fd7bd8d509f821e6eb027494efd8dd8e992b88698eec2ebc5e03025be789c18013f201f77aa2d34f5686460e43fb489e08776f98bcde2ceeb9d4fafdffe0375604371ec32f46b81fec474382908e9d250a0ba2780a7d6df407bd2b1eb126748d72511b9b069eb1cd44270f29fe84b9a717751831d04c2818e408f22789376c61c2ca45e32e788ead3a7536bf09da8af4703902f5516a020d89263e93701a2565eef1270418925f35a288e327bab628ac2f0248cfbca3482e265d1621cc343c31f65493f064bad0d7602460715fa486f29426346af53e333b75f5905
+SIG: b12510ac5f2f6d33360cddc67291d6c270fd9ee62dc086b38d932d26473fe9a24efbd4248867ea7e915a30c5bfb3b8b19aa01aa2febf0dac6cfd6638a2ba7e0c
+
+TST: 421
+SK:  a88ad0048d38c44cebe735ea3802ca576e37121c7d4d760dfd88de1663064abb
+PK:  14dd8bb306803e5a758ed68ad21d07d88161d50f1c74713777da1209afbaea0b
+MSG: 2ce8bca26178913b1676e90ffefd945bc561982660e2a75d482ff30aaba1ba43f82d2e6b909ec10fc09789ff5cf32a5180b601ea80fadece6d7e7baeef481dc6979e2f658ae0f6d8e416b93298f7d34031bb76f716ed991a16d09a582e58ba4003ac17be8b4469e1a889b2fbb2289e98af1c6d5bbee77756713c0778b0dc446a1f6c48c4d40818ec799905f069bc95341657ca5d02b7a539a13a02cd0376a50e8343c0dc20346de5275b1dcd4ad7af725131ac75e954825d30eaa57a68bb98dfc41cafe5710556647b387d9b7fd4e47651e5138050798f6d40f4ee7120b58f74da94d73cacbfd393d1347388ee00b79b8dbfeb57814121bdda60c627dce147d4d568d79052e97b9a5f3eb5407cc46461a55e18a960d8094a5fea48b6937529cc4ec919cdbedf9185456dc00e8d98ad1537ee10a057f4eec4b81dc60392fc9188d3e561785965092e44317f2a48e36605fc583fc173b05db9dcbc7557d06487390fbbba77af3a014e1ac35139caa1c53a8d17347f178e1c54d0f52b40e91042c93e7e481d792e288fc27e4c2fcf111fe97d9e2337d2fc1c3098f06684a31d55ebf362c027
+SIG: 1341a148da4593c88ebc5a58821eef77f92186390ff633e76207084e7874ccf0eb1f9ec70a3a3f96b58934bcb061ff920124f7e580fa2b0b279583adf9232d0c
+
+TST: 422
+SK:  3f59d6a018f50a822117e5b473609e30cd64920ca1c2750dcb09eaab807a3eac
+PK:  457d0e59c11f348f3bfbdd3f327de78c0a7577c0aeef42d4c1e56700d108808b
+MSG: 7d103a6c6ba2d09087eef2254c1c903f067695a54c4515e4d13bc1fbfb54d6e7a167349c14809976da04a7e58d96b40aac3b2bdd14b9b50322bb11645f05e5e978bc7fbd02492ef88f87d668280fd708373207ff670fcda97df8485d5e46dc3bd04347f4d7527eab2718f7d93d132ba7758218894e75a7deabe693335ba0dc73bf26c288bfe9be8a736d75e5e0eaa7bbe8d0b77abdd5146e0fc9b30db9f07cf4bf36260a1f41410331f8b47c6b38338c6dc9e801ffe1d585f9b7fc31e9778bca3027c232c074cb18e5b72997005ffeee4bf37c8f874b1b246a6345415dacaca7075a60443ac3319236e23cf6b7544740807052114984b8d8f7e857dcc6faec8869cf96b997dfa9af9184ad623f1d90b8ca759b448eabfce18c17cfdf9a3e3312e63e5f084cea904c1c909913cc4b19d044a3720034973c7384949bd6f9ba9256f98cd394c566da83c31180109f16d10347b7e3e9dd6be3bd3c77ff1a7996a078dcf89dcdce2d1b615695f4cc9f8f4f2a08804641bca82662ce88faa53145b6a45955aec8cc2af81cccb5d7c64f9ece1c9983326484a1e5ece4ce36544d63735f7776f21a20
+SIG: d7425ea194a6715c452ec4f6d6c76e6dd374d3ca7ae7a11995d02b942d4a31870dd734c12fca89a8eb0213eb139c14a87a6a33e818603b2e313023fa58737d0e
+
+TST: 423
+SK:  a1212b34dbca63b7093612d05dab7b4cc8f7b676a934ad01f659851b3bb44e4e
+PK:  ba2fccea9a080591be71268d7e951f250dedc00416e5f3f908db6cc571254925
+MSG: 07c37c46be3c68d05689577aa64a932b906446b29baf12f6174a6b42bbaefd1f1f373e0bccc473ddfcee1a7f21b96a6260ef0aa1f2d8b2959e71d12c953358a2774cc5e6f379a313e435ed69dfd6d4a59adee3cc7ec4bacbdbb3fee5430b73f6051a6096c60e9bc92cc8fa059fac2a93ef7007d64fbe50064964d5a0ad601175cd9caba453f9103b25485545d301f03c5f9f9478bdf9d414bf1dca3b1c1d9daa9971f9e617fbfaf5b02a7fbd5d4fb894c0975c54592b49a0fc85dd0853f30c51502d98fc1ab85a17cc58961aae9764570ba5cbdbc96dfceb8d11da53364b4025fe0b8ba8a353ad23686720169fe973432ffe291a4b11dedda0aac79a5e42620a64587d2059e787013b40ceec599208f66ed0ca6e1be9092ec27db216ee6dadfebc21705bc4a85aee577e57d239af586efeec22cf38d1cfb3cd74dd0d9a3381aa81e6a297e39b819137ad27d475e2bf54aa426dc29c4ca8176df343137a2d79d12ef9aa7be1cf6775e5d8a4430a85c33db61cd2f35187b4f6ea9ebdd753d1c4ef72471159ff07b77870906496249d4278e3f3ca6bcbf37a265b896539190f9a31f1e7b4b65cd1
+SIG: fa93ed6595bc958dc042ce1645167b79e8f6734c46f80f631fd5484908f5e51a22427ee686f564ff982f6ef4d2ca1f0ca5624910cdd63c11a3c2b16d40973c07
+
+TST: 424
+SK:  d9682086fe7dda30b87111060193d847566ab94cfd9c97ab6b43e7a8d3f79382
+PK:  8b0b1372d88733ef7233f6379790d1e46e1e07e9d3fb8b0be252ed04c5fa163d
+MSG: e8814be124be3c63cc9adb03af493d442ff20d8b200b20cd249367f417f9a9d893fbbbe85a642be2701d1d1b3cd48a85cf58f159a197273143a578f42e8bcc8b6240f93271900538ffc187c0afc8dbcc492bcd679baaef3af5088434a94586f94b49970bba18f5ea0ebf0d27ee482aa83ad0dd0ee609df59d37f818b2c8d7c15f0f6f544dd4c7e7cb3a16724324f77d58948f8475a60d53e5bd510c17137c99e1cfa515af9bc85569d212a21190729f2817de8c46915e021df70ff6d60215f614fc21139904df3b292b749dc4dea02518b62d15862c92d2a4c996701cdecaed84ab628ee984fc111eecb59e48444efc0d456e2c852518441c3db7630ddd5156249a28730983838ae59ac4cc7110fd6de68101ea5b2ff69fd364e3c9448defefe175bcbe117cc11b4ff7549c33e1025b6b592048a8e31969e818dcc188bb19d7a2440a3baba4eb1b81c45679db46b31bcde7776757d9931ec2063fc6f1fcd761ecc57a7d030a85ea273ef1825b05092ab9645359a444ff7d166b575fac298308d9faa68463d1d0f7b7df8a51c6815d37159adc0b593224a818321d7219f09686cfc952259718dfc
+SIG: 1793e497eb521ca74e35d14a63868cbe9499da2f21b4eb5260340fca3c1feca78dbe5b14ac10f3fa76fa2e71e4c91461aa75977e5e70792670ef7ff0e6a28708
+
+TST: 425
+SK:  b52b249a7aeae0fbd94ffcf9a9fde10de61c3f4cbda14b289fe01f82707334ca
+PK:  735163bfcfd54f9d352e1c2f3c0170c95c1842ccc7421623ae0496980cee791c
+MSG: 1d445e8ee36f6e1064ee1281e6b4a4cec50a91c2b667c8305d1e9a5f7b73a3445882581fb0c11e64f6ee92e811f9f2d6c59c6344be7691d116dda493cade51c0ce77372b61a7c4fbb633401333cbf71372ad2f044e992ac035f5879c053004f8223f237a24a409b7894f6ad518e046b8a84c3f4c6260e6169fd944d57fbcf9ba2775f2d60ed772c46ccd63c850b80d587c5208dfb1a25878c02dece3e602e9632fc3c2c79b25ab41034c6e26b869255357a686781dfe6e644beba9b627da1fcb5ec0be497cf188e1ef1af0601bf16b2911fd9ff34f0e97ac95a7fe2cf90ea6ced33ccb0ed1ef2d4160efb07c591a5cb16c70ca1694fb36f2ca19eba52be3d4ad895abcada4b36f0261d65f59e0cfd2a6148a8892ddbb45810db3bf4a9e26e92c15ea2618cfeeb462d8628f254f54d2af27113bab4f9a7d06791811942bdc32f845922d7b2ddba959140928f8c28d98b44e1d19b97fd39cc0f9a5236d349fc835ac492192462e40ac629bebffd2eba72d2788b244bb777ad0f7b7f96f23412399fc1d87a1d087ba089027eabbc05edafee43379e893291331b460bfa7332e0842ec2573393de95306
+SIG: 6f48a9f7f0fa192b66d12175a333612303e180b9fab18edabebcdf6674fdfcc53607089bf980ce35894c2f9babdc4438667ab3297a6248ec0269faa99c724807
+
+TST: 426
+SK:  782a93efe0ef06cb2534330efd0e9684e9969b5258123e490239bf24bf9f6523
+PK:  942fa1406ee2683e29377e49f7ba757cf50ef0723707d4403d2862257045de87
+MSG: 46a4e319a670ac993994a53300c3f79144c2f7fec1116eeeb3621c76ac35da79dbff6e189ca9dbfc9abbda054847b2971b02facebbe926d469eb0a860389ac744162bf6fb13b42cb9bb8c9d72607138e7800121ee0cd633ed535c7ae5f4060bbdd271c9d110abff5e060ea6ee83890b1e92a9256d7b2ba982a3114bb6deffee2696f0a2f9c21aaa5b2defa11aab7076de6e57e86f284bb67f5a49ee685921032c95b74e7e3eac723f175af082c858e0dfa01728c38fbbb4c83581f81ace6c63c6bdaac5620eb9a568e7ebb7b72b3d1a164ef524e7b9f00799ab086715976c14d0df65f7b96bf9ebcda7feeef113422001a03a7633df5e49939a121db899d9b8ac2db4fad0c30cf0b8bdbc9e9802a797c8238e46511ff24068cadcff2448cc0bff92769223348d45d6b6f2c8f1593388c0bbbf44b6ddb50b98cd7f09c730f7de4d008156cb3cde0cab3ad0a58a83954e234a0a8a04b573c9a8e9b929ed38b8b228bf55a3c6e2c6b51f682652fbb708e74640e3313e17b4694d7fdf0111f90608c1b5af422dcdecad9ddb7f50d1bf5bc6378ccaffc3201e6c787b48c443ba240d9d50ff6c0e9df7f1a5b
+SIG: 93e7405a4044510166c8ac264ce3b5ba6665d68bad458712dc93c2c390568d7402ef7d57f549b8a1042f7f69a679aa855f34f801d57d79895deb8deadb352308
+
+TST: 427
+SK:  6fe7bcf7a684423de1076fd76da783423373b381329efd6157424ec4b2655a94
+PK:  7740e91afe45324f8bb990ca2a341279ddaf232c3bb415f178b6092fba195fec
+MSG: 0baf0ad440612b4c5a136c3a42be1ca2b7c319862a44a9fd50c4ee73541c5e6457efa81825b6dd4a72194a2968688bd49e5a8f4c04dbafc2e7884c0c70c208d4e954cd1675da8e74c65c497cf9dc69424965bdcba5de52936f925f62e201f99505d3777beb3c2e08b2ec9a873e5a9c21fb4a2f3e861f3cf4d6b5dcd1c88bcd9163539ac62cd0659f4ef232c2ce57fc77f90285eb350169edc6a806ff50f61c7e0beeebecec63bfc9d3983f5bb4b261c746471fcbf2892c6108970b68db5e43c4504ddae2d0ffffa28b6759ae1128e16f66d492ad61e3722c960f88692be81a9f412890ffa346e702c867dfa259703b73f525074f3227c49cec1b645a103bd4471f33f9f1bac327d7917861d0ad91abee60222ea2a3c8cac052ae9a2cbd90855d733d5319133f9541bd0b61f0995268351e2863c1ca2ca51e3c976383f5c4c11ff410036fd51d5ac56b023ce9029c620f22557019ad9b4264ed4d71b434f4a4d17a7d5769fa1e14a69f7ae419ccf5947f8c7682697116c2405f5a1959c54b48f0872f596ed45964488ddec12bdb636d0b349e749eb66092ff4511fba59b5962cb93cc85515cc86ab0c6b2
+SIG: 9914cc50fef0935efb89b3d64e3c1c3412aed659b90166222c0d13ec1ce3a68ae6281b7efd9d4ec64b82e73e14479f03fbac8fa3abdb41ea4215c4a4d4949d09
+
+TST: 428
+SK:  dda48a0d15a29eba9a76305d360e466e72d8040efe2e89c04b6461315a9b8bf4
+PK:  4f5cc36a809416b58e15d24cc57968cb573b76ad90887a8ef36cde7eca400fcc
+MSG: f5ac19b81f2111a0db0ae30d1513ed343e7f57f7f77d65b8ac7ce3a601174baed9bfa136035976f516d5a870f45db1919f1eb1cbecbe88ec32d191e9248821a7e7681fe3abec11584bdb33de1b4ca94891eb66dcb8539ac41163736ccfd69abb83814dd38cd60381318728052a25cb665471058650ccc75756dbee688ab826ecad4ad5a7db57e8f65f1b64abff82dd53334b797ac40228dd817f239d3ee804a19aeac8cfe33eb657ec9ce923d6b388914cfba2e72bfc2bc3d6f985c0d97534db958eede57b16491ffb755c1a58d78ab377faec0d311818e899260e3ebd1ccd29246fa82d0b76622b2c4bc52f549fee72a30f554f331f36d2a74d999ec10a08294f002b4361e590279c2fb1bda4312ccb24d75282ce7c061a0ca5520c74f6f6333b18c4b541cb6c51e01575ba80512ffa7ce0accd22d14027c53aba1f7437835f1114d68e3acf3ff8de94c8e4ef6d3ab312c91d02970157508f54a5816f467a214e9b1284300289e65f365a610a8ea284666cfe5518e435bccd21627501c725f0b8eb5725e0e06e0cef5db201b48ec91ebf878dd57ce8dac7334848a1bc82c18b065955e4f59be3398594dc
+SIG: ce71bc82d531d0f93b57bfdc2f7316cf404ee09af88f33bf806c7cad6b8ffa366236ba74e75c15096ddaa6e3a62a8f5eb1c8c3f6b6c94a6a349fc7c0cbfb190d
+
+TST: 429
+SK:  ec57b941adf3ca13e77a780577cfd0df5b49edc85351052da34e99f8a9bf3208
+PK:  2859c071978a04b7f5407b6d22401a78efd0394bb966b9a04da6b5ef819de3fa
+MSG: d2bcbd1bc361ab32c66d72fd48a8e227dc6b8d6b150848ba715ff47dd35c8e49381bb4e2933f42cd26b75b14d9c0039282b62b8556aaa11cd691e828382be306889fc9205137b169d3bf17b7f37693fce286039f03809d7d9d98c8fde46f1101942a279c516706f50191a9112f6a24630e1a26c321e46c9ccc85b6ef942f353a642b9e7ef998c0fce2d3a75b999eeb77f31f9b0813a97e3014c3a86e2558734621a3066dae35845031e35665f1922907dbb739786a8b7658ab60276f2d921d1a51230fc74d19e80184a4f10e9e834abc9a36c429726bc055dc8c063f0eca9c61a8a970bd4bb5f424ee4d04bfc295e3bb1f34becbd9920fe2e77fcf36763f32fc9cfd5e465979c167cabf5a1244b491fc06b8946419046ba516c5b233c414ddefb6da04f2e13daff7a9a0c02a518ede57ad9521de64eddf6f49a9670f632d3f7d42425207d053604fe39d13b9f52c8bc292b0076ea42a560056df25de51ad35881d08543224d7fa5d70b8603ef23ce06339d6cd09e22a95749e50dfbd3b8ad69fd30496b984d1c0a199c8594805f38ba44631a2c59eadc6554d19f9bc98366dfdec2a121d0e4814d2cd3f5871
+SIG: 118e1462126b45b8c6803523755c56dfc4e123e4acbb66ba0ba6fe3e053da4119f5719295e0c82ac64d7c5cb1ac898df263ddfd360f3008d91018b26f6a1730a
+
+TST: 430
+SK:  cbfd91d7695c1f270f69246ab3df90edb21401101ca7f8f26c6d00f4dcb7233e
+PK:  513879cf79d2f46df4b85a5c0949eb2116abf981735a303164cbd85adf20b752
+MSG: 264a933f7d0aecbac13eef644b0b53dd53a1280904100dbc1ab87b51148998f9da0b3a0a6337f5e3486c2b7e548d211259397aaa194ee4695bf98c2d5f4487699f7397e5d3a7e6d5f628fbd05497c556a50a4d05e2b712cdbc351068e42af19538901b8825310e343e1a17a1867dde0eb47ddab456d316f3521554937bf808ae4e4bc1c3c5b4756e4a165ad9e8827f5316f748cac6998ed2d2104f268407c135e62f26a922460eab6d851639a00e5f08b34765ea0244f475bbfeac183e3b5bd1aab798522798a08ec6bf2257d4692f5b03cdd0a2133de970603e3251475aad8d934af6b2bfc7a650b91bdec143f8ad254cfa506bbff28a03beb659ef5e5ddffe76e23230c4ccd46310b37dd91fa6aa68167f62a55c8a69f9ed1ec6cdb144dd81ab0bcbd62643420bcae67869f64c0b169f3cdf3c905895b7d35b6fafda25ccf23c3d10de32e7f271e300d39597da8f843722ef08364a5f7a105b9655172df7c82d7374f98264c9cdccb496f2e10fd8262fb1a9a9965b0b841ac0d0e9c1a3d9493ea7aa600205b8f900be0d7abb4d98a06583d2295c276318be28d421982dedd5bfc33b8865d94ef747d626af99
+SIG: f336137dfe6f42a6669b55f74b80b3035a040367f90656fcef0a644c52272ddc39273cd7726010ebcd8a30a05201ab70b8ff97d0288a2cb94cbc49020647390b
+
+TST: 431
+SK:  51a4197ab7686f82f6003a0c32f39d0f2e47555f4e9f8deee75bcb1bd1ef69e5
+PK:  06386df86b61f1f8f4dc45b73edaa841920968bbd131cc5ca1c5294eeed5c8ba
+MSG: 2aedb7e82f1fe4ce469ada48345d006d1b3bff40eb21867f51fce965640c409ec13ad4d52f891bd79066d6b4d944ca868d8986d242b57eccc4c4a488291b159c8de4392be4b86febaa75eac5d22d3c4f8d6bef79adb9b92b4914d5ea07c7f021e2c29f58d07be8a084100bc152d51ca897d7c131644d0895322e9440a8339e1aa390a7f4fcb51ddfb6df48aaf5676337d87ddd85b1d925e1a9c29fe0818f514ef72f747a674946476907a7ca99e9db8d209641057a7f44a317b90974bc86f9617a968a76a6b8387cf5853e608190c1a79f1e1d686e0de22db6cd9aeb8532c5c85cc90b5a018579f28e502a770a4ec675263d0dd781b4fa53c9dbf8098d57b33ae2afbaeb3e68266ad9aab7174ba68c6479883992670ccf3e5ac6a17e65e31e1fdc85e269c80935ef574f20d239568486e7d94a4f724ab7006098b24f3f61587691435c7f29ce4e5ca71b2b1874556433a358c8c5ef3c880843030c2d13d51b78c9bf1a8824e62e111844396f5af2e25c3126ef3626e26efafacf99830aa41212332f378a167233a0b42213afe36d83dc4582a79693b9d571a57712a08b8566d361ac902647afc886603e24283efb
+SIG: 2c072969ff4719212a121938b506c602995b4d02a22e6198d6e87dd6ae076225ac70bb25ef8c0ee81eb6fe953df6b1815949e8ed0506cb012e873cd36cd09b0a
+
+TST: 432
+SK:  b1119c36118b7a065a195bfb8b79a5c287e09bd287c2daac5e6b01164c5d737f
+PK:  88f218ecba99e770ed214a8d01a92a10400acaf1f6eed420067e136ee2c0c670
+MSG: 8816b1eb206d5f6dcc2e4cc391d23209006de935e318152e93fc8c2cf08e26432bad9adb3203d898df0a2e7f1f83dc2f3ed3205bec8efcfd31adc1aca5755db9bd4efe54cc17073077de4a3fdd11996e84b6a052f034b41099226c9c272eae12528f16581b91b812850c207144dbff3e850cca848ec2b1dd164744d7b59337d7e3efef008162e680bd4a0899ced60b171f8cbeb48c5158df6cbfdb26240881bd58ebb8b6a079587279679cb5ad82f371b53c8013804c35596c887e436d23926f994e09d98fbb8ce2704174ef38b68262a7f1a712da0ef0dec639606814b3bdcaf253ff31c48e8a752c111bd7101031cc3d38efb0c9c7f19c59081584a0e015ee7c75b10a4c51ff543a30e52d5f94d8188c6b08e9df1e84a4e2c807170ac124a771b99465a0d38b1f1c6330403c82543582c5bb61b220de1b9e0ef69bdae26023181ba4cc077a5f0d425732ace132ae0c6ff0bb18baea83e8877afbe650fe0bd02093f00a7b5365728dcb66fbb881f592945058a5b350665af91c557a547250ad295e68b4fb72457cfb9d5ea1a7b2a39c9ab7d7ace0af5d51669cb6c2c4c07b2256d10e5ffc6b97c660006313c4eb8d
+SIG: 24ec1e54fc7e722d37551d02cf135d33f5d3ff535773e02991ee85ffd3aa29997f9c464470197fee81dce110609f870b27c18dfbcfd9320548525e93148e2205
+
+TST: 433
+SK:  cbb587514e0a34ffc34cbc04f28c9b4f6465f1eb225cca19b864876daef37d7f
+PK:  6b705d4677d2d849b6744b1ebed167dbcbf645924b1ff2e6360794bdd0e09788
+MSG: bdf7d17c706796efd3489559b527b1c0584b9022c9cbda3aac5146da340d9cea69f916037cd21b3eb1104348880fd5c5b7c65ff820f7499346016951cb715d8df2b41c88cd3c66105458b7b590c21c1ae2f6ea9ddea7470f25e02027d171e0e574a2bb21642f8f9da508e21d8e7335b5ace5935299407bd1b01bdd1423133ef045234e701f55549434ade94a60be1e1406ca5c758c36799ce1703084476e484fb1740530aee84266d07adfb4cc689f3265133a59cdf992fbb9a4b12defbe241ddbf65d12b2fbddfc05af0fb8de42080775bad29c6b0459841cbb648a9a95e48d6e36ac514480a3deb4b36554d8da620808ae9d47329710d20aaa6e5d7f547d81ad30f84c0e3d239cde5b169d9ddf294832d67a8060ba329c4ef39be94ac46434dd2185931d1231f9b6df878a5af0831e0e9d8a08d08069ded6a961ef7f39fad501ffd17d6d9b7c654653c1f58fcee1a6cd803d2aef166c78ef5514a3276d6998dc7c09a3fa982e427c785aa6a9e256f7ba72d5a6ba33eb46f1f9fe9be2bfc14109f64773c00c063b4d5cb4f4f8a0beca92a9a016c4f540feea9c3a31e313bbcbc2ff5eca9967857f5f8a909a29d7f20d
+SIG: 1274d6f356eb641472b6b9e5b3ce65d2654e6cb87d3a83fb49d0f7da9c44be2b532604465f6089d680d2d94b0edd2b6b2b805c5e84c379efc059673d31007a09
+
+TST: 434
+SK:  8bde3ff61a16995ab9d539f6053219081bcaea1d458ec33684fc1c01fb565bfa
+PK:  cd9d782a356e847b7a04c885a9b0907cc33ba97ad5390d4ea5fee5eb198d08b3
+MSG: a1f40ec5807e7a27069a43b1aebff583ef037028c02c859525eb8fa4c3ba95a901ff3aed78c4f87752fb795522f5bf715be7e3defac10fcf17e3fa5c54b20089a472333327252ec945718fb455e3f27ccfdef823d12d406e62a4aeba3cb9d1c61b2b17e49e200a8418f935f26eeb57602c7aa3b3a24f7e6238d3e08d2d609f2eada0332bc8cb12916cb03b0d4f9cd602002586d3e4cc7e0e0381c045ad2e1ee28298ae7fcf0c10f212808565296f158d2c32e8cb28156581af52bfc3470c3c9582138d2255e8426d648ca237d7aad2856f171638558241d8ae3f62ba92db596568edee3ec0ef370f83626aa0445af08f967863660e8fba5a41c8e8ede1c960514a14687a4a81e776ae0e8e777fb0f250d51a83b55f8c1ffdd78df3bdc97ff177afeca046c72d72af924ad0d0ab2bfc11b7f4abded51c3987a8bb94d640c8710e5fc9a4190e8a008363d7419cea17c40dea20ea5156029f3debf05241918f54af5039e2c4cf2ca2e139f60e45cc65595cdf54a67d92b6ac66fc0c5a290495ca57b07ef5750d05f57d87d0c228f7e4e15ad0ba0178730f951c697583481c66cbfcd48032544aa8d50908304bd81940308706
+SIG: 7464df0b67eb90b4b73ff082ad0d60ebfe0660dae97069b52c3727223bf70e29e48711a2bbb438f5f8d8a33bb9c48fe7b628fa8a542ff0b5ae36269d4007a505
+
+TST: 435
+SK:  da59bbc523404f07646add7908294977e46645bc8a38bad2809641a23de3b15a
+PK:  b22c0f21aa1c2d45f4b2e56cc9b5e02f9e31a2eaa367ecb482f874cbd8e9fe34
+MSG: 097106c3624d774dde2551e0c27e19504e6518cc86369ab26ff810969e7de24abc68b4b53f11d945d49ef078eb4f6ba6bf257ff7b608afdcb30a5c59a756fd77a6c1247f6f2a41100d99fc5206af3bcc6de1d3e4968e28fba0123f6045a1b54d693a42bdfa071b2b914b3c3c0c29b2593d07e8bdc86ca42ac555b7dcd9439df9fbd4bbec730d6327bfae4fc41ed498b4f04a0eb14cee608283aaa6e6aa46676bc88aed5d9939037aad4915661af94bb5f6e653a2cac123287073270e0b13fda1dd4871af6a92f992f539df881712fefb038540d41191123b6b3b4b6ff87ffc929a6be53c6cef02f48f2f0cf2fe64a45fd66025cc2d7ee55ebe2316c000855661165e2a5ba41afc2097957b6fe4c55221204b6fc1f317dd3ba13cac39924026bdb66be4542268875631d277f210107a33767f6d9596e25742d7a90ea791ea4bc9ee84a67fd328b80f791ede96d89663e937f0b755baa9d52bda210cee1db339ff1d3c4b000b653b9bde338049af84364e2177f80dd51e2a1672ee555d6317589f6f1d5abe6c2877358bf94b0b808ff857363fbfbe32e97337e4b8a8c221a9e75962a8dc9b5a3d7ca5f9c9b61c73c1469a72bd
+SIG: 1472459cbbae2cf21ce44a15bae9fc85dca40b8182da7d52cbf56ed538d18e03477c140a3ddd0efba43c96aa92f5f9bcdf3481286ce762a7e2bd1e779ba99b0d
+
+TST: 436
+SK:  40ea82da41fd15b06ffeb99cd616dc6bc8c1b21477ea239466088e2849bf1016
+PK:  5910e580bf412c31a87451d9ddf32b3ab713f9e4a22c590c641c14a5dfbbe0d7
+MSG: a06c4e02b83ab7e191ad818cb8187b52a8da004fe838db333c4e02548db6bdf791444642e57fdbc8594e59d7023280bbae82986f399805434bb072c8a27a2dcd5aa62f065bc58b0621fcd365f6cdbf4d57d577d91150301fa48f182f87e8dca7ce45a7d64845ff434d1bab0534ccc83aa0974e88b38fc2508cefcbbc82135b73b384c80eccb8a09e2873cc07129021d81ce129a9df65e613410af950197dbf9afc28edc4e65c3e84da40d2ef841b886bc44719a5d59db2c6dc776401c895e2b3c83783d7817bba68baff59470d6015bba8d975f0eb712f3b8902912805523aa71c90499de689d31ae44e210b8446f2484727cc491b92a8e8b199d628e1df79a28c561e5a7d882e30787d08fb2d5196ba61196309b3bf0c5824a3548c700003fe9913befe12223150012685e90720e9ec6bc4db607425aec531c4fa36086d3b9be391a3f04635a8077a447a16a6fd89afbb9a72d0d355cb0b22d562f43f59d4e37128b3e2d906c8ae23d0aa599c70d3778a076c1a39728f1d6937bd48b978740850566138d34852b63075e89a8e2280edba6f4ee8f61511e9b768e95c78d197b693b109e88818b486a9dfdb74b4c5550acdfbd5
+SIG: d298fcc9a8ecb76a98d4a71dfb01d276ab2d9670a95bab34cf1d8364516d1ebdb23903460215307125afd09c758e981a452da95c0ac2c0b958c6917e6874190d
+
+TST: 437
+SK:  28bb81a17d4584754d52818cd0f1f21baa777e695844a15122ac05344dddc027
+PK:  d5f61d519944d13b84bfa7cd67cb0bea4ef2281efa461f22ade4ba882d11b252
+MSG: 92e84c7a55b0bea03e17cfb65f7085ce3f445b1542bae997de5f092a24ff243380286d137091a598f35e6dae1a1c648f5a494c819dfb240652ff908381f32d70bc513100aca16fe7220295b1c71835f16d9310a9d27a04a980ace297d5af3f7cb7c78b24997ccb41f54ecbab507eb73ea6a3ed470e49590509f5d1e6032a2605db87f4a9b9ec91602583f14e2fe1bdb900ecb8971196b55c0d433489f26be9ca157cbd56572887ba859f39674a8e0ca08f2dbb0f27073551d0b1990685178b1ae9e7885499143d9d72c8571d11e0d85bf58df94e2a74d9b6846557f9125ca0944ce5718d2cbae1672ba02b847c17a6f6b445634d2f0175a75cf6883c62e5b521c57141f218b2fb0994b372a716c4a217434beab75740b8e91c622187d03c85da001e00247312a465225f5d6af232064a427d3018700ded774b9026777a5275fc04754606c86600297bf7b71aaff8b9a746677a3662f3750e81b50166f6237000051ffa15868defdf090057722ae229964a4ea085e0dbc04ce1997722c5bb65d2b47ecb746fd83a9f6a69c81545a9b502f5e76d3130c5afcb1c9af99d918740837ce89d7cd213fef2fd062ce8850f69659e4ad327
+SIG: 9ce45a07dbd28d3f6f1b35630a3fd56f1d548f84ffb1c6ae64b21498ae38e596916e77f79905e609fb1ae0da36138a80f242122167068092cc605796c5669e06
+
+TST: 438
+SK:  24bfd4fc45d5093585678101cf563ab8011fd6430de155f2a425f0633ee3b7cd
+PK:  9cf5c5fc0ccfaeb28a08ba67707b18dc84ea0698ffbdbc169a09c28123e6c2ac
+MSG: ba54128f45be2001dbb060d5dcc47144997415d4294f6eba8dceba4f6cf2234683c4265f88032205296e9b27d68506232d57b688407648f87ceb342052bde9d0065542ff1715c942027e67482af4bc278ff71966fb3f62a2a5323cb1b4bae1e7b8fedcbc73ea05b4076421b0b4fae8bc3337416a17fe124e7ee465ebb38d8792306429d8279a1bd54c37bee8f9c85eebe3afd1f64489d4e53ac5f50657bb6ffb97120744b75d47c6226d5a9c9c264ee3e6a6ded05062ca1006669118454550010919c2633cf086950345e514af3843148e5c64352e69037dfe60d4a8eab3eb8cb54bd39af2f353d5ded2e2bc8b11c09f612e128c6efa41f6eb2c958087be34c6335a43005d11a9d3b5a529c2d1b0642f77afdd8c6b1d6fb2a9dcb65f42f4eca8ea9a054058be8613667610e3eed8d1df0739eca171954117989d1b12189ab57904aa960b0ca85541746385efa985be9d97b5a9029989a9c71498dfabdb813681f57e276b64db491b8f082a885145469a531b7f9f04ca0a2c2f8dff20ccb99c2861f54e5eafa962cc53eaf18d3d5e50d337af485f19975f05930700a8a7253f11f184130d0aee70969d96fe08f216951d9dced52388
+SIG: dc935b60fde44359af8f50ed7f919f483ce3f24e2320c55ba92f3e7617c19bfb54701903ff183b42cbedfef0875f42b12875d36a0aeec73ffd09509d92b28b0d
+
+TST: 439
+SK:  2fc2f9b2050ad7d139273e93e2a0451c7b5cce57599aa6b08d3edc5bb07590c8
+PK:  ffe5a17880d718cc7988c2fd9825b03b93450ac1deb8fbd1f1bf3b8f87805954
+MSG: dc1297990cc027d56d1fee265c09bcf207a9583e6bab8d32478228e0bc305b9818154c338ceec34b04c4ade7ac61dcb09bfac8ade00d1f29de317060b8a4daf1987de409ca2c3fe4380088073ccf485e9a69516b5bbb4130f20be69b2dd6a9b465159cca1ac88b328b80c51b66af7f4c50f6228772f28734693ce4805a4163dff14b4d039811ee3fce65935444a6ea9a72d78b915c9c3b766c60b7e0329e43c9c57ede94b91525ce5a075a7297219772ef3c029649b586a95a73bbdf16d8fc20368de4ba44de1064be5826b376be31a86ca478a52efb98f1fa333157719bd6e0da80ed68d0efeafee5a13bcc3b457525258f1f7e031f7b403a461506927b1e6c7d4a0c8d84b5f3dd0eb8bdb13edc2b514a81d088eb077a52c8a831861feee8110e41a325dce206b2d67d25f90ef57e0fde709f3e5a39c04eed31e57c193b283e2da7279ee3f1eed482b3bbcd373902c1df811ac33e1de06429e8f8443f602019650bdc2ee8d7f650036a7a22b8fd88517511229c729a3269b3a3e8fc72b01b5a4b3e33f5272f3ad21629d08b1f717935e9e104add2f0f2033432bec82e2121d98c9c1a58e0daba25536a1be8e5088347f4a14e48d8e3
+SIG: 7aff162a3c0d28dff41715a974af07ecac2132fc18bc43a198fe664659050da19ae22758d52c9cbb94f1358bb02610a8a351c2116279e7245adf69675dfd360a
+
+TST: 440
+SK:  8afe33a0c08aa3487a97df9f01f05b23277df0bb7e4ce39522aec3d17816e467
+PK:  d004370e6edc34b3e8818667216f5b226b0ff75a58484c8616e1a866444cab57
+MSG: 86fb741f1b9708929195031aa1645fb709a8ae323fff85e5470194452e11b7b1279194b5e2427ce23e1d749c3ddf910b017e4f2dff86dbe482c91bd994e8493f2e6824bba3bc7d7a845f217ae9760b3cd00226d9ff2616d452751a90c3d0d3c36d4ab4b2520f67288171bd3a34b2eacae8d44c1e153dda1f90bcd3595dad37713b8d340156ea90a4e135951ba7169ac175578b81e97a541ab9bfb76328798d7d631c14df2ad613e9c6e1147a0e84062ddba035859d46bade5fadd9b32b43dad483c6b8023b32391e51ef1520c68c6191326c494423080c623dc4ad0aa074748d826c29644c38986a77002f0cab9068e6c9ec73cc2e0c584b80e0bc375721f7a8fc35317a5e240e8c66092fb6305b012c70e17aeaff13386d5e28d06430ca585b0c85b274e7fcbb63e3423a982579e5a64a0262c41908e55dbe43dac1e5cc1bb7298be428720a12e3b072559ec2675d457aaf8f13252e28aad63c1513f5f239564d363c8505ffa4e50f6648c1cb82bba852bff0acb030cbe73f059dd87bbd7318c5586e708618a4f4c9f3bec3f4f07c609eebb24ba878c6bf1e4f2d0fd1450ab94e31755217786fb15182760ffbe5a267cbe998a4ff90a2
+SIG: 63a8aeac025f2dde9a73286e56c2d62dcb79a241ba0b2e2dbaca8752ed2fc8cc7ab8e6600b67645fb5e818a4e82c29180a6b2c3f58d099cb635ce52bdc157004
+
+TST: 441
+SK:  6dc7ccf329378e8131b6defcd89370301068946336b0b762ac5ea51487dbd39e
+PK:  04e90d275e79df5f2b6ef4a31505aac05a69459baf2c581b3ce3db29f0f1fc14
+MSG: 20cebbe98401ac8934c3e65a5738cb0ec0cdc75fdb09dc96312894b187c0a46d2c38f4855be3eeccdcdcc56d926a8c08ce6e748e2a858f53532e7e5fc5f7014c8c6f86310cc26efef30ae525a5157940ab535ed8e403112b08e35e2bb3dd91a9ae8f772d2aff37d8c40d2b5cc887a6f15050a0f5bcf0360c3a9d12d5918655edc3c13c86ba6f4a2fa3bfcd405ed38f871cf7dff0f75daf2c321084ee9fa81211adb105b25c2288f0f2f7f93ef656b2de190122e7a4bfd4a1bd9893a8485b509ff0bc46cc961051c1db5a12490c7e741922ccc0a665496470276f69c7b77098c1e670af6b9f851252996875eb8035a817fa9be07f2be0bbb12025e0565414c817e9421ac700373893862f24cb165f9a271a64fd2305c6672c46767f8f075be5d2d4079bfadc3956288b0215605311b5bf32f0037b7c5ad502013e82ae3419d9d8f39c545b5888f47106c94d5fd6084d26034a99f5dcbf26a84eb4ee149c62a0410d8c707b1a9b071f74ed23932585072ce6cbd33d4d54ee917916f5dfc64d26a498018438b455739345dd60ae0f4750625915cc829ab6822d6f05f6d2bda0a7bf5601e9a2ed6de960371d17e6f43709c9678ca743adfbdb45
+SIG: 04509db003a1a6ed3fbcec21ac44ec10cc06d79f2714960882170316275df80423a1c1a112d881fc24d2812526079058aa8b608bfc6b5e57632240c636d6eb00
+
+TST: 442
+SK:  ccae07d2a021fe3e6ee23836a711b97b04e0a441f169607572731cb08c269488
+PK:  a32265e5328a4f49cf06b467a98b9f9d5b997b85dfb7523ca6a0a1d627d32891
+MSG: a4bf8297d0dc5e4c92bd00ad5b9c09b1238b503d619116ef74260378349a9282b41f3f4676a6215e3ce6d02238480a96043b2942b3feed12620b1fa97f7703b3eb683c1601bd2f51825c450df4fd1f33b0bf9c23c03223789e06e24cf136d3b557403a66981f4b777dcfe890d2ba96da4a4742aeeddd6a611d05fc215694a5d89a5de6760b1d9415155044c049cb02291a1514faa2e77d2ae33d44585bdac6365bf481d9c97833937eab636ed65742a0d5973b24d54089b2daf084d5414765105e4eca14aaadd1053338a8470505232e4ac633345c5cdee1e4653d1d93583af11854b1d9b65fc20281838c56df1148f35ccf9bfe2f3f80ab73f5b791cbed2d920644cf0316f0cb5d3662b9120647da56afbeb47a952953bc1a37de857e4b39fd92b632b85159f46cd05b6abc2338d4632d48e9a178860de8f65d9bc23f24507b7c5629e0bdaac067c476c9c3941d86f788944d744852a61da716f95f3b04f0783a562941bcdda439590fd186b2a8ebf19a5a7e4f4a3aaab7a87a434524fbc9799c9931eb8ce4e34e99b608cac94ab7e74495668df136185f487d9fbcb6605ad725345403ec57f3f6db364a87f38fea4b4c271552e9f2e4a1be
+SIG: 0eec754105447f97d4a9cd246c7eede3fd069018f0d01a41dfabca3e90a741835ea4a9d682342267b250fc1c8c547c89632d9f689af536c7929004ded0d96f09
+
+TST: 443
+SK:  db5d5f41fddd6768709747ab8239bb4f42a31d34b4fa88824d94bf78d3149264
+PK:  03858ce6b2d24079eead66ca0dfe772ecda9af4d46bc9b5edfdc286b95fe9716
+MSG: 67ee03de45c3e7030db5246ee5b51bf298bba3e4d0934937fc12d9a629604c53c070e30d611999a9cddaf2d9acda6a9f67202b352369d48260eebce0e78e4d5ae54f677521f84a7be0017fab278b2b57275efc5fa57c617186fc1ba49edfbd3308634878d864f2da1583ca8d56ce9fae77c462039abc32d0539c0a60b7bbba5029e9329d275683d9c4ce77d0b908ade98b0e32b4420d9aee2cc10e4be922f9572582dd8967141c1d402e215f20aee0a890e2368e406dea11bd11177f2e038aa2f1a0dff51a128d955d5e5f8d5d0009aaa82440a96864d6c697f910d1df230f467f0e02a2e02bf9e45da95f255410cc5aab8d85f449a5de99aabd44fd763ec14629f3dbab1a247bffb7174648e43b9fb1eb0df5e4109b7a88e05512b20865bad39f9ea79d52f5188e7ca5194405bfb1a09727617f3f6c88192008edbc0c6585dbf261f149dffb593d42716e5a5777f5462beeb1e9a56a2c76e6cb735117cc1183a38d1e00b303d174aa9cf5c731b2c70edd79cc5dc96f4018f1d71d7198bbb7d134cd2ff8c15f9a04280db26a8fa9997eb86b133c022eda15d8ad5e77cc9f62615960bac2f9bbc3ebbd198f72c572b97156fa7fa229a98014e170
+SIG: 5b3d0da7102355486be4d69cfd65886c9d9c8738b293cafb23b2104bfdac8d7d01298eeb18fde3ded6491d41b419cc663752c4e67dbe8986833d20e4ef34180b
+
+TST: 444
+SK:  7f048dfcc2650cda59491d4ce2b2533aecc89cc4b336885194b7ad917db5cd14
+PK:  08001b5d40958bcb270beea9baba3387e3a4b900fc42275657c6c691a2e264f2
+MSG: 917519cdb33519680bcae04faa790771ce7d1397c345f1b03dd7625776f3f195809932618b1c64acd93ad000ead09654a33d14f748b46b67aae0ff12df3cc163280f47cedc16a8579034e49884296772ecbdbb71ca29c166233533c8de54012b412ca13cc258f7c5465d83422f524e4c05f806313478319fd143cf5088e69837697d3615d80a7fa7e7443fca65e753ac1b11d8eff3476636ae02d7a20f4b2388dad684002f5ce957caddd2053d0ed533132a81ca19bb080bd43be932028cb5f6b964f008b5b1c1c5993bc9b5485b22bbef701f0a26a3e675ea31122bbae91d864b54d895afdc79ca58d4fe449213353b149f3143b5144d747c5b4697479ae68528485384044aa2c99ba4b17b184e94982269bde2de0b17705d0bfc46d6906a90edefe89195de6bb8f3fb6a374186c7cd086d13d1b3525a3994dc8020e1a00554ac8a82d6047c5bff5e7f12450f4865da161e1a021fd9be8bd33a32bb54a4ddf874512e74b5cfd3fc3cd9ac11edd878433668e3fcc782b97b6d905adb0ebec42c9254ac90f35822c00f97ff3f0c7c39ed3c7cb3920f5608bb45838bb242a52a8637d7cecdcf489fa183b45451c6c9fcbbbf914f5f7e6b223bcb4675
+SIG: 583370971d24652ad213c42615911938fa9aa3d9b7196940e6eb08151200c7b6729d1eff8f4f0904074dab3ddda6af1e4e562b7d6220c1a562683beab268f80e
+
+TST: 445
+SK:  9feb3df88c494a99849c6fca194201477a2fa7564e29fb06cb44c1154e8cea3a
+PK:  c35628ca6ee28ec1c239ddc5bba2a9e09e4846816b143c74dfa2aec1f62551b6
+MSG: 95fb7581bd25ffd442c3ae38a19bea7349c7b7683ba6767e148f0afc15373f67c16d471781202e6da8054ed7fb9ee204cc0f63c210a670a5f9ced4294588196330d31b8e8392bef6b48fe3c92078fae11284b4c3ba20d937e2719de7bf67c00669ad23e61384ebdf8c6e60735428c084fe217fdb4709ccb6083fc0ae4a05273eef739023d34bb73f662dacdf110b6dbd3e74fc1491e8c96596075fae5c36aabe2a0a53052bf77c4462438063aa7bc0c50ab920c9eb288671560ca5ba7af44a53db2e2ff43ca56069ea5517cb214e76faa53dbda100003c4f6175414041be74de22ce155d2281b6f4035be39841afdb96dd89aa808e6865bae62d6bedd919d3e86510b9fa5fedd1977c4131b2b86e0f48d7215eb13d5498ca5d2368f81895ed855a527124657ec9539efe3b2499a3b0b338262f26340e22554c79f4fad2b4e419c70bc1a2107d206456b6368781be4b5e2c54da42d336040fb7ba49c32d752321adcd92986e78bedb226ceac50292089bb579027f702217745afe06a5be136b3998a3604c9ff2acd6fa3f3f71633d3102fbf03047c5486f84c4dc2447d863796383d55f08c981fd4dd7dc1cb72b8ba4435af6abdd74e6f6e6798f1ae2
+SIG: a1c2607835bec1a1d87872fd8ee488d0ae9ed23d49fd6786fc4996725e49b3262118babb4834877c7f78fbeac02df40ab091b8b420dc9951381e3bcda0670502
+
+TST: 446
+SK:  bff68955dd6ae0e8ba85ab0d0cdaf04a9f5befd5ef6014f49994a78363dc17f7
+PK:  0ad9493af80b15f07a521ccd674fe9e5212a4a28c17c74f6605ffef78a4aed72
+MSG: d8f5650aa3581c4d39bd1b8afc96c1ad7c4bf723426f9d7fabd1a5c8ac1d2fe54a971fac765e05af6e407d7269bab661b3432292a484f952c11095bbd20a15d77c41f8f3731a504d518ee10cd006c96ee57372de5bea348ec8ba159162170c63e970f1c7a3465a3d592e1d56c6540fbdb60228e340909646320c95f25698cd4896bdff58e2561e3b3d9a73b89747912a1cf467d63e41455fda77477f46fe6937bb0e79d92ccd52e82dba908a05a57c7ecf49554ab44c0b718e3bdd5fc0bf7070d9c58f860591c18bca8b3a9a148a06548e0f01602b1e6f686037c94ff732e155d52d5b0b44703b3d11163e3f56e3b9c1b86476e4dcbfc53fa05984e8c75dd21843cf96f9e494abbae7184aa42736633e3811aeff402b2fcb7d7f702e447241e22a58842fd6d0c03d33ff5b8c792200e173daa7b217e4b2f4433e6c020acce501b9323aa0241144434b08e9d2469139ff67342208900546200fd971a65dbd6db6c21e3ef9172abba1ea9ea2a249addf1a1eaa3ce11938b13e30913cd0dad491fcbb3285ea378b8ef9227f3fa80b586ecfeae137066f8448acdfb78d6d3e9ef4a6b362df4241ad9ae253b8e1597d656e000cea447a02fa4933328609bba0
+SIG: 9319eef740633ada1af0e137644c61fb3e11ba4b01d3c6f25392dc9367872a23be56310d312efcb91bdbab78a75e576ebe9081972415f562db41baf5e2338b07
+
+TST: 447
+SK:  1ba919c066bb56e640c3335968e1d1b5bcc093383e2d7cf8b5fff5c61ec47a77
+PK:  804c90bdc2b3618b01f075e041fa971b83c5b6cfa3b6b3974f3fa43599beacab
+MSG: 87c5c75d8ad07d52acd781d1bb95f78c70e21c2dd66f7aa44234152f98234d128358a8aee98ea903a77b441db1447ae6ff3432ddd4570f7f58036122c1fdcc93cb21573739c19ccaa411508e08de2606f3d8f2db89df6a44a46133d57018462627e22f57ef36d1de024de3d4ae41b752df4821155934b447b2effe512487521be0356832a74ce0e2d8301b79f93175e8b6b961b1df637d8acadc884543c6864f8025ececec7c6e4fe0fecfc40dcd95e8d6ab93ce25595384436b598b73c74b03d49ed5002c0f858cfd9d0df61ede937cc41659d6708b96fc5aaadee109e2a68846baf2c246dfcf3d27c28bd1371e35fc9412631442ee75f38c6e4958070a74f6e6a220f75c7280eab4737d97e37882f3624811675f16caf60cb944bce92e75884c56483c61f26b6371b1b51237621a06543eb4abea7becc4fc31dbb5475b3deb9bb3c8992387104830c6072afe1af244bf681a40329c9b37772b09c5e88e78f7dffbc04549ffa13b4144ddfa538fc4b3300540ad830215e25f11446d289f33122c2c880de3da71c453d7e88f7ca4ea3d1255e82f4bc9e5533dc401c33040e16940b2cf9cf21feaca1c2c6c33337cf75e1884b483bf801536d304089115a0
+SIG: 503eb7ed6de1b776c952f255bbd4bcfb0e48bc70c2cc2f1f72bf6881479040c47524ec542ae13f6005ca5016b58b736a50898dd0569d4d38ad298630d68adb0b
+
+TST: 448
+SK:  9b36247c17710e95261a7d702f57fe81f2971117a50c87920193b386d494ca97
+PK:  29ae39f273e35fb3f611da091600650efbc4fc4d1e7b4c76aced5a83f82634f3
+MSG: e8d9d53ba27e98edd55df3c6b245eacddc8a40e3efb007bc918ec5a869178a170bb4a635b7f8f742e37ad45d14a74344a6b522830a522106eb960daf192dc1e0fd70f16160e122516892d0e2abd0d4ae0f0d2e5adcc99ad55302e251b3e7a4d0cb33774a497049905c33de1fbbc1ad2b6c645295fe416b4d12b232efe0a33cd2ad8732eba1c3cb0eaeb0b2a57fa03ec567ca29210bf6ff9542a766f496fe68058aa983806cbe7ab10a47920bac8248818e54a41551c9a0959e8994cac60fc868ad48b5a24d5f24a7a5a3fd90b847e817ad3dd5d0d6f8de2d204f642483bd53585a92ef925415a9b38fbbf07fc0f35e707569cf488b205453ce5433eba6fde8781af72b52bfbcab85ead385d9d3175e21ad3373ad535cf0e357ed6b5383ef3829a9d5095b87dc9aadbe0ca7abadf33ec3b6ffd6eb94afdcc12e8d66a6fc05acf97368db0f69565dcd8fef4d1e49d7dd4ac053c218f5240c812d4ebba440dc54cacddb1c39329e5bd0c3c80dc3259a80f059f94679aa0794ca0115cc62af25e124cb8a9d4160eace6d22c7b1c44544f81142a19ebb02a9bda6429c50e783db4a07f0219e857c8d3c5655a582831c8eabc3f19b59ad8d2c714adeaf4039d5cf70
+SIG: 035970a672e93f87eb42cc396f6ea7e1b3dd5c5951572826d1075a15c2d7e454df195b51aae8dc61ef7ab895485f64e5989573d98a062e67ae7356fe5c9e3b0f
+
+TST: 449
+SK:  6fede7396c462033189acd23d2f9d02b68898d35f3a01a798fc24d488de93a78
+PK:  b34062060b2c20076a98fea939b3b3a50451a5f49f8351c0ad7591dbbebb130f
+MSG: 5abcc14b9d8578de08321de0d415e3d40e9de31e1888137475ce62bc6fbee8fdd03b9d47c7b88bbceb804444490bf6a3ccb7a273261e24004ea67cefa3d5d173576d01e38f76c1e0e515083c97e79914acf2be4160ef9360bbe986b36e9ff93346b0e70691d934e47f8a503fa933ab2a50426947cda8e810c9ebe3b36982f09aee6092739fa2358b613c7f129db0dcbe368bee52f2f7f1dfe3d2434605b5afcf256071717d924fd0803bbd0dd1f9555ce834dac781df4cc7aa19e7f11da9fb99cb9e6b9e1e6fb4f7e8dcb2236c28aeb6cbc55a130e03c1b17a991cca1b794e6c13732d5b0a66f6eba860ecb98555aa4c218d112b116bce238295de142741f687be0b2487f58ffc5c12a0a519f1e23793242ef857ed398a20699d4351453fc2f092762abde34f4da2dbe0ce2aabaf6bc4c0159f3fe1aea16a036f7eaecd629538f3e0eed83c9a4dc1abc238f90daaf489fd61b34d937b6f4607a788baa82061943dbab26c1d384d8d49f99348800bf361f871f5d6cda18f689918cec31ad158f1863d13ffac5405c162c32de06e32994cc4106f95bb4fffdbefe7d629ec7797394609fdbfeadb46927370a11fb38471540f951b93c6eb238668dc006c21660ba2
+SIG: 88a83e2012d209ca03b8ebf6de5bb7ef4ccb5e3df5cac78954aa694930e4de82544ef5083c4892db9f05d77bf63f4fdfce15a4d1c3f85bae8077062bec0e7b07
+
+TST: 450
+SK:  d559580134ab050aca446ea7750ef6b371d92d7645ec7635fe7851100bc4e51e
+PK:  de5020cd21a8b32339decbedff24664d9580326327aedf09c5ec6b3fe5405226
+MSG: 6842e3190a110eee96c507d4bcb4c548c3a0ed7b1a8ed77dd93b38613b23c73e830b205e62651921ad8296b08d1e1008ad78f2996e3c7f38032e467cffecd77b8525e243cec021f85296afd545d7be1a62568bb0cfcdb90d614ed798bfb7efc655326816a61082251df01613aac88efcea1e0ea2961b8f921ebe1558dee83374a0113a78c55857ce2055bb2c48badbd3d8f4cb19734d00d0604b619073020d72a99a1923e6160a09946567fd4bda66442ef5a7360786d178dae44922f350ce2edc6af73d1bd80dc03ec3ca7005f4109d10c6d4f7d8fa61735110f8dbaedf91a0bad7d7fb5c04d706373c15c645063ff4b4fbd2d559b0afad432d4c496cd8abfea286fa675dc076726ec522b3a3c2f47aecc539f48a792169c4cc8cd41cd2cb6b63ddbc19373ac9691c2bc2f78f22603d5513715a16d4574e7acc4bea6dcd8ca7f19865a49d3664a210dfad290774b10b7188f255b3be4dc8fa86f8da3f73a4e7c929951df30fe66a17c8cee23e4f2ed2063f0b02ab40372cbe54b9a708df7c48a06566d39b19434c6c766987b3ebb00675f44c4b3c1e9f4504e7a9270589c0d0f4cb734235a58ef074cf9decf3601aeeca9f1d8e356cb2db5fce79cbc36143f34b
+SIG: 6fcb1ac9290ab767d59b598c9a24ecdb6c05bb023ec36014a40d908ef0dc378a4528b3760d889a79174e21cae35df45d427ba6ea812bddca16e35a69b5e79f0a
+
+TST: 451
+SK:  9d4ce975547876636fea25437c2880c9aa8ee6b270d1b2da197c8d7f95e7dccc
+PK:  bde4993c030477c35890aae82bb5087e914e64b94ffc64e2d7a5a7c919e2d902
+MSG: ea0fa32a4a288811301b9ee533fa351fdfbf6bc1d0555a7402767a3a9198558f74bba7031857995b9f326226f1dd5df107b06342203eb8d40c5f1dc95b4f3f88975aa24af8769e2670c46671bebb7a0f1b7568729aee477e8988af9c749f3202708171fd94b337ae67ed21a6c44174014b0b0eb5ba71c277978d488c24c4a7841309846b4e30a4fbbcfc45078d7e14014114b1ac64f7c33c9ac25ea5626c2c819fbaa2a4de8a2bf5f1365d6b70407e8094f99197ce1f0c35e11a98fbe372414ea2064a3a12d1cd5c8df8fc0e79f5b770b58f477f91976ca0139895120e246baab5a026f2d39c687dc0788334b5c626d52cdebe05eaf30864b413eebdc5581ef00d439276e52f479c9c05b116395826b60490b3ce700cc0027f61e46ca2f6fbc2c9de2e800806550afb06d4a08eac7a758e24582a4d6d428b433d365fc31d4444607afb64f15e370794005a3a2244e666d5d4c38ad2009c769a51cdbf738d235942f412d07feeb73b3657d0b0c91cb5940bad6a706e14edcdc34225b1c1f38b1abecb2adcaf819155a94fe190fd556822d559d9c470854d3a43bfb868dadd6e443d98ee87e4d8284f5cf3a6dafaf295b902836c640511e610ae7d0cb1b1d3d6079fe6
+SIG: be17444cd465a87a971df84eb102f9c7a626a7c4ff7aea51d32c81353d5dbc07393ca03db897d1ff09945c4d91d98c9d91acbdc7cc7f34144d4d69eb04d81f0c
+
+TST: 452
+SK:  0273868232f5be48592cfa05134e8d5554ed1f9a57bc7e3982a330c57e5a7f3a
+PK:  f172208782db66d466cbe4f4417f6fc477b7349f2a98db56c03a47227546bc5a
+MSG: f7a1d4614cc64a3bc48f00c6276304f34d4dfd15e0617b93ccef126c5c638c9d9953aabb7df42df4e0aaa7eac96a4b38c7ba758d860c90d05e3d14e479e545f319b0e5a85ad8f0991b43d6e49c24fa060e3e5df95c98d9451ab833e12aa97f404611bba359496265a6db11917d0da5c6a702d0b102de36dd0c98df5b54806ce626bb96374475f68a6060eb350a7d2aae3204b3dfdf9f1e31be81f7170f8a1b9385413ff8f6881e10c1e8da4c88afb50639ab44887aca2abeecedf110d2958c13fd3390d1b96a762d16ce196920ce85f6c415bed545b1445302a6f001eb8d00e97c751887868d481a0b1e4dfa04b6f761086ee8e697b019e017104bafb98fca242e334c6f18f1db5b6f295f05c559361c6831dabc42c2110703f9d1f64e12ddf26a8679854e9f8ef8479e1f12c35447aac02ea7f242e58632cf2fd063fe665070445b80f3dc6a3303bba96e05fa88eec201c5c2d00ca81b8da6969d0a4dd0483b3477d325a71facd6fa2209b48cb4f6525da73c9c05b2d9789b01448e1527e56a09a9bc6136d9837243c2077b925bbb933f8fb1daac963398c5802aeda3bbca8ae3b8f4a9a871f7ea8e2c0ce898c566217b5c06ff55ff9f4fe78398ae7973641eafb521
+SIG: 15e8d8dc7d5d25359d6a10d04ee41918a9c9df4c87be269fa832434d5301db022481bfa395a3e3466f9554ceee0532a8183a0d0550e7d1abe99fc694c6ff9301
+
+TST: 453
+SK:  336a83b55abf4c02e25e540329b5275843c2ecb8df69395b5a5e241bd0d8c10d
+PK:  dd60569844570c9f0a82643f446478b5ac6fc542214231a7ca656a92b5fdaa54
+MSG: 9afee8ab482010e29264b406d9b49453d1ce6d550939072182863e4665284ab05d86258e0623b18754c4785238f697f075adfb9e1d31a42e85934ec071ddddecc2e6c2f61334a79526788b4952190716906dde17fba556eea4c8b59727514f6f5615a19ca36da358fae6a6c54f7f4b7a929e31ba7cc71bde7882fa9ffd87300136409caf3ca64eefea616aed58da5dfbf28b668ec1cccffcef6e2e14f8109e9cbf76cfa414f91ac00f48e93eada385dd3d5c16e1a39ea3dd55c761fca361b428f516c05e694fe5c3c345cd94457187a8e604b200a1a0f937ae89f4d6b5421dffcf7ca15f2e2c25378a4113233f7613f4570aa4b909a9135eae4c7b9ead458007ae17126a11d145258af9563db2f7e8925431878b0eeca8affc01ac5913bf5bac4fa3a857c54cc8906d6af77de6b9326b6506151099e87e99b1e819c6fbe082688f34b803d588e416d853169765d62f7e0bdf72c5cd66669a0335562336735e7efb734a2fada327f858bec602d0da08eba4479e7f6dc4def6e4ebdbb730ee91a33445cadc9df52c825ad36149cefbc51ab102033530814bafa7e87961b06367ff896f08ae334a9b1aad703da686706c11a04943ea75e12992dcf6106e372077cd0311029f
+SIG: d263f56d59cb9b2896a947267c2ed78a945bac5abdbf3c14dc3ad092b2308cb9315c464942a0a20b2024511d766e85c936499a149cd0bbb209150a1643265200
+
+TST: 454
+SK:  88409172618b490393db27d960171cbc187eaf4dd8b320b3d2f824980043718f
+PK:  ce2e7c5839ef5632a123dc373dc14b1f0505766e9675407604ca7cf54e8d44b2
+MSG: fb3e82f11bc286267e123817ad8864e077d9f7a8e7a163ac7eeaf93d55dd111de8083b66b53ce7bc771fc5071a2d7ac2f85d6fc6adcfcec446e16aa1046df37209ad7a29cf9665b439a54d6f8d942f89bdaa56f2f11260cc95993038b0e8fbdb3214f142e6c90b61a1d2b142076206af30ac35784a6dc15a1e79251a8c7731a1c53978038f8d76d70c6c1cdf529fbdb84d1507dcffdd42873dfa6a8fe6bd6f7fd29c80e4b2f933d2b6c9e62c9457e665472655059b63b618e2a9a8e5b9e41c3646173a892b8e6d4bcad6a62a6fccd3455890b58ec2681a95cc9776a9fce83c54a9ef312a331959c7ef3f79ee576eb7b79469c9234b1eaef609884708fe4bb0efac662da871ba61ddabb3fcbdeb8f635657dd9a5d7311e639a824858b9a9868d3f9384da612c7f2e771a46bd2624c99ea2b6ccbca996c1d9c375554f2a551619ce6d5e6e4d6b844a4dbea83ba732331fcf46572c1fb0e257ce1041b265df02e690a92814bbf3b5ecac69ee998766a02b0d2f908b3c15f952699616f2c07d589198989e6056c16319aab6cf8771902c078046a88b2570c13bc5edeba2ed1e3ba131daf94e6891862bb3de7d1063fe405307a5cd975693e9d58e17c690eeef4a2603cafc68c2b
+SIG: 93b6e29d63945d5c427387d006c7f0b01956a95fc0436ed42b46d0f17b5bb193ea8c0ebbf3d6d13bb539e35c91f3f0f9fa3414a0223c9060bac83653c6fcd906
+
+TST: 455
+SK:  e571189b5cd9e788302de3919d850c227dcbb615022e568bdaeb37ac5b2939c5
+PK:  edda890f42dd5fbc7316a5fadfbec38556f23f51b8efd2625437f6b5069f1ee5
+MSG: b62c867ad6227435bfa6dab830684e38d196e1f861aade0fd6a7699b6d60901fefb2d799c35c6f3d8bb94deee834403981866bab84946ae9476c75e9f1d3602b42cb2db437bff33a775822f0d6a257d4b75400eba5b8abb314b71fc6b46f8a34e861a9a62abf33de8482f63f9d7169e773a2dcebee03705dac117fd1499b68e7414f51ff9437f253a1d9901ec3b0bba86965a19383655487b58010f804909de1ffb2212c0252ddd9bf2a56ac46bd59c0c34dd59e46598b6babd4e5f3fffde55e48dab0398c22af9e26baddf77275e5f017b35a9b8f8435f9631936b391cb95d7adf35d1d8545a0fd066412d508967bbe9a20245a269e3be2777117e75fbac170dba352be69b254d353b3b2cb3b7e21b721aa9fe044f8916b4b2a6f8c28f8abe66ac92b91323ac73afd93dfbeeaeef26d19bd9f67e99d48cd2ad2d3e55e45d24d54b50f44a39b90e242ebe9b42bebdb230c470bdfde1bc7721c3120008477393dcc2e15fd22b251feb0e18b02883c078aee4fb760655a671dc7b8aadb9a562420a3c2efa2d342e1e0099d951b42242984f594e6914fe282b1ee128735984ef93a669e6ecba26c9fcb9f09f09256645617f1392d35908917cb8d29e0897c7503cddd5de1959686
+SIG: 7f797a31715d7c356f8f1f783700aa9974bb936d661661ad968c7cde1ac9e767be56a2dd49b9230e90110c67c0ed187cb7e75c3053ece844984d296f0d85cb07
+
+TST: 456
+SK:  371744ab63c115613929a343709bb019b7357dff72d2a149f1d0f71d3a201efe
+PK:  e58abfad4a13859f0acb05d0e47d59638f7b1b4936100b988d61e6e70e22667d
+MSG: c219de1e8d7ad8df08c49377396fe7c1f2d57bd2170633a00d708faadee180ceba92849a7778506cbb366875bf9124701894cecdb3385147d0671843922a649aff7c435eb5a9c74927503072d0067978716dc80be1545a2dbf5a1c38536e12bd7720c1965d3803a4e8aa55765192a13b705ca1059ded0e806362fc5bbe6c76a1c9674bb853790f7e90af00753e00436da48cd082ead64fddb689890162082f8482924f33acd604640f69927352b43f64402d27a883fa6b72aa70d241dffaa1701a25cf1079358260793875f76a2978e9f9f9d68634eb3f5f01bde1ce49e5921252f949f082795e4eafed7be5b49a9f95edbb4a13532e3f3b3be62e2652231253a20c1d5477e8f4bc57ed76fa19eaf03a11bba429b6496ce76246170e043bc14f2d2f703d968f1deb09388715c37cb4752da8d464e348e0313c8993e24133a7c545284e3c9c907d01b260c4883f9cb3e3dc5b6f7fb6d75536365f2132eaeddab570e7273afac0bff5c9fc0b820f2078e0336052e1fe7bdec86674d0998ec78da1c3f34751f886727695f35eca1304b14734766ab05c1186306ded9db3eef65d3c0456cdae8181afee04b296c6722a88c7ef3088d26f7fe74bc89cf5285c688f027b7e68600486af
+SIG: 5eae4ac72af0174ab256527b7cd337a0e5482e615af068db21dae35a64640742604df73fd4ca02ed9515a5608d73195230fadca7b426f02a2fbfd02061af3600
+
+TST: 457
+SK:  498b6ee6492d53231b3532d193578ba75d6a894e2e530034e21ab8ad8d2c0d1f
+PK:  d124665b28facd2d17946a04dfe3d129a4561a2b24eb326d84b62b422e44dbcf
+MSG: 0498a59b87cdae28695547e10863bce804d97de0ac8008f3d5fb652c1757419fdc9e0f9736f4c59a34f21cfc74599fa788fcc10c6730c7df8c3d2c1b6a786d1230b65585719d1cb5c490359b94435d6dd671f54d6e9a19b9b5aaad7e0f233f8797df997828d88cd92ef089ef7dbf1e95277894a2f7c2fd0c8e4dfdfa6d3d14589ff01916dbf9ddd811c2f5e01e94298990a145a6cfc26895614c7c963fef308a4e3856c32dd3e359bc56d2cca496ad199ff1a568d6430ac5cd208e0e2d07803ca523e0d813ad3733ab50bdcadcb988aee758ea50439bf38ee649997604f151c602c82900a8205d8f6f670c8684bf5abb5f75ff29a37eb9bf8105199fbbfb4707e162e64c715270f853e648b0aa26fea0f6db562896bf424a9ffcb292fae85b76cefb8bd5a4b3ce1fb39bd2a50d0c9e6d933e167ff629b8a494f2a9b774eb303c781ea02aff1a8afadc2465cc616968015ed6a5a33c3120b945ed5351981e32fb9fb96b2212dcf8fe9ac56e3cf41dc524f800631020b025919178ce074eef078d6842012a276efa628db54058d1eb5b5b705f1e1818d2df5164baabb0c61956ecdb8c706e562fc4fd64052870530ae425b221f89dd6f90dab882e763e7a7ffa141bbaa8bf7a3f21b0
+SIG: 112f5c6d3bcb3dd99346d32ad69cbfac3e653bef29c68a33f43231f66cea1d0a195427d6e10c0e77c5d55fe2794287ee32e5e22bafbbd8052ad3606b90f94505
+
+TST: 458
+SK:  cefcfcd1cff4d8910749279131830b1da19dfc5245f78ca68b8c3c1b622b4551
+PK:  1d394abd1b4ed1aedf966a60efd3ff882140a7e56b428374ecb443289a9c7f00
+MSG: 5ec94ed06fc1257ae9c183ce56271207aca37a23fdb4b0e74ac9307a1bb112e05ed5a5d047c93109e2e59477b03378346422de36714c2961bb9736a513ca3671c603a68c2be7317b1b52a076dae2aff7bc88cd5eea0aa268faaadae539c938bb4fd4b6069b1945eb6af0c9e6c8aa5ee4a4af37e90c67e248e8d27bd7f9589c4d30e905651baf45364fa049957ea5d9b7146ca68204e5e973d0f1c91a1c4bded66115028a71114f0f4f851bd115faeb954e3f71a01470b2481a0098d99f9d74898c8ba0287cc7834155214173d1fcbafcfe9b08250384439476055883833816c9524cfd5744aaa259db7ebd3a6aa20b5a6546dadefd140668eb0eccb5f668db9fc62983df980850c9d19882a17550d5dca3542cd36003a0d03cffb04575a3e8e1d07015c7b30eca9115cd2b72e46dfddf6a4dda1faa2dbdc89000d433f6ec9adc46146d939f32121b99b28983d98b9dde8c3f6e5779f2b0700cb023db13de656e0aed1da2d5c6ba2652343648ad420f6ab9e55a97482a1a22b3bc2ee598629abad9547edb5ff790990564bd871f81b24b12f2bf8dbdfe7a88375fad9ccbd9fc0ba1d3bba5e3c4813c18a0348aad83fb1b82689054d99b4600dd1760d0dcce44757467bec1946406d530
+SIG: 7d83ff66ec79307b1c0c093fda3968a96cf6044f5c802888584018845e7caf2a135ac6f1677e84d22e458e227e4f930209919bc11b12f7aaf2b8c94302d64200
+
+TST: 459
+SK:  d107cf26f527db71a206e41d17955321013225bb20f93e12df3dc7399e720ca3
+PK:  186bf453c95dc0a2fd589a78e2c80040b3f6ddf9a6f8681d146036cf2146e8fc
+MSG: 78eb9e13789928a74f360141728ede98389685c836b91fafbf1a7e8c19cfbe21bd3c3d6c6ed83c409ef693f1d735da3fa466497e19f38e30fba2a1023785459070e6e92c1cb7c9bd0c9ba61220157866c3bed2b01e6e6b9b8dd3f0c47c02f181346a0a9b9b5d3d7e18a94d6956855e16e8eaaaab71b10302f35bd8fb1f9b5847304160324926645b0582c2f2f1533a24281461514241db2850ef31c5763b2e3d4fb18fc6d8c1d7e52f7c13392c17e27019ff60008e431f1714370bc0efd9452a61f5c56488d91a185037f1f647f72fa785010d5d78f0a11587ccf66b8088e0e635fff3774193b2edeffd92d6e8a0321128ae64cdb862e631e2ee5ba0da44bbd589dc392b5a113b86a727a8ddb698a334cc668b39b1cde199b88837ca5f00f553f89c622834273641d39bc10c6a24e1eb42587542f03fc1627524ed6b749391f11028706c42364425b2caf20180e1b802c744b49b7bcd9bf7b15c23a0bf1c6965960d341554e1966b6ef82fcfbbe41d1e09d741e309254446777f13c29a67b8bdebc5f7f04d160d60e332e3d0441a0f2f7b192c3e2bdf6dadec2a424f88669806236ee04dea692bd8bb6f91ca0682ece349142575358b9b7be70600b3cb81e1456ba0799fdc01ffd68623
+SIG: 8071d97f324f10358f13ac8c61d424b4f300dd0419571c39e40d99aea5f03140e62ab4c97127ab33e98269966ae1d4557e459bf7f597b313f351a20122f0660e
+
+TST: 460
+SK:  af7ea8e41c8937a4ec475ad81371a171d3d0f9fd7519a04c751ed4ad8ff8fef9
+PK:  15dfc71585bac71ef20f374987c555a3f2f07d6b9c787066c10d63cf06e02ab0
+MSG: 05f2263f0245ecb9faeb14e57aca436668308c8125df3116c4ee20501d0cde701b366e2b50a1c5edf484144ce16bfb1f7d26dc4275ea9732e264ba4d4a362b40275ba47377dbc332cb65e2f4c8853894aa878a4c175dc5b3b2a757ff3c8d7de660973b89dadf076e2e4fc76239b7bc752a229d44e000ceb667104cb0746bfcf59d69603ae7fc1bcf11d2e33f61dc497ec1b0bd5e4f1dbef435f2f291f30b00a85e833946c8b10484e4abd7d60bdbb1fe6dff5807a53bb89382153013b70ca08efc91b7e9fc5b5dbbb6af123b57be2e140fc471a45d89fa8284cc27e0a1fe771f55598bbdcf068d506dad0a592179ceca39ee9526f9e4fe47bf2bb14fb1486a677d4d7b99a520545676a0f1fa809049aa2414ae7b817d9a036e5c157886e8341d4e819c092a3b48b3606b03acb727c6c2217d0af30121546a94af6b49caa2a8c9b1786fa0c2a524ec7a023e924b5f8a89a53780c7f8781c5b8e869430caa0e6d0437967e3aed44f45c901cbcf1026fbbd4e3dd9a091ecf8b34f7dd5038e543dc7eb6ad5494efb145cf63ec0d355bb8e172f455d8a6b13dacaaddbc56e47de3cf762a1a738ef092f1436680467b5cd82e9e36e2d2b6842b3bd5dce77180ddaf0b643378e698599dd47f5cdbb
+SIG: c0f1739167274bf91831c74beb645af790459b28bb3f21325365130f409acb66df1d223759a9758e08fd7253737484e285a6fb47404abe2eba5ef249fd025c0a
+
+TST: 461
+SK:  0c57cbfcebde10ede02d1cb01df360d41f2e66a50443d58b5d4f0828c9a18bb7
+PK:  c4d761ba189971b9462c61bf46a765f88e2ecaa5bf2211220afb00ac657f7ce5
+MSG: 337703243ab5b4e4d3481ee8dd1f4494507174412658a93988b5c30403a7b7ed8522ceb46fa1ee02753a874ef0675d397c575da0b08caa8cee3393784d0f0db8459837af90b9056df4e38e417f3ad2eb1a100ef207ce2ca6c610018021661e307099f2b7c4ae875991140bdd3f0f99ad2c5d55aacb84cc1cdcd579e08072b6951fd45ed289ac9ff7f0986ac88a4fbb9dc9203d9baf180c90edf937258c9d0a6d48e220f72d250c7f2c777eaa7fb9fa11d50a5798772f9fd976b00599f1f0276f3a2e4d988ae92125467a8dedb7a16f9e3a56e8d00662b3eb67a35b9b60e73bd935077ee238df8f6e833b9a5523386826c1f2917b1c3ec98e0a5fde89c48b1d446da5d0c885fef0e374bff30a997c7bafd5e743c85d0c6aaa6ef10a061211a2327c6d84eb747a56e9bf60fcd5b553b798834d0c5ccadb9d4b54e7237d12c679c193a287bb2f511cd4ee2a2d8549b44b21c11fbe5723381c6c5f784687fd90cebc5b495af9e414f2961b06a1c8433b9aa3292bcff4241c227167f8d1de054ba33ad81da3eb3ec6e40a6e26854af349540171b75d75fb9a8d12937827fd594d317b7a8d9f1c2fcabda56375568c3e9e514c2efffc3878363dcfad9fd95436b022e8772a88cb71e803bf90381962
+SIG: 8af7bbe01b8ab93951d16fca05a9c967d1c52c974bea151ea72e4cebaa20cc783bb61d8d69385cac5bc6d72dbd162beef1fcb5dd0e0a08b48ca0b9f6d9a9880c
+
+TST: 462
+SK:  fe7172278364194bcfefb4783142b79f59d5fd978b1e47c314d78d4cb3f61c8a
+PK:  2e82cce47910c7e2a79bc1f419dc3c3df54f23291fc8193e8258ccd2fd38d548
+MSG: 23509451a059969f2b4bdfcee5388957e9456d1fc0cd857e4f4d3c25a4155d5ee91c2053d558062eea6827950de863bc9c3df9672cde8ba741744ebbddb45ec1f4284570fd0aacd07ea58c581be2afc95ae444e678edc2a02439f387cec982ea3a44814a8a302bb3bfe8228d58de039debdf7c2a7eddb4e71ca474f94f7e2bd89dc65b1610733c91fff89bd499f40154a6198fdf5ec7ad3722d925b292196c429499075be0c5b6da9c090c0791a7019eb5e7366be6ce58ab2f04fecd9127c42718047bf47030691521312c0877aa3f36cc5fbc9caae0fde3945d2a868ee2502a3833208eb850a163cfcbf6da9ee6ad9fe067fe241986fe4436d6ae4edc61561938e2a33f4a33db63f69d3f1a8850ed40028869164103488fb795cd82ca067fe1b4897caa49a7ca9a80f3a8151fd13bbb7ff350e8579f565dc1c4a9ca938d27b15b3f858ef45d3dd78b2c358635356315f55a97528ecfec5d11a5b721503107faa406c17034e601474b3b60cf48692e269261158fc353d4df4274381357790b7756087b00cc79e3b9d28a3f2439febf199e64a8b37c91b5a4334e3354e8faf3a361e856c54bdaa43bfdcd6ee6c9f9679588f6069950832348aacba2bfeebacaa2071ddc7d77898ef0f68793cd25
+SIG: f6c2a4296b9a3407c6d7a5679dae8666b503d1a17eacf71df493791b8ff0c0aa8eed36b327a29ab7828f46f22de868b628b1cfd501e8599fa31693b15f61080f
+
+TST: 463
+SK:  a951e4e6ba9f1f0b354831c986942448faede37e11b0f247da2706dceef73ac7
+PK:  30362014974bf75c8495c2e271e713d57384384d0a5da88edeea79279c0c58ec
+MSG: 20577dcac89174885eedb062489cd512fa72863ec5438e31e95878b75ce2772aee6290a0ba3c8f642c1d0ef55da8d5bc1484f83bb9876c7a8c0b6b609b94d112a06fc83ce8d2c1e08ed6c735e57b244aad6ecf7075363d565ba47865695c8423510909e0a3db4b61ed7aa67a7471331e83a0c58b8220a6245f65661549c1a12d4c0d50c326fb94917cbd07be51e83fe8bb3e46ca01b0a260daaf1d6abe3703d6a925113bb4d57ea1a48b4c7dbdaa03eea814a4b5f02e1dfb545cc623fe17a3bb18e4373f5f7ec2fb5217d23e4fed54a772e11323e730aad7efca8c464400e7679055fcc125a876ef7b8b9de186e229a7abf191d0c56d91815f67872e957bfbc7634aac403576a58f427bdbb30e8c4b6fc6c447741024ebb503a5a9025124a4887f825a43ee940f210a1bd5ae4f6732d60f95f2b83201c4c6dfe279412d7502a5211f8f48f800db30fc3776c4ed3a38bb4634822c98a6d6dd3233be60e42cca45a3163cc84e9e8da647c0711bc4c6ccd65aa1e972c07404d103e74bcc31a7e2c3eea5ac9257ab428947ab3dd3fb153d90694a4073373c4dd9ceb131154fe877473fd996f424f33e316e4eb02b8c7513be6998e516cbba54d94cd0a435e0ffcc2c0a8ef72b630ec24781066aa5efb9
+SIG: 0278c86a15208d9be5b1e1574761861b8af72ae08d40cdcbec354e65a9c3d0a06b5fcbb297d09bef397462395986c3093eeb22644c003c3078178cdf674e990a
+
+TST: 464
+SK:  38a9b2d49ba8b82f301a5772cea0efc2218455c8b218b22cbaa2aad2d7ad3b35
+PK:  9df5ea1f78f810a521774602bbba4942f0459238966c8bcd21900afbf3d84293
+MSG: 1778167c49b3a44d4a5ba838b7388553b1e13d36ea4f86d30242e1a822a3bbaff5cea63e2ae2a4635be236fef2b8135d14fb621c0bb773c9c17753f80926eb55d0f115bd09a885d844b818c9f04489a331bb5e032b8e58cda36949c5a8d08b55bb8de965e1f90d3b9cfeecfc6ad9a4ee5cb4047e9450acdc64640166a8c069ea849aebddac1ae4afec91ddd17fa5553fa87c56f7e51ec1cd6b5cc23351d057a4ce4a8923c8ae6ac7a8afdcc0881c0e74ebb024ef7296162cb93c68e50bbb074e651ac87dac9ea59d4c3fbf0fe379f3e97a24566ecae54303bcfb6f0cc9f15f6639430e66b19a427849fdfff833df02689e9de44006c903c559183459b9f4a97f54a0f2a28df7b0e9deeda8239d7b516977f5e7d6971b4502e9885f750af8d1a6669e25e77d5f327c77c87a86e0a1872bc96a76060f5f8a0c40cc973bfc7fe6ed9bca78f884e6a2828b94d489d32a0fd337e69db83fb8789afd4e8ef54c22a78c2587468b9ae071bae3b202d3183ad5f0f8e842e5a8de85bfff49e03c8381bca7fd4278ddccaf0134fb5593a395a77a5cbd434593bc4ad0ff4b8400ec674c4ecaf1d57754be0cb2fa9a6441a9abad7b42197ad82e50827e4a4245573a8f0ef87f58228a2867f4b3b834b6635037940a
+SIG: e19e62ac539a9ca251d12d4c71055b0a3f581d19f2682e672404c78ac1f12bbefc91519276a5cbe16f520cf7a7f687a240f0329157c59f50026a58dcdc50fc08
+
+TST: 465
+SK:  9a1717873689a03c112dd6b4d76ae73b89b416a598ceec209e27961e7bb1ee8a
+PK:  eecad1e0e4b863291881a8c241db9ccfffe4e55d8b5a42f307b4436acd0649a6
+MSG: e26580470901a07ab0931aa23829802ce04da59fdc2f773bc567f1e65b4f2e2d4a1a6aec1f54158adfce9b099790b503a13d22097ae23ebccf923f3bb1986d6e49111a8cf0d4eb8236bfe0d7c9e93a5efc7feb8e6a9cd1b8d921efa21e449ff49e06c1ccfea31f93e033c3c2a54ddb0f653a09fbd18a70b56315f193e7be56e5168f59563821d4bc3bbb0eaa2048286bbeee5aa3f3e7536cf2b750fd322602bb3847ceca39b75474322d76b1de80fa2eadba152d6f8f020d4d931c53f0a2801224d35deb6ec13b014873e689903607de96d9b7a743a887d2f48daf2ed2eefb202abf6082796981123b966e936dcf3483e2d24d694ecb865fbeb6969f347027fb8b175d24a4c045c0bb4ab5e02ddcbe77d4756c46d137b094473a02307a108340acad9d03bae8403af199cb75cae3162f3815813cc68bf2a5e499e594921149f3bbd214da5137e756521559dc80d9a4b74a0f4943022c7cd5fca42315e0bceeae9069615ce67a04382412313a31d67b346c329ad82e742c0a6ce0a6a02454c113e52022f3cc03fda691ebdfe14c53c8ce5ca9b932ca1a386e3eb4e90a4dc6e8ad8533b5af1aaef5003128655ca64f67fcd97c6ac803002404900bc0fae98463bcc31409f9981748789ade2d07783bc32b
+SIG: 1af8be095538965800d8eff6d723d028d65d0e9c6eb5e9d125bb3b1783f11ef7079a49a807e27ef1260be26a3b231d03b2ae151e49f6f189f15b1c83eab01c02
+
+TST: 466
+SK:  43bd924db8156008c6b3994a8130d427d514db8a613b84dfb0b8e0de6ac30676
+PK:  1b3461c269d5b0062d5df6fa654a2586f647a0684218a06e5e2f7badfb394131
+MSG: 6184e6480c42e96cc877269b16371545ff9523c45ea88e76a1348c68ae7f318b088fe4610928239185b6b55bfa0f43644c4a4c97c56ed77d08b1f4aad2f4aa069994abeca96b7bf81b8064ea4350d8a8b02297a51308b61c57c8f1873c6f97007aca3180429e730a6643f28733547bcf7b9adfe327e85736bd04af7f1d9f4fb84a7f3affdf4e22b574ecb4bc8836b10b8453aeaa5c1bf132248b826cc5230f75e075fac9f037561136e00643d08253e7ad652f702c0d15b6d7d48aa6f8e9b5f5cc146e3f156fb2522751c3710041bd922f37a50377e028b0c4e4bc3465d7c84af6a5fb427acb3b41378b102bda46d8f6f203a5ffcf395d435e93458a0b0a4c2e7782fafe119f769f67058c6677f6d10d9cf5cb8748e1805798ed233f6f930eee0e5075bc58b97af9177fda75d53708beb04dc4f19a43e768074609f14065f48fdad5077ce109bacc357174a6b7956f6e7f32e38415be526370fa58c3c0b31f51e6cd4b2cf27f8bcbc21259d9e5c3b5c2946a9fc1b00d9d15c3b7d80bfd9d05db91d249d3e42d8956682044548d83bda8d5cc9212442f30b45cf4aead80cce9b3512c39c5c737d3f8d747afbab265af5eeef8ca9362ec76e943b0a0d7a39f3db11eca14458a7b592e5e4ff2275dd48b2853
+SIG: d2a05d88d9d543d94d57ec88ae55681750f20b9be9c1e918cdaf457767f2948dd629e94f068edcf3d9927e330234badc3a02fa5ad3d9d85e948cb0b0cb3cd70a
+
+TST: 467
+SK:  8fb086206dd95a2621f598560ccb281f8273c8fc72e23611089baac89d3c3c78
+PK:  20276ef479f4d4523ab77420d424e8819c33c83779ed80c7f666e8f4403f94d7
+MSG: f02903ed4266e849a4485205954fffa8a108c323b7e3f84331043514e48556ab019497233a5a127bff3cd7c97086becef538b3f339d7d06e532dc7325e597ae357f816dea42a6a22c79d22074a2e1ad8023c424b7e096e5ad8897b05ef7d00d30a04aaf2981eddff2b347f1e27e20aabbe7e7a9544978e092b00cce420aba06187374ffbb37b4c22d75f04e57590f610a27347286c298312a6c9b1bdf24fbda8513c4f8356ccf757068ffc11bc65113783a5dde7722faf4ceb19fbb62f40702e2c6e6a8bb49ef40446450c4c59a2990944da4744f6ee770b930c246669813ce5a9f5a47dd80388981bfcc3a56b5be2c4c7e659a2e9182dec0aaafe9031aa3954d4fe7c431196a561a5b78eaba64f3db1b586c53b16f679a84921a642c260e4653a61de108ebde6f7053afa2cb3f3668ede121020dd1bace8418aebac3a5bd5142f105ac26fe49e5fb140c19b22d54a6291dfc954670247881646874defad814995519f6260e9774a8d185c37881b4f2543c4b63fbf1985016ab41c4d728cbc90b3ab876267bed41d0c0902f6b50e8fa906fc4788f7b820467306e0fe9e036a0a00f804f91c3ca718b95ff6d9e2204bc3161bf70fcc17b2964b56bc612e29402d96f50986514bc7d831d58e42793786d5806f
+SIG: a9305e001600d597d05ef671699bf09f0dcc0c44475d3ca31e7ff1bffedc0c67daa1f3b76a035948c59cd87f82453a40950a1c9703c2e7d9280e7303966da301
+
+TST: 468
+SK:  afa1b846c210b52300e97696f81b8ea774d1df12e612527c55747f29c1937396
+PK:  b609566bbd1947bd7afaceb14389e836227169215fab66851aa5d70d6e2e3b89
+MSG: 4cac1b1f4bd48284dcc9afc8b5955b64b436db704b0335d9755cc1f97477f8d323cb6410ef146ab8a9efb9526d8b62e3bbad1f7295f47ba9f0de958f8ec9b77ab42232437ed974856444cd22e20be35e91813bff4b016f810d0f61d89f6b614db33f34bd09985b593fe3e06e065b7bc6cd39d55c2cfbec7b6d59c0b37dd1d0d35135ab1d1b04f2f30c2f04f4ba2b36582738081cf59190f528363db944ed612931d1d514c6214f9ab92abb1833926183ac52fba2a4551e20e4c0ac959a49ddb167a381e0241d40c086e90e52aca017258975dbab2ba451ee539a718f076a58709c6697418d9c6f13e4d391368bf0e8bd8f2932dd95ceaf7aaca1241147d341a3acd08dc32905483572b89a80cc47231468ab8de359dd525a6257cf196c2ecb82fa8a78aa3a851c7c96ca25bf7ca3dcf3ca21453d0dfd3323d5a422dec84316102f684c359f226bb53779c0b9950939281ef79a58c011993eace085497afa4daf64c9687b0a11aa116cfa7b03936241a5567b646e7e42e9fb592405b8fa3c0a821fc3121b45b1753cec9a83947d211a45499bd63790b87f01472fe566d87696efedbb74ed00048c384ba7f027b3aa4298dc4110349fedf52a96cd05d08bd635771ed4510738d8f07a6021244d1903579a3ea739
+SIG: 98b0c6313cecaf7c82cbdeb3d0280641c61a060f65e563aa93ce18300a9b58272dc8680b485e8cd11cf80fdca868fab365378384a142727f2f844f87cfdf1905
+
+TST: 469
+SK:  c85913a6877877131001623ccda9cdc12b9d4043b8a83793c44696632cd6421c
+PK:  9cc67c6948f7bf6e556d0849d3b8d203457a7b61549b36681d754f1dc0841e96
+MSG: 91b5009e83d0f6103399c2d3feec0084973a305bf4176ec782537560472db187a11b4dcb4b2ffb7f0644feb394b28e5bfe97247c4a4a231cf6e916bf99344ccda88a7f5d831d6de3d563dd102eaeb108c5bdce44e0632d17e6fa55b18067df2fa8d200a9869f6aff920c51d46a1ced2d903b1d9b6b075facbf91cd05eb41ad811a8ef40d9118261012c72b8979f15153dbb8561293da9f8b77c8ff14f75387536f0036d1713a72ce8c35b1062f2c6732aebf32936799b51c2cbcd6572413e7dfaab8641a02c150237381cf7a14e22c74c6c20009de7d3b7e69cd1b4584ac2c01babaf973c56b3814bb0089720e41968106cf26509d4aa546fcad5534af303ffca42b16ae6c93ee06bc3cace12e4ec718844bd30d2224cc486d106d1c456bfa165ea0120fab3df2c5ab3a523bbfa789deed44032ab0be86eb7cc09cdb7c07aa948dd5277c3df1d9d1843567dec84f9288e085b05ae4b8af2cea5d9a184d50bef85550c836613d5d3af5f9c2928e6a89660fa62719ebff773e46b77e34bc0470da4d2cdbc7071da758c4d39fe65201c88aaa8e6603d0bbe7c3e9b2d9e41b634682092f147341ad6d667f20c64e81a68d629467a54dd86e1ce12c560a6f9b64512d6f3886cbb9f37c37eb3985c8ac38dd6682f48fe1
+SIG: 01fccfdb1fb6888b0310a913170f7e366816daebe7650d72513d9506e66f7d62208a49ece0af1871497f4541ef605bde711c9e0a1205ef48f26c03dc1ad4af03
+
+TST: 470
+SK:  fa1e11dc8364208d8e1cb66a361be7e84c5e368166587d4fdb06aced7f62e17c
+PK:  4d8e6f4b3415df6cedabfb295c1984fd419923c6ac41764e32d22daf372c50fc
+MSG: 294e63bacccb801bbf04c1f19d0aee16f5650a6e8eea6fe41110663ec01532bd4960a527f15eca4af2f4e6b7b0fc340cf97aa234e92cf7d69d50e4009c2496e3ed4d9aff000f9e185275b817d26a0bab69b7f7ee1ea30daec8bcee387ae46b4b299c27bdc06eea63f24dbee955a6c0969037eef91c34321e3c5c972fde993183b7d23f6e019c3e0cac7589ae4a1521af87ea42df8c22c2270ec23d6d140f9cf6d4d52fac1b9d6c8939ef8131cb62a035c5261538bcdfd6db419a55ef9fe5d7a5ac44579de700858d74a3434844f28342c565892722e27f407d7f17b74a5934be915b20c2400643235f8ab5795f324e33c50644a04033542cb3816d770fa899e7311c14301c1bd0f5aa60a2eb3165680c720e1efa8096fc25d2779275f1842b2db53b4da0ad3e59c07540c28460cec1fdd3cdb7a3478b91a9caf9ac891cdf3aeaeeca9a9656ac1307259922fca74c5cc69f7e25c6bf587973a4b7d3e3ac0635b0db22a0093a79076881c71736ee1d4d45f8ed2d29a0671a64e6ca2f7a5ef404b1edeb842034f571b699bc59e5a37df02054e8482bf1e7b77d8e8397da15d89d7355a5dce86b1683a9ac4e406c08a94a6eb00e5ae16d96722972e5c50c7bee4a84d0697bbe67ceb7ef295f06aaea5abba44466be0f67
+SIG: e857db087e28d6750bf54e53797251d8439989576c12da2d9c811a14877c3bd46c4efab861a10eebe7da04c0b0b445c7a390a50c13de36f3a3c7ae0157022c0e
+
+TST: 471
+SK:  24a914ceb499e375e5c66777c1ed2043be56549d5e502a844710364042ba9acb
+PK:  20d21ee764b1f35f94568200d63bd5828aca8c5d3e9047d23f478b925295fa2e
+MSG: 3ff9f66fa2646ec66a1bf933c2b4cc0fbf912b4d6db50534257f97d01e698d05485747de2544e9f5a4a4a075388cf4400ab89b0353ce86198202db3a903767b879a2af9daa155843111af15a2bc35efe41bcc92c8207e00113b04f1303007949ffb6ce8df4b0b34248fedf5d9cb2cee94b812ed58ece2a0ce0454cf14c20e49e09fe664d6e25762e87895932cd5cd32eb6a3abb38ee163078c133e93588791dbf6af499a31ea4453bbcc7a85e406c9848a664052f11113fbb4ffa760dee4c261e396942491119da29a33582f821d4125e0b4162f28beb066031a652d05749aa7244dd4f3d3bb15d268328d6a02fce2501815257f8ad5af4ecbe7cb8ae9661e344f9072318791f3e859091121e08aefca8982eaaf66259d9de4f46a31e716dc033d0f95d1fa936b6c6079b137dd1158d1def113018c73f8ebb9807e0f7415404ea9c78544ace7ce463cd1d1c57e31f4091bc091804cbcddad0e15a40ca91acbe1c6224ed13cafb4df2c84ac9f0c3c9b546007d9dd6e524c467072563d4ac0d700cc1bf30febb334313dae5761745ec0a5e9e8815025958f00fa2e58060d7e9a5f2b727f48699f929c8459930892573f784fef5692518b5ca268e2a73ebead6ebdeb7ec24eac92aa7dcb41b598bd6eff3632d069726291
+SIG: 3ae0cc7bca8d73be83a9b809b13338c12706aaef75c4d1a478178f9dc565514c7529e298043ea78d21a5a09dd04f10ae87441e5686a933c92c75548427ad3a03
+
+TST: 472
+SK:  5532e09b937ffd3d5f4c1d9f1ffcded26ee74d4da075264844690bd9c8613994
+PK:  5093969f377bec3e35f59efda01ab4186c5d2a36740cf022675e01096b1a3f0a
+MSG: add4d7a9ce3f63d1f946e8679065545d8c7bf0a2cc3a4c00b8f142f0945ae362c4c9462a7576a4059d57861662884bd80b96d90d279a952eda952d37d4f95cf0d70da98f4fbaca39e169f9d945d41f872397bbdd5701454303d77d31e86348271da40a1b8f1e57c36fcd803e14fa17716c5631efa01d3a795dc20b2bde36ab73ff6a2d533bc15cce22328713c3c9ccd072c3e450d7f22c0c9f94919752cbfe45ee655d1b53676593cdb448704102631caaa976952eaa1f6c2e876564e420f0c646a0f88365f76415b4085f60a338b29c51633e540f0bf32d4087e7d0fb685be88c7595dc531c99b489584560ad8234b18e39a107cf5d842dabd421e77d26ea5e0f1405ce35fe792714eb4ee1a8017648ac1ae739a33d7b1e089105d1e5add27a62ce64154570340af9eb14e7fdfc2f9a2c2fcfcdac3cc4227763f4d629497479f849216e5d90ec16dfa36b72517f7b5486baee7fda4450c352cffbbae73926c843224f8ce44b38dae53f3ead21890b52a7801075291684fd5910ed86ad33e8a007f6c3f85c16b209293740184f5890874d431cd4e0ea4087c49c3471d789c813c6dc9a78699363a1d87197d3b92c0286689311823f4df22ce8035e75732cdea7f5621f67db0e2a4ca6616193221c0aa3d6de50d85282ee
+SIG: d527ff0d4a219d61f418121206a54ae4985854a310482744486e4d130a7de97c319df8372c82828c936e6a8afd9c5de1828573d8261ae9365b8f237676182402
+
+TST: 473
+SK:  eb36511009d37a9c46c4d1374d0bbd0d9981e78cee7d188c5aab983ec239e10c
+PK:  b1cc212b4521bbe7b19a7693878a558440eec36205d8439d040a46a9902fbf55
+MSG: ba2466e56c1df77f22b6f0241fc7952ae9bc24756419a9446dd2b49e2cb9df594e5b6c77a95aa5fbd9dc57fec83962c7751eebb4ba218253f916a922a5139663e3203e3be482be379ca151c463d9ada21446135f356994fa5449f084478f5bb4f5ba6145c5158eb7b1c43c32ebea25e09c900f01ef91e92f88c03c76504ace9646016ffc2789559d0f3cc9d00fb61bdc6af7d3940f302e588e04f79f7b3d4b91a5d193a4f8222bfeb69bf0347d98ad81ef99d130ebc7b36b0783394eea92a38ddd5e7480d2add4e4def53eb99c449bff94e4718b09f2ea9b1f2b886594a95c33a69e0333154e440ab34b7b6c1134d8179b6f0c56251a9ad8e1b6b0f9b8a5c97081a7f8fd05d0b0affc82dbddc8b0c0ab7e833f300626d4b973b3f60feac55571e89cda0f2b441ed2faa669a70d556cb48f9b1d1cbce32ede5d166b1143e264b11ea327681cb559edd13c364bd2baf1fd54bb781807bd59c868b0e4795a779e67f0bd0d14b5a6b9e440b57a5823328b59affbd027eda7dd785079c5f02b5e32890b038730986a39a5a9834a3fed868b6f45cbdd28acb2709aff556263864f9ae1e757b3278c288dbe2932825712773e431f7c29329857fdaea798ed93920893631402e6b13bab62b4855461edb94620f2d1751865f445c466
+SIG: 9f583724de552eae82f254ac6e2ed483ec1a07346266735c490920690c1e3fb2a9e9a34194ed6473733b300d4f23c9aec0da5a2022054ca43885a15a2984320e
+
+TST: 474
+SK:  7dbc81902e4eaab3077540f559995c387403cac306d486e959c5eb59e431c0a8
+PK:  e03066139082f613448bdbc27fe53aa3f88994c31ddce002e36bbb2963df3ec8
+MSG: dff798b1557b17085a0634371ded5ddf7a5acb996ef9035475e6826336f64ad8b84b882e30badec2b4a711998752f4a1574bc1f89d4325cf2b39861044dd03691e71d07768b5933a3052cc7c81d571a9de061dc19026c2f1e701f2dcf26a88d3401bc99fb81559dca76d8a31a92044a273587d622a08d1cce61c8f948a34ded1acb318881c9b49f6f37c30a65d495b02d5429e7ab4040d8bebeb78794ff736d1511031a6d67a22cdf341b980811c9d775fb19c6478f05ed98430103ea24c0f414d4cc07d860b72dc542ff22d83845a42f8ba45ca7ff3aab0b1e7de2b1094deac08d16eee01969f91bc16fec29ccc061c54db5345ba64842dacc99ee7729468d80a3f095583d8e8012408519d582cc3ff9a2eb7aebaa22db81ffc78ee90ef4ec589dcce87118dab31a6328e409ad5059a5132c82df3cefe2e4014e476f04c3a7018e45267ec5018ecd7bff1dda9267e90666b6b1417e89ddacb5085943befc7ad2f4df5f1ee0af9431aeeb6b24a5515b93dbcf68640f7daf8c961e567d7534900205c3df2184b6ac2da961c4c1d2bc49b4ea96b8154ffd4efffdc5e55a7119cb8af429e85105dffd41fe4a2ebba48168aa05fa7df27c4298735ff868f1496beb4b2ed0b8980c75ffd939ddd1a17e44a44fe3b02795339b08c8d
+SIG: 5b7f652f08f229fda1b0bd759377b3fb726c1b9c9a10ef63426d352dd0869bd54d876c3092f1cd411c3757d3c6b6ea942aa70c3aaeb4217a4c7364d18e76e50f
+
+TST: 475
+SK:  91b095c8a999e03f3ed749cd9f2faacc0076c3b477a87ab5ccd6631738767446
+PK:  dad174d359daecca9c6b389ba096452ab5ca91e6383c6d042a284ece16ba97b6
+MSG: 9b0d8b00299852d68bbf497fe603961a485466a99a5484005db73d4e4bad814e8574efd54d648bd5c91ae8483c54b2f998b02e1abd6f401a25526843a5f2a23a97bd589d1f7e1ab14915b1e359a396d352c360ae6584325ae4bb7d624f61255c5c7bf0a67acab46c3b57b34534c0ee8431d260576606cbd84d8d1839e73da6fe4b0b8b78f0f958827c2f1d93ba7a346dcc75cb563dffde26f997598e8b5c2f1617c6fefc9be4b28b5401b0006413a251690d1203aaae4f6d8a3fb21f24009ab3bff13737a8a7e6646c02732d9ec5a4a510469e2d299e4cc1ad6480a482aa956f89ddcccc64a136fb15b876b6ecd88c7c86a4dfc60e666207c604167d163440ca9ab9cf87a5e0f7bbc5517de4dee876c037f8cc9d959c8ff5dbe944ff54cd91a771e29231f8b5f17d61de904c955fe2025dc52ed480fb3cc90f232459c607ef7e2adb52c7482becd67ad2149a4128f984038b58aa90176782393604aac74c18209a3d6a78630c01955a7cece5da8384da3baf63aa2ddf5963fae05ba3b81c6a03d86a00ef78edb4184fdc89b1d6bfeb310fd1b5fcce1e219524a3cfb2e972577f06b1dddeba00865dae4979000c008ad99f3b638cceb8e8c7a0f998d34d92143d81c0e1c096a925ceba65c43003ee18d494d003e9c61f77d65759
+SIG: 64ee9efdb0c2601a835f418520641e436c7dd47c333d9fc30cfbb9e390fe764530654708b40b03581899a9ac870efd766ffbb4637152f8ff277964fe35425209
+
+TST: 476
+SK:  8c568b310ace7d1f0edecefd603a884000544c792565d481c3d3e06e2d82ca96
+PK:  5fa6e267c766736841411072d1983d1900acf01d48c3ce11770b26f78da979f7
+MSG: b59f5fe9bb4ecff9289594721f2647047b0da5e0e4941bbe57c5b722b476723f0ac5970b4111f893bcaa411f28fceb4f585a2a7187018a904b70ef8fe1f6569a54d00ada37b69cb5e9c9d26c16a903518148e04a1b936a32329c94ee1a8fb6b591892c3aff00bf6e44dd0a762babe89d7060c17b90390d23bf9d360a293b8308383086916e1182b1ba4336f001b8d20deae9a029f7e85397a9ae5cf3ca10c7f3875588b8ffabb063c00ca26f580f69edc527a1accf4f41397b33766bcf6d55eb8de081a48c981d05c066617b80d8f6f5e60e59dd9b930bc4d04586403bb868df75933bdd86230e447036c175a10de9bb39953dcb1966a1f11912078e358f48c5b209a636c7f783f4d36a93ad2cc2e3244519078e99de1d5158b3961e0fc5a4f260c25f45f5e8585e601db08ba058d2909a1bf4995f4813460d369503c6873685ebcd3330a130b75f2365fb2a5a34ea63d958a2a867e90552d2cec8c390084be0c108b0fd2d83cb9284db5b842cbb5d0c3f6f1e2603c9c30c0f6a9b118e1a143a15e319fd1b607152b7cc0547497954c1f729199d0b23e53865403b0ad680e9b45369a6aa38d6685abd397f07fbca40627ecaf8d8d30133a6d9d5af009192751c9c45f77c0bc011268800bf552512730e69973c5bf362ab164894bf
+SIG: debdd8e5d3112fd77b394aa0e36e9426bac91df126fa9c317cea7c9d45957cdd96a45ae3ad760413ee1205afd71a29f9c3cb586cd2d7cd1e93bc1652fc34dc04
+
+TST: 477
+SK:  3d09afcee3c432fdfb6bdcead54e3da5b1b4165c50d6d310b7fad787b444d680
+PK:  b0d9028c4d1487d293ed585a76bc94fffbafe2c65d980c494e141e4810a35cb9
+MSG: 767165caae0e578f16537e1750be7de87a789a51ff2de11838f564e2580b2391362d2868a5a4708af15d2e2db7b9be39c16adcc1200b34e6b4d4027ddffc1a2a3595e29e855ec5261b20bd55c428b01309badb59e2ca3edb967fc2f4bac0729ddf54fb6c20057bdda9e7af7cbfc092fba865fd3275b9d3bcb0c346b951d170ac9aa650a86df49855d48a1b37ce56c9f27389f5c8b15f5c2c900c4f107c064f603e4f867ef2e9c10a1b74210e6b89bb011793aa85ded43b51b749ba7f70287b6bc1b89434db8b8c8b5d73b214b41e36b528005bfbfe002e21b1006fb9d24babd72106d093e3c7093b3138aea719d69479084647498cd6c9bbb744509cd7da8dd61a627100f03c21e750acb3fcf4631d7c0f618154d2e5fa6656fb76f74c24795047bbce4579eb110643fa98e1f776ca76d7a2b7b7b8678173c773f4be7e182fd24dd76291ac67d9f26a28c5e3cb025c6813a378b383224642b4aefad0c76a6579517b8f360797dd22613ee682b179381950fb71609a5fb5494d2d57dcb00f26d1e72956f4d6672830e05c01b3779677c07ea00953c6b8f0dc204c8dbdccb381bc01b89c5c261db189ab1f54e46bc3edc4de5ad4f0eb29c0a120e437cd8f37ac67d48c7f0e730278708f02b54aee62b72952bc1c0eb437ca8bd5655437
+SIG: 89739fe441ca0ced08a6eb5796e9bdda0e74fb473528fd4907edb659aab44d3343229046716368faf88e85c1644af66ff2dcaf0b17ac93ca13819f3f241dd300
+
+TST: 478
+SK:  41c1a2df9369cdc927164aa5adf7757136abe51395604266334cc5460ad5683e
+PK:  40557834cce8e043580a4272a8804d4f926e88cb10d1df0c5e28b9b67e1b63da
+MSG: b64b14ba77d239e6f81abe060accef85f0442b650c44015efc43a0aa2ba10bf48d3018b1953ddfffbcda5bf3bbe0b6b3e4b0d9a32c6b725bbb231e0a2704471ee8bc1d594f5c54226f5dd9dfa163cfc1452c61f93e4f8139ab4ce4476f07ec933661eae91b6d500bf508ac63e4baaf1ffc8f0007d802e005f1b4fc1c88bee4d5e9e76384f5a7043bd660cce71f3b67f01f6ab844298531aac73a39d045370088855005a09c6d04238ea478dfacad1e6b22b2be4c46b0d59b1eba1f060bf7da5d1566cf1fdb5c543a33926af63f01a0db86e1a6711c473dc795ab283c8d93facfb5701fa2f2f6bb99f9b7e3749b071d58607be44a7089bcb503ec1495b5feedb399961fd3677d7493eaa3b3e9cc5e3642f40d47de9bfee7c20b0e519c4eb4a40f4da446ed6ac7aaca053e759c97dabe0a8ec2f58e7f2f9b2072762f9f794a6a4e36060b8872bd2c18d06a85c2c141a78293773ee8cfbf154b9930cd39da31b497e737a7750c90a13f5aaa147cd0dc4311f2e34941252ef198b0c1f50827e56c9f16f595aced6d2a69346531495a6499774d360766ca9be5ed8881c0db26ed7c5e6ff3a4f9b73cd8b654640dc96bf43bd426a0f28c9b25fa704d62ff0288fcceffaaebd3ea3097bcbbd778420ebc520a417730a1b5b3b8c96cda9f4e177d
+SIG: b8b2752a097196c289849d78f811d9a62fc767278f0c46628b521f62ed2759d74462a175da22403f15020445cae06da3ed61cca6203b7006362a0e198963d20e
+
+TST: 479
+SK:  a00611489467122c4c164bfb6a616e6a619b9f83c4367206b85d3fbec38cd62c
+PK:  57ab58babb41dc0da0bcd506059aac9f46eca91cd35a61f1ba049a9ac227f3d9
+MSG: 34db02ed7512bf8c67d359e7203a2ea441e20e729766c15aa00fa249a3518fc29ef8905aa5b4670958c6a460d77b3a80efcb473859bbaff862223eee52fe58acfd3315f150f3c6c27ff48fca76552f98f6585b5e793308bf5976bad6ee327b4a7a313214b9ae04b9651b63cd8d9f5b3bec689e0fd000dd501770dd0e99b8f99eafa09c396a245a4a96e56896a29b24190b1ef11063f39b63ee3a586b07627dd3500c4e170b835dc0ec236fa5a35c44184707565c4a50662d8dbccfff7f9a7a68d021b4af64d532b7c3d2747418c2d717bb6aca6b58747ae4dd5641d826f79a8a315c38211a538a929e5b451f623f4fcbbcacdb86c8752ea13a617ab414ab653eb2e68d5420df7c6df92438168dcf9c066581dfe7b2c468194a23707de4659bd67eb634ff024741c5fc8698fd4dc41fe5dfc6299b7a08e6ffca37109c0210c8f94ea2d3ddc977ffc0b3794fe6ba4337c7aab434a68ac665484ea8243a84b79aa181ee6ab5aa37a32d879725edc018f8552181816d7d272ca8818a7b92e6ee4454d1f7828dd8afba1a790364b4ff28d84e028597353ebbef24837bc319e1ae8f2b0b6a851b489c3e170eef53e065f7032653cd6b46d8e57e4e111b789ba950c4230aba35e569e06615403407bce0369aaab4eafaef0cae109ac4cb838fb6c1
+SIG: c771ba0a3d3c4a7b064bd51ad05c9ff27fd326610fbfa09183039e5edf35472dded8fc2275bbcc5df1bf129860c01a2c1311da602fbaffc8b79c249c9cc95502
+
+TST: 480
+SK:  de1634f3460e02898db53298d6d3821c60853adee2d7f3e8edd8b0239a48cfaf
+PK:  9dc1465b3383f37de00ea2d3c70f2c8fac815f0172029c3f579579c984a5895e
+MSG: d10c3e4de7fa2989dba87537e00593d0eed4d75ee65846dab1498b4749d64f40e34b5911c5ce3b53a7e37d2d02bb0dae38ed962a4edc86c00207bee9a8e456eccae8bdf4d87a76746014201af6caffe10566f08d10daaf077160f011feaca25b9c1f6eca9fc53314a80547951754355525257d09a7fdad5bc321b72aa28d1e02d8696d4f9eb0ad3b2196f8bcfaeb1d6148287a3faefef91a7a3e0609c28ce59d0ca14d0b3050dd4f096b7bc2513988ba212128d5026daaa7188846db21c5c1d179ab9487c1a5bd346588127c20398d362d4c759cfab2a677750b9e45676a1e7e092ef02edbf278fb19a58e9bf6c9e996e24edad73f3ce31fa04b6d8533436bf80b4b2f805ed91e7fcda3bc2bab3b2bb157158af0ea8e3f0731dfad459d2e79b6d3715fe7bf1eafc5397593208857e57b7feb2f7387943a8e0913470c161aef4fe205d3637f23177ff26304a4f64eba3fe6f7f272d234a67206a388ddd0366e894eaa4bb05d73a475f1b34ca222bbce1685b1b56e034e43b3c40e81fff79682c19f32aa3f2a895c0709f9f74a4d59d3a49029ecfcb283082b067f1a0d9505750fd867321999484249efa725f52c94c7596206a911f3f505d63f0313254bd445f05be3996b58fe1819af87352e7f0a2ca320d9cc00a5fe77ad41640d50be8436
+SIG: d20506eb846923a0b16ff82fb2c3923b00c1b3bcc6e2f6482fba24807521e8e0223f692e62eac993f498f67102a04fd1acf9c7e3888d857c9a080b8af6361006
+
+TST: 481
+SK:  c738ef5f0935281ba625fa4014d4a4d0be7e28fed779a9cf658e21dba43cebc1
+PK:  95799faf706d195e544c76cafddf09d02d1beafc42c9d6c9ead4c1845587d39e
+MSG: 168d0bc5598be02f5443bfe7dfb8829985ca5d282af9cf1b1482602f243d486bd82ba039a0750909e9b3c7d4d5f8b8baf45718af0311854f4d1c7837f31d8ee68d3558e7e51e0c646a4a637596ee90057b01ed0a17daa3950b81ab47ae8b94c17d40746913c46ba1478bfca51b167628fc3ee1e22f2f19d6d8daf93df6540cedb7a859d1a2ba5911ba71766e8b7fce0c0e8663616d0180697d78ce3040d438131982f3f8112acca29ae53e539ff8c9ec4106d132f402018518308485f2aa6c9e8d1e62fed60cb249457db33c6fd1fe07445361f08194a2b5a057cb03cc754e5c7d4a7eea53a7f7d207cacca5e68cafa969a3521dbb810399a17f328ee767cf55926b2bd5f029549d3b464579c42655265398472e1c77cc8dd9aff187f7ac34dd456ace999a736ecca6d405d4922c779c600c47b84c9c1df5e5f8ed3b2811d351339113f8453cca4c4411688cb0388258ebbd1872b83610042249494ed560d4cda6a68455d957e806dd0bdd83004c4ca80774b8a0a1665866f17085014eadb3eae7382fa870deb29dd8c931b53019625740e28392f38575c0e2a9e504fc35bd95df56439a898230a2398cd2225c766ef36f12ae7e49b30a9c0aad469d5895bbf721cc0ff51d840c802d4a7eefba84fe5205a2c2f14011922dde561456f79e6161
+SIG: f44371e6c3391639d457ed14648184809411e80a3201f8811670e500fcad92f300aabf7fc68e440191e881d6c3474efd6d28f09dc44312fcfcb82701ba3c290a
+
+TST: 482
+SK:  5fea38739c61ca83bf7b4ad175a2117627b971a634a305a84fa57fecb8035624
+PK:  ddd14b0fc06768d5104c50764bfd3b952352a34007c50d5ddd224ff51afcdf9c
+MSG: 1013c60a73953549e5ed105bdea150b91e60ec39200d43721304bfc8ec439d39609613c2d878044a9da01b26d86d6d65db93d91a137e9c4808a97d4ef286a903f3f1382cc6d1294216b9fafc013c86b9ff68b55a50ea3766e61dc1ce38348e91d62ce732c152d766b9335c68d6cad77be2b4a0cd50b9a1ec632ba55648a6e7e11a14c06853c02aec4809bd147a5ddd9fbc3be9f0c8158d84ab6795d771b42b1814a17a3c7a6ca0f4a8f7b3a0db1c73ba13b16400dfecbd03d216650e4d69704a707246444d5791fa273752f59cb5ae9fd416a5186613d66afdbd1ce691a87bd7d8b67190e9ac687062a080d2ec39fe76ed8335058251872839e85eb62f18ece187caba55b5f7d5edcade01cdc543cc677e50238b89c5635ad5c8fc220f5e0be1bc667d20989753a6d616fa69f8b12940b8ca9e2c48577132d8691b053779a152cbacff3b8b1bd7af692e56c73bbae4634776cfc213c99b9ae458df1befc8c877742664b0a0bb1f6915c8dae3b3f55dd75aba6a3bcc4176b4e3ba03d0c1c04c3c6408778b2b8e5a8a3eb52ed32a7428c00a98a589d8ca9390a210f4a7ac004fa1fe4c6da694f12276e320b41b0b59f75d264a396d450b631ab353f1612709e7a2e6a50d01cb110e53040546dd3b1e11d25732813aa76be5e81fcf7a5773f6815bbd
+SIG: f4e274823f2c396f3a329486aa6410c5ff19266f0770fd04fb14a7602d2b69a4a2b00928e9e1d92389f8033359ed6fb2146467aa154cba597dec6a84173f8d07
+
+TST: 483
+SK:  60f9a14cce5d43fd9aab4ee8cc8379d575949152693bf29a6790b035e42a44de
+PK:  bd4a70740d5acabe49f9a2152082fa2025330e6440437f1d047f313de490dca5
+MSG: dd7f44f9eb728ab48de54ecde6b6184bd5ddd8707545a0129f2e905905b55d3e7fd57e28485d258148f6605e2377d5b267d2eaf4cd4b46e454962219868232b6f41f88a797f9cdd5c39ada51a641214fb9db2c2a9b5a5b16e303575318b625cca970b74348727902a1cf268bd16e107113161c8cbc99303c2b9f235541a7b31e433120feba14febe4bcb0f5b936c7edddd0ecfc72c8d38f64cdb6cfc2910bc29a521c50a51abcbc2aabf789de822cb04f5728fee153dd5501b2db59c59f50cab17c29216d66951019e145b36fd7e841bfbb0a328554b44dd7ef51468c3d5b7d3a1f7b9def58d8cf9d9bcafe92c86cf6d6119e98dba6f38ea57e322ddc9c2198d4bbc3b94ea1329db0d458e01c7081b33925a3e287f599a858c50c3a8f18cc2aa634df63e7f10e403adeab2f41db5578790c3b4f041a8b7a4f69cd6e06215df8201ae5b3e1d1d25a0a39bfc3d041a2f98213ef4141245792a76f06d4de25f6467a0e56f2f5cf69400d22117de7b46149554b70c75b9f99484a4f6f035ad3f10e3753cb14f4f398dcf6a64d10cf6c4fac07c91193cc0f54f0de58c6343e9caaa6b4f475ef91a59e083f9f211f5bc8e7e4516b45cf06bf50beb8fc4ab579d86d4a4190eeac748d06e0852c4b9ba8cfc50dd0a037a7bad7fad55af309a5f13d4c91ed3e0
+SIG: 72f54bb8bdd17e9e422cd339631dd39f57355015d4cbd15acab7542efd784a321c1f6125764c0d154045b32e70dc2e03fbfe1117468ac3e73127b5fac8d42102
+
+TST: 484
+SK:  a39053c5c58bf31d462b27a620b0b37b8052c6b1c4102b6145663aa15e978718
+PK:  3642ac2a3280dce52ad8dfcfd3709436edc4e7e4ae1b452d9b220780b08679fa
+MSG: f65540d3abeb1ee5ea987062c1b579516d3c29c39cbc6b09d60e18fe274c2befe0f5fe7dbd57c2d5835229bb754ec4341394765776d6a9178c4e6a312cd74bdbaca0e88270628cd84100f472b075f93692830122f00f9bd91ac582836c8bfa714aa48e977003556e1b696df328ef584f413f8ab614760699c4d147c3eea1da0435835c9bf7ad54606f0213eb74a1b476141506ae2cd124cd51d66e7e7e579560576305c5fbe8430be3ebebaacba3f9989dd7d199f5a455a50cdb3755037e1a70674a4fef40b4a3aaf7bd3c95b1ab41bb206211c3a1276d3e37d8a3a5c3d5d0f36ef5b4f3de26b7f20f6b2900716dcc22ab734ebaf1e8d00020e5f019551653b9c2f70a4038dfb2f12d25d6d84e79073a6548fe15e4828fe5de83ac3d8d98b7daf92710482c37f7bd2431a8114c6137657bb177882d8a3c76babf1c671a7055365fe90866167a2d1dbc870be83b3601f09d4a317ae254cac9f98dcc7aead9224cd9c9d8a200abc80a2dd108af28fd46ad7080ae741b50054b9b9a9201efb7838bc4c5c2cc3d76ba0fcc49c46e792c26292b7d0312aff955a9f8edf0c696a70a614f3553ad3869bfde48d26a4d367b6cec057e62a4e548554b48b53ecda790ba7a0ab2e3de587bdc22b02f5947634d73099f547db22ec1bbf82343f9a2ca38bce4eb59be
+SIG: f7383e966cb2309deedf860100183aaefac672ca16d5419cd6422ca70e16b3976f5f165afc2786117c868234ba1109ede031f8979b50e567358bd4f8bd958202
+
+TST: 485
+SK:  e0c29df4de45c47539e0896b3a59bc3de6b802fd14dbdc9f25e717ac82c328f3
+PK:  a69002b0f5ef354ce3b2d6b8d8ba70ab778432b22f144dc9c2eb92d99d99dd2a
+MSG: 6a37cb4c749c583590c8d849bce3fa657f10009190cad9be41ede19bf2fdb3c562a6101f27bd37f223cab13ced245a1cedf852f551f857aad9727f62c967c0a921df116f48a80a6040b3c723ab5cb594c4507a3d20cd60514e22164a82b74f19dcfdd83c57bc3652375517414af5d18e0a64ccab36699768d07cf40b7063a83e43d5f607964b1bf0840a45ad50abf83dbc849f40e5b4cfb6a3347b29fec50774046a4b50041032aa4d567e8564b3eed1642040682dd8ae7d7179286cf6e1853dc87d27c3e9e60fa47cf8cb2da0181d53eec40614b07331a4fb7028086d0b1ce2e1115b73a162c527bdd7cab5335b863d108be047bdbca112cc6e776bb453c317314388bb9653efb4444bf5cf1ec8da23b711ba71796c0ae02ba1dcc838455078c3897f07e9e13b76e49274c2e207506b00a0b558883aa122b667db9d670508606a3f54320636cd19f973917fb1875f4363e220f1e12398cc6afd79094743338456813a5826ad3f1aba7cd7beab1fe183859c0cc9ef40a5eab912caf515a8d4c3b93d641b7ab3e76b16c12971ace88ff33e5a1ed9b44e45db8f3085dbf070b256b0d7512ee1069432603d73095db8749ca547963bd71a8a684ab8516b146c4187176386afdf6cb1368a3dd8fcb2cfff77056aaf7823f800b266acce72bf643c6d0c28f0ab
+SIG: bb3b8c5c27591fd8b9c5ba489d6b6ee5b0fb4a7b0de51f1639afc673d0e5f75e313aa7e1d0009081dbca7435b687ccd12f64f74a386e772b9e24781b925c8c0c
+
+TST: 486
+SK:  198b5fd1c03827e0994ad5bfee9b5b7be9966c9c3a267e4d7430343767403c67
+PK:  6682c6f1a866b49b2f8ee97f2e532fa91666bf38da1b4dd65543a1777794cbee
+MSG: 3fdaa15c46f25143db972079d7013c7f69a136f45f3f6ba2ced8b828468eb3daa6b50b4f8d3380fec64a0343be116f6f83b6ee64cc4c1b1d08d54fd42029e4285cfc6c6dd5cd181ab533ffcd411f23a1003da94ec9340e2ec71199d678540d5182e139ffcbc505a170b8f07f4a7e694ca92f58320c0a078564ce9de99b0fa8e66b0d822e467a5aeb83567996a48b89db25cade6457794e5414d67e9d4ab7cd6cc2058bb7a513abd709f4caf24bb67ce1c03ab62dbdfe309ec7db0fa3ea7aae8236f259b922d4536115a63bc89acb2051d09e731cbb0df157d9d345bd9109973c2b594f148efc6f3377de5163b7f69869ffef853eaefeb402e23529594fbd65ca05fe4062c529d8e321abc05200cac1e839e87b1fd3fdf021d68cbb3a4142b69cc3af6f632edd65b83f5aa4cb17da5b6ba3fc03edb17c2a3cb5b04836e7660e63c8a0483e243983371dfa9839f9164ad4da0d5953655e3a9518e136da745737c79243c355fc125cbdcc76aec92216846c4574f4f7f298bcde54fd2444ad3025955c100315de5a4e27c333a00284b2f702fdd3de22ac6c240dbc14bf71e62d131b62f2db992473f2f913f60c916ecf57df5f3f021fb330834395b79472caff19fcfa0a271795c76d69b4db3f85b8d2e5c3441965484dcc39aba59b701274f7fc425246856069
+SIG: f454f35b18538f877e5d614a76b5276a27fc0b433f215dc4e963b3f047694c780c515c6ef6fe2db4b009009bc2733aec4fd46e615357cc0bcc9f1f7fc21e3c02
+
+TST: 487
+SK:  4392f7d4fbd68fe154e4ba38ad5207612a0648556056c39ac116ad468f89bd2d
+PK:  cbeaef41acac02bf1f780ce934aabd631364b369567be1be28e3906f9db120fa
+MSG: cf1709dc9a0867ee908721b136cb93a84229e83b46204777ca8194d08b7a3ca9c912eb243e5bdabfeed352349d20be801b722af0892238e72edf190e6361f57572781ad3c2590b197357641c805383baa1d4972f76c65448532c110834a0baa8f48863e166b706653708cd4057d3a4f9fcb2ceb4120001277d38c43847d822822b777c2bb4da4015a1c24d416d5062a8718491d855aaa5dbf5579c164d8e524a9f2fa3f22eb09861ffe6ad659fe36eb40431222c22d7137a6cabca8db786e39d81f661afde4e39589b4db4d3c51ca53590a14e115d0afc3a877b839a9638bece80c32c19e51b7532024845f76cfe9bfb2ac05130f6758bf7fe993aa93aa272e4e6bd0c75c14099d43e652a223e5bcd64c362d4b8f4b95e016f9350c7fa74e653525d08011558b2c6e9bf4fdf9dbd5ef9b09bbc846afc2bcbc86c4ccc315f6d1ccd489b0cf8ed0d93f2f532a426265c590ba3a59023347d819d9b281ef85310b05316d46c8a8c0365d068a8708664ea4d77ac0cd150a65a56586babd34b74365bb8fe3e6187262284d64432e4c81ea4c0e57c1d71ae980c7f4d1d871032e188bbf9d1758cdc1dff989f2d1288fef4e205e99e7cbf2cc324b8c93046f476c59d3d0a59db6fe37382dc79c5ec16056ab3934a52f7d2880d0471a377b6a8ae84d56ac22d1d54551c
+SIG: 86e7ccf06e79362d40cdb7fb75a98978bbd334a1db7590367d60849bd53e2fb1a4bdae590d1f47b5490d8702e7c1a87268b8ee9db612de7bdc2e38fa6deb7e05
+
+TST: 488
+SK:  0bea98abe7d63f158390ee668aa050e84a25d2893e49fc83f079f9bba6a55a75
+PK:  22192ec0d32ef9835665a61bc88bcf4e1604637921152c116af503365bf6be42
+MSG: c178e38d4e83ed2be57ce1c3ab64253a8171e610008181fbfc6d752269f7f1c5a9ec62cb27f19ad99ce1f5116a363d96fdc5a42f358b6dbe7cabdfc9f60718e4012c1bb1f842c5560811ba8374a0637747ff92eac21ca65ddeaf43e9989b7de2d432520afee364ecfba4da669ad4893d0bf69f9f81e7df69657be22b92069745f216c242ccd46d02d35616e16c755e0e37f961a6f3637752534f6dfab8805ab759a032a4e7e4c81953325a2f686bb69a029ce4e03becb3605637c5a65b52e331c26c926ed4711a504d3733bb53c97b80eafe4e75ddd9f415362888c3d4d37bae0e63fa11bf755666437d72f58c91d7a2f8cb619b7620a070b26b18b4d50184c5818712110e36d3e2830f6a8576ba57f9cccb8fff4028bf8ef9cb814825bbca827d649547bf6f2bef931704ca7f6df15f780155ed46eaa7ca7d72e22434ca0483bfb2f7902dc787f617eb9bd41ed4520adfd430948c710805a73c1ba5492e96484c4baa7da24c7435c46a052bf3515d33e42dcef517caa45f36c879121078c688dd10d76656a119762b6a834136fa1f8a643224b9224c543cf0470b3f8ee017d620dbdcc84d985154e9d1ae80e5f14387b88a0f6a5c35905aa57fb3abeb0ea6eccddb004474633cc483b56b8a8e20e8f2e09e979aa09893087875c6b117b5f13847ad8fc05604c4
+SIG: 7eb3139b880fdf66376a2090818840049767c837f3ad0036b141667052b33609817ca5e240ed8cdf3ccf3aee29274534594db0b4ccc5c6e5bba3280b873f2901
+
+TST: 489
+SK:  c25878b0d1e0925c8f5f04a1e5799080963c413a1399c118afb1687c797f4839
+PK:  13ac2cad41908c255f671f93934ae5d7be325346725c8b40dc39ea80d70ddf34
+MSG: 6856cc7144b6bddcc4b58954d1a2e7101d6584b5d5e719a0aea0fbbdf221c2a2aacbacdc4020c5c8ce681ff7381acd607b0f5239692335700655be2d94c53d7b5148e92a2bc16338c2f4c1a7d1c595af622c240ce579a5e0f5b651bf562518cec8aa2ce4b4aadb1f2fda6cf6295bc37803b5377dab65c9b9a2949fdd49bf9ddc8f96d260ff951bf8e8ccf9827e6869c44bfd973358cefdb010db5e1fe5dbd9f5d2b2ca393c17d446f637059e692d7a91aadcc7689f5f9e1b3052175d9b6b208f9026787fdb66783f45372a24946b1bd1687bf0cfcc8174ebe4d32e43284fc78d7844de0fa22e2065e07528baabaf015cb34d629c3596ad040de31c5620eb266defa7533ac0401998e5673a754365047debfcf7e137a20d16cdd6a5521982f444cfc3429397c641bd7e74a770bb11fcb29483e337bae5169ee82da9a91adf3af67cd814c2825d29018ef035ea86f8de4c7563aaf66e0c75d17ca68f49f0758ec2d9c5179d01aaed7d4515e91a222b0b06fbde4f07a7d9df2de3bcae37ca2c8460c2a6b3749e9bda36d08e66bcc356b390434b4a18cfa45af557dca3d857ff3ad347cfb07e2358c2acfd5cd53b3b0ea2a41ee5c0802fd473db5f30526334da41eb4bc7518383898a0b7507ad4ca289d66c5e2eb75cf255dff312cb1e04eebeb47f2930b90d5e002eb0
+SIG: 06f55198b4191914b74306f38e381316eac40b5b5adb8a312464f67175ecf612e0147b1cef46c2518750a5606bb03bc6467bb9321514f69dcbebce8f69058002
+
+TST: 490
+SK:  0b2ec62763f687593135da1961ef29a288089696d944b265a5f96893cd2d8225
+PK:  c1e234fa8bc96d268e7aad028b03f0a911b697715db3a21c2fc7df48ecda8875
+MSG: a83434c68693d5fced91bda10213fcd50c48920b90cee9b73a9c61081a0974933f4fdb0a67e671f8351b0ed5ec0fe7b5fb0c87586fe582ffb1bfa2db5fcedd3302428234b2bb0e726dedf45b13a70cd35ab3e299d13f34503508278c4458eea5b7351b05836bdad5b05f60e445fc65737ae27d2e52df9c39e5da0286392d08fff7ecb7066820fc90fc8a44d5616561c50b52714702302bca5874de85dba045045f9f0e604eb86d6d7fbd775f72ea493b2c4ef7c3be16db2ca7e4d8bd79eb20cfb5f0f6f05336b75cc86d219f3b8f2e91ba7d52b64fdd6a6664f04f2fbab758cdf984168691c32f53e8616b49f76ab7b192b900903082cc89656a9705804cc9b9288a3e42170984f8dc454e0864b9341672686a178c060050178a36c6d906b2ce070d8faaacd9a58c794a5ea4108b4a485c65811c2dca2ee7bb10bffff75d4586b990f43763a16fbc0b48ae1fafb08a9a36fa4326845dba5ba2fbd32bbf66505c5e8657ed0107e3e16144ef31fa6aae72e774097483f5480aa45540568fd08cba0d577768004f58ae9b95be374ed7f0299fe721275e476e0b9ab72dc06ea328384e39bf3ac331c625484312cd9b06b15a2954d33e7aaba6be2261886ca811db96b1143d06dd6e0f3cba7a1ae9b94eaf67771bb2d24e2f94de9c470fcde7bfdb32f410198b5aa9698e32
+SIG: ff701f34b3594de3b80045f429e5e32dd88d6051d4195f1685be783766e80119368f56b3749725b913f1223f87fb0fb24d9dfa0841d6a0e2eb1fddf775c2d205
+
+TST: 491
+SK:  8960d7bee8c6b39ca5934d7cddd16f16b3663e6e03e833c057e2181e4597cb68
+PK:  43409095d4f50f5eddbd5cd4d2012298cb41a40e99492d5a2db08be5377ea183
+MSG: 308d84c7a5f786e563e5c1ea57aab5e555c00997749d15aee35439efa645da2c3967703115c6c63ed7f94785c5478f38467b86e7626e8fffa4d51a2dc45e6df2a35cec99555eabc9f7a93e2e2b689459b4e0c92b351562c417b1997113754ea59e4a91510728ff3071a2bbd1f465a687f67dae955615031a8ad551fe738a260bbc446b48dca1d979051ab5840832e19d473b666217a9183980d6b27e3d3c76d93665ba2393e6ab1a42c3904d4025932d601a202a59a4c49fdb77f0e02868247de5afdfaa1b894208ac00d77c6bb54c6b2a73a47657e44c85137963b57521af20976248eb261482147cdf7a145c3643e29e0588bfdae6a082904853ce5a10d24970ebdfb7f59d5efdd6a5e7e0d287971c846acd54d84dd45468a4110bab6ef8d9a5b4b2426788900b7e1adfe0624344f98fe59ef8a1e6c405b344eb97bb204773744b6a2d8c6e65d17cea07de03b7f0fe49f1a55c33d5f15ce55df7c9561b251c6ac807a92553e1ce917012dccfd69e7dbd038c7eeecae98623f18fbb650e2218a0bc0fff43a75a116448bb7362f527ee6bc8e10761cccf9bcfc0d000f2127b4cc19211d095a0bdaa4e4be4519e6c8445eab9b3144a45cab9996135bf7f75a78d22275900f4ce1f0a9eac136364103062893dad4390422b77e5f5d1d94d7029c6097b35ca64a7a476fcc7
+SIG: 7213dd4a79fd54dec0c548ef42e6cae015be77802bf515cd2582768f72f563ebb2da36af4aaeac56bbffc9932c2e24ec95daff00a5f7a0acab9c8bd3c23bb40c
+
+TST: 492
+SK:  ef6b9b51fd4f8586ca62658e042fc09a83b943033526ffc326c65eb3a5fb594b
+PK:  1d6eece805e0887821876b7ed6ed5b0714d646fbecda38764f94c8155e61d004
+MSG: a8f3f19665de2390d5cc52b064b4851273677486d8f5563bb7c95fa94db3356161ee622221f10cbb1fa195aac7231ea716d74b46b37bc85a70dba3dfaa1675217b351199e74a971028f729b7ae2b74ae8c6b3a0679c3e3296802844ad5bba343f6f9f7c4661b4a29b44f17e89e114fb220e984cd980e94c3d2bf9873e0605c92301744a3035ef046bad2666b5c63ebecf93cc140291946c0fa170340ce395092deed79841352fbfee03a927eb458f2a633ed3271652f5b0f9960cdf9015d56fdabd89ee71e259af6eb514b4c1bd4a666f5b5a35c90f35b149457af2944dd0aa8d9b542283a7e5412b775e421d2126f89bebc3ca37f73071621f1321eee52e9690486a33cd7ff9c9967fb65ee4e907b6b852211473d21e9d91a93362ac761760e8c7bbea486c3d605f9e11b86136819a7ab3f32f13ffca16817fed197ff880b4d6d9a808f7f878763a045728df72faaa963e4cb1c09cc2b2da920280c8366b7d18bf8972df16cc23448fbe6b2e6e16cbbf0745129854053189637ce115d2398433c15d6f116a205334824af282fa758494c47868ea8f4dfadc705e861aad2eb8ef3dbbed2a4569e15834a760cce0cbbc84b289e779b988346b9069c744c97ab2bf42b086d2fb0a411f5ce99f0819a3086b4fe9d96c7c9908dce28df1ddd30f3501ddaf78110734f9dcdfec3
+SIG: 71d171071cd0fea1c6a9cfad1f7fd835e85ff906778bc6345a4dec4313ecc2bff755a717ebd912a5e02840ac073842f9bfcaa58913e260e3c73393d36685c70e
+
+TST: 493
+SK:  bad47cd4bd89849067cce1e63c3d91e9b787aea8584edb07f3451ef67e7bd79b
+PK:  ab0ce9ba1d29bdfb85a0e66b76b5e2e05ff732569e4375ccd75098e9e71d17bf
+MSG: b5a61e19e4863e0bb5f3fab6c4970d878596895521fa1e7f678cafa2de53322fd458a98aa6e35805429f651291b95bd9950e155f3ada0b609159a4abda5990c04bc2e764422fb49ef42f12529ff6f6a82029ff0185662e658f83c546eed09f06b5a68e857cdad0eb9ec4eecbfd88f34bc80990f8644a9bfdde1d9f3a90d557a8b828d5ce06a64e3b238582bb4cbeba30edc49e8122c55e95badcf502cc567869c09e9f46c6ff3f6878986b1de00b72a1858046fcd3a6e9cdaf5b073c56f2025063a2d178bd4c1e8cbc1e6e671aa97fb2cb4cc8a62c20be41c776372c8e7be63b482e6c63fa85d7cffbc1b2820bae1fc128343a1e20fcf1bc3502eee81358cc9a74c72af63530f96a25a604648ff570df1eb89d1fddbab28679ba2e9b41977e9a9c1caecdbfc361a1dd055ec51620a9bbdbbaf718c9cc136d2007710399536d13332485ec38879785e0c9ce9915a80251373990a59bce440326031ab1b458bfa5b8a4793da4ee11ab7af20de2a118c9ae521a417b68207fc885e109d8463e9f022787cc730db0b1faaed257bed901710885b74e994f54f6f2aeb64f0f60b59efbf2e3bb6515424603a113c0b8a31ba3c1e9a9b8118c87ec6949b75f49627ea7b1328889391104d4f4a3892cf00f26a73cda2a40f9b7157afc40667f4a04f647dbf93906b84c9a35164e1bc902
+SIG: e5724a1dd463a97d1222c518c4925d322202d10f04cd078e771e0fb3951dbc1493a234460754c3aae3df93008dbbfb310c99592bede735a4aeab0323a1210d0e
+
+TST: 494
+SK:  caba8e0533113a4be173408ba83c0db74260802f9186c391402655acde6015cb
+PK:  2d7bef6164c279fa1028a9788e3e8ee8ac15edcf92a5855062952310b4684547
+MSG: 2413a32bca5ce6e230e565eb858493d5d04e6d2e2a7ab1f89a3b423311676bfa93c67daafd1cfc7109e040bac52cbfe07c28280bb6acf6e3a31073dab2965378dd77f61fe9247135c1a631b79ad668c9ea1cd4112d8d3a064cc21df32aeac7dd718b091fb6915b8bc063bb5815c376e01476312a2e5433417a7a9315d65999b02ff464a474a597e53988773670eca46a6e26cf96e9488e9e6344bc783ddfb535e76bb3b9a603ff4c59c7dbe2d8b6198d5b24490b4ea96c95959ffbf3d8218e760daf20e01e2f36c84bb097115abddee92bed82d16b15a9e192e9893ac638461df507207b0cf595884d8a99fb9c7045f9bff7b73f00ca3fd595a5cec292adb458bd9463be1204d01678d2f4389b8720115fa597c402b4ff694b71ce4f3d330d5e2f3c3ad6d96a9b3439230fc53a44794cda595557c406ca1589bc7be81e2d79636033253fa7bdd600c67fc55936bd96ce0428c3eb97bad1de0a5fbb9b675157de5f18bc62a7c22c9483e2802e679b5b8f89db0fc37f7c7150ad5ac8722ceb999b2435e6997217092336ef1c8a2292dab9a46ff8a9e10d3355765cac9d6598770f4f01ea639125fd031609dd1a507d96280c7d01a3ee987e9b210ec8744cd48c74f8afee961e8ef221f826a1fe6e7df0cb15ad7c7ef4a91f9d0f4c2e1bdea635d275fac8c4bc0601f490dbdbc734
+SIG: ec35ec32c8a4008827e178492b3b8bee22a4954fc6b25f4f225dd7ed23698900de8156756a8edc35c51d10f82b830a2a659676eac911f960244766e0c3c60705
+
+TST: 495
+SK:  9bf3fbc7308b46f6036bade0c3ca199fac662b07f103bf75181d52ba6a58be05
+PK:  2f6ac6fc33bc060c1dc3cb9d1a2b9115845addb16c4b84be37ed33adb3b3d3a8
+MSG: d65e36a6a38195ecb91de3c848b51f639245fa2baba8a6f85947159dec0ed3fae80c5a0f8c66ff24793c89c0c687543bc633547a1f37f730d97012ebbdc7ac339c4890c0856bbfe2ba29b25a7aa6b089c033fecb76db62dd3c00f6421b9e76dd0ea366eb2d4a052ee6cc736e3819191d5ad7a66d2be042cc6539e5f35652b155a727f3888d93f93a9102598f7538a9ab7c777eec79426a6075d6f38d64c485520f6413ff4d358a8a9cbdab01adf4db02adaea26494d1f5d617637f277f8b0e6e7e61e2eeccdd337de2baf0ca264c14c8cb8368000b9c714385f413737d6816e212cae2aecfffc32fd16d46c3ecee6ab074c0d768bdfe99b86cbbc8df9c47cd586d465871268d4a9d1c877236ab78f8859c114e251cabc4be0f8bc25d148c5f543e290745d11803e49f5b53193fe39969c039b3f249b32f2b8598b6acf4ed64d5752bb772ff4ee00ce0f85ecbb4cfc4ce07daf2809868c2903b781e12a274105f06181029e47f2bfb21f49480aa1e444715c0b9ff07ead88975d93585d2ff424832a9783d94906a60f877ae1c85ff15317badca1e61317433c7ce96279b678ec9d174dd0870080b234154f626a53462cfd547842eab8705605b8ee885729ee78d1833aa43f55ac22731989fdeda7dc5fa9c01985f2661e6c7326d346e6db27e6f921fae7c93a2170e10dd0c460bdc
+SIG: 0c3136e01f9bcd99e10d3d124b0cdb0772bec18a864be81bd1daa44d818c3d470dfaa8ab6e9a761cf03f93ef9cc78291096ed6d10c08fa2fba3bac04dde20f0c
+
+TST: 496
+SK:  64e89304a335e903cb36c0bdf1a6412ef368468006b73d3d2d61cb030cc5f8d1
+PK:  a180ef3a661c3c479d5f69807c902748e35e7f725121e37a5d91b8bec88d83a6
+MSG: 2f51074d981bdafafb02a40fe826c45f3171c1b3184d8c260b82b8411fc625cb02ccfe755dc29dc7895bf759e61b2450da1a656a38d4f70d2ee748c518c6420306e5f01ec7a0ffe0e9dceb93f6c077b12662881584f98ce6ab945f87fc6d123c45d6cdfd8237a1ce3635b623a79d020df44c74b89ac14a321fbf33a8c0a2559fea1c2b156076b813908f842ebe4c2b949089e52b1ae40dc6e4b2abbc439a0bf72369679aab6f4c00018be147f7c0a67b9679ee88a53819c49f7b675e30a8b5af39661ee8db21010411294968f88e5d604d0d88d76a7e4864fad3a56f5f624ba1b34ea9cb720850aad3bd4f0a882a7d25fbec2bb7ca86da616da96c1562c6d6a1abcc641e1b58b2c178e1c3bc8a3b36ec9e144dd2e75b0bc8c08ccb0d6e3427b0322b3d6ab93f3f60b9cc5b61dad02385a14949f9b87a8e3af1e0e0fab7a9a928c753fc6110444af7ccaf8027ed641b9ed87fa5d8e1f76cae465d57a70dad9ebfdd3ce7576ac4de89d98f42e282ad87ad6a5042577cbbbc4d951e2a8676fedc8cb1b1bdf76c3a38846385a85aa24706c20a8b38465fe2ae0e41f78e614b8e9642fe2471a9015747db976e0c7848c23ff3f417cb05a8d5ef40130adf855c998a62104d7e2fb7c0f9aa2a496075623ced2c0f7eec10147ff9608a8a042ef98117459b93837fd1b8d5ef03978eada74cac
+SIG: 92eb4454814001ecfc18025d6421f64645a5bcbb5cb8fd85c14d772617c503e8be7d3bcf117f5e6801d1c3b96f9090a66ddc67f8cf8ff0f1c125b16b15e2ce07
+
+TST: 497
+SK:  6f634387ca2c0cb167a740d6afd89e2a28f5307184e81cba3c037046a5ede23c
+PK:  011f2a9a111c38f3490cad1685be78eceedc6fac4a3221301c69c84b1ec7b3a7
+MSG: 865c20a94ac3f2e3bd5cb85bec9d33726671fe01f9c537017d59c8d5106e43360bf76fc06186705980c8a87ba3633a4a170426ecc0defb6db2670f5f592533774cda50052ae597d48deacc2637063bfd519f2e79bac81775beccb1ab2f5b39712e2e829469b75a2d2dbd08aa6d24723404b25eb948a4834c55246c8079a82ec64354e8c2388f8c5a616b3cdc371e6263fabc9f6099219e861585fe82a67d610dd1eb5c81c96b5cb354a689fd8aac8db76c433f0cb0b31cf1d855b6a30a3d2a212e9b4f7d7afe619951f98d2f1ba2c101085ba81f49b36037cd6457a7eaa8f4f3bedf68d09fc9fa25a9d754db65360285412d1a6da53788905fcf4efa8a80cd86ca48b845633d8c31c2ae06f16c4c6bbbe9cd1afb59e101be50e03535dd8a65e45bba46d45cb14badfc8e93ab5267f4e492ab1f9a95e61fcab81cbf2bd867a3ec7b4baa189a0f08567075596129dcf9ff1c502d3279e8aa6ce56eaf134582a9e430a5aa8ca10c3da8bc793d0256ad19aea7149f0ea7ea95facfac1c5cfd29d7a3fe1a417975739e14da8edc819900472ca8c69716328e8a299f974edff741aabc1c074a761b3ec8761dda2e7eed7af33ef00409849d415497c5ed5dfaa2259a31d076398170b2d9d210208b4a4c7db8c626d1c533562a1f95489f9819e4985fc4e1d1a707be5e82b005481d86377f424e
+SIG: fd17c618cdbb5d459ea2aca886f0512c623251284aae3a83eb5d7f60da1d9b2ba083c455a5e2583a3cba736e7b961ba19c1cc8dd90745da82a15dfc662e8e10d
+
+TST: 498
+SK:  4b2e1ae60fa5d383baba54edc168b9b05e0d05ee9c181321dbfddd1983959154
+PK:  36c020b18552345619ef8837eb8d5494840e85f46809343b4d6f406125da557d
+MSG: fab98b2bbf86aeb05086812a4b0049a1042abb76df9cd2908755706303efedb1ad21e8bc8d7562349e1e98ce0d752f4b3d99e677368bd08c78fe7425ec3b560e383bd42af6499886c35add80a5828b61d6644d7dc443ba2c06f9bad2eccb983d24458f6ada1b10bb5b77172c5cdd56d273d1e41010b25cf48a7d58d7255702ac12f2a6fe2918466395f460d15236d035ae9410ca86c4605128299faaf09015f1adee7768ee1a8f8ca06d10dd7f95c46fa10253065f9d6f90295908809fd779571be29e0ae66e0bcbdeb7913d2bbb76ac302f3452c55ef199a48eceb0e3596c7b4c0386dae7101ea244a33c4cdc830672df83655b35338052307b94d223cab1af69e07f78e58cbb0cb3c5351e3a6b0c4a927f7562c598d2d3df90569f61db1a3cb0140b56ea02cf7745fbeec2028673d67f1ec5f7daf9715f754a9d8ed46a7a63ef722ee0d5899331b63c974fa880429435767f96254ef46c9968f3fedaafeaf3e8f45634b54f5e0a5fc2d2373ab9e98d9acfe3697e642a18e0dfd9fbc2f094866d401f0a4ca2a456edf6a1a77b9c296c3922067eb3d5a5ca0a77f430e4c8611d8f05a1baac1635ef7ba83dfc69d301949856be4d2c8ab61de29cf39250c5794cbf5750cda95d0468afa2b7f23dba4ef5f5295a3bf4140018b7ed061884444f5bb1b7d239312dd739999536c684456ea06b
+SIG: 2220119e83d69a6a3eed95fa166d1d1128a3f232ca1b78bc94b4d476c4779443614b8772aa2232cb0720a055eb71d8407f3ab19baa1d962c052c84c0bd589608
+
+TST: 499
+SK:  b216cebf878024c20dfc86ce4b37bdc47aa28f29203b5b44925065d993a259fe
+PK:  c36edbb6254a913f08fe259e238780638f72ec0b3007264bcc60a9e81ee9298f
+MSG: 9c8717cc86fe02480bfd9e922bd76bffee2170c4cb1b13df834ac01d45006086297f1b8a26f2ba674d33e1d162f19367feba97352b7df2e75b309d4b6f8b07cc0eb6777e81e268e02d07f2a08f8f39d5a8320bfc01fc8c9227d2cf05e12891ff4de885a1c93371a0910ba53392aff9ba2eed9a2055977ec4157bd65b34df79372f4d50edbc48924353cfa1692319d88a7a5bb726254c209291e9b1d2c1a6c8236398109c59ed42a0ac9e7633c520734eccfea4fea95a47a8f0a068b4275000439cc97c57871e105cc0790e9dcc9c25d5af7063ffd05c4f3780e7bca4c456d0170da709fc6cb3faa72bdcf562908ae9340aef4d0c8b91f0fbccbcf1cd898b1c716f4f1474c3aa316242abdf6368e57a247ff2fd5ce23d187f694f11e38dfbfbc3d9db20903b4ebb449b9049ee020f6e2f508e8b2b165bad7464dbdd178cbd423233765d371e7ae1c3e878cdb5b824b20cb309867c0e473c067e6744008527b6bc076d077f4867622aeed1c253dbde7c6a76c7015962fb73391698600bb318ffa7b0136ee4ccb07daaf01f40ff9c194f98681f9faef8b6f9e99f95df0080da8966a8ba7a9474c537b92df9799e2fd16f788dad7a7bcc745226e1e6371f52ebcdbd144044ddfe632dfc0a43d3a450923170ebc7ae219e50e078a511bc12ef14cd14b5309f38abd65db2b2a7af2243b229c9fd2e
+SIG: b7389ee78dd9763f9d2892912edcbe3e8a236b8bdc25f44b9cfdc8c47cd58168ab56eb0402a5bd752ac8f4978d2ea2b65d2fa85265966b9f57227ef4a59ae009
+
+TST: 500
+SK:  afcecea92439e44a43ed61b673043dcbc4e360f2f30cd07896cda20cb988d4e3
+PK:  d231f69235a2e3a1dd5f6c2a9aaf20c03454b9a29f4e3a29ab94689d0d723e50
+MSG: 0b05f89ebb3397947687afbef0ede87cf3810676277037521d952a3bbbbdc8565988a095d8d4f6f59be572d3d821dd789977ef77a2fd7110ceeed9f3756ed8e188267b97a30ef8957c78aea3a2963deca61860545e0c40824881ebb1db10f607e10ddbddce400ea236ba4745aa99a05641976766789ed0da7db55fdab459ebd4b441a6282f7cfd5a20ea06effa335955e5fd29181671bc92c00052f7f75c39277c9a43b787ac9fb1516e996232a509774d1dc21d8c0513f7844b0a5b5f18957581f99044a14223ccda8a284de12fd424265fe57b270215f8fa9ff2bea517934e4800a47d346fb6c361cfbabeffabd9c4164f45156e245c977edb473642c3940be5ad6fd1a7119a7b18e98d6dc843e0d254c93d0146d18e5c62ede1490f89a605eb454f974778cfae20932e95477bd03bcdb97d5bcb76335942e92ee668f231e69c570ac5446d0f774066737fdf49f10ceb1b52d6d8a4639846a3373a7c6f3b4b3159fe2e7af7eee2f0df172d94d255d017651da3009005e5eac3176c09389ee40d70383bd37117eca083598a1801f592d057186e568e247c252be4b14f723ab7ddb97ae9768c2682fd63acc300779fe04e2b88874751346c9e0f97a2a216772ff9625c33bd7e29fed8003a08dbd33b5d17899c943c25e95ad754fb632e047c112af7f7ceba72362e1a3ddd2935aaf7f818a27c
+SIG: a65545cf3df456b28d83a6d94c036a19d0d29fb065edc27e5e93a1f40279897e1c6f25959a725ababc87cf2ae727f3467b79570e902711917191d9cb0d2d660c
+
+TST: 501
+SK:  b834c6e0facbff580dd3b23753959a4c2154c219521b3d27035d071f6599bd02
+PK:  d1c384715e3b3d02c13e090605534c7db740da2aa560f53200a3ced8beae8cf8
+MSG: 6cf147b1605528a36be75716a14b420bcf067c03f1cfe9c4402f14987fbfc9d3ecc3ccf4f8d2d03a55900b8dc79af3b6e77436f69b1417ad4b68fd44e5e333ed90ea7943fbd1122609ec8ff6bb25e42e9914f5920fc72c4d013b6a9685c996fbd8352aafb184c22d9e47871a5280e4ab7dd6a5cfd10a5994a200f670e0b622a9394d4793d0a420e7d8806cb127c7ac690d45a2e94166cea672bcd982b0e9baad56312d2570ddde7e0b9e7f47136f0481d00f66a2aaca4d1b09d7ce6c5a98a76b68cd97d5793968d667073f8217f9054735340f9b149c0dce845b099e88d0709680f0f77603ff0a2331c558fc36d5f24da9a62d69af5190d21b5c857a1e08f014c6d456468665a7f845c66f9111f9c098c68940efcd87b657070cb9164bc9743aceb7439a0d01c0062a11af2e11349397f5d152872b13c5ab32f51cc58f1475ec82ac671561dcbd343cfb3c5f78d0fc73053c6004b0a4ca3f2043ff4b0c54275c4fcb9cadc6baabe57b1d5acd531e972ef9335136cd1d65512ba1f5b6ccc4b66b4250aafa2967dd4211a2742e0f177d8f4063899f61815cbe6d8fbfcdf74812bd40cc10084e46a99ac128058eaf16a49a24b6ae228ecf0109c52dfc06e37d6a333bcb24aba312164c6c0290485d251280538ce9541c0916640e36d6929dcd9588eb99577f5f6d82bcbb198826267e49f5daff2c0d
+SIG: 0f19b7066d5792328a9800d9d4f8f67d5b089b541226a167dacd439fa485b0025a5dc7f2c7e23fc4a5c6869e7619d356399700c93650e89cd25b90fb9925e304
+
+TST: 502
+SK:  2269a5d8f7ac2cd9048f5f49e349e5c435a159b319fe3b30bfac8d0d505943f4
+PK:  1c817943dc39c24b01da38a487b175482460c609e4726349a9aa7aea9bc0fb34
+MSG: 7153d4d9e641aa61920db0ff4bd537a6d6130a396554cc94537698f9cad16b99eebefa5f2776f2feaff6bd9a6904120c67e0883f6b96bbbb195e95aec753b699bab3d03944c13c72fc84e3f2cbf6296f645549111c93fae1a759bfcd16fc09e60bb9785535ad27da244ef2f857f2de99a6e92188890e452c7f5b9e3a4b968e11743b6fc7faf1275e5360a5468941797894d770fa7da364a337302239fe83ae0b0d084aa12acdc63462524e0eb10fefe81ba96f71f275f3449a3f8db21d58749a38853d39b0ad8e69891bd204dfca8f6c239dc9a0ac27f54db4238d4706df11d607369dc7f704da1d39f2e82af8c283d220c12431f56d803069b4acb77081c031ae3319fc77fca7845097fd727ad0d080895bba23e873d2def8cdc216c3eed61b08761bb9ebce0282cf502aaf6ce7e8c058637958c3ea1b72fe6e8df8d37ac055db6992587fabbdc467f52475644f918863af620492f34680f2056cbcab75e2323626c094759c0e0e99ef19759527250646ad760120ba386699d53934f956b8bbc7395bb496ceb2dd223c7b501b92d36a95f8f0a02eb5ba4dddf166b9b95b4a59e72a30c63cf21e6085751923d54b30281e52a09618e6f023ba0a21675e7f989b8991588c96c2b56a78f5d2945a7baeb6a0c1bbd5d95af3ee830f5809c794a15ab4b5f89dd2be2dfdcd8fe0520fda2b3f02a1ac0155
+SIG: be0fb3308a076a61a4a92a97f6ac55327190e1341d6dd410d86b41bdaf2d3374093ef720bdb77feb7014e0f77d3b809623c7ca53e2ae4b097113e96db77a2d08
+
+TST: 503
+SK:  e965b3f257356685c98b42b964a253fc495399cc94b099c2445fc81c759c68e5
+PK:  689f5410c8e0f4d37bc07c85d7cce6c9b63601f9bdafecaa448a5eed64afc8c6
+MSG: 6f20a9ad27e30dac76b30d4c19a5bd6dfd6d049213f4becdd963d72b8b2dad687b003808201d50f7dd6e599ef58ceb6068c545ed99b9e763f9b0ec1db5fcbd7d490a121ecec6bba1eb5edbd6de85364707c55e300c8b16bb2530f70898136689c988591d5391d9cc347d7931061a9b7696e2c9f35bc0d304a81c2cf954d9c3a88a22e1d67bbe0a85308477f62918c25db504e4762f0e3b4246007908ac701779006b77d72510edc69e17d0f6394c77e5551875a446f81233415d0a91a0460b51c413d644e850f8557281c46699e53b22a7c73b068ea38652cff3b0a7b8ba30971eab18fdbbd8739ee1ee0cd5cbfb7d5d41757b6331271fb7809751e203513c9970f66d91bc0ce062f4fcb28be0a699867b79594c6458a0d307acac91f413c4615877dc53e1b018da5cfce1b63f40be1e55274c4374cdfc21524499a683a231adef779d1921440e5d3fdbd5033dc983cfc931abe638c35d5a95869e9fe3d93eb90bd1861f855ce1f608b7bcad6b5e1bd97edc95ed5ddcbcb715d919f5ff77df2da438f7a3a98286dbd5b6e043fc7372f69704f09d865530f4f0edd3300f185b6d73d8716d32d32b1c9ac2ddf4f902d3f216d35a33f368095ded10be94bb53d6f256560fac2f4af0edf5c5c702143777126e7de32d07493932662129ba0e7fc7cfb36fd2ca531646e8cd2211854fc510af3b1e8cafde7a
+SIG: 8d2bc4e1cd256aad8a151dec010dc93a5e5cca58298dec49cbc9c4717b5cfb5460d430be726b0f302cbd926beea19aa3c93aeb452a44f6007af49adf2f05bb04
+
+TST: 504
+SK:  bc3b1e0bf8d69ea5b4cbbf10bb33fc955adcbe13fc20af8a10872ce9df39d6bd
+PK:  accd2628155919bbc7f9d86f91dafec35c711a78c79ad360eddb88fa8a180b2d
+MSG: 4c73e04abe0819de1f84d70541eb1bb61c4f42920e1f2d1d9e6281a8a2e8b3eb45537d83969027f99ef0ea27ca085b13f9db480f00c02f3fd7429dd567708953bbf3b9e8e2c6ac4d321ff8f9e4a3154723085a54e9c9573cc7350c09f8973f948b08730373597a5fd0349821ae0a3cd6c84992b189128f3490987e1e9ad4f6574ca538fdfd83284c1eb0953f24c08f74932d4364dbbef922542440dae80424a92eaef27c1889bd08c44f9df03a3af30dffb48fae445e625f4d9265cf387a1da35fe4c231504535db72ea81a186805f856ebe6a6a65241432530fe6c960c5f9be6c22957060304e9dd8efbc1e482e7ddbd8af03bf2382899c986d916611e4f27ae52f817ef01b6a141fe4f685d94dc8cd52830043934587704c1e642e8fe56be6d6b85bf4a6feb2b6858f1f007f99d39ea04c9fe5fa7ef1b91f495ed0e7fa4213dd68cea42b6729f95031907e27c44098094386fabfb04ab9b4de3d6861de462312c59b27c76f7b6a4fc71ea0d5daf6b7320521a67e5cb37504976ad73dae2d649feb75e2eadd3401a7f2f36e16dfbfbdb2af5716cba1bce20cd47ce1c1d7be00697001fbbeb4915aa6e5393b5ab20e0f31f5119149a2cb4c4d452c8156113ac7824f84f09aeb81202e8dd3dac0aa89399b5a38b1e218301960a37d52632eeaefe3687455464288eb17d9e19a3a72ed9de32c17be79a3b9
+SIG: 6ef7f0e91f2cc6715f8e5a98574b4400c261a643e0545ff26747f8e1739899d76640b6451c43c1d03a4775b54fcf9bce18ed3fccad338b7764024fdfa2de8201
+
+TST: 505
+SK:  10718fa6e2d7f6ed38fd66cb6dbfa087e8f1e8a8a24fab58d79d7954b8720c3e
+PK:  870d4f666d06fda9f9511b58602eec050d754ea6d8e79cdd19f601c477df1aa0
+MSG: 41259b6eef13d6ffe33cdde799b995c40be782cf978440b66be51c440582abd42f526696bb3cb92265b1ed0e4bba764cae2839830a252635dc80ce5f73d521b3d6ff03ac30e198ad20567e75a34fa825ebf9841508da84cd674236ca7b43de3564c94ab079408fd94137ce3f90a5dd5d3ac39a05ec86715a8f025e4539a7640ab88836f4efbabd5e1652c49ea21613acfe343a880ee5a42f2f9134ef4e3716b16d134a9c4c71c39b3c1a857d3c89439783eef1edd71bf4492d05fd18673a5242ff4187b9de47ad4968da49dba5a6092e95ea27ddfc7448dcf5972d9d228d63e5291ba6e6fbd07e3241f9366ca4976bb04b22d01f0dbae794fa9c1d9029f88a83602b0e0ec55e22c37b201125cadb5341ef73f6da1abbe2b1c475f0750345b1be4259d8c28531ffe7788667c410dac339918c869b00ab80f20bf7990d366f9b3d5e8eb2f48d7ed0e64b85dc9fe3bb998b1eecd1231e902d2d152e09da2d2592bdb32c8cd2e2c489496b2980c03dbb09ec7f8a4ea2c7020f2a0faa657cd6ced48d6da27864cf5e97eea9b3c2f0f34abf8d87bd2adeb60c7272fc4306d955bdc8023d7d3dc2f3dafe9ebe8a8d138965a7f6ce93517cd2099663f67c34552176ddb595ac6ea5609febcf24c7d69d412709e578670a21ac8afccb8bf2b18ff3af7de21dc71d50d60d37b6ed729db04beff7d34b2920d87551ce15
+SIG: e1659186f1f76fe43ac8a11703360fbeff53b5e57b5974aaa08e2575579c27084cf6802e7c206347314475b603197494e7d61fe4b1ee7b78e18d94469352df0c
+
+TST: 506
+SK:  c1d4724c6cb1bc6723b2b43034278b3c5b48fed7f8a3cc2318033e7552047351
+PK:  c27e392e7c3664b9061ea76d2575dd7c41eaf1da3a65f3a986e0a57f6c40c17e
+MSG: deee99d7a77d4300c17aec1ab323c571c6e9e73a43491a3c7888b76fc03ec43d07af42a05a2aa322d00c8560acef314106b10b9bd12654357ffa26f2390050da63d668c9e2df548f87639e096a35853f82e761fd711d2a265438f5d4db5e32775708150da6cb686a2b4ca211d7f00dc0abcb2ca150e791116a10a5efcff3514dab8ed80a7092c3a015152cb25d9f86ec0d1ca67ddab44d64eeb1f931bfab2ab188956c743db4814808c5cde1b0745b3edd340eb03ffcc80a78f3db310f4f5c20009fc0279c2c1bcb3cedf990bd0e20c6f9fb7515ad6e933b07e99da6ac32b97141187ef63bdb1062e37220a4dcd419d6244cdcc34ea41d0bcbc3138b1d54aefc0190e30b187db073aa7d6cfe04bd3fd2ac00313e3ddd64a181935ca4b8b2a85d36bc27d97b7626767b93ee38def8b6b2c8da9b00263614342faa9d3e738d2713c45ffbeef8c84bcdbc8da4309c8445530f5c617dc866251f548950a14f075aa3117f96e41f899dbe7340b1d90a1352d3b8fb41b79f16a82bc2e4a193b8a7232400996b73b1fc00b2ec1c667577f82824d39fb7f6e7692dcd97b1d8ce94083ca197e9a5d40fadff0b9ac57e9de761c156e6d31d52c332d513e9f58697dcbdd80a5e42c551702c3de7beccc3db845b1a04c8cbd41695ea7428abba89e0dce3e3d9e70230ae9147c2b88559dc695d6809a51ccbc1dd9e089c585f
+SIG: d37a6ec82ed45ca9b4855de9cb942564e883ff70a79b8e712d5f604ec8974de5363ac849cbab28e7aeeff28ed3f2d14b608b3146c2efe0735ad815c7d75a1a01
+
+TST: 507
+SK:  37c070d4a53b13be760635110d1bd4f01920225afabec576faaec910f2926d1a
+PK:  0aa85f2ab1dff895d1fad0c119f2bf57126aab601c528d37698e97702d35f525
+MSG: 10c646447f81ad94d015d86d0d98b2452dca60a47ab35264035e33a0942b954e3e23b91d8123b8593c6af7c8d3ecd290e0e5ee36fd4e53b7be633a6cf027a5ac3f0f679eb1bdd210a38ea6e48b0558e303010af474e7f6df2a4e457699fc38e36938b05ffcaa1b694e32f3d1b2cc5d00cf256f12184c873e519089ec1df15b0dc76e7bfe90780df58136fe597fce894ca563e08efa0f2d4d208bede9a874882873d251baf019fe46d1d6504b3bcd243b795351f34d2e7606aa975528ee50d59efb6ee6992a89b2426956c2ca4247e0df0129852983e9767a8eed1bc7335ffca8d0289f04807f67ca7da971f58db8b9bc9fdbe4f83cfe9a00f1ca584798bc71d851ff7cd6c51b8990aaba4d38b416b92240dfb70ee3c12b5e731057762ef90823fbf683ca06d05c20d3ae2b97a83ebe70ae17afff9d16609d546d8d3c74bc281884894f3d49e083f10ae7c11c1dca0effefcfa6e0f1535081fac3a2819fd2e3265527182ae9d391b232bb7542e68455cd267760db652d19e22fb2ed11cd1305ba8d98c1ebf2d1969b24d64f3e319af74e092006d2a3ff744872a20ebf18d17748ab7110805096ea136bce2f968b205e650b803c531d06775ae5ceea28bb92e9a0edec8951ce2009a88ee1b64d9b9e89f69051203384210a102a44d2d6703173b68507dceadd3bf6510df2a5cefd9c80e4f385b2f9e6215813ed32
+SIG: 9da60cc4a64d07dee1346bd3d3010995ce2738208ab35b34c2a8fd1787ae3a1e207fe784525154fae4f5794cd8503045fea85cf77fd92f6a70cd0c5a52c0810e
+
+TST: 508
+SK:  1126496a582ce58d3d618dd8a3933547aa7a8a30fb54063b8dfdd31671c6c73d
+PK:  e10229c623fa8ad8982c3e4c36ff52df0f219b57915b6e980e5fe72ea0962e22
+MSG: 6a4b52d730ddab829b2a179590cbd4c372498e9f439977c0a10dc13c0ae1736eaaff063371434fd0da80360ec5890607d2fae1c9a2e1ab0b7f3d667f5b1b9c418f18b10c9e6fd669d3ebec168efef44163e577a2ebd0f2cb768f80c23188e86069e4d10f410306cedd7a341a61e0f4f3bc25041bc2f922ed073e1e2f1b709c579d10630f33071754d707894a1c62190de18882c564dc4c01dc545dd8966404ed78fa3267a9469f63b6120abb65f9b3ba3eee28d79c2eb4e7020cc6987dfc5c29672f8c0fa3e690d584fe000c64f352610179621bfd5ff3eb30d18f1a0250416db93b1c1e93cf8a3646517560d1cc8fff822b51ef27b200e987b592390753453ef138bd3d29db7cb1b5f45e4795b89c53f49704192752237c6ab274849f9594ee9777f6efe70483129d067f97199d9ae36090703864f7ca4750a6f3b6ff83824c910484394d1e2eceba18446fe4e994ce07433a740ddd05f0e396d482894e6f14acf7b97bae6c7eb88703039fa785d60a3af78b13243a4f88dde1d998617f2e3fa7eafc2f435dd4ac1ea9c238407aa09b4eea8ed434927b406674ac270458cfb3bf29c347f94559613179b9502192321b88e9af0a90e9a4ab9eddaae382e3734d1415ebe32499c34e6fdeaf15b0d9787985e08dfe495460c54f6743d81ff16881e5e30c51f4b092373783f12423c3e1ae8591130a269980caa1cb5c
+SIG: b30eb56ca9b120bf849a3a9d56af033de8a590c9e1240c1e36dbc6cf0a71b78a11ec143fb9959a8f25b57711d6a90a67e01be3a4da2b69394869bb8d64b87e0f
+
+TST: 509
+SK:  9c167aff3b1b788f133d422de8ca9a64316409f9e35bfe22032ec417ae9abc6d
+PK:  efb534f0d47c068e77b28a906d95ad8d213a4d4fc1c70542f01e596d57b5f019
+MSG: 68ac0fc2b607ba38e377fae845c808c8f9fa614eb1f31158a9620a937d3e301e85acaa69144bc349a39dfb582041c4a197ae99b4d4d59b7a2ca3d16228b5591cbf57c18a781efd19193c47b16c6023a3a8ba3d668f05a37f1e83b0d7febdd10f63e48ef7a20e015b1c6725d4c300a986c60e3a115469c8e52ba05b51c05d0af40d89fd9ed76f36950aee3c7819898a903cfe0361a91c69100b495141e86ee79d63d17403fb1a1629ef63cb7e9d2720cbfff0002b190bcdc26794124dd38d42bcaa7175405eb0bbcf8e37d65d05a37195b479371fa2bbbb167d91cee88235dd72ea88fc73ce3ce43d33b715f25f192ec215dac124899c5e7586e86340d8cbe53735defbe02e4cc9fde69fb9794d1db72b98c0f19766ee5138bbfa78909aa299b4913c499deaf54b4841d5044829984936700dcf92f36542b2fc7e86441b9925f5d0b78c17a85cfcfcb20b0fd751349c27463abde4d27df74265288713f96dea013b945521808b4996b1b2dc0338b6d236efd6d2b27dafda46ec5fa32b965e8bb5e8bb61bd966edeb774681e0ea8c17b8c99fa7d660f0f66c9bc6d95cbd7dc094724098eb05191b53a3df6566b9c90e0d7dff2943848b61a20d48c22b6d3c958e293d709c8f48110230ff51918562877daf6d920c85a82e07c451fe7ae9759c0a77e97bb298b5d0592a41d08f67a4ed5a1bb41e937b6a68aeb38fd5be9
+SIG: c9ae67fd6415dcbab292fab394ca6c3b7d90ca244dc6a7764e74fd202bf4b2905bd2030e6beb914c3c238db371b1cba6d9261aa392ec871a4b8b12fe9c1c970e
+
+TST: 510
+SK:  e9948805eb341b2867479c668fd3532c309941c0ad4cb2e54231756e6a1bdecb
+PK:  5447a8e34d6a640002d8d60bcf1ddc711e4c465c94c34b50bdef358960ff81f1
+MSG: 91cffd7eb1cf6bd4756bce6a30af9dfba26ddd1cce0394c194a3e39cc3d1cbc221b7eb70bea18d29c267457176a3c9e53c18e47d10a67c464505197702e6b2470d38869db5174b158f9992e4435d02246f540258dedd3ce33df582555a681fb76ecaccb1c2989b177e3b7e454aaa529de59bf5a03123d571df2e7f7cb830805c58b74a653bac0e5a888e08dc2236d6cd496aa06d0d67cf3b335e218c49dedad82fc1be9ef20cac61905c30eb132d739b16ca8a8c906619c0e0d8b33985327e36f3d4b8fda387c186cc50443104db761f7ff9301270204a713e58902101fad000ce931647c577fdec148dca95cdc08918ebed037c60332fadf088f036083ebc92e173b7ddcc30c493f27e69cd17a20d30b78f83a72e4f5a747d86d96c5e1bb7a438166204013e2164d6aabc0d562f54015c365c80445607145e5692ee34f6353077fab7452d88ce3eb01d2b3797dc91b341a3a726301516baae18e851f74dfbdf0866bb2376867de55231e362c472c52116544cd4f81e93571c4ec820e7e653f4e21be0a942576c9de91e7d1251683d859de448f822dcf3d2cf55ede2f9c71b6063d1373061f8f5936b698d1384e65459ea2bc26ec96775ef425207432dda0ac1fe28526c5e4559349c3d8df9918230f4044683cc2c1b858d141ab8d0805bb9336067522aa89c810f3eaa7ac2d8dd28c3751225a19ecec8bcca52439946
+SIG: d3dc62d6ce9c766f2abaf9a7fbe09d6bdb07a4747b56080db09beb4a4e804a70d7ddf4119475c7be834f31956f4a71dad029cdf2363dd0365ce22dc27f078003
+
+TST: 511
+SK:  b01753efa73bb3de7aa778be7afcbff66a5d3e2c2f8b5aa2b048844050996965
+PK:  d0cc6cf109c999fbf6d16f471fafd0232b0a68d4c46406ec7545dbaba8194158
+MSG: 684e612f27eead0d34844cc81ba911c28aaf6d66e71229e8cc3462f7c7a050daa30cb74471150f07dad459b5a91358476c0598255d8a642dd7c0802811bd88e4cac597efe41ebd96cd0f3b5ce72db4be1a3dbd6b84f5446e3da600d3b1d2b460a009bd31cacd98a91518ce33e9a703d404288736ccc43103fc69e67974f31652fa3dadef3337f6c897a3d201303c8f03597b4a87c98f291ccd58a3f1e898332aa5993b47fcb5ddaa1c0868b643742d0e4a4b9cd427038b3b74999bc89ac3484c0ca13f25aae8e78ae1ccee6218accab81a4f694f5324a347629d49b55e4037504a9acc8df58c6841dddcd4fc4347f7b6f1fd9de0564577e6f329ed951a0a6b9124ff63e22eb36d3a8863bc1bf69cea24c605967e7d8948953f27d5c4c75f0849f872a3e3d16d422fa5a11e1b9a74df6f38b90f277d81fce8437a14d99d2bef189d7cac83ddc61377ed348b3c4fc09ec2b9005925d04a71e26d641667bdf549294331c6ea01cd5c0bd1b6a7ecfda20b0f1929582b74697cb262c3927d6b223f4b5f3043aa6eb4571a78e9da11c2b36f64552580caa7b5fa6b90f929e0162e608d1240d7242cd2f47025c03debe059b1dc94770232bc6765148480bb1d9f50da1ee6448cf9c88b19dd459932c06ed811c4a64a12d5938bd1c757bcfaeaee8933fe5fff21763de740482bcf1ba59afdc8fcf873c3d507bb394e32e45f736519
+SIG: 16b7421227ae09130685cbb1a0c60aa57a5e1afe1bbe6bacea0c281bcc8998e6824a772c3208a6b6b4d236695505c9be82700cf93a783985a39e16e377a7410e
+
+TST: 512
+SK:  4f4b20d899366f2f23ee628f229b236cf80f43ba183177c97ee34829546f1742
+PK:  c94576641f4a893cdfcee7b39fc21929b86b349976d7b0a46d39a588bcfe4357
+MSG: db8ef02e3033e6b96a56cab05082fb4695f4a1c916250dd75173f430a10c9468817709d37623346ae8245b42bda0da6b60462ccfdfc75a9ab994e66c9ab9fecdd8599610910affe4f10215cb280bf8f9f2700a444796dae93e06c6bea7d8b4fe1301baa79ccec769368feb2442c7de84f095e6b3bff63d388cbafb2b9809dc38e9b12ebd039c0a57f4d522e91ec8d1f2b8d23a4a0ae059af85393bb0a15f749110f6774a1fd731a6ec213e4ff435daab546d31ed9ec3b6d8cc2edacebf4facc5566556eea92e5b3f2542239b25e28012dd4ef40072eebf83ed2a255181f3a442189d68c6c609f4dfdf3db7d67d087a2fcd6d2dc50bbfed8bfbbfcb74d3c41f02a87865b13b8efcf5c3581257be0aa913f60c370527bde11a475c136a17c5eefeb03f5bff28693ed841e8ed1f7c29102f5599dd444009bcea6a92d5574152458e0caf8a36aa72b5dc4908a6461c9b741453005c8fbcc68113ae184208ee14b835480c6efafed18a76000b38e5858290f4d51f52f096cbe490e1eb5cacb226ec495a55a7fa457843d57fab67f8be7e209334785bdd665d7b63e4daf57b6e78928b603c8c0f9bc85464733b61273ef9e2b8a0cd7c3bf8ee0a6872e34d5a27a625e35eaf7ff5440b8b141af704df70c9c18623bd11209513192505105cd7bcfa5f0d919da706948fbe1f761f315846aa3b4813dd9ba3d81b9204e5409c0382b6eb
+SIG: 0f80ff5d17488fe26f93c543b04ed959b5f0643fc61c7f2c3bc60132ba9c6210c8b250ea5e84d07b01de68bc174414eeeb31fdc2ba6823e231e312a91ededd02
+
+TST: 513
+SK:  d2e01d2578b625a7060aabc25765f168c680cef767aa97ca0e5eb3d667474b2a
+PK:  191ac223575424aa354b255b812dd3025d70ed829e0826c01629f9df3545082b
+MSG: 20d5dd699b2853302a6817094d5ea512bdf8534504cb289c602467410740ec7eb8ea6442c80f145935068f9122fdf4a39f2010f33db55b814d97bf2e5872329f1126d4eb95b806ca1973113165b116be8716371f81331779dc79a5cb3942081ab5f207f6b53db0e0038107d63ca97708181982dcb5f3b93010ec6edfb2cfd31cab00090b3c38515f9781769686cb17ab81d54a8b775754d42fbad086b80b28d636f78b7eb77ed9ca35b6843a510f0ad0ac1b20267a000301b3c707a20f0214d59b5b8199c2f9ee25d32060ace3e0f2594650416a00716cd3f98604a5e104b33310fdae94c314013cdca5ba2414409eb7f1901394f007d6fa0a29dbe8ec3df98c393c8d72695877cc9baf491ef30ef7db3371608ca97cc621562520ee581d5d1cdbc78232d6c7e43937b2cc8549e6f1e08df5f2eac844fe0f822b2483ad0a5de33be64089490e77d69800fae2589ee58712ac15a3f19e6ffdbca42fe1894e889b94c04b04240dafb0b2730c236b8cceb2cb97afd1d515dc19d1067fd4aba8ce297fd6d110b35a21bd3c075c577d93fe1df77d648f7119492099b017af44eba09c807f11a4c3f4a11a2fff306a728ba78983323c92a2fd5fcc80c18d423426f823a73fe04094955284293f5f6b3ca4ff1080dbb1e4c6f74c1d935ed21e30094c7de336b82dd8200b0d659583c5bfd5470f9db342e70ec4000742c5640a214e3c2e
+SIG: 87a010394a9f2c904effefca9fb4d5ce13793301a4925ba51db119123a4d730abf764ce065e48d90a79d907d7254c40cc358987a46949e928bbb3cd085dfab06
+
+TST: 514
+SK:  7cd7ec99dd03aede1ff1073ec2ca7010276e947e2aa9b0e65f877e4ccf1b3a14
+PK:  e4c39dbe9493176b8213f1422a9de7c74fb6a59190fcdbf637c7ad5ee165c04f
+MSG: a6034aa3c2484923e80e90e5a8e1748350b4f2c3c8319faf1a2e3295150a68e1eeca1bc84954cc89d4731a7f6512af01464fdbce5df68ee8066ad9a2fd21c0835a76559ca1c7449a933bcb15af90223d925ff61cd83eb935698347a57072709a86b4e5a7a626e07a3f2e7e341c7783a540f84aa73e917e867bb80bace6254705a9d1a1185de56e1a4e78aaf539e749b8f765bd052c4cd15b638bf8ecf87d9814606fed5a69f4dae9da47f3806dd90be64fccd3365cbe9e01c588fe65d6b603280740962aa8ddb95a3f4f674c03bc4043092c544595568270a2c2a8aa06e3f67c31998c50b9a58acad00690d3848114cb193293c8ac21016fd996f5c64214064f82167b2c920cd8a839755852ac77c3d90526dd3adb96837cf4e726f34bd02955cbac5b82c92cf4aa8b54bb6e436dae9bf893ef050c6f135a7e62fcd834dac1d2be8b8e59d696131811701c4318bb6e9b5a20bec656fd2ba192e2732f422963bed4a4fd1ec9326398dce290e0848c70ea236c04c7dbb3b67921440c98d72753f6a332eaad59fd0f57742923fb625fef070f34225ea06c2363d123666b99ac7d5e550da1e404e526b5b229cb130b84b1903e431cdb15b33770f5811d49fbd50d60a3474c0c35fc021d8681819ec794cc32a634bc46a955aa0246b4ff1124623cbafb3cb9d3b92a90fde648e414636192952a92291e5f86efddb89ca078aea7717fc7
+SIG: 6f99202770964535e483a0ee01a529442eb321303fa805d475604d7fc728a9103fb7b558b955f4d03719eefaa3b7ed5b0da75710bb98787f5c2282ed66e9f60c
+
+TST: 515
+SK:  e3ca3713a2fd412ad5336bc356b77be027d5b70815b3ac2aecd8340ef5f889b1
+PK:  1d516cb8bef116a0c1b6929009933f6eb62c23050745fe7e8d3c631623778111
+MSG: dd99baf295e013eed107ba8af81121aaf1835a3cca24f8e464b4cfcaa3c7bffe6f9536016d1c8cf375038c9327e8e21b004066f5eac0f76a3e8edfb07be8bd2f6bc79c3b456de82595e2c2105bb1b0aaba5eeee1adef752167d633b322ebf8f7cd5fbf59508fdbdbecf25e657a9c7050af26a80a085b0817c6217e39acd54cb9fa09540fc7bdc5226d6a276d492cc8a3dffc2abc6d0b9fb08cbccdd9432e449821a5dc98cfb3a418e539c890fe5a0446b9f81d306700927ade61cfdcc0624f13b5840748774604805731d92e77d5def66be44cc817946f1cd758196cf480f99e7117835c4c87cbd64077a562a80cf11d8ca65be7a94d92b9ddaea997e93f1448577ed6d8436b2f3144692c1fd7d28a03e9274bc9e8669d8575f5de20cfbdbcb04e9f39f3451d7048375e2698e722846cb4f2d19a810c53d4c1a6c3b770fb402df0530e7b2907223fd0899e00cb188ca80c1531b4e37fba176c17a2b8f5a3ddc7a9188d48ffc2b272c3da9c9b89dfe53f2fe7e3672f91d11818491ace140adcae98502e114f4b352b90e2e7fbd333b2459e7f15dd0764c9c34e4cb7cc095500cda035e8e2e4e3c8fd5df5f3aa579a735dd8a9f19ef336fa971114e46618734a4c13d30c81128ca21def47330103d23d80ffe67421a6ccf9f36a93f05603c599ee10b03451f36b2133c187a79ad9e6fdfbb12595ab73bb3e2e2e43030fd37e591cf55d
+SIG: b3857ea61baa9e62838c4e3a996502d3364fe1ec594258355073dd10e497c600befb1f8f233fd6e3b2c87f10dcb7261aaf3481bfd0902605accc900fef84d407
+
+TST: 516
+SK:  29a63dcd48a351771411fddcab46bb071e91498576e8d02f8b6044f5bdd3ed90
+PK:  3923fdcc2a9fe5cabf6e9932e46dbd2b7f3632500f9d95552db2b045bc41166f
+MSG: ff18ca0c204c8386a4aa74ec4573c7b69216b31470daedd96a4f2302116c7955d72dacc88e3714550c09e6f7b9a8586260dc7e63da4c633bae0162e116e5c1797b78d87d47ffeea3d7819df9c852f0ff30936a105d3af5531a8f89549711c14c2d3ee11564e7c8525bd58864009762a05541d8e07ad841a55a6a9a007ef209ccec4b5640babe35651b61df42de4d910ee73a933c0b74e995757e84a99eb034f41807183c90ca4ea8d84cdba478613c8e587cb5f8fb6a055081da6e90220d5d86e34e5f91e488bd12c7a1a6b3c9fce5305e85346658effa810d0e8a2a039db4a4c94965be4011f9d5e5da266233e6c4e18ed4f8a25a57e40a591c7ed590c0f8b1a119c7c9747f691b02196cd18e6945213f1d4c8c9579c6e0a2ac45924128d6d92c8e4c66065320353d48d1d5e13194d905f837078f8dac0b68cf96ae9e70554c14b2fa29b19630e4b0f5d2a767e190efbc5992c709dcc99aa0b5aaf4c49d5513e174fd604236b05b48fcfb55c9af10596927bcfad30bacc99b2e0261f97cf297c177f1929da1f68db9f99ac62ff2de3bb40b186aa7e8c5d6123980d759927a3a07aa208beeb736795ae5b849d5dae5e3573710aaa24e96d5791e2730d0270f5b0a2705ba515d14aa7e6fa6622375377f9aba64d02569a209d33de686e089ec60118e4814ffc6c0778c6427bce2b6b844cfcd5a7ced0e35303f50a0dfe5df5dde1a2f23
+SIG: 12bf629593e2caadc910ec40bfe2b7a62514126b16ba3a438d88e2d21f595aaee8abfa4af2ec870361d0ea04dfc8c6a330fb2841c2d8211a64fa1e7e7d273800
+
+TST: 517
+SK:  c7188fdd80f4cd31839ec958671e6dd08b21f9d7528c9159143734f94b169883
+PK:  019752ff829b6859b9058d00c2795e835655440675753f37e85eb7bc5839c4ca
+MSG: 4af5dfe3feaabe7f8fcd38308e0bd385cad3811cbdc79c944ebfe3cd675cf3afbef4542f542975c2e2a6e66e26b32ac3d7e19ef74c39fa2a61c56841c2d8212e2bd7fb49cfb25cc3609a693a6f2b9d4e22e2099f80b777d3d05f33ba7db3c5ab55766ceb1a1322af726c565516ce566329b98fc5dc4cbd93cefb627688c977af9367b5c69659e43cb7ee754711d665c0032ae22934f44c71d31178ef3d9810912874b62fa5e4020e6d5d6458183732c19e2e89685e0464e91a9b1c8d5251e24e5f91813f5019a740a04b5d91cbb8309e5161bba79dcab38239a091f50e099ff819e3a7b5205fe907cdfe9c0dc3ee85e32d7bcd3ce02635e2058388031e317fbf22ab9f39f7f7e3cd1a11a9c1f45f4e1e42d2536c122c591837911847108ceafd990813c2b6344cffc34be37161dd815626900e8fcb85c21afb4f6be8ad01516a31c2a6580315857c6a216735ca991009dbc2ea5034160747a869d5cadb0b47ffbd5d3ac97fdd0526cae6eaa35cff7a16eaf4fb950ca31511346fea6141999a3f754e6281cfba15e8a826932c589c5d247c909d94b4eab7ebcb09077648af065c2d86611eb588453ed7c24780d73c689c8744afd533a86d9ee9e3365732cbd0c351e436f898b7043292097e03e6081a23ac865e19dc8858969b999d01fa65ef200c3f269c818e30b9365ecc683bcfe69c203b4e0ab6fe0bb871e8ecaaae82d3acd35d5b50
+SIG: 35c170dd0c6dc2920a595775d8e2dd65243e9c1bf96ef42779001ed45f01b7dfebd6f6a7dc2d386ef4d2a56779ebe77f54e5aecfda2d54a068476b24dbd78b0c
+
+TST: 518
+SK:  38ba0621704d2155fc2f78555196575de06d80255c35e9dc965b6fe96a4d5389
+PK:  4388f7f68a9effbc366e42d907015604daced1727cd1d89d74adcc789fd7e6e1
+MSG: ed4c2683d644b05b39b048ef1f8b7025f280ca7e8ff72cb7eda99329fb7954b700400705275f20b858cf7e349a3510665b630609c5e2e62069263ab9c55e4123a564dca6348c8a01332075e7a5bec9c20a03807957fefa910e60c35ae579778ce2ce42e6a69a1b647681e43ec4b63bd5fbefabb31712cb3d6419ead78dd41c8a92aaceb63cbfa89d2af39606de010a397e302053a615c16e5e95ad9935c079a0b8103125789471a1e3574f429b29e4d225c7723fbb3cf88cbd73823d9f0b6c7d05d00bdeb0fb0ad3d7132033183e21f6c1e8d8e4c0a3e4f52f5001da687171345c6dc8b42c42a60d1f1ffa8fe3e7bcece59a035878f9d4d81127e22496a49bfcf6bf8b46a80bd562e65255071f9d11a9eb0481f4626d4d71ffc38afe6e358a4b289179cbce9764d86b57ac0a0c827e8ff078813306a1d5fadd32b46a1fbcd789ff8754063eecfe45313beb6601c3a3010e8eb97c8effbd140f1e688311092d273c4defca47da6f1f0825744676f9a280b6c2a814fa47fabc1980d0b37f087a53ca8778f39ffb474ff5f1171b442c76dd008d92182f644a714a0f011e215a78b97af37b33520ebf43372a5ab0cf70dcc1dc2f99d9e4436658f8e07cdf0b9ea4dd6224c209e7521b981ee351c3c2df3a50040527fcd72804176046405db7f6734e85c5d390f520b0c08dcbfa98b8742480d5e46f9be893f6d6614340f8161611d5053df41ce4
+SIG: 42bed6a98786f664715f39bb643c405ae1750056460e700469c810389504c51cffd9e1a94c38f692fb316265316d8f4dc3ad1cdd8a6d5991ef010cd1489d7c09
+
+TST: 519
+SK:  ae331fc2a14759b73f1cd965e48514e12b29f63b06ccfc0ad49f36820e57ec72
+PK:  08803d48238eda3f9cebb628530121de00f0f0468c202d88528b8bcec687a903
+MSG: 5716003390e4f5216598a03d7c430dbf495ee3a7557b580632ba59f15198b6180a42469c237db5bc81f29cfaab0aff3c9966309ab06958c9d7126add78e3b32459ff8a0e0bdef874b58e6083668f38ad7d63aae1f12e26a613348f9f03ea5d205f045d78cc8902d47f81e8b52293e70e86c9803d4dacea86c3b67458ae3579bc11113b5490bcf3e1cd4e7979c264d835161fd55efe953b4c26395dd92ca4930920e904fadc0889bb7822b1dfc4452604840df024db0821d2d5e96785a5c37dbfd2c375983283e9b5b43a3207a6a9b833948329d5de41e45008bcbad493de5754dd83decc440e5166edaae0208f000c5f6d9c372153209e5b7578116f89cf2f8b1004d1307ea79ed37480f3194a7e17983a230465ccc30fcc1a62d280fbbaccf006dc4dee0ea796b81accc61a063e2c083daec039bd9a64a77024af82ec1b0898a3154329fdf61673c36e4cc81f7a4126e56290e4b456819bdebf48cb5a40955bab297c2bbcb018adbf24828660a5d12a0613bf3ccb5eeb9a17fb0a0547db8da24d2efb87ba1b843142a75e4ca0b0a333e4a14fab35a62669329ca8753f016ac70cd997e8bc19ee448aeaf0f4bf3ce5230550578ab64c19019446ce2d9c01a03d889a9909860aef76f067c50b61c3d0f12cc8686f5c31bf032a841015cfeff1cfdae94f6b21dae941b335dc821f3284ce31508f5db5c448ffaa3773e9be1a4c85a1c58b009fa3
+SIG: 75f739088877e06dc56daec8f1e4d211b754e3c3edbfa7eda444f18c49b69c5a142db45a0a7650e47d10550ba681ff45dd4463c4ac48bf44b73034bd5659220e
+
+TST: 520
+SK:  82435f39790106b3af72f91f14c928d2465f98cdd10084c4a44d19af71a1927c
+PK:  c52a92646f5adb21c6dde0de58786837f8a3414c09aedfc27c812218a7e7239e
+MSG: f3d6c46ac5248d5386b6b68462597d647039f544bb01ac2d1067daaaa397d2dbaf125a1cf8fdf280a6afec324d5311f543688a156c849819bb046b911c42ea3ca01b99808c4d1f3b8b15da3efe2f32523ec3b09c84b48cffd13c17c9e26c912d9c3e9346dfae3fd0c56c8858780782f61a4c4dbfff1e9cb4b362cd8001f9cdfeb1a72082dce9c9ade52effc9744688ac0b86c88266b53d895c17ead9e89ed8d24d40642f3ad3b9bf9bbc4dda7966ef8328289fb31e17c81fd028ef1bd9a1d4c792e86ec2dbdce3f937eecc3eeb5188d325941919bbf75b4388e2399507a3d7fb387502a95f421c85826c1c9176c923e316310a4ba45c8a5ef7557cf87b77020b24f5ba2bfd1228109566307fea65ec015019691217bce69aee16f76249c58bb3e52171cfefd5254e5e0f397169186dc7cd9c1a85c81034e037183d6ea22aee8bb74720d34ac7a5af1e92fb8185ace01d9bf0f0f9006101fcfac8bbad171b437036ef16cdae1881fc3255ca359bba1e94f79f645555950c4783bab0a944f7de8df69258b6afe2b5932217195da245fee12ac343824a0b6403dfe462d43d288db31f99097ec3edc6e76547a3742f03c777efb158f58d4053fa6cc8d68b196af4f9de516fd9fb7a6d5d9ee4a89f9b9bce1e4dee357a1e52c0544cfb35b7092d1aa5a6f7f4c7602610e9c00ef5b8761bc72279ba228a18b8400bd76d5b2bfd7c3c04aac4436dae2e98
+SIG: 1daa44ef06d4c10ddb48678423c5f103a1b568d42b20cc64af110fce9d7679a2dee412b4980585c26c320dbaa601c472defc3c85415daecdd6d2d9eacac85e07
+
+TST: 521
+SK:  1bea7726d912c55ec78b0c161a1ad3c9dd7bc329f85d26f62b92e31d16d83b48
+PK:  c9ddb42106ccef4e0ef4794551d21df94a6306872f231663e47e241f77cc3e82
+MSG: b11283b1f0ce549e5804730ac3207ac00332d2aacf9c310d3832d879f9634bd8a58adf199e4b863bb17481d28acb2da0e1557b8336a400f6295625031d09e4df4d319bbc1e8f6e9232d23053bb3ffac4fe2c70ce3077fc0060a5cb4692a1cf0b3e62fe454802ae10b83ded61b6bf454ca75e4cdad5532f20b70654f12ba906f003a8b9e986f15a39419deb2ea1ead7598290eeebf9252b0c27605a7a73a6abebb42271d71a3c197a46bcc8db11d9242842f378364a37eecaa34e982135be34182c69ca8e6e3c8c90e1b4b2b475815a178377ae0165a764c8ba2889b5ab290949d8487a88e0d3d2bc7e2520176aa6ff9ff0c409ff80515f4f0b83c5e82c23fd3326cdd6b76252e7fddcd6e4770978cd503ed2d6b480101167d3f191fed8d6d74d74a2007db1092e46a23ddecddcdb984664047b8dd7cc8a576e1a806f52cb027a9480a95cc44b1e6f2e286e9b7a6bf7b396fa5496b7a5b1c03d9c5c27da1a42990d10b12fb8640e1596f26b366d270ba64f99afffe3fece05a9b0254b208c7997cdb512fc77527954a1cb50fdab1cc9a45162741fd6f9d3fd5f2e382853d7335dba1e6b2959dd86e125e67b53dc8e453c810bc01bf20bce7b618dd5d1ed784106ee06a3ecaf6b3bee0b56833b0b813139c5a696000a449c97906a2fbddc2d9de9406ea282ac4ee5ef8bf3854c74a6b7173dd2f79c7a126f3c7b0433fd4ea26e877a14831dd415a19d
+SIG: f9b04517bd4fd8ef90f2140fc95dc16620d1602ab36c9b165fff3aba978d59767110bb4e07a48f45121447ac0c1abac585d391d4042041898628a2d2dcc2510d
+
+TST: 522
+SK:  d01a0ead9d694833283b9cd7299a7bd75fa90b1d2d7884e4557b33c998772a68
+PK:  a0f757479ba627efef95d6ec7a931dfac4373df33daaf4ddc4ec6894c8261ed7
+MSG: 7627534e9a83d1e406ab948d30d1da9c6a5db08e0feb7fc5ba5cbf76849ee8add4847ef5ca5a0dae411aca097451cb4c2b498c947097407007640dc19ed938e3b91bf51c9581168df860bd94751668dabd721dc73998400be20c9a563d5051ef70e3546fee673312b52a274041057e70848eb7c5a21644c97e448abd7640207d7cdafcf45da6df3494d3585b0e18ac5ac9081cb7a407a39a877705cbaf79a01b915f736eb025c58b4b5d807fb7b7566c5969787c1d6ca4eba97d509ef7fb3550d21d377eceffcf0eb6681895adbd246ee7bf3c935a006478b832ece46de6118b17e466a27fc2a44a896baae272f9ecf018c65cb50cfbfc8d260994a18a832d971928c449675724585131c871533c9897d8f80f9c0416b718786b10fea8eb5bd813a269a1b677b7a2507a44b713d705086530995e59335ddc2855e847e4f4db06c91f1d54023d8a10f69f9e61bdce4b686fb617bd5030e755cadb1f644e1ddd91619b96ecd605b00198b9a6eddb5a84ebd3692b665979766637c677378c1c77041fd4a6b3555c1dc8a83fe9013bb6106cc18a2b037c9377b7a1a5a5d0dcc54918eaad7e32c880767b26fd2ea2d68b0405f5e074f55a19d8a39ffbb7dc32faee6a7f9532aec8a0776c3ff83ae3a4627738496a371eb9e090b74e0eddecfcd41bed0c0ce581275243472d26da8c998e4b6d6b44fc88ba2ab54642225417120294417805742bdb33b7b122
+SIG: 9a0ff7f35174ec3f66d22a6f06df60e09c8f623a5aca810e23a88d0e6a31cb6f1ce1c1f9dccc9e1484b68dd004ac53597e29ad6ab72e8ce2b75ad5b80eb84803
+
+TST: 523
+SK:  df648940b578bc31d2a652965f30391caf06d5f251599a737ce10be55f4a9d0d
+PK:  27de920419c186b01be54279fb8f9be4bb4b2cad75ca7e8f792bfa7bb97c7f41
+MSG: 1ae520beeb4ad0722b43067fa7cd2874abcf34dd9237b4478eae9772aea297a67fb79b33070204baee440b9c87e2fbcbeb76801dddea5e4530d89e11583179939a00a32f811332c52291cc7ac91e5a970cd5aa708b1da26be9fe432a9bbda1319e31e4bcc9f1666a05b5c05b876bfd1f766687ccea4e4482e924329aface5ee52e9879fd69b76e0f7e452ec4713bff216d00c82599d27ca481f73aae136f0875c88a66b1b6f34c50523ab602e9d4ebb7eeb9e043a65e41899d79752a279d2ed46993926f3621e7c32c9a9b3b59d8dd57beca39285434de991cbd2dfcbc5ca62a7779f475d0cef2f3e562f29acd474f3c99ec5bd8de01101bed2e0c9b60e2d70fd432c892fc66f8d4619a911b5625163e9a42bf9ea38586d8e764001564d335411225fcb0a06dc2a82da0779a3c444eb7864201b43ebb72b921f34d3c13089df2f4fac366ff1e3c0b96f93d2b4d726a5ce4d6916d82c78be354a1230c2cf0418c78a1913e454f648cc92c8dd0e184645fe3781d263cff69f5c60b1ebb52005a8b78a515c7e8886ffe054dab428e2e221d9d76aff42654168d833b88178293e1fedd15d46cd609483129c4d2d84432a99d31ffe9bdb566f8c75ce65e18288e4df8c16731a0f3fdde1cca6d8ede0435ff7436ca17d0aeb88e98e8065cbcbfd0ff83043a357cd1b082d1703d461881872cdf741e4f99bd146745ba703974be40f579bf5c4dba5bdb8c941bce
+SIG: 62bc991c45ba9b26bf440116264162c34c88597885e9605083c604b5f5d8fa6f662ba214f76e6cf84e5ec04df1beefc5f25d3a3b72f98b5069831916a6329601
+
+TST: 524
+SK:  c8ac234558aa69816b368b77b7cccb5c8d2a33ec53aeef2ce2287143bd98c175
+PK:  5364baf1fdb2c63840b30d4031cf83a2e18e620793bae59d1035c0ede55e528b
+MSG: ce488d26975c1c9328b47fa92e19561330041b23a0e57a4b8bca89eb5f615e73dd7fae69c2380e3212f9b73341c356db75a6256d7a20a97f759d4cba7197178ea724dd932949360e96c50a4b3ba55a953372c397b0969c2b14d3609e0a852d484df70eaab11249ebeb3237921f0a39a55d7dccfef205d94ec80d9e1fd6a2c1efd29844101dfe2c5f668adb7975915dedd086500cee2c1e233e8e48855cc1a6f287d63dce10addd13cac7b7a187efe47e12d1c35bb3974052b23a73668d3e4c87db4841af846e808672c43d0a1522e2965f083951b2b2b0c409548ee6182f0c9850514c9e6c102f54ba4124c92a90274f405891e662f5ebb3771b85783156e9e5836734d09d1baf5b2134c93162eec4be03bd12f603cd27be8b76accc6e8b8bac020cba3479651c9ffa53ce4eb77a77313bc1265ddab803ef7a6563ba6f799d1ef30ef5a0b412965fdac0b9dab842c78ee2cc628e3d7d4061e34ede3797e154b06e8c66cebdf2ded0f81b60f9f5cdda675a435277ba1524557e67f5cefafce929291dce89ecb08a17b67a60c582b487bf2f6169626615f3c2fe3b67388b713d35b9066669960de4db413cd8528ee56ed173e976a3c974ac633a7134cce38319735f857b7d71ba07f477ef85848aa8f39e118118779ed87b4f42aa358a89f7ec844a451e7e8fc0af418b85bc9bf2f26d1ea137d335ec7ee757b70ae2fdd9cc134932f0e5425bf37fb915e79e
+SIG: 32250361df6ed283485f95f3d357a4f1c33a8cf91658327cd453d49c953665510870aa454cfa3b83245220a827d0ec7477f9eceb79c4a29f301f953cc8caac07
+
+TST: 525
+SK:  2c47f2b8b9d2cee9e6f654bc24658f9eaf439c23beaa0a79bf35cc8cd2debaf4
+PK:  444af2f34fd32e5a19f61f87d03e107627a3eeb8bd94d2faeaa348b05dea1980
+MSG: 044c8faa8c8aaf9f2b8186a6b9b33847ec7b452423b22a91743d2e597ecc1e1e22ae60053e9ee6233b044e775920e4e3d66719901325cfdd39bb532f8aa469aab42e9608c21260c04c27413a7a94e466f63c4952e90ef90c12814b3451b1cad7da9147f8409220f6498cc0a67fef4bc04fc06e1d898a5515591e8be0c43d75a6fe425b7cbefb1b91b1bd78b5bec7829056982efdc5be24af6678006adc6f0446202e7ec3a2d6979cb0df7e25d74233914d9c58b81cf55be06967d3a595c1b9672869994cfba67162833a2143aa91cc93acdafa5b45208df3e88ccc01a2a4d220e360098d9154d225a7ca5f2f1e52b1003d106650a77b283b95e4baf1e7336fa9a747a2b3823d360910412e76db725ce1ab1e1d189d0d3abef82d7666bcf1b76669e0643b44f74e90ceafa0c8371b57c58f3b370a547c60958f0fcf461b3150f848c470fa07e29bf5f0d4b59efa5ab0d0341e0451d0abb29d7414cddc46cc6d74cf3dc233d0d1707387bd8c7780ff78e546fb77294d58a5dda5f05c1297e3d1771156d285635bf7ecedb38a9e5e77449804f3899ea46a50266b255aeb52d18e0fa136e535cc9026f678552fa3ee2146081d999685e24bf7807cc47c130436c544d35b4b875bd8afa312ce3ae17cf1c7f5ea1ececb50f95344720cecf088434ff8e0ba044ec19c98ada7782116304cbeac1c3e35f5a4f44313354dc9a40ece5a0f9ad3a2025acef262c5679d64
+SIG: 8554b01d09ed86e61395b91a2b1ee18715c42f9c7e7f0700d79ff9fb5781293d61c558dd5b431c93718dcc0f98fb652b596f18c30f82215e8e63e4f6568c8800
+
+TST: 526
+SK:  887fdb4870681d4fb06a936259f75cae0517f501af646bc07a4d72bee7fb1c73
+PK:  c762ebd48b2ce02d06384e38554b825ad322ebea74d259df1547a4d547ce0024
+MSG: c5dc779f3f3fac06dd28e5a67e0e524af5b5dc3b34409657b63dface9471e9a41e1132175a0b569c8fea9d2eef2cf5d5962c7e0b6145a9e7a0c1aa33772044f9c3998c5a8c4886458b4e586f9307608361f511e7ab5092ac41ec76e0586ef5b9c236fcf5ca2fc8dd6aaeb789367f2e7c990932555dc52261e44e49423498b524419183b6c1f1d42c45464eccb0c2f7e25177fe5cd463502b403e06d511fcf9dcb64012e0f20b34c2ea7c004d9e484a7ed81f3260c41c8b1953529f47f71e867843cc3c332ad0366a63817ed12dd4730d3dfdbd7572b9ff798045940dd19fad0c8aea0b4ab61c4016de32799c73aa2b92d2c25ee9b72d46fe8f0693c58775efb05e9e17a5c346a81265d35be69a22d095de186066a5c6d8c07a3d38d002a10e5efdb866da4a9bdd54f5092661b6c2d743f5aeaa4c6c318fb59323903057e49c237b45f67542a4f27caf65b57cfcf88b71203d43d7f95322160f95c232dd10abb113b721ddba2226b063229bb44102336b10bf1656551161249786d454f4e0909d500017f6c7564f733c831af4e5ec94dfd3bf8ff5f3021b70a5ca5d28c6dfb8a2c18a1a662a33359f264d169698c1ab55783faca73bd68c0f79d1d04ae0ecdb52ae761892c02493ff35f3d84f66e236fc58134ad6a77d92254905d773900d9ddf2654c70b46f341dacb4793ca51eede45533eaeeb6e3323bc3e6c85a7940651c4f6f98191c618c891ea4e220ea4
+SIG: 410a5af3c59b7c6bdb214b166cb79d96f830cf98bf52dad7b6ff2979c97fea4fed5ef7d3d49f03097279b9a099226e2a08dd30c60786254e2da8dee240bfc308
+
+TST: 527
+SK:  88b3b463dfc30d015eefbbbdd50e24a1f7277775bcef14a6be6b73c8c5c7303e
+PK:  f2b6284c930d4ad32d0ac719040ee7886b34722edf53da801acb5f931969e119
+MSG: 17c317fa6bc90c5532328f02ccfb6c099e6fe1000174f2af3a3a9309428506717c5c4335bdd7c367ff4e448a9c047503afba68fd8f7987237be7f7fbdc6d73f24c6421cab422b3fb25f67b2d71042e71570df2af37bfe5c114211fd5524b6c1c6cc52fabc3cd7fb464cd580bb74071cb300f8c9f8a46208e5aa5ddfea5fe90697aa2f14c607950c98f2312a9e16ef6346a8fd129232733827e1501a660c77c29c56d2fdd1c5597f8bc89aaefe3713734fe82858201891a1147efaf1d78a471f920defc880344553eb716cce3260e86a1bc0be28373a6a066116e8ecb10a0c4a70ca2b5364e119f84aec60deced3a4eff1fe688c5e3e251470ab516fa964a4b6f28368dd1e283597934064dc0c5b5691062cb2e267bd15fd422bcfefb83ccef7aa9a2275ef57e473149988c1578fd18708d2ff69f8e5980aa826a82cab7d8b92bb53bdd46db046ecdfc8cd7ae5ce44f3c5b8c0565b5d3c072c76b95ce900ac3ee5510db0e75d3a4150a98f3ccccc69e930c6ba741dbb0eb9fb3196871ba206a58e0dae39c8d6bb72a82399c4b7b9da38577ac17ff1524d653c0bf33679323ca7eef4e9228729031560ed8f2e5193c640b2f5e608075a2ed61428dfccdc00050ba4b99ed6d1536d5ac1e939674b41d16312ae5b07def1bf53589bed4400602ee11b850330f38aad33ef04170a3905c28b50ecc57dccf4f29d0c00f713d32ffc857956588a6326b9549edb0e4fe6185
+SIG: 825aff71f79303bf4592bd8da4d7d9437ff267976f746437655988ddcf29379465a3b48c9fb0f31cef03e6368861c369b4364fb8e4b0c72e26a9a9dded1c2504
+
+TST: 528
+SK:  427d6e423917896831601b8f4e21561db6108571be009e29dca49a5960ff314b
+PK:  8d9e6360fdef249975df27b3106a71120587722df3270a85a13a8c3bb8c9809e
+MSG: 9c2cc7f2462e09c4c58c2709ab4259885a4e887d9fa531881505aaf203c163fb3a0dc028f4ada60670638d4a9727a39083bedbaced58edb779e1ce6ccdfb428c362bb1db0c1053006bd8f4bef89a1a9de01c774e357f910e5c39b22477555e5f7c0498b5b28f369e5d3fa42ab360e4f451c69f81ba0f3cced43a559db600104278f868796b2c911b3b032b729f4b22ac149dc467a0cae48d19e9d985b42b62549de171ff566e1d1e9bb8e56cfd1ae8f7bddcfd8a2341827dbe89c882ab3e498339ff681c7dc1104de738b480316943109f703d471ab86e4ca4287e4cd74c312ff7d037395606fb25f871e7277078a787d02f31cc9e815be8600a7c47c6fdd82331ae9c496a547bdb235b8a56d53259e6296124a32c3b625d202419d064b9a4e83efa87f13537b4f513b916a84fc866d8a899804c7833eaa019e0d7e0e8075bd6b5cb6ffc766479f3f6e20e481e6ab27bd808ad906cdcc7827430e312f740f275ddf51dd83248fa057c43c9cb77557b2fd9c2d52824ff9e146deac1e6691d450213bc590a49bec72d52e38f6b4dc6cca951eef2184d2425031ad59b242effa68b6c72c54c9dfdb419c02eb43ef3f34d338d2a9dd03a78cfdd014098e249259e77282e0c3fc1010b02a67ff851e9cfd9749c1cd8f06cf462e6ade995ac466fab5c795e9eff13e55b4350b94c7316aa498df9fdee9958047793e3bbb89fb81da85f4b9d43e4b0d43b381b94cdc9a99d06
+SIG: d1c9a01c56e33960f49df37eab963bc5a99f25c600446ce2ca48d9139da5733b718fbf1a987393f6e5823c2d130c7ce60ea3db3543c8854ef12b98d33adde705
+
+TST: 529
+SK:  be935209f62dea6012ecda6a6156cd166a4d761150deed456816eaf0ce78a7f6
+PK:  d39a89af72293948b13421fb883bbe372af9089c224d42b901979f7e2804e1c0
+MSG: 117f427cb68150cafcfa462c42206141427c4dcea1c8eacc2d30bed1e90207d5ae305e1fc16c54e4c54cc6878cdbedc9f51fe18461ec37c557b115d13c8682c4e15f505296a1760e1e75f5ab27a5c15a1357d2c8c40dd5355f7c82fea5d27e28876358c12e9113ee2983ea6f09c64e06e297dd96b34d9b5ed49fc47a8839549c66b002fe945e8f94e7d2315c50ca4dc098be4b3289812fbea96b47ce604540bde0e5ab0b1bc036be9b6a95e09c81e898640c8f05d60ad94218d0e66ceb85a26b78292220bfd061dd073512923b90c79dcf5a1935fafe8e01ef8bf81b4d37c5a571b50c421f9bd2194bef3586fcb8584877bb7e0481655b05c7b643b1e45b04036272841852e31940ef8f3b6d4feb5df079d176f979c18a11a66d1214e52f687e9063c1c2b7277b685d5c72ad569f7873838f910257a053131c83ebce86e69d736362bebc96bbfa35fcba1cb527e748e5f579929fd40c56b1a51a222e863302705c86f7b54ebfbb9482f7e280f7bec8caf3a6b5671ac30cd1be529288797c013ce56bd186de7dfc1828691425c147c5174a290d80cbd59c19da7adf77918882a7b2a9a64e6d76b48b92f2a266eee6e251d2e817652b88b502de7399782d7529a81d0a363996b9df68b15a7630904c8c246081fa4f09299f15757958e089a901c3564615c0f7cf2752b8b9e521338d836e3dae4ce2374642253c4c9831974e5d8c2842f49007b71775093dfe57f44492f0
+SIG: 08e098a749fce6d12354395878a8be35fe9edf72684dd8281224899b1caea4ed687785dff55a19989e03636e1666386f22c3f443ecf6fd34d599ff3ec2faf101
+
+TST: 530
+SK:  6818c60bb6439ac2eee2d4e128e9d8691d4ad5d363fed7d6577a62b6569994a4
+PK:  7345ec11bccc056fc4effa3e4ef670996aa26a1bb1b83391babc39a1a59601f9
+MSG: b2ae658b3c13c3cdeb1dc993b0f45d63a2ea9abd0b7a04f1f5ce5932806c2ca9b7a204fbf8d066b7f0fe6ae0d1da68c885ee11f6f6db7e8320a2ea650b533851cdd99d903aa0b3faa3c950f702f04e86b4eeb3a1c7bc854b2514fa5b4766d375b4f1ad61075378dd92fd626c2b47e01383ea72987959262c562862b45b7557671413b66614bcc9f7bdb9ee46cbed8965bfa505315090c7204bea89175be5f20802e3deddcbd8dd64cfef7ee6a6e3860ce1e5799df5d810d5ecf32e615d16dff87abd4a636ea17aa4ece5b6b2c046b65b5af749862b45790c39176820b36901be649cf4169df7e923956d96064950c555f45acb94507cfd0c3b33b080785e35c0d2b0addc4c0ad3fb216ac2e601c9c7e617dabda333dae603cc9db1fc62ae4e0e45e3ccdd166a6781e243b7daa138806632f538844ee3d140b7a8bb2b540100778c458e066170705e5fb2c88029098b992c39bc9ff6330bfcfe7752320e6ea0949d2c871aedc187be27fef7db5f72a6a773edde0dc52ae2ed931cb26817b85b1545894d92298aaf87ccbc783e8dd6d16493f56ead2ba852ee9c7d10074406440d2a279abc874f15468dd66a717bace37be7b7055dd9681f8be81329ee7af97e3abc434ac1c93aec582f23fd1ec0fa5aafcf7bfbda00ffa97ae317ae918d349d21a7f4619142ba23dacef7b390ae26a17e2e2962ae27005376b72d4da9e2979653a66325a14617638dbe1a5540b683ac0017
+SIG: 1505967a27b9f86e9242444002a1e3197d74ddcd89659ec5140202aac794b8adc193e7d30f3382642990f6fed7a999cac8c61eaa39b7d90816f1d738744be101
+
+TST: 531
+SK:  6d1da5b483e64b0365990ff09381fb1702fd8ec3a1a369cd52e4c56713a314a5
+PK:  08055c261f26e02a658f66d9ba01fcde53e9ade3edc6bf815e4a6802e1677ab3
+MSG: 79a2c37055f189f3247f1f8cea19b2ea40d858db1f5d1392ee6d411c7802ee23de52ad02811725a94d76675da89a96b5d07abcee233a1a2e1fa324fff9e78a4c196147f8570b0b13713d96aa5d750a15d7cd162e7ba2e75333607dd698eb4773c7e91f7668ff8b62f04640eb12ecf122fce6b832e0d0df928eefd2c2002364af6bb55291d3f54929085be338342f09da73e279c87c8324555819ed57e78d7ac40951d33f65b94aa1e555e92a063d11f1ff7b12694341e3fe444933d01aa36753ed3cdda890bdf95a8205b5d893221991c795ad0a4a946f58d40a453451af214fd465e28d3e2f0a56aa56def8dc04aad35713abfc8bd7856d5a9dc3f60a3f2bd3e6366f1f244e941d6aea892f6a88931fe1c313e09078e90bc6392d490533c9ea3ff6deaf3aadfa8dfdc4e90f64af47589ea65a87acd2199602351d3afc2103196e0394ed523aa799d31e11d34fff546d44f436b34859f9cfbc9ce403de5a9830ec3d453f0d45970f572c144f191b2fbb2d0ea6cc9c8e24d9c0b2183b278072ebb0be2d70d037fd2e8ec18dc4c9b21abdc6a4ce8d4668a220eebd6934f04baf0e88a488d2dfc735a7c5a70dbb0166a21ae011fc6e7da10fc320336271d9eead510a6f7032f2296692be508021bc98c170be4235f7ce31f2bcd6341163683376ae2c5662cb4770c96e018ef1bf47913319c9a09b9e965ab5c3e97bbc756a5666b4567f2cff2d0c3a6a4026158cb9f90f950056
+SIG: a5b8b44a91444c64374b523cb4dcb0cef4ce52408b98126d7e1ae8bdc28cf51470ce4e253e0be62bd68ebf5fa6bce1585eccfa9256c073ee03e54c525bbe2d0a
+
+TST: 532
+SK:  5146f5b7f1baa19fc8cd785c896e0f90f9f659b77b1b9bb4adcab5a6267205e4
+PK:  688a8de64eff33ba6bbe36cdd6a384bb67b3f42636db234ff5efe0b31743c7e6
+MSG: 97bd99f518ee0788d576d99c043b449dfc242ac5eeaec344a19432b345962ec412ce55362b3b851d98119fceb9328347f6fcc68dbf56a2814db09e9385843a931189ea3e72da9d79a45693053c035701dc5551240f95b303fba16f89aa53a43882b0f1381202c78f9c7419899f2351eca95e20bfee76351c48d00499f591da56a99524bb74fe1c834ee91077139f1edf67315c07a3fd97f80b7c276b6cf6b5cc36be363b731217f6319f5129ba7b14d054c8d81d8e3a3f3be62ac31ff62df6a3b2ee2596969b991704b31c689997ab4628bc2660c67872132e85da0c4fcf567965f1254a8f432692a17bb86cb3c1dcbaac939552f09e50ec5b0de2ef85e0ac253a4165655db5b5c49803821d859c60961e061d58278b827dd4d3bc47f1c22de094906bdbbf3badbdde22ba24255855eb86d1d7f37082059311dc0728ebeaf26c4473bad1fa9e614b533b811b6bcb0650c06d879a5245788f3401b46197300774a9aa73cd978c0530c81a53bdb3fc932414b3e30440dc127441eff1605e7fd9ac8c632e82bf1b453d4f33a57e4b67b0b6fcf6ed5555b5f5a300a14a00d0385a33750525b00edb312c6bfdd64edd3b5316d19f958c517634f013b008936d34e9b5e1e9283a5f0fd7783377c0e5090641bb9d338cf3133acd0b971e537904f17af92911afad72ee97f9a8283a16a7e26ab428416c1017dae9b1a99c4c3320ad163bdcfc328bfaf9b8d5d7d26d41d1ef21a5208f01
+SIG: 4bdbd7c64f13e278c23969e7eb386bbe499dbdefc3ff4e30cfac5cf86f216c24c9e6cde20e529d147fb7ea08f2593ad50903b5edbf86b4d28f2eb32ef137f00c
+
+TST: 533
+SK:  5e6fdac9351a637b99f33a264e1287697e2abab0cca16621792484f5606f44c1
+PK:  57e5f88acddc8cde7dd07a3146fb1d4f7a9b6383a8f6b2b8d9b07ebc3fc4dd20
+MSG: 4d6cd3bc2f86266b8bb1b61d0e1caa9bd2d4a180361aef3a18d390b10f7e860f697e247eb6c3e51d3b976bf0ca183d01a69880f15c94b875668ca30dada0895bedd4d705a0e03304d063dea87c7fdec98b89c06f130dd5bd586b54d9ba737826bb405cd8ac8bbc9500acda3c07461d009440af0b2531e72f3ff5016ae2d86d69b87fb273d1e8dd5f6a264beebb2f885996741ffda277a0fbf8ef08f81f22ee5961d9d3fc938362e1ca12004a91d9b5f7a6833a6c22955ac0cda3390671910cbd51e685fe095973e415fc2db8adf10b147ec7080c3b8ebd07d21bb9556da85430a268eed8486b1e31c94313b01649fe91b222f85adee15eb77707d78ffcb660926544d33be9994a297620dc7aed97f392639053f388b0b3aa3bd0ac5b033cb414be520b43df6826b976890d0c53b97b6c92e7d1a1573d0c7494d747e0cad9bd8ea538d62ad59801ad0716f170193e3009d9959c55d2ff64799bd959359abb94ca9723b5ffc24c9507f8c5fd6e88eaae7a70add84d744ccf8b98363788f0bfb1a02522025751e534710d40a2d38a791194eba293fd2046cc14dd3876d168fc6e236cbe146d6369d225bfa67e53979865f78873a9fcf03c186fa8521f0a5545accee80d1e55107221e21f0f2291c143de023e88d7330cc87d4c51ff29a3090605e9739490c1dcee713495f231c2a36b11ab235547fb6328f747336d9b1ef25a8ab99ceda957b2dccee4075b0d03381b94ae18d041ea
+SIG: 987e32e00a8a1632f47b503194355c980cb22adeb326b4e3115ecab04b704d186cd92e3c3ac7b4e2936cbd07cb794ec0cfe91a97872ff2b41376f5f18f55b805
+
+TST: 534
+SK:  fcfff0932dc86ea5902a8d33073329960cd8188a075dd0bcdfa8382c20b0e78f
+PK:  0c9205a90bbe7f2d505e17fa3d080b522a1d7a152cad2d85d31b34a0471c0d4c
+MSG: 3d4b76122373e212a346d19a66bbfc4b623292649bd0ce5cf6bb135648bd01db7403b3d0bdd1697ff4e6e908904116754d370c40d700cdb664c46a91dd84a358b9d2381443e60f2c3f5640261b6b858ba8f828b0971f4122b20288a26ba2090ba14fd276360cc68679cd8419ae19c6d4dc7b6614c06df5e5c0510e2cb686de0ebd75e5210a215562589b28c9ccc7d272b98bd4bf93495efe4fc5b78defecfbcaa9fe126bad30e89b3a389b4256f6a48a76c345de5a36a1449f08345b9a5e6a001da1ff9cd433709348e9aefbc78ba52d3ab3b46986935eba8ecf81edc43c5b2e3b5eb38d9a165e9e7f72f617605463bedba973ebfdcdf2b0889c71412f8f850c7a3b5518ecd89d2e25c0c1c30f085a0ffe540ef9c0e88fc7ec4af1948a4e6f7a6e256b307a1127b71ba686efeadca0e4860947cf674fced6caf7310ccbaa8d9047daed30fd5585d41ddeae4df2fed4b6228032c3e4ae2380e87ec6cd72e4d74b8b4c3813fb043389391e9c13f7d33c3aab5a78fc4c6a634c61a70f02a940548da177c65df6ab17cd9683f37ea821c740889d82e88c834e7d5dc11662ea78b13c6a4b6218d31784219a4767595b1a56216525cd68938b22bdb1f8c5a7f1701afeb961888e2e0ec0c838cd620cb7dd8a1493a02cd56b545125e4700c0889fa2644e644a3af531d1cd6bc95e5df9175f137f28408cb699c7ae66f65d1d2930fac57ca8a60e6311a4078488c9ea404948a9debeb9d5e10
+SIG: 37ddd83f98b057b7cb3208a832c58aa90694563c23548d432291380b73591301f274b04cee2ef78c06d96c3d9b7c17521aae1a8ca50d347c09c3cf703bc8830b
+
+TST: 535
+SK:  a1e4fcfde044f1bb0e7bbc631a831a8d07e90ae08a966ad627b620b1e28c42cf
+PK:  25560f31168bd4b72552ededd08bb6bf79a94063c1f1e1d304869dd1ce049b95
+MSG: 8c1454d4e08a1401646bf7a8859e8a145e85eeeb40db38ff0169709641212c81b67390749c01a79807f3ccadbbd2256f36ffc180cf9ba44bf4a7612d441c23b2e25d33c48a73e16ce357562758adb00553c3142fb8176b6ae8fb610a60f923b0911814b10f5679936c3677b70e846e218f587567f2019c7d282a107f3cc84763adaec88993c0cc5003e77af60d67db53f8cb727aa6672de004498c3b3e222aa7082d91f98a1a068374c510ff53a5e559cbe2d6c7c3442d7238907c811d58aa7f5a46b8311244f0dbe1b9c0e944dda1d8010864949c59396c6b346a11f3aa866d6bceadfc909038d22efbc8f1dac810a9f2fafcce7c0389eb0a56c0f68cae24ae3ddbdff7116d2fadeb9b0e7509536fdc3b83e71354da6a1aed16887490dc2f4df57bbaa7244528fa3094b99e867581acef906270b2cf4deda6b8fd9dbb79add7bea8f86fcb1f64dfd50e385b4209ec0b1a9f6d2e519068297a2b5c405c216b4a2ed983ff69c59b530effa60c0367051267dd2bbd1e86a9ab5a114dd4f69b540bfabfe97c0403b8fcbb27625761eda3e2ad8e625cfe4b615b7025531a498918c24e02a00e797bbafd14f9d3f6827e390063c436080688d037a6e2993c56d3a8e95f375c10040bf04f030c972623d9e3801c13b4ec8d01cf183855f5935f10ddb2c54c51c80cbed0c24db56e1ed148931d89161c5ea37c2f9787f88ef7330e5dcd0e43d81bfc8bf23ddf7983cc1d733843a33ccb395dfc
+SIG: c8001527bd902c15c3dd5ae18180525b5e8202be66711f82885c8222a15f060092a2a6e2f7d7e980311209191b32b8ade48d3ea98cf245f0fad62c009c5a7108
+
+TST: 536
+SK:  bed1bbcae18643d6f6aac34f3d9b6a1478394d02b931cff006d85f21b7dbc747
+PK:  4f528b38185a424c6fdece46511a0c29b7c04b32eb0483abb52d5f8eb6b352eb
+MSG: ff7c6413e618a056de401ee10c40ade3d7c0e6861495d97c2689ec6abb69dd2ae701fdcac8f08331ea5c5f5d805b5789ee5e241ff4ac8b960f4f2b9fef6a727fad86dcd432de9fad6ba45e00aa3687b0ceeb2c0d430b7d5fde63b4f6b982c4f9e03c430abad9044d06dc49e89df481405d8febbb0653e9686948aad2d9072544df9424fd487f4e24ba7f2455ddec4105828c3981bddbb1b7fbdbac155903e960fcd94c0716e736f519867fbc52c51260f571d7edcb081a23550ad8c70bb268864ab276aa2cc2dbf62383bb66030ebe94354174ccec2d2a907578556444507cbf8488bb23c62423a3a98da7cc968f599d3dc84dca3afad7f14ec306e1db534143216aa22ad18074c719570805ea46bc86b71a8ff58e41e73cb29ad5750fcfc9a1c54292b64b47ec9538f53816e36ed0d0c1ae5ead06d477aa975ecebaf62d9023b77e50e7b6d4abdaa485ea34ec766beb1d9ba03c9c067186e2e38266c6e2531e97480214638a2bb31431ac2086797155fc775b3aad8d5a0b904c381edd0c6bc23c66a1904955ed450a9cbd16459c32f5ca354bbc2da7b1a4d814f1b8710aadb2ccc4f397758b7e9d91f3a91e5825ab8682ff5e41702e07841ac7698c3da9f558edd01f86ce2c506bf4c2149ac9c195a59c7dd7d4ecf93c90b4423b4350588d41672cedc8510a7ad53b4b7edcaf23e43e05669d27a1fe97b78730d3fc060bd4edd9872cffb96285351bef148ef783ab392116bd7b907bad
+SIG: 0fc99dd3b9a0e8b1fc6e635af5c64006b67200fe958f53cce1b9b091a4e70669b593f15594bc0842e5576259f9a6859a0db22d740f9f8024b5baf1ef6f958c05
+
+TST: 537
+SK:  c718823f43db2217c66ab2899704165d208573de60f33bc0b9338d880f193fb5
+PK:  2940b879b63f2cb1f6e3ef9c9d333ba91770fe18cc5a347fdf12b0efc5ca2ec9
+MSG: 050e6877f65ec726eec701863fab140b994aa1e92a487db1a18701312057db44bfde70911ec26eaa28632d03794d545dfcb2aed4340cab7d092595cd59ed23994043f50ba696e9802bd64990121397286457ae69d76cb8e34d7c1ab245cb07b1b408f2bbbfdf33a1bdd559636702c918f982c2ac0221f7f94db91edefce28118259f89d994dad5bb013c678c1c338b65396b15e8899c169921f278859ce0c856d889b8c63418ebc573d2d625d5b5938839f2b169b6916d8e40dde70d3b72887ad2478ef6fb1284fa0e4fc524e3c6fa1dd22ba6b81def8279f382bcb45048851b17cd659d59409f571fa8a920a20934d9dbe1022d635840965400240f870aceffd5db7c7df08af89e47e1b9e20bb99f96ab073edf53694c7482890e3631340217e687ab27c984b60825169457d435a5409ad8e42da0aa63e20c2bc67bd8b9a267f39673a77f7f3136dc5cb2d24948dbe7bcd7129318c68c6fe95dd4dd4fe942286831ea53352fbb252a1288bcd838921356785d072134cb820f6279cc71461f431be9d3014724321c92fdc576320137705cffb2c23664b705e9be60ae1a190f3e3484f70058e702407b056d7fe5d31cee9c2a6ac6eada3516abc5517256df1243780a03bb00ba00ce248076eeca6fee91d5ef9eb907b801af097f3e9eb256bdcde81efe4baf8189b0399e36f1eaa3ab626617cf3b47dd89caf69c64c5b8f68bd917fe03e4668538460a1be88d9a846cef39934627d474734f
+SIG: 4c9cdb1ad46509560d871d3089afb8734648201b10acc953e8b61f2cce2dbae0fb9b868ac957432b7222dbf7e4cf0bc75309bea360b263abbde188532dda2504
+
+TST: 538
+SK:  2543d166c9f5f7427ff3034ffa8103cb117bf472331a73d9a2f1bc0a02a6ff1b
+PK:  42678cf3857021aa5567706db031e792715ccaf8abb02a042bad17db3d5fa103
+MSG: 746d7abf0bfb2662c25ab5c5e4612c306f16d13e44d0db394a0015676ce609784f0323da1dfa94d2b2f1f6e02444a936d019b143021f73c79df9309e7bdff39daeec4caca00cba4ef31c8310c1a08ef4b36f81c377846b5b90acd411aa671ed7af278a24229b7893c1b415d79888d7637f5cb5c9c6c631ae5ffa29f1340e444096ab533617fdcb80ff81da0a7c6c142ee0fe5ea82f68cc3ea38b56f272b0d80fd5f4f55ca9348c161881435813c3fa9fff66a2ee6d5bd3edba0d2f9aa74b1c44bfd0e64678d3715124963ac575ffb09ee16437da484b3ba58e5aeb8ed8c5c0f47b59908fe580f37ec1de266b295d6be85e62358e9bbdc78964fb837eea29fdb7de86cc56f48bd9a3e6e2be51d8a1dcff3ca4d56ea934c682772bcafb51497be5d0f2a23dd4970c02c44c09ad897b4241acd7d6ab12d8f00c9aadc334b431fec5bb69a285b7550a639ece96952682b7334b68c65152e893b1c8100c694d8c5cfe26ac03c1f3914e65c84f0e777290c76f6acce340bff66da7220f73175e94af52f9f19e61f80dc1f35716b3f48dfa5025c9ebef7382e055830f5bbf15c6f6a95032909c892c0f89c8c15fc3ea40a20ee1a4529b521951df44d9d79d74e0c4c2e0fed849b8785206dbe62bfa2ca21087a912e9b184551659cd8a587e95b04317192596bb0b7fc9f7bbb6ee049c8b02fdd758b4e79882073b71eaab18aa293701c17d55f9ec46c52de1e886b6750fb0fbcd64f4568a210ae451e9
+SIG: 20ea9368a2ccd08bf9cbf48d4a2f7d03f0db08a54b87679cda03e296af9ef378be9b8f04b4065b009da6db016f3df9db64825873e2fb4de30449915cd73c4609
+
+TST: 539
+SK:  85e0a80f3b30c20199d9c1ec662e392fdf1546377343f12471db2a0310a705bd
+PK:  540a3a1d83672e495034cff408e1fbe82e538f0917e8a1c7d17aab58e043d3c6
+MSG: d2802f1596f8383b64edbdc594060bff0e7013d5b7c85d830fae11aeb34dd594959da624e044474c5409c0059673bdc61a671ef5b0b8a26f30100b3b73968d8e4d83a72f25b513448d2f6b6a4475fdf89e31ca9268a30705af3f649e3fe01dde0cf4b29ec2da5436444af091d62730acd4cab608f0df26f088c6b9b9673794f0747dab2ce190f90592009fdce5464b3661b7e8620bad65509a6c752b727a8dc8d3efa584fde0272c451d65a93bece4f59d87dc6fbeb451401e3e2e003c6aca7b3d3f92719150c6778f015aff2a59bfbf2e91b21b0ad6877536eb54567059f587f54d4e2a6fe1fdcdd6a7fdcb8515575bcc3705d77859352fa0b044166e3c318846a5df33563003cb20bc942d30391093e8d583e8e64dec570ee1c4138762f6483898d32e2032bde9bbe07ec2c3eb47d96876f0fc0f024d753ceb34ff8480b4cf576230bb8263dd80eeac662eba31d8a61f309e175f4c0143e28a852b1c3061ce78efbd16a2873dd28198a46ec0a800b30dc8a93b8dbb81a730de450b864dea7680e509d800e82329c261b07e72aa80ee16ec375ddbbb6fe3d8d47b0e3c5a9f23c4d20b724c1df59835d830dd22d10403d8f15c102c4b3769c41666c3ab8c7e80b940d0bbb58652d10a3ffe8d44df1012a3ddc4e1c518d49019f7c5d3d9f95ed93a319746d1e543ffa69edb49bb3439f8a325ac6a0cb4edd65ba60080a0447c674faa72d8aebdb5d2544f2f2d847c72c2dfa6057a690adc5c441a
+SIG: 185ef2246aba2b1a568032c7df93c667799b8a521a6f97321ead5866b4cb9c65b64a1c40b9b6a910e742dc32a7e66d11ea45dbeaacae9f09511b8101f8af0c0c
+
+TST: 540
+SK:  82a2c6493f11ba80e4b8b3b43841be970e2a10a94d2249d8ac6f5414cf5a3cb5
+PK:  4c2ee01cdea07db3635f5d4c1082b92f298deb17d0f905df71b66fb2274eae99
+MSG: 09854d13684950419e0bb16464e09988905c0217183aa1e48adb147bfcc2eb57c2300b0dfc39d4896655a57ae20415408bb5f2c238013955f0a4fc782e0c993fe42cb08cd8cf415ccbd6cf1cee2e8097f04e8f09ae5da5f415b16c2cb30cb2ab6652ba50ebbcae4a59e31fe11e7ef3699ca90aafa586bb242c89cd2e332b2bfa2f8142accaf436f89b6453bb4805a1e7f3ab6270f0daf89389e717d1b70175ec5707c8f512c40ab924c457e9f0914791750dc292bb27d6f63ba8ccf54b90d3eba7f19eb300d9eb8f3b72032ba93037f552b409b580a5f65116faffe0fdfdc6db3881386c3cbc16b67eb25763d7ae3aac0b85aa1e9aa22e4959609d4381e4b6d7159ff3e3b2d37b640f88cfbe4f8a77f8016457228ba6d3af5c4e33125d48bcfcf3678c163b698e52e85617ab1a75ff20c690ab07155ee757598578072d4a09dfc6c6c094ec048567d513ce2b1834e163df1545319d8061e0e57f58ef041b7bffc4966ac1660331b97abbc97be21ae2bc58c6c3274a8adad5fd2c3bc16b92e1f8de877b6a26f0c6ab7162e8aab93af8d85918c13d3e235a273748c62f0d22cb1c93e134a495b1b5ef8f1a1134512d53b7a211263177f7a60bdf474691f224a3b5bac4006db345ca6725f5ee703eca0dea10d712676f63ef3e537e63abd2608cb4fbe200e15f18209153496072908044c95a4e9c5356aae8ed5f0959eac091e227a0b81f5803276b3b3bf4b6865a55fc6782f62ea6d63990f9befe01
+SIG: 68a91d4f8d241c1defbd5ca9e9e1ed8274419506751c967947b10d50118bbfabc765ffd7b31a0167c4fd8b1175332412df19d8aa1a909590861320923dbcb204
+
+TST: 541
+SK:  e55b343a0fa1fb747189cb00dbc3a6aa2dcf5b86e57d7693f307420389761153
+PK:  23a14460ea983cf997c782eb4582ab3c8aa6dde53325b977b78e33d2dc5f27aa
+MSG: 36289b5eaff2a85a7c6d575bd15ea594b2fd8510874a469b52109163696d85b68c5b211d2964efdc66e625abe8aafe4cd9220cdb341107ffa8276ed4b370fe376c1482687167dbc8f7b205a3f3301a1664d9072877d9f98b8f69831301df9994717fc88969242391d9b0517d6efb271701eab3f4a9b1204213e8cd13f9d099048b8207562f2e4ebc653cc65e9d5512d65b41022c79b4eb37298769aeaa6efed69e9a8cb445c7012274de62f509f4e4814adcbf4453b4fab85d7c8fd845e00830ef5b7b1e63c67613984caefe915a548e18e505622cb2b39299f427f4d83983ba2aa00d53bee1f59aec8318c5ea345d294252369792762add3e56fcfa6e7797f028c799479045edb2e205eb6dd6ca04eee56f9496d2bf26099357c973835b9936024911e4655d3e22c811c8d4dbd1b04f78973f077523a389b6f28f6f54216142cb93e33d72b4a5052d27e4911e41e6cec7bebe1b0a5113e6b70b479d2abeedf69b7564e5a573b352d16cec890701bb383d3f6656eda0892f8ccc70940f62dbe528a65e31ac538826c138ac66524e331637ba2d37730358e6c732cff8fee940afd22c39ae381e5d8826739b23fdc1b80aea5a62a2cf0ff1525e446cf31046195051d58503eed1befd793eeae1d5d1b62a5c9845157a095cdc08a1d77ba47e84a5a739980f0f5be7aaec9a215b204b4bb7cb1b386ded58d7aaf7285341907c63336ee3e6ef077ad111b974e7504bd989f566fda1b1b59abaa91c78bb40
+SIG: 07266c18650ecf0632e225624ec4c97fc387dc374687a61956dccce72894ee138aabc80cfc90c9eea6dd4c59af4502ee29635a92880786678b14a3931a69f907
+
+TST: 542
+SK:  3973038fa2ef6a278d3c1cff9a225669e465a69d0750503de748c002dbf9278a
+PK:  c75e77c78149d9d2dbc263ddf8ac4d654d1ff455cb1897e1c3ce31b94cfe3210
+MSG: 3392e02f3c84661eaf81a5ff04357f212e92361c5c220739d96b4d3d9c22d18df48be6b55126f581601ffe0da63f38e19cbb12726ca0a6aa325567a003a7849d06783992eb9eb92853297d7228dba980b250bb110f63d0b84670e5ecb319cbfd61278f1f4cabf1fcb3f701f12f6ef8d3cc4282fcbe589eb5659503a2ddd8bba38e5eff092dfaf539fd804f21f73a90adf569a00bf9d25a9ad3a63309cc6093142471a478f0b8992286de023c68efd49987ec270bd946f6db48f684f1c2adeee26d68dce95a55e4cb27bc60523080df6ba2b199996b1f1da6920d1559f79bfde9fa1a02deae1480c76f947f9d213fc43bb2880a1b4d03bb14f5b044a0fd83ce0492f49ca3af25211b86faa5735ad7feaf31a1a7491e708b41829d68e32414f68352b71d1cd23c8e12fb02da711484f6ef97528a00d24fcf91d4e06e9badae9a44dbdb3f778041768d863704d736810400e7f2931efb85c8724a593426aa2af1ec5b664f85c2254896fdcf316db0924e11aae8d683e9a021929d0a9d6fecb4594b1b3fbc16b176d29d1efb1819a4a423fbe0ca0559c57e9e5449f14bce91360dafda6a427ce4a0993dd03082ddee066533f6d3bda5660f42fd7757690d670598ec7096f475a01a519950341a831fc9a281c0947a863f1f6e03bba774de77adc23fbe525cae6ccce47a0ec4979e8bec86f332fc6a5736e3b98fb332e9e8244e68a100455e6499ba8dbae98b92ba3d9c6b4ff980343e4c8ef4d5a4aacf8b1a
+SIG: fc0c5453839ea99296fffa501d58366628df89f616766942d5040a056056dab18b4405c04abf9059c30868d79c936cccc84c4fbd6fd30b60f8bcbd7a66404202
+
+TST: 543
+SK:  c71cc10ad2d443e025ad0625686b123503e590193a2bc8cc57a7b9b4158de6cb
+PK:  fc06acaab53ad08e9762dd11cd2122b31599bd2598ce6f248795e732219c2fc7
+MSG: 2e0846536dc6cce19ccf82dc2d0cd21bd4e1ca7bc317067af8d90ee4818c8518bc3ef960ce112a41d2b9979a282ae13d706a005e0034f06b39ff4b0a5afaed70b561bcceb1bbd2ec19f97448eaed4be620e36a962d878c6f80172b9fad43eed07ff93db9b9ca2262d5a3c229c54e30a45e73660892f048e363f37144ed1921f72992b4d01529870cfe373b7e7cbedaf969269fb70aa783d1e74417c7bae0fe03d951fdb8c71c62e9be7fdd5d233e39f46fed057e49b6f34068459148da3d424161ad2c869508602e9c0bb30bfb88acd5f4dfdffd473503cdfedabc4442b743be075e7c6f610e64ffc2e53187745cd719658fc6e62a5be518437c5bd6a4feba94ae3f44f2f29308e831feefed676909ce5e80c84cbdcac47e47d27c9712a01f6bc5daedc02e6414407e911c0a5a53e5328a5a5fd9f040aa7fb70b79b31cd1b6fd9bd5029040bd22ae222fd2f6870d07f435322639cf3193ca5709b882b07a58f952a9963e568f8c5a584a6b9e275c5c07957a4d2cdaa9f1eb444ed1224bac6563b2f9273e80301d44d50ae383b597213b00da5bf27e5d1fe240cc3bb65aa5030d651b6b5b31761d53ce0c6d74a15dad5479f31c915ccf446659853b89a51a28ee8976853553fd2e02fe7243538d00b4ed07d8b8a80b5c165cd46341ffd8163c555702663a4e6ab2952b7e7443d0f6b123b6946721aa63e87b1155eca8a6a1bc9fd25c6762e52742c86bca1ba9d8370415244f0edfdbe0932b5ca0611509c9
+SIG: 2eb33bc2d5deb7f3a2dcc377b0c6a862134bf3191ec40fc128ac28abf2316ef1401649b8f4cfa1a936de79b532dc043b6d36024b4c37bba29290ac9f449ba60d
+
+TST: 544
+SK:  0a4f5e1670f1e24bfa37b73c994330b36e7daaf930161b78a4a84866ff25e3d5
+PK:  9dcbba903981594c7b677ea8002001d664cff7ce8e5cfae58840cf74aff0d3a9
+MSG: f4b05b3efdcb1d5c07da950c46565528440bb48835ee4c13f43d7a1618de119ebbb259ea7480a5048174faecc1055b32dc01ac7156344321e8eba698f302ee1643b5f04b8e7ecca63b91561ce3514abe7851b6fb17fc943bdc94da308c8e4769fec20fadf4fa8e7f62b6ffb5f170d644ed29355ebd22cb3aa1486b1e367c729dd3f79bcd40ffd08af28cebc8d776e1a483e911d79bc613e09cc621cadeb034dd6f72374771985127f7a3a1aa786a523ae6e34ee433dc30c375987cff50bdcbc997fcd51c94567a67aefb6ef5edf9bdd65964d464be9ebdfb88c0e231b07ff6405c00f82531e961bfc5ead266bcc08718878cafb1d37536f183e48bf38d3f6be900252d1fb419e6a2ac5896039f63c31401fff932ce9814b085ab20416972a2b351c815a62de509674628b0d3566fc9c2e0a9237b93f9bbb2deedf02bff83bf6d868b6399326d4809d0419f31b2f3a481285b94078b47061ce91dad583dd5b13bd010fb30f2495bb70420183a930159e4db193df6acd124423e039a67f15688aec50c5927fb271822aaa66f294bc805d3bc7c8341878a541009f30da99fcc0085079ce7fc55e0011685562abdb3a9471ffde6176300ef5b31e0df609a54a1ee6624070da99c8776891fdf6aa78b4d55b1f5dadfc061add5af00fd3adedb448c559bfff204068043a5d1d6214748628c3ebc5f0224326ca18ef048425da9300133fb695d4f263165ac22f3619d405af271a71a9afb198bf631241d3459b95398
+SIG: dcf353b2b99a4ef45f3fdf6528632e8abdc433342476a8c2b37900404a4e333d387814235757ef7ad03858a0f35d4615e8aba484fd64f1112ec1b1aed2cb640e
+
+TST: 545
+SK:  b855c81805c7087410e69f96b0240271dc76c1e4ade38c6a9278e3c94fbea256
+PK:  6adb025a40260f569884b8cab3752b4f255c373e2b424b6287ebb510fa06fff0
+MSG: 85a9bdb70a6c752897e43a91106ee9a99c2ca94ff7b4461a44a39174c17ecd99df46eecd81c3f52513dc9d547dad3721c6d5ee1f8fac0ba5afb3687044739ed535b844008704c09fe1e5d785d4c9c3d0b05889b9c20fc3fd68df12dbeb2c34f6f7ec1c6fb7fa811ff846b5a61fa5fe55379ee63abcd373fed00254ebd06bc8b22f7fbf2f727a5fad88514159e26d78dfdb0957f6efaf51a8e80b585e838b9621d051074a4f5867b4ae2f2ff6d62b85bccec0b4aaa4791637388c0901fd49dcccce7204859f81eefc639fed92280456e69a1509b4b1bd7624447d862c45a0c8b0c5bb2c4ca512cbc037f51b780982b183a5cafa15297585c947a25be8c2240ebfb6868ece5ea2aab2c239c83754c7d594b3725aceef344ba7e6aef49f7f313b0ae82ccacad387a6e9337f05f8c799efe7829b27b4d5b201fd5ae5834351690759f3ea175fd4741be228d807fb54df4a741038faee47edf1f561652598601f27155fc50d9d5011433711c106d4b60785a5cc93b3fdd1dad70c0c8eaa33f1512e35a541745e376c15167fa8f6b3b2c4c3a366fc41497d297357816ae795a804c980e7cbfb0c74d8835d929ae3bb52bab12964566d746bd2c1d132b6233fa34f75e268edee775eb3ce132e6beb2e8d71f0c8762991cde4e26f71439dfa83978f995603861bc0b1d9060bbccaccf86f8745ad96994d5d007d52e83aa5e69412964bdbfbe4780aaa8de41be1298abbe9894c0d57e97fcacc2f9bbd6315d3fcd0eaf82a
+SIG: 3caa813273e753542ffbfeb21bc3e2cf8ca7d920faac7c49dc2aa9911768c7ad43b38b0236db27f3eeae0b1206001e665a607078c522ed7a9dc4688534635900
+
+TST: 546
+SK:  95b9c8a6ef80ebd5cbd47a04ca54387373df4d67a2b475597765ac89fcf93e93
+PK:  f2c947b18adc3ea6a23f7abca364b9853ae85a2b0c8c26f0d3173c2732c3c7ff
+MSG: 7855bc392630ccf531d3061606ddfc81a0fd9294c54791b5f9559b6827254aa1f25c540b7d7df3ec9cdf14256629dbcf9b725feb3412ebf35f0ef9379e4131cc77e0f0fb6f7459a738361a99ae4ccb2b60a99fe92bd6c3a53d6f454ee9005bcec5aedcfa82347392efcf1175e578396a8d800daba0f4c2cf4d4913b0528620e3baa0f6d86e0628e47c0ca26df3b0c788c4e16557f7fc28df820c12fbb6ffbfecb9829ddb65ef8d63e90d68fc7194b5b885913f08edee84567647ffa3f0d0d325d082600ce71a2345c77d65bd96252003e5c125a718a07370c31b5708075cf1837c6925635cc68dd1b751e40ab608b0d9d8852c18d3069219ef807b76d288f92c29a93e3d75b5b2e53681671d3ae0145ac03ccad3162e44703b0401d3eb167cd8ddc1e1a5a326b728b1e0c00a94d86de61352a661e40897175d28d341e4d1d9962e35f4de18a54017611ad05359ce08b97bfedbfbe3992ed58ed40f517aab01c0fefe8b63643da1a454152730bf99af8740adf98a77b8d73adb08e609e00ce9b1ccdfef3e9a9b05aa56e0bc79b6bbba80dd8e461af7cb202892d89b2d05a4458ab3fa54b474b8f8f581795d6c2739e59d0fe062400bae2d2d534b340bb8e2615777a9a5615bb2cf437ba525e00e7038f22a57882ac520b333e75c3c92a8b9f0e37f671c94b15dd8182a08d7c143e94e9262b3cc5544c294f5f335c2b28ac119fea00f9634db063993988b5f150579c7cc25b6a1fb0dde94804fa6ef66ff79fb9107
+SIG: 2c8bf543e2a3e00415ee4f107b2f5a6687176f5d521117759ceb561751bcc77d9b08a6a631f6447cd901de96699aebb168bf97500dc54a0543ef14e4b5a08106
+
+TST: 547
+SK:  b786ccfb586d43b8c46bb97b96c918731bc2cc119277f123671e30148158d2ed
+PK:  90c7004600f3dce409fdeadc8ed018f9ea263f75160a74ab54f4c2399a90ca78
+MSG: babf48bd55ea91bd0c93b970241b529d9db43d4927fea5f1a1f7082dd6cb50a52b094b3129fcd903a44fec8bfdb5c86c002a2a452887ca25a60eceb5e1f9f5c93dc59423c7afe747c6bf407cacadeccf5d787970cb0617bb3cfe7fd17563d3a0dc91631f71b84be24ae800113750f031d01fd05364b4f27f86f8dc3ad7407e1ae9e768154e3dde58e867129e2474547b408217964844858d056b31c374991b7f161f52f088b806e0f313d68a15c5401ed55b2b77deea586cb054dcd71af2ab6ab11e84b30c539345de3eb43fb7b3a3b48987c3bfa70655d599f2e31d12ad23cc96e86d380bfda812feff3dd3024292916907022891e119bfc3ed9c25546cd19fc992d8a61e6059ca3ce7802af1118756620b87a7242bd83897c94dd5a36ed40fc0f34c2c93110b37d17dd96a22062590bcdb546742ef7218adccc5ad28f4fce6ecf705835f4113d82ea533903aec8c3820fe4b4715f37e20cebc1e71519aa0b240b4840aa4fdcfb52467fedd8f4d1f9bc33ee114f3ef85f5fdb09ca884af388ad3adf84c793f386efe6ff8a46ed81e5d45a37c25cd80f2d7363f43ae45e3772c0df89f11447939806c096ef933a13944f0890d887c2e5bbb6b12ea950b09b8fe425289377352f35f84cc4dcd4d7a449489fa9251c03113489225809cdf3cb63475f10d341709371c6fd4bb7a949483d1bc2b31ddf4d963a07de7ea5c3fee9a0e33f0769f2faa40612a546974bde0b7339179e4124a447bd42879ccda5c8ad1819c53
+SIG: 52ba9658a1a0b3e98ed5209e393e420066a37d3714daa73d5c671d33075a5f5727fe4e081ee0fa3c2133dc953a2da620291371f00ccb57d8792eb596a2ff8101
+
+TST: 548
+SK:  dd1a9774f7584d8589b19f92ab6939ac485602fe1644cee2f6f3cd60fbd58400
+PK:  4bea7d0b0f4bd590f9e3579f0c5fa4cef4d60a49d2c437a0aaead9d43a73d4a3
+MSG: e5dc3ed26c1f693cf852465a05e3048b505db5116d9e31592205a9c3d4720bc10b6c20639a0ee2f0e147225b5b19ea511cfba0c21aac10715a2f232f10c2c8aad41112b6b012e75a4155f8c6926253ca2b4ddb7bfe7f86e90a53dbc0cba89e485ceca8fd26e50c7f282a253573cb0a8fa88cc44623e82e8fa2edb6cbc7538ac92c11e4c5b1ea5f68966d15d93c34f396d27572f864382ab76a7be65a557b139766368a207d98bc0c20926370dea27048160363ed85f4099e7cd66d12d0988cfc9e2f16aa565f8f33b39e978c0587371f92db5056317564411bd8a3b6fea09d3487aaf734034918ffed1c9fba7bdec6fe68876fc7360cc5629b92104027fe5759c5ab365354751e7969116c3b9a21b152330a96a9381af730d17822d78ad6ea860006915b5cab447a759372e05d495ebb328e75d248daa02f5d2eb978d2710cf1c5fb824876770e32ca6de2c730564892415bcb53e5981d707add961c5f37fdafa1399af8aea960458d2ca310553f7c9866ccbe8e9d88e08a446872ea66fc308c824514b7dace0334db735e6f14c85b5e619a5d605648a881e876c78dbe0657233d4f7f3bfddf63b445311d6abc476347ec4fb43c8946f9d17c369381d1c564ffcfe2dc7b4726fd57387f0b44db8ef95a0b4e32a7bedf319e53a9e7126c2811f9829d1f4ae9abd9d5f42efef2075f47051c63a4f8202040ec4723686382c6033127c1fbfff4bc82373508752d431dc473f52ddeab0342dc4f5447f8f25738ef65d78556
+SIG: 1959bde0a697a63993ec47d158223739fe65871fa05870d7de0d38086591202a51b174d1c6182808c6ce62631d81dba34ebed4af2f29b06c00a57a3cb6663606
+
+TST: 549
+SK:  66f5ea8cdb95ee1a75e32467d7c83c59447742c85ddd499c43c08673e149053a
+PK:  a8ad04b9c144b97fe867374d4fe57d7ec0c249183e43bdfb5d52644e7fbe1df3
+MSG: c0d01dceb0a2d17191101879abb093fb077571b521be7b93a117c696c0872f70ea1139ab628329ee5655fc0aa77e8111d2fc884748c1f267b9eb09dc26f57fc402d61ba36f63f4d589aae63c76eeee15bf0f9e2dcde4e4e3e78fc6c29e3a93f3ff0e9a6e0b356645953890debf62dbeaf4905178d4f0a5a592c19294eeba7c21cf8f1bb3f4512187376de72f1136a48ac2dfaf32d0f37de064592592b6e1bc0c512cf4d2d85d16797853a80933b09c2f7bfb9e54a69e51a8e423a91c3e5fdeb4790533e87a4b1c0e0e23a9db9573ac17ab6ec7014d8b7c4486e15725f8d264eea3050e835ae0ac449db334502a6d97358fa859106ad0f6f4295f2344920adf9355a6949d8d145c25628a46a104ca099bd9dde941119c83820cdc2cb2d09722694901043c37cf0ae879be2030d0373158b9c4b0718298be45f630f6fcdc190f7b2926d87655a18bb797ac50757fcd3655c9e41d5163293d9a13d984f591f75b7e4e5cadb64c4c9fdfef76cab69381d0f60b483f804bb3b33364df8cffacb3c9b13ff4c8d8d4ea40766a7d42d8256c6b1c11c191daba1b8ef21593e47b18858ec19d817358678d8548ff1535d5fcf4414b6a11d34a3742f8d7149fa681383a9408887f1c0a98ed521e72793277824d6f746d49b63d444e312e6d9b986611258196a5b012b88faa29f9a6c67ed25df87b2dbf0dbd2dc3080c5b8d15a37d34729098ed0de92d75807429b2cae5d7283c4e5c9bd196d1ad436c7c34f3c9466e5cb3196b443f4b
+SIG: ec5c7e8392fa8b61bc829681866e45ac8be4b5b7b6a822c1bcd0f2cc2c8c44c33cf83fa42d43a2f1884141b4a59aaff47f9be07e632e2018759324eac9d14900
+
+TST: 550
+SK:  ed2558e5c56784bcfb4f4ddea3c0dfbef8d96ff1cabf158ec4abe60aff66999e
+PK:  1edc991012ac6f888fa7e6045777e9ba1d4c03c40292d2da6b722b4ad0a3ed74
+MSG: 2c6433e9bfbf4cfd4e071f15ce6b129d780a4b3de014fac034e0d44ef772e2c8b0d6a3481d7b3ddeb237632673553313deac1efafe3702a7a4411e12bd341e8d8e96c59c5e30c36807a8385a538e9b66907d6a528400bd9f95eedc5216b28fd7437d8f4a029fdbdc7c938e4eb9812fec05ea693229629ace6acc7af6ba4c238e7722f312f7896b004922f7067ede106f8e70154d783fb41291f3c7e2e4826045b5741bcb4a8838f87a32e0049704e9b53234c224ff898a756e529134c1a9bf50fd029819b2238b60b2aec1128f34d21f9d66983bed398659d808b67a2e501b5a1f25f71f0f0c1eb2fea0ab42d82ff3bc9358bb20c27520c144cf2116f4a49cbc61994d2d710546694c4f602dc406e0b0c27e5f5e64667e95c2ec9df2d6529cf53622ea10b956b345ec55b6c39a1e6ed88ae66e5b457179425d1a849037b07c46cf5f363301095837ce811bff4960bf9cbd15201c1b6740bd70102140744c3327aca9d6d6d154936798ac381fa639db436ee8165667d538a6c74a233c124bf604fdad51984c4170b8200d2df73c29bb1e376affc314dde3e86af9d2c2e6c3a6524d321bce93e21fc965564faf77d0cd1accb4d7629485f564c79f4d8a2fdefb465454028c6dd1428042805370743363bb18476a3f2320db2589c72133cf5e29dafb7d07aa69a9b581bab5a83f403eef917afa14b764c39a13c0c5ea7019d2fdfbd7f3f7d40eb63b2a084da921895fe48f4fd594017f82569b467ab901169eb5da9c40171d5f
+SIG: ab9e01166524fd288e5c689e56d730d4983000551030493334a3984e2223dc9f7a5b910c61760c6157990a4c335e348e3a7bc8223e09c10c5e520c8d61aff500
+
+TST: 551
+SK:  b72798b811e2338431256d2480fe7a3663acecbbe6e6c1b9191e9d9a22447940
+PK:  ce491daad296b55727b09513df02ba5928a371737cd35841e5f735acab7c5df8
+MSG: a5d46298b0790610aedc0970fea2a7075081847266f22f12478b93d7e674c6c517f3c14ed061269d170ac31e2a64f9754a565bac1dd9757322c11132e7bbee5f32818e0e3063ab64e552d09b0fd1757639b9b9d1c770016b677465872b669dd48be038665751674dd2f40a966a26748fd3e5dbfd92265eb936f55b094286c010629904347cb4c526e377470aa96e8169a6f211633807a50030e7ff68e38911b3555e728ed8590b2dc45fea69945cc0c9a3d3e6c954b3e80106a5c91d3d22e89e8c0e1de902058e9cd0f8ce806eac4f893ee0429900fb5487b8fd36dbdcb34f2d54fc6cc74a923951b863da70f1b692bf0438484366cd85eeb880b279f8fca9d3242c558330f1ca57c6a58608cdbc0773e16082bca964ddc40347da8a36b2a9328c2f46609e092fd64b4134eee1d099813e1246489e8ee5b19b3d3b891c28f30b38b6a28ec1d3e9b005dec9c63f8b9813bc1de4aaf995f1779dded15c7a430d70ca46e7cafd4e9a543804446ab0807d64f255e201ef428a474dae8a0a75021b62ad3988ffb81cd8221b243085a0ad046fdc16c67f17b9f81820095953a5b98acbdf93ebcf80bc9c99af5fbffacb61a9251c5aafdb22b1129bfc60c98e0f175263bdf93dc9a08b8efc2e8cdaf0f83d6c49ec901645eac5a4ff63385a6f1af2071897662a372219c9301f545a2ebb8f5917db7f29ca13fc861af38d90c35c03ac9184c122e57b057cde426fd76dca79e25e64dbb41c8414a0450da4905b902ae98d2da4ba792801
+SIG: dcfc6fd47799fec772c2099b3c6437246c3ad07229fc740e05311a206b18b02ecdb026c926f49c6552e347fd35dfde06cb639a797c50612f98e2478a92aaf609
+
+TST: 552
+SK:  1fe7327ea907d3ff179b117811d30193fcba4c347b90657feed98deeecda9ac9
+PK:  eef301b16fd7bf3c7b640bf5ee8700ac5a87169eab5f56015b3f499d955e07eb
+MSG: 19a832f26fbb0239f0d9d26a2ebded2403c2a406dd1f68318d677afa64f35043316a5efd729783c7f9d18c09824614652091886cc954be9f9312d4586bf36f3035ac703438b0cfe3dec5077813c710d1447561ab6157bc7ad5eab5b0c0afdcc9db77e66fa8071366829c501096c3d3a938218a6e4207109d1eb81f7d88bd6fbb2aefb1adef3594aae57c46b7b984db9468cd962c6184fb976f0e2aa84152deb1c76aea75ae488442943a80ba7d98a28cb864b5e87cdb284ad6e8d7aadc6b75d69d3bd345783b3ebb676ff95d7b4191e599851c9628835c7c01197e7c8f86f9c8fb49fe3e28458ba9b0236219bd46c28df6532496994ac9ba733c0105a02a269a2be8b7cb40074b881602ef9247052de9d637089188bd4c185ccae258a2ae9856a2cbf8451117683ce341f8096e1d91e874c5cb8a4e0939eb77373a9a0eb791645b8f5460472d669d8014681a5e778706cb5566bbd4727d1716b23c620d228b5d4dc2b352b423931f8a7e8fb59edad8ae42458729861a98e0c850a77ed655e7fcfe4fe36f9772df1ac3c643ad31db5630d571df9fcc9c50de7622108411962bbf72defbf49e997059c7311bd9ddd5b338a9851938d37e7a262108a291e2016803bbeff4f9c776125ceb7e7272b51c7c33461d8089f8408d8dda92506d5002084d4f414d8a4d28d3694c88630e31801990d95271cef47aa5c263f97b7daca1788701436329b5bfaf72653c166db087708130c5c0d78cc4e9064f860680271afe4c409853c2fad675
+SIG: 9c7fdb53fd606bc7c9c223fe9431e1ad009546d00098812a495197f2541e87f8d6f5da22ecefcbb7da56662a7309d10a6c4a4f7f299278d51bbd11e0cc1b8709
+
+TST: 553
+SK:  5f9dcd93fb140610b0e211b39addb1eb87ba97804877afbcc381388cad650845
+PK:  182a237d878c581933332b4178b67ec408b3194d44e4e69392ef800b267c2949
+MSG: c38b874d3ff010fff1a6613bfa134257b24833cb536de3e74992c3cb01fe3bbdeed97dc3c4596fa44061442bd31a9d4aa8c81e34ad9888718206635509b133b1ba69cb1aa0e75c7a1893c080161d26152acef40f6ef4210e952a49828b5cdde804bcb536cdc349a8e831b4b69d3785a76bd9fb27080565972d0b8fbd16f3f960a6bf3ba0c5b9c404967ec1affe59b8c4ecc650fdde1cb06b70595ad4d325da0fab4c5540a7a8d5ebeacc4e99bd0dc96bde82f2bd7d9586308465e55b1cc388d750486bdd5c7264d54f5614d48726d99e44d7778d9ed0323958ab9858e2b25df2bf994ba3e625e2803b6c6931e7a9926f1e61ed862403ce392ab83b7d1b66085dcc06d82dbf176d016d9f44cdcb5072d004591e92d0459ef05a51b8f54ba17251e16621ebb753e5b1590c02d21e40f4b75eee4602860b9741fbbc0d2e385b8daca83cce68c34a99bde6a60d13ba64347d0a38d64b2ade250f38852c4eda2e2e4f303c3de1a8a9d4ab3300c9e63622879fc8537ffc63b18561fa1fff65531241515a62bb9b08b80af37667a601ae04171793cc83b11adf9c30ca9f4dabc7b401e16a1814cfc750248cc2f77e03f9c4334465ff6a2c83cbb56db4b734751043832c4000972ee3232f929f23337eba5e651e34cbddfe68ba219b632e7acdbd4630a031bf1689fbbc7fbbb210dbf25ee87e2ef2b3cbaf8d9ebd8fc92c3a58d3c05b1385a76c87791d7cd3741b71b6c329de9a9d7508a0c156a9521a9020563099a82b8770ae9a944a7e94
+SIG: c1915e052b664797e0d5faadc78f2a009d6fbcfde03f3aaad59b9f4588e7fc3b21990c5208d3d76b4aa95bd934e88d3c98c591930a59de2a056701d9f7577400
+
+TST: 554
+SK:  925ebe04c6eac49b26738d6c1300f31fd4828478cbe97dab18bb889642e1e110
+PK:  cd7231b6eb74e1fe9f926f00d8de2c513d49640525b0795cab893d0c8929e3e0
+MSG: e6c0bad23a92ae8b1d85778288157ac6c617c63363341d777870341bb10a8d3dfc89be4f55ad4f64e83bf2499b69fdf72174d2844e6bd289daaa035fec5bf7cf45522119dc7a8c811d79578c5bb0f6d34db507ad1fb6dbfff997b79dacfb3da50a415e350c998c0a02800aa50ffdfe5f4276d8e6bb82ebf047fe48711daf7a893bdc7537bdaedf3dcb4dec5d24586811f59b25b19e83ca61e5592fedc08ca54473cea2ec121baa0e77fb2d9d765657de67980ed57f2f177858b6decf84ff90212d9647f41eed9b9d0ea3d8d621e4bb4041acc5146e96dfcf14ea962d30c8ccb39ea2be958c9b8774451bfeb7ddce716e94923cc85fbd3a3130780e2b3b2bb76da5341912a4e994cafa19bba19732f2ea402d71d3d8a969679b9d104243d9839c69ee9e955e1c60449788d1f4f6651f4bc9b94d73522ec0cf72cacfcf19f1f03ad6232104b55cbb8b5bb1e21344713d482742d6abc5a957174f623b8495272cc1e2b8315e5c80f947f500c83d8544f7cd4f65348949ef4420d7fc831fa4ae2ee18dbba614925ce1d767c177a626c4527a8154b57292186b044cbf92894253b00fd9343f9e697b1412eba43597eb72a669aaa2d77eacb968c20fe19505a38074158621b606f77d97bc6ebe50e7589293db27fc7dfe631a4bee83b22682a77328c36d9d7d1d891d65217cc47864f680dc8b5fd1a01a0f7c34430f77060b691a1ad213d22868e61bbd38f43f0c8b4da68a58318666c099766170c2db766aaf417f556cc9a0a3934e9fcef1
+SIG: 2c4d69bed5ad8b9584d849cf3df2bac72282b5f30de266b14f533ca96e9550c4b854c154bdc17aa880cf001a6454ffafaa2e50178de21216ed126b63f77f2d02
+
+TST: 555
+SK:  4dd3b478ebdc59472bab14a8cdd0c2fdac5723ee04dd8917c7cfe7a536485c77
+PK:  5bccb37e68c234bead49337de208afbaf611811d965859a06d31301247d66acf
+MSG: 1cdbd28556ec44e8705afda92bd5a53f95d8fe8b0ffe463373633316c52274c11edcd61551e3199e494dff6d906a739e7b324303fc47827e56def0bdcc46b816017c712305370263babd2c71be478f41ce30b1df63bedd3b2e6a519c53df515852c4137bc1aca49bf4c4631fd6564657d11cd83ea73cc3d0cf9e3b3c3e7ca99b4f12a9c9b67c8798148e0a0dc1ef8bf58642a14f97a572135514c10b19aabec25a9c6b35aa4034a57aae1b6d05bde2b6330f251d78db0993f0ca4c26386e3489a2092833b8acbbc4f4917fd3093df582fff71ece219d3672455582609c0db8d96a70fc8aed6798de54bfb2b3ee6c5d328db163593f58019f38f339fd3753f896a4a2cca8c1400a77ea391935f34e2639c560860810bbbe4be1d16e012c11490aa84f2964c877c293b300f43d379f3eba9af391dee510856a4ddcf76e0a0ae06a6a7c0f9c5e3fa1b8354fe8977b4ea3b20661491fa4613ba62f556d5d5da8213d0121de2c8725df0aae048ac891abbc06bdcef3c3effdf5a31749476f814db9457945f0d91e14080056be921a16aa964a9298221b157594973e32969993310c8707e19f3143abc4fda7c8ad0160acf031aba652801aa81a016b3137039e27d6738d02800a93a86f9f5585c518dfa9e7d8ac727f37437e56d2788386e11653a04e165169f903972a01484751e7cb38632590ec80d5fce4541601a0e095785a9ee8d359edf26b9946e798da5998cbb736f94eb713463f79f561759bbcb4c4ac693cabf2e1e036b2d0b0879a
+SIG: 5788e79e843bde9ef11a9dfac970196a567c6308c348e5174b387795046d590a47491fd71d97aeaa78c1615971b83490e8592820f9592ac76269b9d2ba702901
+
+TST: 556
+SK:  074d9218c1217e75823c90e010484c2adb88ecccd2bdf0120aa3edffcfcbd4bf
+PK:  3735ad1919033d1617b85bda04b16121da1d861b404154fa961d4946e55ecd83
+MSG: 6b5aa40e9167bfdb847daa7d2786e28e7533e1d6ac53beb6f69b5953795a2bf59bbf7d141926968f50969bad742a4fb579d3250fb1be4c57ebf4f9112c70cd9f72a00db1c8896fe2b5bda7c7030f497c0b001ea25ba0d447f08c36db8b907c2f2abbbb620d3e8a2c66e4171285adcaadd1c14fe239bc595f098396aa8780ffb80fe1446a07001ec234d82abdcd8100793915b0b3f80d84e20e51eabc797806f3be8108a4f437550b06694050a82931ac40c0a48977edf6ced2428d7cfea8205506de86408065d1a19870fa33a7081037b3ee4491b6e7f3d10b14a30c209159a1c81231a35f0365b47d3e0da04a32c95d98333c44f572cdaaa905d069197f6e861b5dfcdfb9db6c7b0d0cb00f37c916a1c4c0b8985b09f334095e1283edfdd4e62a2941099a2b693696604d994311e3d5f6106683e1d7a1c7e53df7b790947a9a801a0ccd484395f6cbfd9ca4d9804f18d52bb0f946d1a89f97a6fb0680a8c4c057b6062b2b9de7c0374879b8a6a6d2c10aef780508eb28bb569a08350944c82f6ef28db2304db697c3ae1af43a500b0b974803e9f46ea2a02e85ed27dda616d24d6db3cc4f5aed8240b1aea3dcf69dee5f14f95e6e72987bbe6189bc2045f0d783a7b47bfc19830bc7f4e798abe90245fbd43f37c3f036d1cbf1e73dcb1d9daa87379b1106973481a215c1f4f46c1603a5d5cd97b7076f1f5dc789aa6a71e72ef54ed328a4ab64340539ffd164d0ec645f322d1bc37112dc08d8c8079d19d37abb2353f48b5c492f806ed2
+SIG: b1f71c3bd1b6bec43337e26dee655a8d5f4a8dad84a51184b775b686fad31d8029e3876927f9576e90c3624875fc0029a5c10a8a0af75d7a880c6844a4a83a00
+
+TST: 557
+SK:  d2ea2dff7af0ba2a6bed7f6cc68c0df664a6b10ce801c42ed5bbe617bcc8b84a
+PK:  ab44706344026ed35e21982964f7b4dbbbe207fd27c46799701c19a4d88d1d72
+MSG: 03ab5daebc6e70d352977932a03107879bd55dafd0c6ba7ad9697a17b127b3a74a3eaebabd0f8eeebfc0483d63fedde52deb46a3752449c9c4495c51a1c91f57e3ad2e6d01a13d0c470c5291b8e912288340970fbb85787b8b376d72175250e8cd90c07888bfef5ebf5086c8ff2abcdd12d214b9c45d120873b4602e57a6aab0b828d1084dffaa3651ee35662695b7f3433f4ab530c29ac6cc5bb43eccd1b6898b9ef7aec6d5aec68d5c1114bb5df7820966594c994d640891b8f2dc5d25638de43549d86d34306ff3f574575116405b9e8e286ee0cd978a76002c4435feaac6e84eae1654f339a567d8d04fcfa3eb6a04b9adc666021300e9ee5972b3df5d4d0dd4bf7921dc98de82cef2d1b1d61b797fc9968e118484c41342416ddc6adc4ee5d687d94a40ce572f42a2048668c175cf7b1f24c4efd020554fc6f642e14a57baec23e95c2514306d0a6d33648841497eac48eabd96d04731bab08bf5ea9d43e0cf9a37faafa732869d68e7d5fe6954f8a319ef55da1e178e43e84a3b9aa3ad00c29b1d161163df4b79f288e9391d70a2f8813d66622e8ac333fa6aa5311eabec383ba4cc122815de008877efbe6e12c322c975434afad173ebe24203d916d57578bd2bcacc78f6e2564513f8d113a833c2c226eb97ba2e23361a5d02664ab377f964c4300be2d77b62d9240823a09884df307eff3be5664d72d11ad513e1bc5610dbfd1009db39f0cbfe470555ec1b56b871670793d3b704fb06ee950b1ad2a4d7297ca58bbad810c3fad4
+SIG: 9abdb9dd2ab77b6f5e1b91ba0b613f5f360efb500d3fe99290ef7ca14bd2b330f405a4f7dcdaef4923d3111d40bf0320353386f634b40de6f04de9190ad51c08
+
+TST: 558
+SK:  7a60cdf1870460de8ae7781176d5127e71207faf2f210bd4dc547385b667f2f2
+PK:  ead67a9cf34d0ff14e79afa46f2dc996e9ac0e3e076322fbb4009767b133f01b
+MSG: 9dc023a525d01ba3513798b738c79162926ebccc0adf1e57ac47c20dea6ce1375c3d2aaa1733b7f0c3bd945c335ff3576112bbdc10b6783ba654e8c61047f2773aa229bf846922a89c6a73d5f1051e8d96ed36d7d6747e063a7ac602f19fc52e021a4bbc28b03514fbd51c7b3fd659f12d547d0592dd09f873c9ecc6439c7e931ad0e4856be31c605def2ed9b5d13c5942b2f325397dac6c9760e9b1bb0c06f713cb920c234bccfee9f0b85dd020f7988f3be1cc66e9e51babe2fee237eb84ec7eff9409aa91c194e30db1e065015955de9746bba03f7edf9a587512409a4161fa77ea62ccf431602dcdcf365ed6bf0aeddd32f7c844e3a34d266e28382f4062fd4d6f8214252104d643a9bfd8071716371ccbb54c8cc8db79add65bcbcea0d080d8402803fe232df70f76577247a63d5583bbd5642767bc63f3c5a7bb3a47eb12984e4541f41fdb55869a08fade66c20f69a5a9de25f6b36ba18ace5b4ac336bb2a8ebf630ad03e8bb8731d01e84b91d024d117459a74892e93d53b61e6b8068e4f04b4181f0387b4567ccd45e1b8718a2d7d787872f3dcf87a15935ad7daaa744ed68a28666a51a10d39fc139cdfe9a6873076f7c425009c38faee135e513207b06e7ba35685f5072da34b6045b57cd5d1b1a1fdf017b8aa8ebd27522bc95e47908734e41722a767905c5ecc30c72481b6c12bf4ace94d5bb3a3155691b7075b40ebf5968fdd903d8fd3cc50b8d6464859b10f755132c6d9b6dad1d6f14c4185b264d3497a4e549877fe946e
+SIG: b2e08142bdd62b786592c091f5fe6a9b7f30ce134c3b236fbc6dfe6734f88270ac58f6d74b4fd99c22451ca465a42c006db25af215ed241af1189627c6050f00
+
+TST: 559
+SK:  3379d25c1117cf802ec79c06575d18e6bece4c7093dd43fdee03685c70b2fa9f
+PK:  8525156fe29fc2fbf661ba50182be20c8998d941493d5933dca4d8b41fb442d5
+MSG: 7acdb39f1226bd3abffa50350a1497d761f8f0aaefbfbbbb925ff563e38976aa172d407b61ffdfb1cd538a4cd000b57818a0bc92c0e0cd0a5abfcf578300f5f4e6cefa267275d17845da7066fd4e18010027960cd395e682ad71af349bbdad5ebaa0f11a7761e19ea1bef6610743164b17141453b472ae2c8f36ce6b080f1c0745352454ce5aeae11c9d75de3c08004265fc4ca80d33b26eae1400dfd8977bf723a616daeb6d42199010b73e193ab72a58bdd248a7f4111ca50c1de646bfea7b4d5baf0f93dd973ee93649e21ec0c6c4fcca8cd6ff69df761612021d85ff1fb2a95337da4805a76d347ee71ef19c0dffb59f15f650293abb9721053f7406905ae683f96c83a3a7447b1afb14e1208c639f37a9750ba21da5552cc204eac453ca036282f7e0961093c39ec118138dcf71cf2d28fb96a24962b52d3393f880653bcba2c9b9d57b77c522f421fcf5ad75fba9cf3389b123aa97521713fff88467deb8c8991d4b57c1438170537cb50cdcc657e50e5c480e12c0d44939b6399944e7c71e186c2abb81fc57348836d5e57b72b224a6b71b6caf721aca73478cb6cf5fb89071ae3a398202dbb38c30812563bb9a23406657a956d305a3449a60cc8641b62175a7170c23bd5a25f0f12e15a7ed91fada6a4a2f0e7b155a3d6485ec03ce6e34df7e216240bb28a2dd732ff790d2286e200b33c29a31a5e19ad2cd02974badc4bc22deb7504c15241fc1060c8acef4fbb25ec7602fce36a27bb87b6e6423e6b4f6e36fc76d125de6be7aef5a
+SIG: 4c36bfc81eef00b9cb3ab514c6d451b993361e09a4be4b5040926feb0e0d9b52f03de468e7bad83f379154bf2c437a71f754f3f40798eeebd62e55f2be771403
+
+TST: 560
+SK:  ef38c3fc74f054ae43e8d29d6ba6dc80b5af848270d4af58844d24bcf987414e
+PK:  0ae1478b05fb329965ea0fa928dcbe81a0bdbb6ff66c811671635e4388888051
+MSG: bf290db3dda8763937ae4c83746705327295c2c248068f5ab85c8b5d756f4e3e34062b5549387261476bcbd1e7331990f11910d11f94607c2b71f65b771aacabdc10f42ae918dd2594ac71051c85b330779c47af00a5b98191b56cbcf7efe41a27e87c677168c8abe9496eb2e7abbd0b1604286ed1a1b18d264d733de87d0d3f8055528c4d426d7f8e6ed024a74140abd354007962a2a97a5c2ff976546a8d1ac4924c09223d348ddcd8710a3799f91bb870b3f46d51f1e7f6892d6b08b991748a037a867ecc39ee8d6462a7614488edd3c2ba615ca2e37854889441b13dc835c36b38653f6598616f35783e2e158384bb931c901b703acb3991fb7aa5ba69d9a5bd0570242961a71a52470315e982e341a61c64a619bd16fe8119aae0d7503ce7d7e926146b91c2892f131669d1e39e5b75e9c72452618099a57dc2ee377be65875ee01bb88ed526fc394e2f5c8127a5f69125e67385ef94b1f33ad52629d720e31c02ae0b582339ff0f0bb07ff2b030f48fa7b692716501ad7773ad3151204a2a540fa9436bdd4202a157309ec36cecbe58b33eff557fd33e03fd3eb19009bd7a2dea9efeef8785567aab2a4c98bd1f2a81011b343a9f20c44c577a452fd54ba21029d4706813b2987c76bb242ab2620843c2260b669ad358efee7f9830dc9c7d478a2de4a2cf8c43da770e288e2edbb6d73bcf2ecb023de6b2dcc6b166e87a385eb0adc305665c5bfa57f250fe223ad7ff4518de39c79e87dc101a9faa6821a74442bfcfdf0a9e63a509e2a2e76
+SIG: 1d3ac6b6bf18ab5309148799485b276d20401c6af5f9b2f6032395a3c2f4b673b7140c07cc26f4fc56a5ee00b0746b2a80da6fdad17edd114920101d2c89c30e
+
+TST: 561
+SK:  7e7b39af69380cf44660e2c1ff308334e8250feeb88be0d43aabe5e68b8ef171
+PK:  ccef9daed92523533d4a2dab6d2419f6d08604db64ce37e32904ac77b9b4a01c
+MSG: d4a3976dbf8320185667b5a8236640f2ebc9e45e6d5f2a8d92997927dd9bc5db95f44634bd654eefece10d99d92b46715791645004accc6d140f32a1c872e54aa9a7493af94588b7bb400d94d458d43292307c5a1a3882a1c8a6a78d9a945f79d64b3294a28c3d59d82022b009cc4d2da93a16b071c9ab8ee9a3663d72ed344f151d68c666a4b49652d97a46d142a4741127f3c57f1551c40976cd1381a82aeae7bc5adb398720eb433f0899487ed2378446b1a8dc6a33fcd4537a05fb603ec0a90a27532300242b2000108621b65ab000bc06381530f690d7e56f81604dacff1910715040410aa1f944c92dd9bbaa5bd08ea00c8442df94f085eb3de97335b6005e6f84f823d43470ab1c67da12ad449936c6b55f9ffd203dfd6e3f33309e8a9945a59320e66734c79c4814dba5a1c14095c62925a1e1733efd94817a25ef9e479dd9ccde6ca8adb7a8053c1b55134697504af8053d595b844640b61e93168075468450eb5de0358697c104afa6a3796a509c26b4c277c23fff42df146de55e95d0d4b80a7aa177d99227ecb2a0594deedebb9cafb1a458aca8072cc7d77c7175f610ca300efd7af9388346498c22991564500e0b0aa4d2946f18e6f5375a848286f36954c1ca22684c6928c2a25c7fe21aba4a7111d7e05bc8d70b3dcb4f6aaec064845eef5525f85024c2570f3b78698c4bcec0d71aad5378d8819e1fac44ee416370212dbaaae54d2af2939b82cbaae7f42ff485d45b3acc21090f5ba41ec0da309e52ef2838d1de471e0b7cf985
+SIG: 1062a2dc9cd5379675c04f5e21338dcfb77dfbabcedd62b2607100d7649a05e80871e96123214f80f4f73b0d9b06e2d31f56119cea69da2347da84a275b7b207
+
+TST: 562
+SK:  a9048af0c20a125f5d39c50f22b805ae742cf64f1fe8dfbe8dfdaa511aaa576f
+PK:  158655db94b15ca72983877b6db231a5843df5dbca2810a7e496fb59ab7104ca
+MSG: 8eef2d9f5d59709959c924f87c22789767393a155d5c87de488cef50b7bf7da870e3adc300aee6603b2ef08764d99d9e7751e5dce92aaa71aa18a69cc823134e8552d959a0dbb41117e0a593c31833b6ec2172ddafaf7848ddd18d28d0d4ed33237ec804f65938aed8e8a3280d42e353d01be0187b1301f83d89849067b04a9031f7e0f33e3416240c53d9265ed0663959971f417cb5f210cdc5aebcb5e1db7dfb82df435876a6e98f415b0df869f0d8851535375645eef70faec744ee0dc3acbcb040f68d502c2c62c8db45ebe54854a4b36f43feb49a6d1c2c2ea79914a7c23c60baaa67cb47b2178e12dce76b004c87b7b8346efadf380b9e1e41f63148da51781d75cec040e4268820211f3c462501d80899894e79d618de42461d785aeace53ae14b79d33501ed5629bbdd07128156db0725f5b4bed593a952947830384f61df00ee0aa099099c3cd9765a9c1c7e8a6a83430b8d9867c8e17920ad0ff64d8cd2ff5f114388ce6d43eec1715d035f022fa97969e1a5dd9f58d896b17c1221c9e6c8555597235eeda6ec41b0c117612b00c5f0ed1816b057363582707a8aa0d98d4d4be5e8fa32d6c9d278221ef3067b8ba1516d9e051d2f68b7d1b151f74a3534e7812c051e5f2b63b3035f8e5703b5f68fd2d65bb7565e8aa67bfd2a12caf0bc5481197a9ff89d77df7a0e9655ef029b43dd906d0b888e313ae9d1c7e9368a01352d00c6680dd0f1f574a5877348a7ea2c0b9e8e2727510bf0c9ef744f369eb3c6c4fc16adeb6e1945be8287d0f30
+SIG: 18a312b20d86ac339a58ef2b852d467c23bb2cb1227cb15338af07fd04b9a711e856ee5b2c82e366c17f861713d1088c1b2144d1c37d05bdc00d739673852000
+
+TST: 563
+SK:  f8c9183f23105fad0c6e5103358b583288f9ff6c7dfc91106d07987ff69ce1eb
+PK:  4c79628c958cde0cc3cf686095b8a2f44b7193c616f51b21b670b038ce6f67ff
+MSG: b1d60595323ff3c844874190e1836e4101409cbceae28d5da81fad298fe47f6bdf44745b7cd0d37131c3ec365b92f5a1a69c09fe2d9e81da10cf19d85ff5ff26f9e7db9f0793b25ab26e6a74f44eb8c4f078eb7ad18e65a16210d5c844d3cef75f1daf44eee558f90e524a032b6cae6c8d23367c28ce1c75fc25ac87433977d597533c92ae65f2913a18907ac7d9543df24127743943fefd9cf83ed833f63ec8367233d897bfa12d466d2c4a9ad70d5a672fc10775ea2d204e636de7010788da271df03881a25c8dfa5af73ee559f81b529b35aa127fdc0ee8fd369c7a0436623986aa6407fa67a1420c46f3211ab84f84466dd58bb79508a1feb0a5a5dc3bb0c1b248098262a064f37bb2f019e290c60afaa1206651a2697caacc3ecc02ecfc077f272e8f75cea71c3bc3356d2b5807276f1955001cfe10a61716b4082bd6f84cae4bb0d9a4b75a4b5762f81079f19d7d19eaff8631c924885bd3a64e129f4cf6b79c7a9829665511e9d85c745eb22c1b7cb2a17a49b6285cce37b3de415940328323efe24a1a07ee87468f6510e42dd206fe7f09e3d433fb52156ae348383115648863e45bf6a371b17e70e19f9627d7f0a58b95c6a4788d5fd7862f1612c0347325b797651be30c3e1e60ea4ae60b5745a38b6a9d4eb4935d6f3cb8d71ad3f39adda5e42e2219de0d381909c9cd317dd4379421a2a84268a7ea7180a64c129be1e5e8fcbbf5ed659e9f7e763ce84f630d5407954f9f755750a6dbf9f7660717de8e2adc1e9ac9ee31654d1837cee39795
+SIG: c6a8bc7a0d5c6185b6ecd6033e42321d5c871bf889be72bd54cc0083ed60a470b2cc0fb4682c894c75b0df95f1ecfbba2d5acef3e1aafe54b9f7e803a1d0150a
+
+TST: 564
+SK:  16089a1b932f8d14995688b48dd841edae3da5cfd2cb16555306f3fe8bd3edb9
+PK:  9ecd9fdd7e0b923deff5d887b242585d9d41cd2c7c10f9c345b39f633f4ab903
+MSG: 58500232388d9aa4b5faf85b0233247e717fd16840de9bfd0ef86e01e61302775513e224125e0d20420ea949f6c26425f70077911f9711310cd6fd8bff27cdea11480c73e8f8b3c37641e7e8dd8607c1640218fec80a020928b93d4d557ebe82ec0bb17538867d2cb14d44d3ea727fdd52820b0da944de21cd5da303d776fe99cbc2648365e6a0a98d4db150842661768be84c68507a5c45d207840b033537786cb21dadad5fbab9c5cfc1e3547de550d313631dd4fbb7ca8f71938627608d2ebf655db4325abf3ed504dc183058f9de1e449312d904c846a184a028f364c028b27eb4946427e31c21e1051df364d499f477bf51e7a8893183e5ecf77d513a1a76b1a6fdfb16be90d74be4c4345a4f9f87ee441a1022d67ee844789f21b0c31adcc0d95663cdfb40a895b922dce8069b932c802fd3ab1ef0ce6bffdcc5653b1cd5257e19a0951687e545faf4aa66065a55c4b4191e34e8047d6a4ab52d1b06c369a426ca2d16b51a0271f27f8d744c711fce3aad9d4ac038ee700e4e971b21ca489ff2b8c778a3721adf47c1ae5a41b9a27fa742fd0f18164ef3c26b8ae7d1fa29b7c0cc4683be65025c96537a12d5fcebbd05e930c3693ebbba0a78adf59d8a3b598a348eaa9f47caf531fe449652db5b20d68994e35afec2c25709055a1de26082e3912d497c647720a3f873621456e6a5b9eb613acb43b66d47d0b954c69e8fbf2c5e634c486e5724930e0b56a516940c8cb0e775274deff97cbb7759ce90a2b93e9efaa624e6b38a39849dca1df612736f
+SIG: 7878ab741ebae2747c7897cbb1d105482f37be2f5f91795232cdfbccc526608918e2756ddb7536b3680c162cf8a1ef38a341b9362bfe5d468b4bce21df234f0f
+
+TST: 565
+SK:  94d50915144c7e7dd0f85fef87eddc2206c1569ed1431c8c5a153e32e1cb2fb7
+PK:  3bb098cf160f3aec3170b57d6add4f56739270e4b3a8ef7966ec30619b299102
+MSG: 4d915f27332dd75051719a24ae8d0e9c30da790999e22d9b587ef20321bee4c07d0a12494ffe599f47f96925f5d92517fc3e5f041d0c709f2a9783125eeca6652997201c429aa6f1ce2f07a0d4a0a18cf20b3e9a4f7663ea5262cad8f949411b05ff5c5edd7b30b217d75d8c86c94e5f92c16734374e8cead61b0b27bb4bf5f43a313c1dd5b83e0ea933b6cadfedd7a64aa5dd5b5d02c695ea20e091fdaa72ef4e7ca40f38395be8bf7a255c6d06a632d7d785d9e047f232aa50fa14529f986f9ef9d7b580a03965b0154788822a225bb5ab3438b89a5c28744ab0bc0b2014e5796acb4935a81b02a04632acb88caa7e39e069c7c8e1758291094a53e362fcedaaa583eca766efebf69b38e8cde9ce58e012c60ec88e8c42beadfa838cfe440fa0c01d659c9634576d7d7a2d3a044f99c6e4263d4c0b374a388a2acf38eff29c777e9daa60d598035a7d9edf67a502c3f573207b119cacac3fa71e2a0207c601cc0dd637ef562bacc35c57042738f1f55815a5268082cd6a508292fa29e34e9645d87a1a2b6e58adb7f4a57fbb53e9213ef3dc873f29396258a1ea546fb5952ce343cee9bbb90c1cda72c65a7c8e40312b328e231920c233077dca34d04f9d89daa9a2f43459165fd102ff5643c7175230b39ec7c3c475650ef131609d3220f5a294a403b1e1c42cfa162cd426f0ae43fd6b7ab547a62b7d5f847403c4e5987953877158cfdee23c04f751c7c86d078e824ca63b5e65543e978b6b0cc689ef664412b01b8ff165e7dbde3c099bf4f34ebddcb4c4
+SIG: 59a1ce55f5a6badc1b9391263620542cfcae87a0f2b9502250cfe4bdcbf76c461977c334a48d916edebd56c21ce217c35a6444cfbfd3b11a3d48fa2edb6eb40f
+
+TST: 566
+SK:  0d81926f513db4b25dfa1e52b5dca678f828a61c7c913c828247c2eb0422b7d1
+PK:  0f32411ef91d4e4b6941dfcaab142ef3bec160983993a5262ccf27fadd2af890
+MSG: a93837522f7ec2e93a2e4b4c8b46de926a81ada2d248bcd33b39b6c95fb62a61dbbeda1aa85a21d9b96a08510d8d3a658cf320a10928695999d2c0d605c7f95a12f56a8718507db0f497e3ead613132ab092cbf19d2260358630358d9b26e68d50ddae37c8af0bb7d2741fd2929c21279a78d10e2c5f3c5bf4a42a3617036d54743647765afd8cd910f81b38ced72390630ee68944a37d29c2fecada1cc59ec544075bdbc14c63c6234b884049000c27c73406035604fca8760b49a5e2109ef91285adc4ec48c819d62d948faca90f62cfaef0b07d6fe576d762bfd0eef94cf6b5332c4d422511607f2facc7ac046a59b9617e8383d1029cc91ac592b52084413032be841baa9bf96251a6bda671d4cd4b125da658a4e5a50f4428eebf2614fb0ce5febe80f721a5f4c0325506d27a8d31e33d86253870dd63c08edc7302b280e9b9bdc28beef05c7dcb30d4c162e9be832e1c785e37551218421eec852c4298213b2f27f8f8c706d391b9c69a56db7ce5d81548fca5fed456f2d8afd0b75f79f85868316f4a0921f0c6639926516b3c3e52a9cb22554546ef70e14c77ecbdcd5c0d59a81769b30d5d131f2fb449c996b8de8ac7f8084f8499e1a56f7cd29db6aaefccae8a60e75616a1f702c3bc8deaa1004a8dae0392a59cee54810c6e940eee25fb2e5d573267044b893ffde378fe75ac2613373d84a0ca8187af4a3358e50a994ed03367de645e10390fea4c33bb1a6c0c39858b8db4a69fe894a4223d45af69b36c6117c4dc25de49a63017002ba9ae551ef9
+SIG: e0cb6c71ebf8d705e50cad9f0b8cba3ecf4b9e3793400092aa5b121e7dbbc8bea71df29528ca9b47abf87c198a8dc4e14d5180ce932dd2114a3cdaa5552cc205
+
+TST: 567
+SK:  6c8c53b56bbcb4c0a25dc40c18240b6a5c7576b89dde45ef13fb158ea17f8ed9
+PK:  238e51d6a44fa7ac64268801261ea35b62638a006cc452bddb9f16fc5803060c
+MSG: b60df2944ba015759802d3c587bcfebe521a7e77b9985b761c9676454d24a664af0b0d44225a557512e1c1cd7dd8335c8f6adf928e18f89fd5eedf6f411dcdaf996912e8c3e23d1cb95eca4b9e24e7539c3b98bf3d07ec251392096c19ac5374dcba526132b6d9bb8f6c859ce985d584c7bba5b02a81034b6d8b521bd280e50d77daa2b2413ed679834f8161d5d0573bdd476ac3cd0a3a7d8db45334e89c00ab66bc368a07b423e246434636272aa4e4637a5306b2c3397992781f30238de79ec104acc7200defad960883d391443e70efbd22f1cfceec5112fe9e8e13bb941c083468dd71ffca976cd51ce161793110ef00aff5ee2ccb7706a512b85beb94ac49d19afb6333655cf3aea535a6f9c75e034841e763c5a249b4704e1be78b0ecac6802c343c1b7e7b5770de4c93a3a79c46e6835da8ae5db3838e1796b564a480a4f290b60a1c63a725ff3fef434d2a0b3d8931978742b525c83bae6794ae64193794b370c289ba35ed79d37072a8dcfcadb46d5ffaeeba1bfd4f87d766b504e62b4acdd77446e79ba994d6dbf4765ebd74b0365100da56162c36fe5a95077f6b4265e81796b4a57443782970b96cb4569ba985c55fe3a718380bca39f16624f8e47cc63c1b6fa1bde1aeba9c51f94b702b13108cc1481d42e6fa981e3ebfe064d2dca7420c74595792312ae3fb9101d4b66d9916dfd6c13ae883e661c628228be9794cf60345076db26184b617e272298cd4183f27bd52d40510bb015d2097d4cc76e76c0a62bbfdaf53c7268775bbfbdb8870eb9bab
+SIG: 4bf1e7d49cd4d5c3c1fd4a4bc48ff6b6e52fd9510a411812296996e4fec56be44514c567d1d33477bd5dc083c3958bd95bfe599c153f21ae26252967b7326003
+
+TST: 568
+SK:  69b320fbd4774030a29767a0cc1550d10b749b44d619d41dce1146f7ac80a755
+PK:  dc508a79c6b8ab866cd117a5a84dd9d931fda450bec29335344d0d219216d65e
+MSG: 217e33f88622c96f8d092c9e26664fe9efc0d8d2eb59a036fa464cee65ce4489caf903dce17afafbc4f18dc9bbfd6c1a4be7b83485a6ca947defb1d35125d0773962a344a38b6dca9a40c31c1c4eb2d7f6818f978e573d66b990921b92b777471a4f6f05477ebc353ace1d86b00cc251777aaf6af3aa1179bff78df5048e5ef29968670e535483568d6bb16da829568f81c799b9afd4aad6ef085252c0ce3ac01ac21a9ea69bd58eadc66968f55dee386b653f3334efc398ef3c37a38ce93b21f107cc54dec26f53fee5604eb09a36afe6b665b6324a84c7da7b7dd01d9278e472f15a5ce9ff0fd93d0aa0604dd2df8d5bf6a912734ec51de77f0ce099ba11670210a6a206106b0ede2ded858a6bc411e7613e6f80e1aa52c323e30fa849951cc9b776e4cc58c90cfc8f442df64151a7fd4a3dd61a4336da21d03944635d3fd667be741ef45b1f7cb276d9f4de8107de64582f7917c6eab38e0a8890a4bee48bc92617a361cc7b1d25e089453ce0a52544f868dcb3249de761e79df63efa0794e3c4618c554753ee281c52ac8ad78d5338f0dac360a769381bb4a39f190b887b4723806ac4a4f2ff304bc6f9337ab54c866e6ba51df50c43eab52e2b39794c9917e0c31433f03681d2f1d93a0436018caaae20206a3458ad6c037acb511ef128f6dcd05305f07049a13b6c6c3c5b8170f158c8f12d46e160931ba18bd59ae129ec07a0655fa482ebbd3b850d36b832bbb775f538e3c1b3a43ecf94ca630ca15d502813eed3e35e8fd23d2ab638600427d1597cb29da2a5
+SIG: 697d4d897e0e2cc02bc1c2dda57f0dda620b37e861822bb7f1a701935e959ea0d8453f746fb92c087ed65d980eea1d6fdbf23e99b289aae0dcbb128ef836640a
+
+TST: 569
+SK:  66da8b254a37067378f68138afedd66496596a0585524c716bde2b3124c3e7d1
+PK:  85bde28a922ab5eeaa4a6294521a2ccac0ef2303dcdf8c7fee228fb4552012e7
+MSG: 3fae36638837d0edc8dcee517e43c488ed57fa6c9853a745aaedfb109ec1409fb8a2fe51d23e0dd9fbfd94f91c18e6114d808901bf617d2667ceebd205c5c66f5d7534fd2ec33dbfe580ad919f504204eaf242af8700b138cfbe0f372919c06b861a27d720d09df20f4fb7b748e718b0fc486dbdfcb694cb3f1420035ac1be55d31f30f997a043d04708a5c542ee37c0f7fe0b3211d18a87033dcb15c79e6681c4970593d32a13c48f0a3af8bfc136e0f9b56a123b86c4c640b650cb7dee9a89e82aeeee773b5cb032fca41c20c407328bfed29244e46055a83114614d3db56581604b115fba14f618e102a1e16cb036ea69df9275b977a0858118c91a34b9a8519bd0dac3b61434ea088f381ba08bc1583189a4a7c8b6ad18f732d74eff3acef4b6904df58c6469432151372df9327ae71a0f356c94468dcfc2e4a5c0e4ec0b166d90cd465f9260ebd6a7a62ce6c715bcc715be0c7e1f28c4456012d33177a7d4113c9a5a22acfaf2d6b63309078fc1b1baa8f36c7e866c1f972a6500a5eea79201651a7305208b6c93c492bc77cacbc99c9cded179e664a2f4e16938cc26fca8b433eb8012f7b3ad19ba1fb858fe4a00fb3d1f8fd0eddf0c37dcdb2e5d35c2546f22e8c0f8ce90e2df8abf24827a019b2c33fc590bbe712f019287002bc2217c0dc0931dc8ed8f50bb442f8b2de27857362ce5a9fd97f0fd1b2b9251cad2a4aca1a94de2e953902d7228142407443b1d517107648a7bab83074987d0978bc61d419bc84591c969c3d6f4e86fc4738737bc0558755c110a
+SIG: 4082a5bc730fb54b6bd0bcd2a044ed5d3d327dc19ceac8825e629b9e6423cb1c614236f097a6b73d473947cb81c4e270852ee5f13a5b03dc18e1c9c27a9a6802
+
+TST: 570
+SK:  276548290f3e0f900515dc63366c03fe0fc6ee130c21fb60a4df9cf464797cda
+PK:  7e2a3578000a087edcc9e94fde509fc4be05ca0dd090df01ae1121123536f72a
+MSG: f0db442de29a7a1ded550d120002cc12abfff98b1f576d65bde16deaba687e4e0b0d5a8748d7503da2969c64d6a7c28d27b6c93ad257ce32ecdaee375f43fff97c432d453f7196c709c3bdfb7388d4d8eaf139f182940ce17b4552e2d20aed5557ba4d2acbf845730c0a66b45b40950baf6a946437af6c9e3b33a79e04dceae57c2a549542eabd216bf13948d41ffb9483fe29801fc8c1782840deeb3fb4da3192785bca13ed0a9eff57d6136bafbf9dec697b832447b2b6e730fa7f9995bac6b7832eaa09905ee49d465a5ee450f52d1a6d364c618144e886e8ef633dc79d0af893d16b3eeda0fefefd8759f2a0da1930170dd19eb78f0d7a7b74515403375a95bdbcce018bc1edb08d897bb798a95e7e86a52af3d9b8a4a14b0371d63498dcb2016248ebd0be800e9f21d549e5e0e7b4895ca5cb725a0cab27da8a8b1299be38a4260900ae10df5baba11ae2bab7179dd8453969429ccc4d416055f2bcb93c1cac6d7e804cf812df1462f22ee9e833a9769e8e677550402c4094df212fd2c5fcc09a72c7ce0077510073090d0e63db637d43d4c21f8619d34da5db08033f686ce8b8a0821222f95434ac4e6f703094edded6fb1b846e979650979d3c77453f40f7fee7c3e88a96fd1d702e81c2a4f3f3753c7964842dfd9d3958a743da063d1d648e51b210a28ed2487f14d5f1bc6f339b2dd17a661c39736da99e4a4f07360342d237e3813ea3998d66eb31a2d708af065c32b927f757c37a800660674e9717ba58f280eb2aa464fa74402108a5d5662e8d0feaf329687a
+SIG: 88a146261ad111c80fa4299577e710f6859cf0d1ca80e512a552c725b8384037eecf6465ce97585c9d660a41ab9104e5f7c9b2f8ec6fb21f1ddd50d65b9b660e
+
+TST: 571
+SK:  972c0616556ef22c214868fdd822c55739e1f96a93ae83512afda9ca7aa74cd2
+PK:  9e1c6d4107f8ab8161c5db5b88a37ca1de9f4e291367abb1efc84f83f7076953
+MSG: 8689e2f95c8fd50dc44664a18fb1a9f2c8f3ee73c0f9587ee28bfa35c9231c75bfd3d9534174e5ad3fa9f092f259942a0ff0ba2ca2cb59043d192ca8e3c8869bedd2354cbc5ac782d727c0b69407f68d1326df65a60c4d32f87f19a10f3d765ff923434f5511d134d397c4fef6bb1953abfce60827c359aa4b54f912aa8b17b83dcc7e3bcbc505ba046fe57c16dacf4ee2fad538bc06817c9b9d8dbc5f9d9bbf9f4a934f14a42c29e0e2f3a49f46b20ee76cfe20dea1e97450eb6a8fda048168dd827810207f005a3caa93ca11f4ee608a7a9355494313aec8d7075afc94c7cccc75c2319bb458c0ce373e9d007f753b33b52793d58496b2d25cd1dcd7832aac5ddb38f4db19c427219e1a0420ead47ba95ab6d89c65939041cc734c08eb6b476caf7fc76c598d947ff444b10770f62945ae65044f78098299e2626b638a7328d1b7daa5889e8db94bbff2ded62e14463760227c3f326ed493565ddf0a1761b8e4bb7d2410fa0fdbf35684397eefea95895889a0a9dffc5e02c092383b7ce74d2d90939916f26b71afd265f8bec74f0de247c9643905583df3cee23537d6b568c8338ce5fee42f7dd15dad5247f009acbfd5d769b6366959cd0ae150f58f7c80fa10d989ed90119372e5fea5da48a4e8ea9c727875dc4a2005b0dc2e3f697c0ce0a4bdb2f750c04fbc0c27d02dd8286e54c9c3959b6ffbdb1de2affe9e782651e5168a500afed037b3e1790ddd593851a6a6ccca9fffb4a99e27df43818871536ab04f14a06a1c7cb47bed6241ce7430ad3e640a726752fa06a9
+SIG: 54dd06fbb3d7c63f8cdaf783c2d7bac16b4c826e2d1b1807c84e049f64e271b21cfa3e37c344260287805d718806b62c56b47f6d5c508125c9fb5d5ea35fd501
+
+TST: 572
+SK:  e0405d37893e89f53811d6d446e1f193f51afa1bbba725f95eb48033424a2509
+PK:  45104d595e443e8ce654de9d655054bf0a99d35613d77d57454ca2d1c899b517
+MSG: df58c4fd0702a20fafa3d1d4fe7d85938b120fc11e8d41b601f0e60e42236a49f126813bd512ee71359061e13eb314d417f56d6d560285fa8991213284c42bc2cef2dc937bdc0b5e9dc2269afab32db30e6849855951cfbc53ecfa01643863e0328995fe850c0db55421bfa564601b8c9db7552c7e6aa7adfa15a58021a84266e9595c65fca4a15fa70f55f5d212c9e277ffb830f4cad1861f3f495a9d672f5691310639c12dcd07e3ef17a23750bcb46b7ad7eac462eb512225f3be7e32f8f4987a11df341166062b43c63ab858a600497667fbb88e93c7e2e0aab41c09c023eb902ec3baf679e25b96e106921a914fd5de200a47889de23e7b65d0ccdf0c29036467a1210c0030309a2d04ec256d5a4d8b97d46a3e15f345b667170803cdacf6cb48add0a13462dd30fa062bd4566641da07d7f61e063686edd96bfe8f97b986b7c0e44249cd2d7317472999b8ee4ea80c902f3b188936712e89d8bf02ce8ae77b6b31abb0632065455ddd9f9d1cd953a4a49aac1a15169e687d4fd3f7c2edfb3aabc3b66155f7d315f8a294faddffdb4951367a0cb870759e85a838af66ba3fc103da2babc3f381696ef8882d85a8278d5fac3a72f16eb119ee9900b1fd986c2a9f94eed8e0d4f273697e4363a975ff6a7b80d5b4ec5355bf63b42b71cd4842401d38b5e00cc97bfda40e456653683bc8e6dade7dcf985a97b0b5776c4d72ca13a1474e4eb2eccfcd428786ddd0246d73a6377a79cb8da720e226c19489bd10cedde74b49fac2cfa207129c6a108aa164be9d809c4d31147360
+SIG: 77ddd491ca662ebffb12f7f492d7fbc1a1b447f6c85998f2f7cc9adce67de63b6eebd08117845a0302f7349714ba9db2af58048b85837d7660ec3debeee2d00f
+
+TST: 573
+SK:  5756e752dff69e3eed848e4a49c7a8baca12154f9431dec35626ef8d75a44514
+PK:  5910ef00a5b354143c46561da62c41aa13d29c18dc6153bf8e502e0114007728
+MSG: eb2190a3219c792b6666b2752733ad9f86fc390155c4b438be196959383b25f3a749530d5a4b15ebe2c18d99178e6d45bb4aa2120f95a352e0406c63ac867248d9efba124231064873c82fe995dd031c7cbc7d15ec191fbb6c474dc4c777e8f457841eb4624841c152d15ede26e78479a6a25ffa335563f1064ef09558b910e2608418820f49554b670c6bab34d1d60984dea50ed6a375f45a74beadfb04bd9300bd594e2e20ea5d3052bb7ddc51a949a0047972682ebe66d38aac62927270de42150d58221d03b8ace3589933487bf23d29c5c2c843aefa2e1ca22f9d1680f80c766d143ce5ecef253a745cb71e72f6504ad911f7cb4a819cd074863a92706929a3142f8db7ac164102ac2ca0d2e19a725e1b5f81f443c73e0484f26a45a3aef84f1f3fa04a4ac695d2dab6efba456a281a3973cc186e680a66df521a4d1f9edf4dfb274a427097bf863281cfb0ed80f8d7676638d6cdac937843efbcfce91de1df6c52b594571b9315600e4b6552defb8437a807ba21298e3d972212ba314692917f40075311acd009395241b9f1b256c515735dc674f8e866d1eeb4c328548aee71231c4c9d5bd22e39de88d19fabf49f0b9869cbf835214b15522a93d3a5007b11f0b50e5228d4eebb4571b35da84f4f687e3f43793d54f3825b37a509ea564bdf217ff4adf6847bbea4316a1dbcc7448ecd5363eaabc128decf054ee1a0ee2d871979f8a63b2692b09f6e986a138e7f68f60aa426a1c9b01a4902e13b17bc8312410c28bed29b601b0fc9f3bc2d223f875251100f869c6b5844
+SIG: 8157d8334ded1a32699b350ac0d4120028cd8ef8189448934850e50ee4999d8fa2cd257646d92fba5d662a823e62208ab4fbe01714a848a0b90b55adcd246902
+
+TST: 574
+SK:  b904acb19e5cf872d3640cd18ddf3c0b6657e0117ce659dbf50259015d3fbf32
+PK:  e04a8aa56d1818483b10d0a7c919e1d5d8001e35510e1ec62f7114dbe81ae0be
+MSG: 83f4124d5af955139b1bc5441e97c5fac491b4ea911407e15420a0347ed7fa1f8819e36c8ed5740c99d4505a78b619d560749af50b0573510816d61322cda976a5d4ca3205f5f0e60e759a5df1a0bdf36dfe9717906ac57cbfc970ab43b6fa18e6c0006c84fc7254470a0b774727bf5f8e679423a531e41cb5310f9bcbf5a5445ebc39fbd909ce11e97bc2f66a4a1bb6c2f167f2c6e80eb9b8b72df3e8cfd4e51448dc14c0b837f2949693d1d054c8f95bff7f1e364567d034f2223e1594772a43dcfe0597fd6d133b3f2e96ffc5667dd5928f23ec3c750f845993a34e9776159a6830d6fd9013ee7aeaa1fccd69b96df284704fd08888b15b64e2e90d578c5cfc0f95693f6ab65c6947446a857c029c7ca66080b754c7734b78998abe9b7cc6efd09a4418194d88b34ec6c33af630db81de5b99fe65aac8b73362379119c700d107edfc19f270760468ee8e5f155d9a347e57b5930f327a8d11c6674ddd020f9e7d9b761dba5b83a87302f1833e5abd49526d66391e5bf0e35b4453d630bf7d0adbfe501aef81e6c5938f92cb752f5f14d2806f90ae1546051ccc7f913c5d6a38ff3b7b9a23662ef1f00808edb2fa31ecba5c8d3387e87541cd0616edbf3aaa35a537922861f44cbd9f992b8246d9c64c419881701ab43f7fd464210d802ba656d95c0f24a34599b20b1ec20011485cfcb3186b7bcf69d74581a7a3eed6134c4eecd65574a4320d9c57a849c4e78c8a5ce82505004a54f19d4bdc8223401b34946b7d66e47e63cf9d0f57d0945491384bc6868c4b478690e550021df1
+SIG: 9aaf8ac97140d5508d58f5ac82b7fd47e6b1f68a7c78a2ac06f0416ef8e991953f62c47fd5fbc6c1e01bae1c92a33ef52b7efa5f17bb8633bdc1aeebce318f0f
+
+TST: 575
+SK:  8a3501b76953603c9033e3bcbf3ec378d257011a6c50b89762d491eaa72c5e0d
+PK:  778f2019dcd8dbb86c6737cc8dc190c5a04c50b5bf4588bc29fa2a47af252672
+MSG: e609f1224a6a451140cbc0254d432ce5fddd08a8e912f81c412fdfd5182ff6ac2f13c576c8145b15f25b409d853f914409e4e02cefc39d9bef4a2a060498570b2d3a2838c9b0b8e3af4fc37e1915f804a80188585b30b68a3ffb2e960c7320e827d2fe36e6a328cc6e7806348adb0b773b784de529bb6f64751b2105859494fd49db0bc7f62df46b9d7ce676975cc5f43856498436812e04f26fb8b8ab7eba12f1d56722eb82ebfafa4735977a26681cb03fa4bc6951ab9cbdf787e3278f2f57f29e12095f8ca2a178cfa7571337f0274237669f97657d4badb39436d786492580fd55d86be3a0cd17d16057017baaaea00c1e14552159bcabc0e666bad3418e4ec13bfe163be256f0c89bc2344a8ddf99ca8160b189875ad322d90f581325281d5389965c0a7b7bcae2294a3cbe35a4e4e83b54c4276353960fad118532d49b7076f25ad190ab5694914f7108b0ab6969a19128fb0aef00e65a04fc832d07696167b9342b355ec57737ca37cbff3bb31931cb58712a4c468952c6459d567a26e79501e4e31b1b0953537632029e9b490f72e5a6e057ddb4b31756fd9704218b1b8f4dcb5430c025042f47169bfc7c80d71cab8ca07f340afa008abbe2e3a0abe141da8d41ca6bd69d36fdb11a41ce0b72fabc00d97ea605270010b259df8e10dd22dc17c13990a05f0233e3ca856b40971cb3e21c8b3950b13fc84e1f266c2a6fbece88d59725c3cfb2225dbc1ee95b686db704fc937b766f0a9bfe95a42b9010f1229c610d7ede095712c8f0f1fb0047c040a870306cd8dc74c4da51bf
+SIG: a8a309ba52125e76a4a61eb43fd4135c41ab11799b91cc54ffc9c6a20f050cc595b28143c874bdb928beed261d9c0f12aa192e6640bfdad54ba0d478426bce09
+
+TST: 576
+SK:  42b53652d08b5d766e66ad8f3ebf693cfd77907cadd98b5466df77dfa2c637ad
+PK:  88463bb8a4b6388d924cb86209834195435d79d77f8c02f46bbd16d82efe42b3
+MSG: 9ee913c74ee3c5e8c90d64b8ae3a60049fc765e176060bcd1cd09f0eda60bf23badb8a1caac3d66ebc5268146ee4a54e1eb231ed25eff95b90a6e98337a540a3f48449794a4873bfc2e84728966bb7c6ff676a2ff57311c1c25e15fbf3d40e9f25ab5db91fddb7a0ae436c8ec070754b6d743aa1d6048fb5bd7f5b8e4ccad20328389530f11374a489b1d50531a39c9b32b40369626006d264a99eec4fac1341f4e74679457b418e6bbfba233f1ca158f7b29d40d50301f9d92536fdc5c23fe5dee4d6df0ebf13dfa3754a14c856009adea1dda409304c1f60d25330fb10957947a00508f2fd76422eac694cc39fa8ae7fcc77a02fd9ee5f910d93e8aac68f145dd878876ba8eda0a49fcb209c34ea220d4d0605546fc4a809baf010d533e45d17b0e16a46e91ea6fec2cdc5a8b3ec5014b25e92d8e5c928ab06993d4fe23ac8d45c890378dd133f00edb937c071f75cfc13a402e3e429a848652a175c9b6f6eac86f6188a4448a96ce2872e5f65f9bdb87166c9b87a7e958e80bb6566e3fcf871190cf4a867e612cfc1e4371d2b73d2a0ad0aa400ba69e66336233b0f3c52b8a68bca05125601255046e6f49d688d2db85c7b821270516e3c0613f3f23f9c57cb4c8714285cdf95e106a3b5afcaeb81b72f343e87bd92f1581dcf9aa90a024fa4a1048059e30de8ff0d16794dcd745d2b2d534c520f8278538674a934c6f14a8428e3da018a36e45aa5827cf4b15284346fd69363149219bb0d1bc927d8d193c482692f97dc88d8ed337d0c9dc99c7a5e111dced42250d580e20692bb7b88
+SIG: 30c4b99e68ec3351308fbc76d9caf0af6221b596b7017fe10cc633023ba97f023896fe322baa347660610e05fa493d218fa360f18d93e275d1eff666b63db204
+
+TST: 577
+SK:  14cfe00fa7190ae810888ae2bbd0ff6412cf1fd408a308294383a19453b59073
+PK:  4e61afe8c174b6ee1a29fa09cf87b4008139f1070bc8531b6d06f54c9562a4f3
+MSG: bc66f801daa829858e740293d4d2187b8e1a5afba5fd67b10956c65346aca94429d32e4cfb3584ab0e005d0dd742781d47e89447c4e1d81bf7e6154f8f73af03361ad56ea3c06000754b9f327d4edeacc4d348afb54823e1c9d49cd8ff2b19f42021b40d580c39ce3d243661b85421fec915ba9dd2762f850bd208fdbf20ffaba56a468660f17c00fb1c0f4e8527a509dd4eec13360cf6e3cac542b875182f2a7ce7be0a33302fe26d3629629384e35c06789de634e90e964fbda8cbba98111e22e8d0762684266aab76aeba4a380778696814a1e311943cb3505892640c44e3aac4530c50ac604a8d2ccc7ceabffea4aa3d7f48a66dcd7588b80209dbc173f0c663e8fc87a36e892ec9a3ff8f60d2e0d8704e5b6cbb873275151ad4cc0057165031905039651ca10a95c6fda3b27827a657ef9a5fc3eb5b53cac61ddaf5a41704c878570cbc3c41c475b117c05eab0bb196bcb7c43334debd64b9e37450d23f5c10161ec5ab4fccd7cf308e2a9995cc9e578b85e8285a5208b9efd42af9cf2ac2b3b7464254889a2187317e32499709b913953ad46f1c23e1b6b56f024c4a7d48461192c01c56c54c564791ec0a67b61acbf957e6d0d7da8053ed13a41893d767fc5737cd195553da5d5b07065f47d72a35c42b001eb6dbd0f8e77a4b76a6266192647f4155ea11bd1237ba77c87c62bf4b01149fc58bc28f0b5a286485d3717d323964046218e70c7e38b7d5e74ba6b12b022f18197d92c13bca89335c856cbc5756aa3b64ec1f46e396b1161c871cd2dfded1a4ec9192742937c0704531c7
+SIG: f785a46f69bbd099fa011124ba9032c189742c9e001dbb8781d8223345a9569dc144ca694d90245e0e513e88ab023f7f0f99b7416159758dd034e7a89cff3600
+
+TST: 578
+SK:  ac0f7f0418de67e348fa6d5686c46d21ca72622ee69eaabe00d5c9075a34f179
+PK:  feabde08f00a2b682bce9d45990bf45afc958339dc44106dad33b2c490ef7090
+MSG: e8d0e8325335e0f35a85467beed1e11c6a2078c35ae4a4a10543ede40c1712bc952012d2f8fec105aef7c6c65b3634b4a74b22b498b913507d1f6cfde83858e6830c0af4f464a6899d5c4e279aff36754c21da80a1bbd1dcf46220375b1e112a5a72f1ab6e8f641942f66d9bbdbb179cf0139ea8deb0f4b814f50c513329a1a0e267c4433a233182bc4a2acb2c6d4f00b24094d3bdc0eb81cf37d38260c2107dd9490613d276ee1f72266c6e4acca5249811a0f8a7dae66aedb75c3df4c8ca3cb5d9c567ba541ee5a9140c50587272af34530ab8b08b9ec032eac06039e692630e2d554df77c1a0388b3caaa3be3754a84961fb299e402227158ce363eac26478d479775e5685adbf828bb355e3c89cce241503c15366432ba94cd3cd95479144b636e0de70b3f16d1a3ca518e399009a4c247a7f96367c7146608aacc0014fc35b84af9933f09babb89937abb8ced111891343ddb79f60b78898ab5938f8ba3814bd8002605b1dfd297fa07c475a0d4f8f4451acd707de8af6c0e8818833a3abe5c96d1a8c6c96e2cb63328eba44dd1d34684e412f288e065209d11eb8094d22e4cc802629ccba33926bf1ad36a6285138abee05c5a39a475f3fdd0b3ec8c370cd957a8379ec2cdaf03e895c1ba12b449d6cd8be0f35d99e2b7fbaa92dd54e64e7c35ceb88a71a680527cb373afe14cdd158a0b90bf2daec80d2edbdc3128cd6b63fa532a1c278cdfe0f8ebb4abba5e1a82bc5c3fed15c5795bd9ffb576082cc479fa1b04c5c5afcad269a0f1addfe76042c3a8f1f25377b6cb72ec1614eb6383
+SIG: 7591cf8257bead39a1ad3ba1918d518e6724356bf625a573eae501d1af946c13c290cb63156ec9d362726ee50b39fc0a7a2bbd69d4a81b75932a90f8c7ac7d03
+
+TST: 579
+SK:  b5a7c767936380b3e98751cafd3ea89b388a32cf828b321c5bd0cc8dd85baf00
+PK:  be7fa65f1f6be51027f8b848db7a8c404961bf1e21a23df23bb8ce05850cdaa1
+MSG: 6b67c795d66fac7bac8442a6c0992cb5758843b3e3939e3c276c6e9008da82007677bf9e67e9ac5a1a0f486beac0d856191fae25a127392bed469bc78deb0c4b893f67f1716d83509077e4a1bfd4136d03152dcc3b76d9524940a6064c669fbf51f6b91034b6d5f2898678a13a2470f6641ec802457c0102c3ebf6345c327e741b80644b3a99bf72b59ab8016f35d25188a085750dc060e5a8d524ae213f078f288c7b34bc41f3ce356bf2dafdd2e0db4fb8d7c2c319f9906005971702e49ca62e8050540d4121d242f2eeab1bd134e60bf11b3ec71f7765a97c0e098455e59d2235d6b37e7c9f5b21fa112c3ba39e4ea200614f58dfb3eb7b836f0bec1ddd438d1422450ae7ded1df9d71e5d9bc8fa3b6e6f78446ce7c79d0bcfb1c2d26c6fece68682dffc60a9c6e0ad05f2a09f21d7523251cb0c3d08efbbf8ac16339d717024d676024c1ee3c1f62c5aeab7fff937c57454df7bd96f9844a2a399958418aaa6f1848bebf7bf1292c24eb5cd8ea56340c5beb2688024a6953275be6efd1b71ba8be6eb77f0c65a7c5111b96c4c1f39cb7aaf83fdaae8d148d7a8af40ae9e651919f7ce28c8b2b6e45e4d3d56fdd54d00c2412790cbd6f80e10819e0b8f37c84fa004988adafccbbc21c63d6bf2e732d9dd63bd49b0412b9674e1e88f6142f7f867f1f26891b22430423cec4db91b61c2abc5c8fbd46b8b93596fc5160683136e21129822796eb5ea088e0a7d8121b25572e3ec37743d1ff6d8d1c3536439a10e84a665f2c75ee73cdc6ffac4cc28724469f7970b47507df3e1b14d477aec2bb20
+SIG: 60e4d23f1f08fce466c9915dded93256b52b327e5f81fbb31d1d10d321c390366ef001fd759aa9d0a55162d5364d918b48c7327e77cf5358bc4319e325cdd608
+
+TST: 580
+SK:  e136f398a605d13457848cead07c7286f42e2f28df8c128a3d0bb72b29aacc19
+PK:  6aa5045a66f772a571fe3e42d117efcdf6c49591996186012fa98f7c48e0cda7
+MSG: d328579de4c5372f3b382c48011b2d4c6029f904f3a33e07d083d7e2b03756af2c4c97a2d66c10ec4154d874792042b646e4aae5101d501bd1bf6f511751d0aaf821cd7c0b3ee6d0d7c690a2777fe16bdc7e49b7da4bbb4cce3b618ee9b6f2e3a19240cdb70733b984b1c940ec66960b728cbb874b80643123722db9dbbe88322008931b1c894ef5d21099e63e7c65007acd61784db4994a2fb40c3efe9c47fad63763dde06fa017a26b82e71b9daabc4ff0f6c79b8ca7ccb4dc2031bef1087367c7086974a00566de41a71e11d993abe433569892b8f75d7637993245c884478abe3f95f44b0a4bbedefef8906b75e0d34020ae536455b0e06f9bfee11ec9b8604bac2cc6ebe08c8fd5f5cccccbc1617b7cf69a3c512e1f0bdb585df5e12743061f7c2053bc37144361c0b35fd39d56b1efaf92c610360193ec20598b82858050a6d99e082bcefdbd5318ee5efb3b260f3276f3c73f9c24ce0cda33c7acc50ca5dd61bdb85d793825f6732a6e330ce672ac44fe6b2b9afe6e2e965c02d2a1fe0b57cb1b317c1d313efdc356492fe896fd149dae51c95ccdbb7d11f7d610e0c6e2fd3e57fcfef1c57c7119a0af6c7821fecdb89d80302b49fad41743f3d2d7a075154b3143e51aeb947d4b5e8b7e4ca86fec3e80bd9a786e4e46ed1e6e9f7e0b635266d9fa097aa9e20f32e3d2772d7c1f008bcdd3f92c7283c57790c3622cbad3ca35803c45c869dc377ff36bd7c0e6f1bb892f7329a6e08df1dbebc81dc7b115f852e36ae5d928725fa7c6fb9f28b0fb394f9e38fd87625c5fa23aaba47054e8cfea
+SIG: 75a45c6b9566899829b41ee517b7045a473a4f7a2641439b5d7c5673e00d8f5c066f1291f85deada0502bd16e9709f827d4751f2873862e8219e57746a19a900
+
+TST: 581
+SK:  97b6702e246805dbcfc7fa424a8caabcf262d466a05e0dd2d4e7c374d57d5251
+PK:  a716c3d5ce78f4d9c5bee3447ddaf4881c986efdf667ac8977b4fb69b5a7110a
+MSG: eaa86cf76fcb65c6f9fc208ac36f28b200d3b403aca73207461d8d96afa246d7c69d17a7a9bf77f05543563a7d3eca1d4079e22938aba1f6e9e04b49fbc8ed6f63b599730de9979831c02f8cba61e55560d7110d4c6e61679706a7155d5a673c54d16fe4d228c2eca7546faa1339f26d7a0bb4ee339611afdec9a68f5ff5b5d203b600533ad5a3b368c85da11563f098cc26871e7fa99aefd38cc26151db3b0bae38db6a87b6789e5840b10884af511f3ecb3ecbf94ff86fdb905505a8c34b2aa61ff2ec9ec8febd1dfed0965b6fc5b9f8869dc3a47559974a8822996706daefbc6c5bf984ce06b0d32b31cf9d8ad136aed4b052586dce7073b767b234e4a37bebbc393dd2e0f7d155173548c38a1583ef94e0aa84e7fce04fcc9b4e300ad099449a49232abdcf3d1a6e6fcab696f5996f9bd1b9485d074755ac5b4297fee3124c7c03976a40d570beaec2fac992339f885f74d40ed4ac87a4f40cefbc4864f44c3683aa8f1026e2c37aeffcebfdfe24dd0b019c36a79888203004b2ad83e89221f3f636f455bb64e17d1754c7c6dd7fc09a0d65dddded4622fc4f9fba072b45103435e10220a586f15226d2eb377f4064d3ff37cbb4705a1faaf5b348f8c0ef7fd1564d428688f58f3392967cf396a8ff2fd9e7b517b7d6a5ede7440373d8cc1a839900e84d42254283d9699c7ca37e477692a3494008b80444c5cf614cbbc169bfb9296303c645e2ce28d168dc6cbaefae9c73191f57151aa473009d29e1800b10f4c498609ba11520985c78092058696fdbca9c020e2dfb8a043a3de8e452d58cd1ad
+SIG: 90005541dcc1d7ab837f4de5393fadd6a92b26a7d93af3f669e0f1bfd621cbd00c8a23056d2da6786557c828a49be1e4021d99311235ac0d4d56eefc7c953605
+
+TST: 582
+SK:  d1528c1406a6e494a02f635305fa74d745c69327fd31b7d2c2623de2c030ed85
+PK:  0cfe369cf93daf6d53ef028ddb9f000443b0972fe2532f83a41ce657c1836ca3
+MSG: abb3673f3fa17a33a7aff76eac54e7687c04bc84f766651a8b24ba22947908b04ca459feb98ace7cab1e7433a6a6beffd8d9504e2991daa0644d61b8b2e45448f54df8813f50c418b48f49e1034e851cbec3ef0a1850ef726733afaf68e1a461041651c138d54e4ef78187af9a7342f7128727f903bf4fc5ef3e40c64ec26f892f59add98fe394765aaa7d09cae81b9f699a9dd8bf2e2fe8e1ec78fc884eaa0d2dbdbfb8c168833ee0d21803cc35dc628d7c07e04404fb60e8c490a8dd34edbcbaaf80ccdae3f7d3739e0e897023eeb5b1a8c00a9673c59258240ddd4420650fe5771f7e28cb2399f5e1e02ad0b6432d9b49608fcf0b1c0d7c412a445255b8badc5321c24c1ac92c79a0baccb9deffed02d12f5536cd595dc66083b33a3603a9d16ecea2bf38c4f2aaf570f30d21162b2efd7e4d5ebf1ecae9588eee36dd9d3d8e3be7bc6d4bc2185622f11d1da7c49c93e623ac56fee7e3706db8313cf926be92e5c8a539fd16b0f438da8e51a51f2d27640356124ef7be2f91ffa1796a91b12301934ddef0c7938a7a45f36f53b6322d9c8f9d275e1cd2c0f129f8ab8d74155b5d9e5c15c015b0b00003b2bddfa0bcfcc693a1dfcb4f53daec126d1669f33f39ad05519ef7c5ce40e6f4573c247a32c4a0162831352f6d558ff5836a5317dbc4515b3df269a8ac76d6436f264b64561e7968b5822108487b045c92d6c6142a1c2855b38beebd642565123cc827cb1831199e6f12a7e4236856b94dad738f69d1106e7735d711f7c6a3a3378041fc7a21103bbf866907d4edddafa0e7f1bb5ffd41a60d64
+SIG: b8399bc3326cba0a93a42497168bf57f9106ee43d39bf0fc86685199dc6e0a13b9c724ef17e7882af8c2eb70f6c9e42dfa2fbf0c1cb5002b58f1086619733e02
+
+TST: 583
+SK:  512340f961f142d1915e85fe4fa0f551f80892e75accce7cd1869e6e2c9e8015
+PK:  0ca02604fa87e2c20506251f0792cd2125856f0ab16d663f2811963b1f2d8172
+MSG: af37b2c7587a8d5bc895cd357746ab03552a0a561a293dc7164e39b6a1333a920bb6daca6006676e99bb7e928f9ea391e54802a8d31596289fb9bfe30000cf52ebf0c124a5895bce3398c1bf5356be82619b8ddc15a77ca922494bdb04f5c2e1b6e8ff77ae749faf2b8a41d822c17c06dfb7a5f9434d8bd715ec8778e80b81d2e8d06298748690c6555283c98bb9b19b9246667bc41046ff98c2c35d161e1f4d69d254ec5a076f25bd5c7e2c98ca3c09d80833962cf9660287884096eb30c46c54174106af4e2979a112f3e8944eaaf7669c40d5afb91a024abbeb14664e308903e4d26d7009446ee2e830ab5eca0dbbc513fb4e04351df2f6741864fb2371b2502be43dc15fc04431fff5eb8d4b68d72462ae322e57ba2d4adddf15a1902c2113aebd3b5d612917c1bb73e708ad5418e7d45e4b7280fc8896ab80853ff5f8e98f26553fc78e30b3b0d727bf6d064a8f32888768c51ebb61b2c600b4028a77060febbb02eb3d201780e74566c86a34031836bce9eada81e5d0f33960cb2df08aff3c974921fc9b7d3aa7c81e9c671ed6d33e7ae5ed03a5417d7e5cd6faac91b54b8f792f48283c60647de3da816ca9756c5bfe1bb8b5979e575401bda34e9cbc4d77e711d6b73b82da19da473b55e8e72d341b2d8503e48609be0fe291444c283669e5deadeaf52aa8ec48da83f5328cc099fb41f82becdd58d04b1d66203d737bed06cf21c97819ac13ed711ca217a57cf7d80ff082aa1a1cf8fea555cd2e47e4ddab5e3f9941ad4f775f49419dcadb5b004b68caf45b27ef49ba14fb52b09f1b185be9f9c7
+SIG: 6bb4d975afaef41ea9ef085a68c568a05da37ef21dad464ed86ac0d4080e7d0129fb023131eca5f7adb2586a18be40562fa2764ca807e670a0596a5c547bc001
+
+TST: 584
+SK:  b1b636e957574c21a957a45bd195c6f9fe4cc1c57e84134d39b42e1a84329edb
+PK:  95e77b15dda47caf69b72888dd69961bacbec3bc75353003e8bff0a43ddf4b7a
+MSG: e25d329cad8364d2dec24373e92d9d50fc7abe8fdc3d0b4ee57e1cfa5b7cd58c23be918f05179ba841b61e180034ca7e74d49b0a1a2cebb4be65344c913c46d32652336e6bda4efa3f58730d39a633a14ca3d9a62abb0a7398cc29aff916eeea2e7caac80845562f73d4030f9cab0bf1c6407f5401513ef87fe6dc099dbc5dfc3352911c07af6c523bef4cca78379659e8803f585904ee6ef6fde77366d96d2ccf248a5320d9b8298b2a73363879107a02b47f57213a85203abbca5a4195f8af3e3593ed2fa3504bb76a3e1be24b66d355662932cb67dc88503afaf762bff741ba1cace97ac58bafad5d36c3aa02e0cbe20e5f3dc8092c512eaa9c4943474aad41990076721ad3f53fb08ac22982ed9b15c751a9e23382f6a69c72e6e244e0eb681e6dd228d3774fccb37eb6232f825d169a2ac8b7e18a42cdaa4f2cf05890bb0c598cf8c31f829ef8ca2435bdcceb0e6193ada7841ee692f30aedf88b627311b138ac78b3913e06f7c321cafb39d901dfe17430b1a20bc437a555a578fa31e4b6807954456bd4b04d5d887987bdf04e0f14af3141b24c3a7b9ac75aa32e2fcd2171a12609e15e73094fd09221b4d27090e73219b648bcaabf3807c9280b6c4ad750a468be0e1ad3e6e63016cb5cec3aaddc5689c2955a2a8d5b8984d7c44376fdd94d3f5ff1298f78172b565913704e90e5ac038cb1720e19b080f81b53d6a45d4528530711b63dfe1e4781c24d74aeb2bd8a73fd2a993c5b0891392196ac32c523699960d8b23e01664cf9021d93928050caf97fb985554580e33336a4563247df59ef6cae53
+SIG: 763c7d0d46878e5c7ecf7104fc1f2230e46178a27c75f196169c0279edb01c28fcde3b0d5b8635cfe339fb232774b2206dab8a460ce417abf490bbfa785c0205
+
+TST: 585
+SK:  10ca413d70eb3db6e337f0f11abc075c95859e825f876176076952d2f1888030
+PK:  5028ba38afecc242635f6e353d5f4afd123f860a0425220e966552a057880823
+MSG: ea7faf79f6ff5d78a823a754347134f1b3c3e91ce518fdd633feb4f05d125f05cb54336ef560e92deb685112a5ffcd3dfd3964b2758ce4785f6a34bfeb39784f0aee55955aebd12ddda641d05769f74402f706dad201c44c91081c7d7f65e7aa4246de6dc3ed6496d10f4a412060d493bac9aed5be4f6d74229e3c55eb6876e3bb2ed41fa4504b6670dda8c798f6daa280d1aa72021174f6c01aec49b321d87f53acbcadcc4607d5b1e45d63fc481a6d90576c87c1880b2e8ff3e590a96beee1804768c756beb86bf1de8adc408b1b8d666f74ba28630822f92d18b056ae37ce0293ee61b9e80f33ac269671bd62a4059b24f7c1a440807440d5d538a65458adc8158724b25c12127aa0349e55f6e55bc92078fd1ef274c2aa791905766be394a2628f7bbd1a32da5e487446bbefae88fa6cf3f7b499f131fa19313d13b280adca50f77802d17331b381683b5e7edab99473edd31d77443488214135fd6f26445093e9e2aff7d7e892337fdc8779065d4d97d6d673576794958dbfa6c50b1b13ac39607c1e66ef9629761071155fbca6f36eb02ceeae16367feac07476908c847c9a533ef68c94311fa089ff28fbd87809b0d3876b431d9a18b202f9a4049a0577b8177610dd02e5c520eca955e803c3ad4f50976f7c2ea8aa3ee4836a1985df0a4f16ef46981595419897993560af82651c2b494e680b37802e7537ef68a575c34f8588063ee0197206d9a32bb4890e7c216a4d33feca36b549e532fea68556e7540a4fb169d49fc553b2e6700ae42d9a516e68160acf6b270c77ca5ec26e5ad5dc75c2c393e299
+SIG: 6aec02dc6bdfcb67f0efc1fd31e23e69e371ab3802505b3201a95dd525417ed1a128db4e182cb37c28f62806667099a8ad480b0ac9e94c2a7d5a0e96e2a7360d
+
+TST: 586
+SK:  1f0a10a2cb111917b9a67a2a1f38fb86f8ed52607d1d653a457d7f4718d9a7de
+PK:  70c075b2e94c4c02f45e73044f24399741b161feb6f69eab635417282a4a9368
+MSG: 4f6a434bd5fc77f0f1b7049c91853ccbd89439962a6078a674b867543b6b7d10552ec1758c5283042bd6b4cea88c9520db04746f089cf3a260fb0f33858efd6f680de5b72d9876324ba590299138f85a76f5be0e05e8859c02b23512559c8beafc9cfe901b283e15d16c792eb03b92880f6ff97aa38eeead3f4fd6c0a9214323aa39a1c16515e30dbd08b833ee40a814a28809c870e1d0a62c37932d5408fc6afc63e79a655c5fe3d4026ef09e0299fbde5ab34fceab14130dc4be007e8e6444d7aaaec62c873df77e8010743c31e8757f1eae9edb5597a1b5d84bd77ae7642e1aca99873a152ffde068a8e4ad9240b903332795e40bb32865e5ce034307a6c9fe339a1c93770df5ca46329f6b09419785cbf2847b0c6832837123853ad952653265c5b5740d194e00f23f9e966791f005f8bf55c388c2be9e21538925f8555e0dbd83be073df765af4940e59a3790b9836bab7909e5676fbf1c2126fe226d781a44330cc01d32830ff8ae00b9792e398c2cbb4fb83a1005c245549a89063fbe06c62a48dac43c5101249994e95e37f24c1d8b3bc673538c46055f800db1c0f956869b6b297d990f44f05b50c7ad6b856f46212858471dd0d39372b0db751573ddb6b5b56ba01e371c78fe58dcd1be53112a6a73da9a6bac75d3c39a1a705a36f640fcfad8cd04077594d59685f6e30de71dfd4a44c4e7c04d6ec7c2e8be12785bb05b29b39151d329f587fdc381c2df0cef73fe0e3fd9208d7ccb6e08d02f42d1feed27561d5e323aa148624e552abe87532de15b7f42c22c98e40525b1747cbd758bfb26fd3eed3b
+SIG: a4245aa3395e7bada2bcdf1603147cc5f3f0ba91f40fdad8f6d371c3ebefb4c1501d07875b576f40797806a484c7a3f70569e232b0c99d29ca23a233b68edb0c
+
+TST: 587
+SK:  7f05baacf167583cf2fe9562a506991ed987f68ffb71567c7ccce3fcc59b78b0
+PK:  0dec3952852b96fd75587e97743f9e41c09fbe6ba981bfceb4ebb8892d986a16
+MSG: a27d1eab05150920ded1b1c2578af582b294f7837fe4fb1a3169c25efb70634ba66c7e2991b3e75cc5124826a03e057259b5cb706228780cbc8275c339f8340e402a665032a4ab657827b1c3481f7566d369735b82db7628c022b212730db1e47c9b2d9bc4d81b2342d89c6eafc3e0b6de50d484ccef11238c8e2d240dd595dcef8b2fc57b54ff9a8a74111f61f8a652f20ea012c1ade3e280ecde294c0e35717190162ec6a2265e7e6f3f0704cf8ab1a03e5cc953e2926291ccd4b0590d5c20568f94f9ff0fe2ab78cf9ae2c38bcd491e518f23e9b636f880615fc56078e512d7577e09497c1183453d5081fd4737f280ec5e267c4586b78b70fffdfd730d809df560f2e3772191847bbc3f604fb7f8ca49eed318b5e7d1f2b83a10da0c8594b339b6871a5772dd64168ecc27e240a45c76725e7d55bef37e135e3d9e0e34e36c16e34d77459a552f4074d067a31a3ed2a48cdea4895b10bdf1656f4b7a413c6a088c649fc9d7bc56abf64435491214192a6670cb8b9c917f8e1bc7b2cfce78d28fbc3afc2a50e98213e7e026378e4ea711d151adaaa719beb8974656c10ebc7de46b19ec82951ef46a8c68e7f436e1b3ebedb2d09b0575c9914ead2796b53e0061e212994ac5026aea81ec37c81378f4ccfc467700087968597da38fed52fa48093ae4ba1066c31e3c7d8508095bb45c280120f4aa69a24f3efef1f767985aa1a30e140856f76d1520732878487be53f712dbd7d779e315101588fd7dbdb132f92c27575ac1486f176c790661b0148394e92ffa3ae6f8afb2faa2b7f4fbd0ad91e759a702b3c702b4d
+SIG: 0deed2df82acf4529c408a02931f676bec5cb7ade84ebdcd578f70f971382cf311bb83097300456a558bc4c09d8983ff13493fd611eb66c043bf019bad6f3302
+
+TST: 588
+SK:  d00c216426710d194a3d11cfc90a17a86212e7a0e54baa49b0169e57fff83d61
+PK:  cfe6ae8903c6c701aa304695c651bfd850331f9ad481633ae370c86d7bd13fb9
+MSG: 82f97841b3ba22dd9a4450837ea7bf8d27a9731470cabb0c2078034bf24e4c1a6290c03f4002b86fa09f07b5209f1f53d0ecf4d9e9223bec125a954551fe8bff718f5e264868e207f701194e41de39971fd385f49a4b4adda911eba55259fc6836653273f656f4af60b20664956d4f2135d90d09e9037d5366a0253444e022c7212af5fd4fccd74237d2885338e2fd721522de6763c2549028c623b9cf387d234ab5e7fcbe5a47c685b79e75a57b09574082a02221df64a2e841618087e722a21bac1ba4f0d7d87bdc510aaa8fbd10757f6c029ca820371fc74c3bc50bd898c55d8167f73ada377aecc91629d64c360c2c241c5cb42e3a518c5dabf0f418b2a7f3d82eefd92026d31e8b8160358eae821f730ecafe7ace647bff8741de2f6a131d11c969e9787cfe6a2fab37bf8d1c7f4a2f364d2f1a76ef046c1843e63ec00cf7920ffaae561e7370b719fc16fcebca3cfdfaba43f4f090c46f477303a660ee88dd4e89bf14b9f804b6fd495cb1412753474a056a0d8931cd9ccbd64f8fcc7a3123467c5d47f690679e8871288093734fd6a1326038658156413696594c134d73887f34ee67609ae8ffb3266c16d87f15345a476f72950c158796a88bbb444f1aa809cad875b85fb9151a0e2eef2e00e80d6b7a9ba406c0519effdd94126232fdf6f1e7b9bbc0362aa77516fdf939e7906aab01307128cf824c102c09b929c9b2d7af8f85b7d7f9a838b2aed0c697e8bdfee66ee016bb1bf35eff6b2f7ef4b91b1fc04fac9f116e2edff40f95c15b77c31ee522f3937c7fa0047d6225e0c8e55e278c8103911feab2b7f4
+SIG: 15c45c194297e887029f49d8bdf9d610dd8c34799e1e9230269e7a58928938cf396a02cd42205490391e1c64353fb06b9f8e9b818a9a361c204a386995bf3b03
+
+TST: 589
+SK:  dd123972e628584acc46293b8e4ce2b2dd469cc4ede14ef39521cf08373585b3
+PK:  3522f7ae596eedb217035d95395e448dbd6ffbf42585eaeb307026541c78a651
+MSG: 2b2857f45280173e2e0ef9d594e6083f1dc7a65492975b837def6cadd8c8545031ee9d68369a9393cc7b792feb98040b21f1eb84665f878537ce412e9db680d29fbd8ffc7731eae91a20b47548996204fb06ad740e78f0fc590b6791dc7a0f2659286cc16d02c5117b565836b4b8738cf40e285c69c50e412911292367352dfdaed9982d0f899a23c0ab51812b3ec678f6882ea427cdc93ab4b24824377054aa25d82246653340078cf11d14a51f0e686d7e018b36741668fce7458d169293361dd16b3debbed19e1bef7c36934e20f33a09ad3e82b53ab4e94c255d041898b97737df99584af14e404058d0c93bcae7bbbc06395a2aefbdefa7b2ed17cebd1513fa390fe9a9b0ce68cecc2b9e129b7a29f49b6d18c28bacd3af39dc39ca972f0e0d06855d57c2b5fcac2f79cb8c05799e4f65734668dad6aa7a43a11856e23b1e732d00e5fe3885b7dad42ec18ac8e096a080f7d55070fdcff607bc0b852d8a080d2a7405d59414695f2eb7fb0aca23c8635742f8ae57f13780316e280872374e6929598d028a33c05d831cdabd029493c3cc859fff1a67d56216f02a2295665365887a350a80afaa0c367a74d3701ae88f59d8a9d3a1dce0cfd2eabe2af5065a1c7fca4aadcf8e51e75612a1371b4dc8ffc0c0b9c4fadb2f081e2e032d96818e55737adde3e1ac121f56cc86fb58a0a582692f62ce58acce17aafec7bcb7e44f839258cd4a851fc01344ee9f1bd03eb94344f4778693c171dd2892b2426a8829ab0cfe33a7d4a36eb4017f7fcfd24134ab8a45f23717cd138aa6000172e37b4064dc9b6d1e1ef3af84971d
+SIG: 8965a889d54cd8076d35bc2e12b009d56b0704c894f912a0d1d30720c232fe4404bf3009541e8f3283e89ea86f678afbdf1c21c924b23a52b4ca6d63f48fc203
+
+TST: 590
+SK:  3335ea928117cfeefbeeae146003881bdc8889d6580eed1352370820ad1f584f
+PK:  cb20d4fd7561848013111c3e97617f34181d2e7fbcf1bb2a2cd2e8c1775b8b03
+MSG: 0fa7f6a6fca981429b572a6704871bed140dab93ee1992006e9a3bb2e6cc9a09d4c9cf17066b32ff7ef5b6b2e7911178ed7462c4c175603171ca613668b3be193d94c3521e588913b5948b550be99d82d966197d710acfd95914cf3e197536e83e68230dc3d67e67dcdbdee04f0d9c480237ecd28f74338db5f3f697d3d07ff33613bbce542acc9a7fed5d12490b9bfe1d109540f863800dd356da841a45a3cd8a08a945bfa3aa98e1712312c4c0f0d9dd64f6efcf736bd97deafca9dcaa3f06d87f2ed72aeb6a94f3280000c4bf728a01c1862dafd9fc5c7d5a46ec7d3a87af59a11d87f7ff84407d37010e1d946cf225d6b3b1edee2e8bbf1e079e47fb1f66669394fbf2fa68fc56fc89820a6809c251dd62f5b865c547b14fbd3a19504244ffbc7e5240f88d4360f9cacaaf5f82433d3344fcaee0acdeb7beb9c0b3c769eac920ef4f09abc2a2095512045943eccc53b1c03ed24e567f3d7a71977cab9840ce898ee58ed5c73f6adea823394c5c8e3658a6bf5acbbf0055992c312c26c79c5cfbea3860b8764a6d8ffe4491f8a5b8a215e0117a9a68164aee25f8c0bb381195b2400bcb4644ebce1cde5a9a26582cab9dc7f43c33eae350db65aa7dd22a079bdddcf56d848deb0cfa50b3bd732d9da9e8d8ab79e93469de5802b6dff5ac2aa8482bb0b036d8f9d595b8ead94bb8d7418e2ea43192efcbfc05c467bde0a868a516a7c14a889b72c5b73e7d85c2bae902e4e68d1f3ceab2b2773af5bbaee6a00d08063e7833cd4e295347e58f5d1b3397f640c159cc60a674a227b4cd8c10f1dbaed516ccacdd295f11b08147
+SIG: f7c39f9247d22f018999247f0e0005cd63076ccf2fee4163421f86407a41698c405816647351c04e93b54415b62fc03fc8c25e20f7541dab03197dc900b29c0c
+
+TST: 591
+SK:  32a1883eff57a3a7ecdb310221ee83c4de92b722159613ecf816e382437b60b9
+PK:  82dd1a03e5852062ba4a8b6b3b93c5e9c43ff6995bd2aac72606fac85802c682
+MSG: ed2b123b5dd7f5e718e026c79cfa6111924902d189a406ef2b2e56a9ee5573a76ddd1d0629ebcdecf2aaa74e84fcd0208f14eea2e171e7c8608b818feff4dbea52db354227d023250b1f01cb4cc8c52132a98d4acf55a54fee81e094aed66fa0d6b6a200b6b87414402278538b90529a8c603d927eddda97bc4b8cb95d04b5337fa22ceafc8b340c46fef67198d1fd98d89c65cd089e23f53dbdca967798b5cd923205ad511edf706f1225f4648c985e009ef8a2f6a0117cdbe14e75312d8ac1f03d046b37cdee7d69c0f25ccf18145a688a8b3ca8875fe8d90baf86d43969e4d610214f1ac5dbba87a1ef10377e40d7806fd9d23457fc9df29899239fd1d278849681a943ad9c91fd1bbd92b73cb177a878f9059ee07af7a8731613e33d59df3d97796079d5631ed85eb2245106a5ff6a2bca40df5c6e87473b2c08c2212f56fc2933a969a3c958d37c5343ba2760c813a7a5165d231c5feaae62b755df49feca80041a6535f7e03bc48e5f27f9be26ef53673eb7c37a2b64744a6cf17e887734ae010bf40eea03cda212f512fba0585947179640bcc4544b8deb4ead129bc3322800adf98818f99574befd9b0016d4eec81a8e78dc3a2af13cab01649ae2e33d516b9d4208ad6613d8e278c393baa882340ef461ff4f94423d55cf3cedd2a6b56e88365531dd29d68273adbfe369402e6a7cee053da1f100540091a00929252983449024b1c3391110650082f0e7dfddb8edc2042f3c1713c6944ba514ee7407d32bf06c858efec42a78bee97746e5b4879141a13d9fc5cb123b783273b84d57ad3526b7da3c68b839efd23f5f
+SIG: 8309cbe72f804bd9521def5dad4d8bc13886b1d4f662c9bb5b97ba4790f44b801f3195ead0d4ddb660818ecbf9a683cacf85f1dcc9e82c09116d733658091a00
+
+TST: 592
+SK:  22ecef6dabe58c0669b804664973e457c05e4777f781c52522af76b95481a914
+PK:  d4784010ef0403eddc5a62d5d45bb243b80b4b9d69c39ca387c6f5cba028640f
+MSG: c535c13d779fc0985973d6bcd552d81734e92bdf10994b00cd4d53ce365fad8c7cfa96206adb62d4567be5e46631323853e38ce4bdc16d7b8f632a3ad9e02619eff37174eac3f0bf2f7a7517d4b82de6aa1af0063819d5e1f9278fb4f24c8cc002afb15f334c04fadb00303013c01667f4932a6c4b97d39cd4a4598506c0bd740ea9f11696357d7d17fe4d75f9d74241a7af71f9d869ef6cd695687c03fc34ad65a68a4888a1a74126cb55cf7da9cb4a6717f6eb88484089d2c5189ae381f25e7b3bc3b23d0c9d9f9cdbbeecfd1e72a05e67bb483a9764d9fc75ad69e4ab1270fb40f3958fea4da559b43980b24681313e8591e68546a3bf76ee34b339709295a8d46fb2432dda2f221812df692895e67cb29cbf6ff4502b439a4e9e43639ec067bc90ae814a293a7bd46968e656787642300a0ff2697e3313f6a418d3d12a5f7c51a4c57b63385f2d2a21d5d1d763fc8d1b93c13435f9e47ee7a425980a6ae6f1a9d007607476783c6d0c7887380f868c65b382d4cc8c04478bbd79a1d9a964b78171d6bcf0b8eec50a06a4ea234d1c23465d3e75b88bc540dade74ed42675b07f7cf078211e907f86d0dc4b978623d9f08738af928695e542ec2980e55a1de49e25247fa0a09678118e3930bc4d24b3214d6dcfb6ebdf4906c928deb37bb9ba29c8de1bb9418db718b2853ba57ad8cae4677addfd18b6c7e8c242621b35c7f0efe8dd5eb26ff75fd5748b1d783f6d68a7d9d56da2c1a978ac25f84fbb2be5568d91e70938221c102aee60409bcbec0c82e12ddb425eeb6ecd11551ecd1d33ddae871ae0c8f24d0d18018732b5e0e
+SIG: 5d0d2af678b3d1b677516d08a79aafd36ec67c14caf5bcdaaeaacc51a14fb805cf2904e8721db271b20df709bee1a4fbfe62565073b2a7e942724461f927930d
+
+TST: 593
+SK:  8de86330b256095e1114b6529bedce182c166f67a91539cebc4bec25add7a4a9
+PK:  33cb054b55bb790ac0f3afdd9a6e7c050efe9006c24f60b8044fd08a5c106c11
+MSG: 39e61e0eccec929c87b8b22d4fd18aeabf42e9ce7b015f2a8cac92a52448a42fed4cbadc085bbb4c03712ae72cfcb800b978350669b0990084f2dab76eca606d1a49fc55c529e1e7dadf39122dd5bd733893858b0523ef62df4f134cf6c26eed02fdbcb30ce474b1ada3f060769f934bbe686ccebd60883ecec9ce3ffb8ac4a0678cdc5b005ae3dba7e4fe8bc045739957d849f69c1474057b428c5425f3cc2516e8bbe3be81afd4e7b575abe88c87f2f03b56f69f9e3b61b3788120daa495ef0e50eb970a645c13d213c7cfb7d0ad555c920a1e5dbcb46797d939fe0401f547bfd17543221a53010de01f25b64519c8f03963e4b9ca58b0113627c05b9608eeaa7b9ae6305c96188160000ee3a7ade96e0b4bde9d0ed6a0ced765d786840a48175a6e090a38af6adeaa1486a9cb5c8c8c9223ee0ae4c6c02691a3547e32582a5b7059d2ee66fa9cd965615c315b476fd861279cd1dd7607743fc5561296312f11e465ca40bce3cf0b1f1d5a30af6087de4de96ce43965a46c4fcca15f281149b5c1a0c88fdbf27409a134ed4f1fb730fa191816ea784d986cc9ec4b694402de1dcca9ccc64fbd07b07e54e931de827a842460ca0bf6b04ebb571fa77787e3884be22f1e402cf2b8a96a5d39770ec4a843036142a0be970bb1ab165a6374dcf43deb8b9830b2c49db9cdfe4b5242e36f95e0c3e077e8d238fa6a8ac0d586bf61b8248fb3a79a270ab22be8a9da055ff3d5bb2d1ca9bc25f7014b96407719de344c3e73b8c114f792075a5c22fdd416154d3494ec3f02fb112ee5737f70704c1b6b07eacbf94562ca7b90dd84d98c3edf
+SIG: 6d01d237dd2bb4188d29bfdec387976a71be7adfbf9e23639b216d0aa0c11932235edccb3b42adcdb6291a0d299aed648de8b1957949b9d1cf2e50493030a40f
+
+TST: 594
+SK:  bab5fa49187da1cab1d291900019e6cbafeccd27bf7ecbf1262a700516e7c29f
+PK:  f6fb1985ec591f69e3bac807b2eabf263990cdfa09b17809e48e385da065ec21
+MSG: 5cf8ff587e52cccd2984f34791ee6843e77017c3b55ad45c44450965b75d836e78fbd7a1d1729eff6d6d340a903f3cf17d9e2aecaaff2a321fcdde0abcfbbcbcc09f4086f812c46efb01b78343afbe48309f917478455f32000c6a69f79fe211b99f037f5956d72275a7fe7b45296b5f739aa451ff0575bc705885aa5631b0d0850bc2b12c4192435ae5d2f52bc54386497c4a24b8b6db516be09d8ccf1eca785bde97e9be1ac064f094e2afcc307c0e06b4c564cd9a9a95305b37b81f434611dca55caaa031e88495d5dc5a04ff5fafdf0a82a0c03aff1bfbf4ffebae71824e35e751b09270007669860b580035659e23ace76b3b369fa306f2bed95799fafabc2e69c141beb0bacac7eaa347e77be5af3fcdbe7b364a7f9a66d5e17a07df6202fd98c14bfee2ca6f0745651f0c8550f9ffffcafb96ffb3f103e652e78f53916cd6f1dd05b3fe99b34201b07eac2652f5253571fd3822c695d265c7dfdd6c6b14a80b6e87183e6e032e5f2401cd238cdd3769bb6e390823438f5673ea9a479e5c63fe07a07f4e14f57757c4d7d22b35d71c44eaad4873c8eca6f6b21dcfa95520ff9614abf7a0e1885309f2ced3bcdfc319363a2da46ded79a5cc7b6f69383f94ab35c250629cb915d667b6281186754895803e4b95e7418289a6ac3bcdb6e1e7f6f1dc38e77d281914cc404f97cff14fb2c4fd81412d101c1bfb368ce59311e892a8b9cdca86936f3bca7ec79163eddf1cee68f49f1ebaa27ec50f490d61601ca35f8d6ed266054aeb9b199f933bffd6e0050f261b4e13d5ebfe2caa6557c32ddeaeebc2a11f0aa233240da1c7e40f76
+SIG: e316038d6aa15b1c1b61c1a16b36904fe8a289c8d602becc514d99220086b267859f5bf6e9c0863559ac623a56d7532344e8d2f28b3f9df92089708b1b059008
+
+TST: 595
+SK:  74ca122ab60de50cdc04a8e2eda45d9631061bf187d316be5b7cc06f020c483e
+PK:  787defd4fb24a399bd2a4e76dff7d603ed0acb3269813e4df690bbf5b2bc696e
+MSG: a80b46079fa775f8c1a19fa0829be666bdfdca079cad43d70e0842183bc0db95468a539f0db2aea3ab9c7073b45d228a9bde232897a6eb6fc9edf7365e7101ba97c446a519a3649cf527c8a6de7251b92806815ac2fa0082eff75e2582cbca7e1e4da2a446ea233e7cf7cedfb0e2398eb6e11bbaefe3f7ec89f5d73dd34bd47fbcb4d7b22f2aaee373785651841135cd8661a701b21084a316deac3074e24a2e35a0330f7d1479b932f285277c18a441787224fbbe46c62e834a1851ed237998d48dce20ba114d11e941be29d56d02f7370c8f6d6d7e50248dcd8ec89d3b22f4f58778129fafd4bb92ede17714bf022a5bf92be479f18e63852ecdcf8c4211f530dd30f79cbf4bfa5737f0bad3b0106067f41327c3189e6f206f0d4f3c704bf2bd0b161f018fd21cddfb418bac4d52ef02c41c8792e413b04f0836cea1f86c92e5d5703bee2b5c5899e285992024f64e0d16c60ad0fd92547932d0c5cb98d8da22feebdbba8d1de1e7e9bb219a92eb6c1c698d3b33a37f9b8197d26b550febd2601e7a643ea7e1d9e448ae037f629a306ce417aeb79f2e3ca44d8db3848a811f1846811cbcb874f8af09e0fd0173cf175f304115476bf2c6c2d2f332eba534f46aae801c2692c2d2faddfeacc0f1dace440abc2ae5e5a49d578fd7f9de2a841ad6b6769c32b144ceea16d0f3c0cb3a8ee694c38c28073595096c813762cc2c5ec4b0d8d723dd660853278fc72fd6bd9d1272933dd2a38ed9d04b1390ffe4b294a6fffa721ee3bba33a03a149c4a0345265c01ce015e94db419cff7049852ee000048a85758f6d7b1c59c5089ee018ed09b52
+SIG: bcb4b850696011997eb5dfe143f1a3d5628ef1a5407691ee48c79d69abe4d533f817ad7313b5795e46e595f3ae3a9165b1b6fddae86164ffcba376249837f609
+
+TST: 596
+SK:  65eea9ffb75612bde1d9ba3ea4fb5eda0aa6f2556ab15bf1817cee3b95bbba12
+PK:  5b3936dc749b6b9239f15798accafd884c3659ee01b2d17d74fc7da78274e7e6
+MSG: c06936323ce3253cac5ab4f6b83270cd4cfe85d0bf8bac1e1b8d5f0b153f541c8e8ed95f28d5c85a2315cd931b7cf3edae50f92830599162804b1363d3ac0da0abd09751023bddc16288944e616d21d91271978bb782d3ebed7fa61284c7490d27593ca8a3d5b475623307010abc1fbf793a816aaab5e0924dec79d60498965cf7f80ab59fc029f782166755b72b869075434ab606cc870a7c0bc8bf29aee033fa9cc122ed7c8e069b547dbae25901b9e249b41fea0bf8daf3826866bcaed2753b5e91ae937e717b508a0acf4c3b061ff0cb9cfd380e2494500951a662fd4928fc5fcaf6c18e84b1d378e49bd9d59686d087ebd552d07fa9ba816fa5402ca9e7252a648d106cfe6c431cc2a053e2294637cdb99d96abe689edabc5ca070f77c1ecd1d52d5385289f17ced768c3971671b9c0b2f855b8461c1e746c7b38f77896b85afbbedd08375fe922984614dd849fe2cb89ae7149dcd1d37f4936e67b1440be72e009398be6f083bf9611480b592fe2f0118e253db5d2e9e4b4541c11da00f7161a736e5f0bb934208e3ef4e0b9a52258203f060d18a195159e5e268aa28053c834f7bd5db9bd71f507d91370b3ffcabbd4acb3071d3f6d52c349acf35095348cebf5a86f8c59ddc965eff610ac425804c0e2f6be42853f5b46434a2c31d9ac99539bfdc04ecf2fefd04598fa63c139ff6c6d88410e73bd328cc4349ab4bb86f2e2ed7c73de96520ef7730ef38345e0f972a84c5388103687e68c50f9d8c9af903bc632d43204062a4f502e214c07059c2cbef72a54110dbf73e425402d17e978ec199b518cec0310bfbf7d9ad300434a4a
+SIG: baa7113155358c924fed57488a6567f8723850a9f5c03a0d7de85fccd8fb4d17d7753523b00c0d8adb884dc0c8a7a44dc2a60083aa5b3c5b94a8d880f2a94d09
+
+TST: 597
+SK:  08dabd4e5c119ea907ce45f0a7af9e62c0c3f1c9ec61ad10567d79362854c557
+PK:  945406b85d7b32e0b1ab1200b94222de1aaa68624c60bb4716b0bce9df005771
+MSG: 6c4719a5a2a6894835c4ac1ed69159e5ebb5692ad8eaada439f79e96684b36cecfb44b89015631663e0644f6c7ab713989d742da27427253318a52432dfab2121d1e9233ead719e2c86a6be07363d002173f205446ca95fc17b24635827fe315f222408e45e833f29ff08ff31dac583a4bec7076d5cc78cfc94451cbf4f7e2fc5b5ed8070f4ef808be1d8a680ecdff59010f39b1de80bef1719f1e218e0ce0a1e393a566c51764d2370d95a61191d8f7af740dc208fa7831b210670512cd73766e609e9b780021ebb20cc8790d8da5f10f5b6a114a1db88f66766501802d9c366ea3fa6f1b1e1e8b0420943413cc6feab28c6b683cd2b333069c8951bc45e8a13bd522578351c882f7c342fe4331b921f533c92ec04a49b292bc569ddcefcab5727f9b5625b167a902dc896d8bc7d8e99920f5db8dd767839c43e3cdf947080dec954214a6fbbe0487a2f32cd17a6b000370bd414484fb73c510ea0124c6cf0fe56c0846a79bfc59779d3b07a1bd2c7fb7e2d0039f0bd21c8a308fb0f58fdbf94efa0857ac3bdddd86d5763e205ee1b221f060cedb8bc05f031b606cc74dadc5db04232748865a73d6ccddb4d5e930d528348c5be9088bfe34458487a67b19a18eca25c0d3fbe2195eb91707b65d9161ea93eddd64a634b23280195fdb0d1388f6998e1858a45b886999b844e6795d83d31837e4411f71699226de1ba0245608000dcf223dd18359b7c6d459a65dbe66c90f5cb8c09122187a3046a16dd179c3f4373e57cf5ee0eab6a212cc9ed8b54bf37f1d27fbd79848e4ec1f567243ab8740a05149d9602eada920a46d610d3cc823b56498
+SIG: 33adbfcd4ed4fa67c58b5cb59e16987148697812660b3531ff6a21c749b9601660baeee2489b82b4cde132b6e62f2f90d8f9927860aaad25281d03eb17a9520f
+
+TST: 598
+SK:  e0f7d00824c5f3701e5517a4abc13e2f2c0b138c836977843bbd1eeffabd968a
+PK:  52fddae3e018a68473b3168d0764cfe274dcc834c90a91fb4fe74b939dd238b1
+MSG: b39e3ac75a221adcced09a8591ac5e2fe15dfed5b919cbaf14c65eb7cd93086ddee3f7472547e66ddc70062b976297d1a3c170ee525c9c53ba93a4c4fdb23572b7ca6ed13853e70db1d72edeb9944bbc354a520e77ae591f318092efd5e66d9c0981c4a4bda98aa4e59045ff9c4b4ca3acb2ffd893201c70b34a77f24eda54549dc84ad134a35532553815888ae3dd9e241ec4ebbff86f8c1e8adbaac4b91afd18228cbbd5dd805acabf0a1e290ce5dda0251adfb37cb714c139b5a3242d88c64484a37655cc8fcbecffa97fbd14d64d512bf8f6305f89c50922de541692158fb547fd539f1e5877cc649495166332ea2b685cfa3f602019df2ab2c25ed96b68745e9ae89c948da11ad8a830df8b00f2e668192dadf2c5620d35c6e81a2853f841e375a0d9fca2d296efce2ac38d40b030b57560ae6e8341339b3d3c2d061164124319598688fca618fc64c9e8f5f831097a053af19d7dbd61218d926742c2e9a42a79cc1b148912722d8cd5ca793a1ad73b5f141b41809c2fc0530b7630e80390c6b338c71868dacc59bf463ffc489016bf67f9c9d5553c1ede17152813fe0b264b65dca1b2b38e4b809f8c9725ac5b1d8d2e56bec9649fe55c7583ff23b043d6f3768628f1f0516337824a5a56b409520a6a6cb77e4f5fc20b9f6899e00ab22db10d182f09b81e94f3ad568a0b81244df3f1855c6ef222a41a51b62a4649bb82690ab65facac0d81d6fe02601170a8db62cbc5ec9955d7711a1c39656a9f6e1fb6bc183d9bea1503531f17362768bb841f9d21f13a2c991e55dff7f2b336e29eb29507638bdcad7bb31c69e909207ebabcc653ff
+SIG: ccdfe18ad6d0b65d086d632f83cc46ff3b3f2c07bb8e769d0fb4e82df8a3873f9aee35fdd18a5783603180a95c9f74ced9db5146afcfbbdd40df29e04201200c
+
+TST: 599
+SK:  6acd939e422226cc5443d4aabf58c11af650cb40b9648b4da38b927bff9a58db
+PK:  4c0b91756b9e206f7863b155ffc5509bb52477ceacd01ca011435153678646cc
+MSG: 8250d531cf2b66aac2b378d54bc57fd329ad5a414a599255898b3c3b45bf9c0d2c77547566b660eecc76a695a2d608abf11a5f6db3e607fd5a21714b0fad5d814c015ebf48bb73ad75da9c03c4af5489e782b6bf7908a1bd528d7ce788a18ba3528e3537aa7bbf75f6524bbd19a5304ba2a4a3ee58c41fec3132ee6501641215eff746d7800c4d33f52be8357e0ee758041d91cfe43c60c3cedc09b0d46d4cfb9ae2a0239b6f33c6941cff35372670eef5c8859ab65b6e9f7ebce32fa15a9a477aecdc9683a1e33a1edcdc90d420a31e78c153d26020871daa4fff28acc3f11a7206788806b6fa023468ea5a3d186d10f0dd567796663ba37c832fe75aae7dccebf319f93600c46a22f57223812ddd0a68d76baf5e27a9fc8bd68cc10b5b5151d62b41f9348e21b715352f2630b617f813b0c28996285904cf294e9c2856b17ba35f9a82198b8214a035e2896d6568be42392ccef32cd4ebfeebf12be0125206bbe89336d3e762991dfab68fc99dc1649b891383db31fab649e628823f4598cb636a38fe1df73e68d7425fc5d2eb55a0fd1bc9f5ceaabd6dd41f23e4f086c692633dc3c4619a97ab0eada171f84adf20ecc8ecd47c51cca3e59dd809b0aeaa730df94be3bacfd8ee888bba9d570850652cd4d5e6c552a57e9f48a2b06aacdc708d84a376fbc6c94ba6bf64a5f018800a7cc851245aedb20378b329acebb2977c1398082b3a0e5e2a9c2484fa301d3037a8224ddcc095b1dbd8a2315b55bf3318c27810efc3d8e25fa7a8789b73a4f55059080b08abb3699b7b8626cb2a780d97cc1ca8032851baf4ed8b64fc4330865f84ccb12a3dae
+SIG: 79995877ed24c791684f2984bdf9609c3f7b576c57d162ee622d4ce8f36d9c5573169d8801216f1c46ffe2f6e2c09048e47d4beb997e9abc4abb129f9b79690a
+
+TST: 600
+SK:  4deff647cbc45ecaedc3f7ddf22c167af24e3d63da22b0e6a5b8439c0f3b1934
+PK:  0c27c9d77ac8c725bb0663933ab30d1aad09cbcf2cd7116c6085a8499f701402
+MSG: d6201ebc21cec1e9bc28f957c9d029cc38f9e85e06dfc90bf297e61f2b73b407d982a66b91e94a24e91d06ab8a5c079d0f69be5788ea8feacebd917291192233862e6acda1e8cf9a48bffb5491dd65af541b6c72af681a81823d98a0abeeb6ba9f95465b8411f99e119cd28479da984259bdf86c9fef3cca34e224691f183cf095037727da9cad29f242f83eb4f736e27fdf67018d711b74c45b2955a6a76ec15330df5bad8030c6b3a88d72f28447652ac8902b5b76cbf6b945ceabfec04a9b8cb30f43d9eb773e6705594f0de1b70f1a20c99fc4b1221f8c81b0bc30da12cd5dea8f4d90f13a811a2cc11a96846aafb4c42a00e9ae7da256a0d22b198afc25cc1041d24e056cf387601d7bf7eb3182d605fe5e63b18d531a5f84e5dbd0184a76c6c467a8263a98b5c005fcb2aaf989f5cbd0a9d903fcfc609d6e57d9c439021cea93e4c4e991f193caf3243770b32578748076b7f4cb97f17c17a79b82253c2423db698cd0a33ab33bb09b0b08cb8ceadca1e29c5de2fc12b2407b6cc5af5ae976dd3ec630d8339b7dd11fa34caac150c7c4791d8c427b0ad92e0529067a88d52011e1e0a18299b969896f8b8360f75c45c496da47b09b450f9822bcbcd43f4293c516802bf747c4abeedfaa3e79cb9103d3770f5607b77516e5b1ce0f64b6eec7bec3c647c006956dc55b6c79f6afb39d1fc3ecf11b974b44aedb72aed1316635083c2124502e5c72d86ecab6ac90243eb39a6aa9cb9480da38e1edb8d28ff90924c05d5d21af5af95957b8020781378711a29d0920acad8ccb39a311693278c9900b470da2bd4c12a01d73962644017b6034713b2a
+SIG: dd5489fde4ba87d1173d4cee0682afdd4bad80dd770ea7d0dcebaf21acc61dd6324aca295ed0e23a915ecfdad50f175ebc516f1be5b6d87d90bbe38622495302
+
+TST: 601
+SK:  5a19bf6c941f394e93bd3625fb81cd9da81c9020b1c531257a7b5957bb079211
+PK:  20e8699d087ce5e8151d28053dce66c23f28081f35bd26819bbe85d38a09d702
+MSG: f721ca3a32c1e81c9c6f46d5e1fb50e7ce2f4e709333ca2b550d5213b6773d670ca59a2b5086a443843ac50813b244c9c9fac6d119698927813512c84fe30a89553010138f91e8176f5cf25789d7281ddb83a246705dccb999c4cd0ae219c645f6d71d451ae1f8d2f9891af8ccce03f438559fb83667b8077fbe435a744af019d6d1399fd2137f5afb8ef3f47bcf735e7c9ed8a54ba0c1c656b6650bb30adb1d57ecd2074639494231a2e9e2f985ed8422ee03cb3fd738c735a1b82806047460ed84f7468c3c64b35db06bc58de4bba463e638a94133df106ac4f470361ccde44157299d225b17798891baf5921986a2bae326dda0b89617c677bd1408ba2748baa67c8a2c5a969bc00cb40dbf490e07e22c913afdde6304a07fc9e60846992456bfb0663a09def68def67a16d29e98c7b55351848a8cf92310c7463c475f249c6f7557fd0d755ca88f877847fe0765756ac34a23f7840d95c3d294e663bb1518b75927c410757e0f5c07c5a7fb215dc7207433ebf791edfcec90e930f8e3ba9dbbb985413c223be87873bd323997581804d8896da386a6e9120050a0eaed31240aa17c7b6694c30cbcc3c6956a6820fc9ab21875533963dc3b0d88358271276c6056528910dd989ae0c330d1798f7d8e7d1184b84a81434325b8c302edf601dc5e6f847fbacbdeeff78c6621d1dafdc239b18b8c1afdcb4b9dabd5d3a92a932ea1599546e625f96d6ec6fb1cccb76b476b330ac59259c634fac9b3fa7de7ae7053773b5befa001b04929f74b71241e1b257696d65a26c1b4ac86b7b1fbd6957fb9b95084ce7d70090f55d44534694305e91769a82941304
+SIG: 2a2fd6054ef4e79b72191a0ccbd2b18aebabe8b9a71861ded98b7cdcb6a6255328bc1aecb0c9335721a9a96ee4b5b43f90d322ecf835f78b264dae6e387bfb04
+
+TST: 602
+SK:  b506c01d69746eb4bc6358720e438ad330c88b605aad652f4799573ab0a1aaf9
+PK:  7ac8b68863bd69151583789d864a7357e3a045fa86522a9daa6e26fb79ed6d23
+MSG: f7fc18066ed04b30e633d9865da3214beca60bd796019cd7ecc91866f9ef2446c1fab06d8651be7f101aec7bb84ee21e71ad020215fcfb36f2d11e4579ac39f8e2b1290e3896d522bcf513aaa06771f86ee228cff3a20a1f10c564339589bba9605344c0a6e682ad5ba40d1041941bc46f98b9d09ca17f8f044e983b8a4908933df2263cf78811c24c8f4814354f6f4c68b7ee7b78308293bf78fd0ff122f095c14a73a59797172ae05cfcec19563eb18d2bc5300ed4bf6bdc443ea9b8bc1cbede94cab905eda5a6a931597de402146fac9cf8cd6a8d104669f913fa834001ca4d090fb7949d3109a63c0549b03f151b7117c4f46974ba59c68296edfdde7692ee432acef7610647e0957865e62c1a0cf05659823a55452dd5e471b31c5a49ab05b5aafd5a0e530e896b58cc522ecf19e52ec82fa147f9e385174c7ec33d1d9b86934aeb4f6c5700f7d5eb33ff73c9fc6aa47df51e09229e6ae894e86c818bef065f825971a4cb90adfefb31ebd9d1b79422dc9868f9f74e7a32cd4071efb69b27233e6e5c60dedcd5321c030a46cd26f5602cac747ee4b522d857a3321a03f403a6006250406361e48815afba77ce08903441845ba87225d8b24046745d4065645a1b98410cac48d137cbbb8ab1eba50da9c231e9acf322a6dbec0ef416a446c3b610d93569fdf45aa6cdc1b640d8f301d78693b2826cc6ed468568ad9a0f94aa9b9fb92f7e78d484fdf5d8d45c991e28074dcdd680d3b1f189ef6bdc320ee6e64dd1f80d9264d83042d2c43d83581ef0394b1b5d1f69f3bbbf04b7c808ba34c1580f16f76537b6a7ebd0a1908be9494d3fcaa9871db15750
+SIG: 17a19d2691b7b046d7b19669ad73140db92f0c978c7f61bc3867d92ca9d47580a0380b5901bad82af45f676f74287301980f71871a42261dbe0802950336e60b
+
+TST: 603
+SK:  e1ccb80a262ff8af1eda075c972c8e941e77cef57bdb0a82572c28200b493ca3
+PK:  3d37e2a5027effdee07fa511e423b2bc56edcea075b41649766725c6b30a10f4
+MSG: cfdc5497b023afa62a7fe592caa92b875c7705747834002f7784ff166189398815d4e8a7a0038e1fdadddeba51057327ad1960e859cee56526bbb4127b6a5f90d04d08b15eee66c9ccf88b4b7d1ee9d3b8b8c6f42db3c34e59048a15c6041f142c4079368b7b11e29970118b99e5670ae31fccfdff1399142ee06b2e3e2b3c9707dd64119786e2fab47e0bad2cc8b558d963bb48a49ad2c637dd35b25db54bc5a2630222fa2acece9ce12ab0813077f7659f5074429ca6b494331032ae792a599c425ee297451dcf5ee195290312742e647a7795b84dcc664ddae2a1fbf8c4548a37fd82d810e2145f01df1a6d3bcc42a91a10768e091f3d69329a7bad6c072cac6d89afa31c029056d6b62212165cebcd49ac672e3830267af9f28ea319bd042f6c59de4701e58248736c8d976acf93b99d2f4647a547d392447a48dac11181e16b1501a94c9316e5a67c990b35810b4cda0473a6a4e57614215868e2e002c6058b42e4eeec84139dc19edf5f80aeeffa4f5b07e8fd23139edda31899ebe6fee78643ce686b2963a32072bd3b3bba68485a05c2cc0456c3da50c7c8c651a3066d13a3660bd47ab6dfec49e01557a6742896aa4bc6363a797dbad1a409cd4a50911e70ea007af8e9b1bb7e3ab56215a575c90f739c2d48b3b34694b5acdf07980ae528de0621edfac8b8fa84954d56dbb4d03082b984f13e5dbe9c7112ff9716f55053064662ce0fb81ea35f98fd2cd51137a46f64e0c1caf44e5407dc961760b2597f7f9200617d471340cf15176c3da880fe4e0e93a72fb94926faed865dfdc772e185292c1e36b1211781c3e938e3d4f24e29af517a379683
+SIG: fda34b652b79746f897e222d37b77aa250d02c527c4833df80ea41d52189d50700e128b78ee8149c9b19f3abf755acef5348f5fbaf1ceb41c038906ac5946001
+
+TST: 604
+SK:  4fc512efd86e3a63b395eaff1ba011e1590fb9326ad3ffede7876dcc3e9fabdc
+PK:  26c2a22f9bfad90606dc613ff107021fcddbec7237066660b488964349e0c828
+MSG: 07cd1e9bfa38a7d8853465a93c77ab4f30faf914e48bc4763ba07bf96ba808c1f59ad4ce9b7d921fbbc779659d7ca36edb7dd3acf7a29452a845b49fb6543a3b6c5c1c293aff618485a10eea60ee9649ac9d481e6949967d3938b52fe09c36b9ade07581db4eb542a97f5ac8ac73d3eea184722556760cf483090564553061b90a0b6d2dff4707be763937a10594a82b766bb2cf6daa52fa8d7b48f32127c431ad9aaed3bfdeb99ad42118a1b4de7b992134ed9cdad0b5296d197a485e493ecfeca3653ad2ce0f9241aabc096d7c4ba603ba7ddd07a8b257fe523276417073a65fa4434256fd1f239ec1de5da1a0a8c5e686ee14d9dfa438c53b99c954afab2f79e60b7126f2cb58a26e290da1dccfc301f239748ede7bcf1bb7ccb4720e692f57e53e6f59075399e1080ac8aa9a61a568c4c569d36e76a2d7271f2c44de4e363a8c916a4e446b027b64392e90ceabf6b6071bc47a1379b6aa6344763b2a0e7ff7c4a27bff3106721c253e4c1d67c37fa3d7c1ecd055b8e929d52a8e45ed89fb180f74b552fe06f066c7e4318ca2f915946e8320d5806561472fb8ff7fa8072d8e6fd1ce63cf87382f7b9404540c1d406c70b226853677092645ce996922e7345dc07fb7339f9a54ff07352dd2b993063c2c83d1281a4fd178e5a5f80a5b33c229d0578367d44192e9a4d21e9734d3bda083b70f47103fd125177021df3e53d79986efea2dc04f02c0ac278788319ef3a9132e6232ea6db39ca5870855f9592fff6c209ad2f1c29dd168552898979ecff8c81127248f8310515300656129d9b7acbb7ed1e46bc98c04d1a35b18913738e9dde4d2b065f4184242d8
+SIG: 82c824a7d1139ec73ae1d023adf62811441e968287f1a580b859cd66cb33b58e409bdeb2a874bf4c23610bd44f693147f2f7c29d443a905084f3eaafd9330e04
+
+TST: 605
+SK:  0b7dfad05ba665111e1681bdc0bc8ba973767cb85877020a2dbf918325571d9f
+PK:  9505d9e86dcef56c9db76f2862b90e1f2773202f1750405e7ee5aed0fc54f8b9
+MSG: c43fd34bb1424cca4e4dfba75c28be801844446ca089020885c748382547164a9d4a7f9570d3d171ad6981ab50eeee08a4a6c66d7699d23edbe1faaf44660c72f4552d87d265ace8792823474b90a5d7f7401deb9377627f60b036b36e044eb76bf132fddfcc0ef5704a633d845e962b47517f0baa34d3d6e9a8b9f8168bcdc84c6d2b30c6f343e75357f7f2c0039bd254b244d36cd61675581fb834570ed4113a78e606f145a111992c2c6b61c4267628ec87cd88c36a3c84706e44ae96a96e0c8480318546d6ea6a6df18a2b4f19f8360cfbce4e9d1cf1011ffea5633a66619aa4a65cf69be4459617945e4359a9d43260ca1a20f4ed7c1ae5ffff3bd92294ea70abbae0385b0935cd1c0eb5183029c585a0294b7999e32ef7a290fcb095675dc4f601e8f2c96f35b7349a37057509f4ec70c9f50f6011f1f5e6b061c091d11c0ed5dec8ece881aa340508f696d9e9cc7298e6bccd7c210e2ce0ded83592a3cfa13e8078fdb3258b39f1d11cdfe09670c1e60a3910a4fff51c6c7f7d6624f4c93df8888c526f484f9b13e0a7f62964783978684e292679800ed5eb280e287c7e639e85faa53fba2fa2045ce27d8fb308360726550df9752db305f8f06647970d014691999afa97b6193ffcc6d532f4fa69e133a1d10f3047fc00381f4997bb84e5b6cd6028c62132cfc024bfeb980301f29512bbd109d089ace182cf9c2ffab1b17eb00b6eb46ae198da993f5efe7c1dc22d25047c1ee5246517e7f5758f996abd83f13da22c13dd205ee191b55afd4831ef078bb6ea073a625bc97c81296160bbf2559b275cc37ccf01b91fd87d4d99a367aa9978dadd0689f8a6
+SIG: 415adbb2f2b9840577fd1841f9aae252afe8f5a72236017d50db22d228cdee9f5b3e8fe9a17a4d4e98b7341381e8d8625cdcea956d253b74e02dacb84920a009
+
+TST: 606
+SK:  78188df8c754785621e27ae58e100d5080e16e0a15e277051f95f080900ec0d3
+PK:  a1bdeee98b0757ba9c2d8409b87424e64e42f9932acfa9bc71fb3f8ca0e11d52
+MSG: cf70cca57feb1beefe985ad5af9d4348d3a46a63de1075381fb3639a044fd6e6091f5db9c94d39be0f13ade6d9a074e67ba706b3a8806295f6b654865728c58ca6e9419d5d043f2110814bbf36fc4070e4d9454965c251202ca395efe3fdbd544feb187e34ca3c80795179552fce9aa804430e5b6c8685341e91d5889fbf3f981904620ffe7013f53b939e17443d614e7e6bb57ad674f3b4b001630526cf7302a7d0afe7dc24d6dadef6feba3f96973aa5b8d6275262e430a82f678696971a8b60e38d3b2bcc170d5bc20302a39c596d27fee39e5da5b10ea9f382299e19819717a718d37d155f13923182b5b7a1c54ca109b22ca8e8b26ca5ca3f3b9062219461bace97e890c94e41ca3d84587fbdf6e240c35ccab71d58477d28168e93372686d42aad324a3f16afe0e9b89ee20e485fe6c864b5013ba88399eeaa159835a8b2bb2f25f579ca3bae675c63da1b50d99d4ed978692e5600233f38ab7e7a5ae0fbf8c0b69cc38bd30eabd977efa05ee2c83514302bd40c4bdce7a4110afbb6579c620e97f8cf2e9bab2dcc7c33f196e57fe761a050122894b7a75a929531996ddaad78de1d4d924cd93a61df227776bc1c39fbb8de1c4438868b6a3a2cd94c07b29e3f6b23cc7e0b63689009d9d0bae1606bafc7a808f2d2fa2562b8dc093842c01fdb840da4860aced3fc525ca334edcf65948bc416f98c450f0012a6107dd7f8ede40e1c48c9e8a565a810b9cfd20356db19f1dbde598921332e0d813f0cb87684370388772ff3cbfcbfa299c198c97bfb9617768a05161f4169ff5de5d9f40062090fb882984d9d5c7aa78eddcb9634e466b8853d512b4a546d7423
+SIG: b94114eda46ccfc22a4471a64d790892e59c5d505618eb0e701392c709613e2d503a5c2b66601e636a3c1c7d49b1ac798d9089b0f9ccd0579bb90634d0bd750e
+
+TST: 607
+SK:  73cb02b0bf26a015da1dc301fc125d7e6c30b63c9e6eee9e065d4e847132c325
+PK:  ac9e3dd2ceb9b23e748c04ba7577fedf7ceab9ed87dc430b5fe22eac50950e0d
+MSG: 0a2b61ba35e96e5819b88bfdb28b7ce02e64ae9cf572b21f13552c0db10f3960d44ba3472f43abc4e6295bdf790bd933ba3975fd4465fa3e2fe2db02b6377752223dec98fcb2404f3aba43265a6fa7976b6c6cb6868b881bd6f3d25cd9d6f70e512f8089c8ef26fd58245053779e59c4725aefa26467c9f500e17f3e1573f1a855e9b8b21925ea0527f3ce8d88fb54a47abeed14f399cc2d9f1fe54665fae0a8f0c68872a600046d1dc36397d310ce393fceafe87c17ebe122fdb543aea71085baec98273f41ac96698c150cf911d0e5de2392d84841d01276aefbfe9995e10a6d46efdc2678d456c9f36b2e10114d1187e7aca739037ea51f85fd62a29429ba529cdd8ad91347497487ed7e8709d4776ef68670792d0615bc96da5178d606db63e4e5cb172acfbc1cbe20269350f1b605f35dcd479135bd30fb4b5a39176cff744ddbb306c9e7b4167de0379a6166be5aaa74d7157fac957d88dc57597cfef23eb5108b3ce53fc632dad1b972a29da5de32d20d8ecede67ff00da4a08a0cc1a98bee7a94e3cb32fee94ae25a413544702c37b3e1778a070cdd4840bd39f5f45795192a867863876ed0d130d46e2913935082809f7e15a496710f255d783da3d016a654c15ff5df907a3ccaf37cfe11c8c3d496507d6760c053820f0f594c3d01ca269178aca525ab2821ef55f92d85fe685ea34472ed1398171064d74a422ec91d1a670618fc9f32424bcb11a77f6fb4e2fefd2c4e8a73c452886e931664d1a83bd927329c04d250b83521d7dc13c91cee1ec050e11d42a4b0c8c069b61c4422d3a49c07eff2905b7bc7f4a5b43e6b0d61dfb50e4eea2e90d298a781d05
+SIG: 1a5dd4c891c8e132570187c23b9a1e4b26f05460e875673819396df561c8af0e48333b62c77729d49fc40e174a7f3c21f85ef4d339ceb80bd2e037d803af560e
+
+TST: 608
+SK:  db05606356bacf23aff6cddd42b2c694352b5a0fec560aff54d9bd9710efe06a
+PK:  32a5c7cc4909786b48a53f31093f549a9f1730ca6690383fdb5f14c2666e3132
+MSG: 1bc9c2833f37cdf1356fad166768642717701b38a0ab0c2f581a26d222d65ccee4bf0f6dfe64d33bc0239f71d4b82644b01625a1a35fe798676239e0ca779ef23138eebe3bd19de2d8f7c15b4d96f13e51bc633bea5d61225bca1d6339ba53e81f7d8d24c5d60f04ce8c726761d264584f1c7e5b5b6992456c1c76892d6352111e3b926fe025c0009db67ce0ddc7f764e0c9adb0481bc2795484d96373a962a7b74a5596f527a73476498c7823dffa6c8543b07971b5aa271c12255e0918dd73f50c30c9a85ac7c2993dd655da59431263f5914be706374be9c07585c2871328b4dbc39401c95707387e6e069d44b9d8fb058f22e315aa0d5b4f1168fc107962b064f7d845af8e2131951d1cd66dc84dba46d200af4f4c5f51221bc9b2196942f8b40e7ddbc9aeb3d9afc071259513135a016f2866099fa10f4c3b73500bd55c477b2415e10a279ba110d294f3dd1842177d0b4bfb1734dd0ccb7e394b43d16f0b7548362280f434764da57f19ed3e302e5370fba49664c230057433cc647eb27cd2c7c18c7d66906f088246c22f7f790399deb4c5fbb906181769bef5afbe8ad1f5de55be588f52f69c54d4ef5a969a0d995c27407b23edd9243d2499fdf29473b1955c84b3f7cbdcd81b7656ec0be9e0fdb3381356960fd0ca70e7ea74b646fcd313948e6ddb47609476fb6fa4842fa788a0d57be3b0a6ca1819f71614760043ec4904881939968a43b5d1928f84a5919093bc3841588171a9cd390f8fcd61538b54e6ef99770573e1986d150fa96b7a07e1d194af1c0b405500acb3d10e3be647c89862006fa78583e76166842920160eb57f0b2a6edf193c44c5eeacf4
+SIG: 53099b766adf2944b6821374842c25d6e67b0ccde9c637fecb11b8b8b07203e3075732805f4f14aeae73bd62e308b5887d689e29cd89b23a476943110717b100
+
+TST: 609
+SK:  1d139b1ad0c3af1d5b8be31a4ecb878ec667736f7d4fa8363a9809b6d1dabfe3
+PK:  2428cf1deb20fbad1fdc665d825b614122df101fbe1473a79996baf6967434b8
+MSG: 8df2d2df9b984da84433486a813c98c5973a696c11624610b23aa438083464f65a76796615b728c2ed4e60715855afc239450d5bc0911ff2a85230205c6f1349ba5bd87ea6f720db6ba70b77421788e0c654aebc23074c5f41d2290772140d981a6bc4fe709a268e64172a026b270118b4db51ab6a13c99b063186d8d5b338e977eddc6bb5fd7dd57d9845a3c3fe76177d5738dca16a8f9102857500174f23ff4c3bf3c8536f11580ef8514a409f5bbc9c0296f12e3478d4087f95efaa6c636071d21157bf11774bbfe7693306ca7213da4713ebaaab3554edf08011a5ff73da120375aed19628670f28ab24b6f5d5a1d570480f65d3c152bff1b47bf0666929cb7c99d9033faae8534fc35da730b811ebcc25ae10a195aab12c326aa45bf805c62dd4cd5f868623c04a8e1c6aa72f1ea4400c60867dff622f316434f1ec89503c6f9f65c137b4944cbcb35f086c74cceafa2242acca6ffe611c4b5587f5b75ffad349f00bf96e4a580a875b92654069b62eeac0bf78e5aedd71869ee05b9a94e1c98e35a97800a4a21220b039cd5ebbb756d40b4042e2c84a2ae98182511dae8ed3b89f4fa00fb8ed946316459710052ad4c02f63df05d3bb1ace33672151bdf5dab46c7b583db373899d4f035b6c111258b4e5a9e707a11d215e44e68ef1a6f053809aa51bd902e13ca99c1b1cecc83b9c235c710e797d2b1a249b2ea079b5c1674ed7169f1b6e67f1ac77f86b743298969335a772440f7fbfa72513500d84166114a8fd54139464d42b995530d32370b69bffc7589d6dcc97e0bf17856cc3bf4164dbeccc8a881d414d6a62029276c5f8137c0b3c68bc8f4bd4e7cff65ef2
+SIG: dd645e51edab04db31e33172cf27aceeedcc0463a963914a0eac8efd5a34341f6bbc52e042baaf3b40c89a57efb64574e69677fce955246c1fc0f269ef819000
+
+TST: 610
+SK:  4d22e331e0cf6f6a272db4d20687ffb059f1225d81e41123b8c89b074de76a3b
+PK:  b1e4cfaeadd67b12d7b9dbfc0f88edd0373f9a88c7fa33fb7f2b1e475eccb61b
+MSG: 9c8e3f5b4d704030e1ba71f02efc4b87d6fffb55bc3d8d03818f915624fcf701c54adfafa2b694b87751cb9f69918c0f050f4c105d5ccb40100b28dfd4f411d591c12019176ac2016bfbfdf0ddf11db8a7e39aa7b9e216f667c0a15fb977eaa9ba3bc455cc58945f3e944b8ac2fbf4d24fe7e1e619cdbeee3e5e12a9a527d28f5fd7cfd9220f1308d897b6d4314a5a0187864a2d621cf1b2844261247bf520bafa9bf226e115681ecd77427980cd12b08c359cecd1de3f5545f807f81ed76302ffd6477f89b958cdf12954cf70c142532993831647eacab0b4807bfdadb4389d7dff2c4ef0ef5a5c61d0df762e2e9080a7181cecd06a53199f0dfef702627adecf5fcd9b3e68c72333161727f871c7d1c43051ff1c921fd53b642238b97880d64e25fac512ab954bedbca540f5b20091ec72e67f88770afc32f2125ca0da4fe87b56aac9177f1f4f67c851725c5e8afe64f664799833fd79100b77ead25838879fff4747aa0d5672ec0a94348134bdbd4bb39b0c67a0cd30602edf4fec6f7af0cc2bdae126cea842dfaa4391dc5ddea938e1792168240c2d8b25352f9f3a644235ce36fefeb6992ad88e287ad2d85bd850396fc2e517a15209f5920ac98c532b1f4d869beb08bb03cf7c91af3ffced68d5fbfef86ff94ece6e2ead3484ce080db17bbe40f1db432ec1650ed24fdd250f3345745c9b7b9198c9109a37261fc5ecbbb12f83a0e1220a1867d45fddfea81dcf75f4ec7fdb5250e57754d6dea270b628a79530ec28b619bca9493e6305cfc4414c1c1de3389e890197c85f28404f3fa96a1e2fd9206b472e8a0a0d32af55606bb083f76a19b8eae3479ae51d98a99a62
+SIG: c366b802f682fcd70525264fb1a3cbcd0ee35ecff5977c2a554da939229f17819a961ea74c3d7a7881ac5c1fa16bf984d9456a1388d3463c4494429b1dc45402
+
+TST: 611
+SK:  a5228ff9bbb6f232327eb8d879d7f8b277ca72bae1f9a9d0e260dd90571db4f9
+PK:  d82f6a6974f51c8808d9d617f4cec2d8a37eb11a14237c9ab9cf11ebc80ff6c0
+MSG: 1df7a6835e3310983ee7ec731125f5b5cf117af0e36b3685bf54ace1c48c46300560a45e9f9bdd96a0bc4d14e89d4b5721a2caff6618b182edb1202f3d0c5d118d09b61812c010e8b196344541cdeefe5fd1f961c5dd75459555ab72ef2aa7a759a4f3ad3caed44f4c9a8ef95b76ed9a99b55dd8a260ba08010d29ff819f2af3513c1a640d6ccdde4999205f9fca8857115d8b5db9f70a62e5eea0d5af065de153f2ededeec63e15c8e09a92582182ac07d81ca63ca4aa597a2220e70481957d415264e258bc263e1cc36e53478aac5ca01694ccb09b4ffd84739972c7dccf3defeafdede162ab6c58a1df27371e3f5493067fc9e2067e579623c009fc825eef0e010fd1ccf2a8d3fbbb3156f9dfde0c7cbbaf8433098517491b78db9698614ea40e0b1e6a1e36b900453a16ea276f3442bbd27a7ecb981511f5c9209eb096e28588b65b96b50188c0381ff712bc06b2c655cca0751c095d8016251585851e677434dc3efd087a12680fc22e5b8310a10e32caac9b71c876eed31ef09f7fa012ba08dfd2ad68c1e147f50598e550467ef99f295a318faa507ebe776ce55c4da164323c30a5e72dbe027c3ccf96c70197a6fb1b74af133a8be2b03c1b99fd25b3ced51fe3882021a3afd9229f641bc6cad4e1d3cb6ed9b6b68a25f1e1397289981f78924bff24c8dee6a18a0421fa32ae3ab60a0d933a6af4ff704874b09b0739e2f29d8f252d79055f89d3bff10a22c54ac3d8afeece818353a6abe2b7fb8e8e0da5b7ac1cfc985df97580b18211a4e3edff95afdda061547d3ae0406d3286cd305bdfd2c3abf8f74af9a03420e5b03f825e9c53907e13a5812174be42898645149d
+SIG: 97650fae3f59ca76477f2547167749c5830248883225e354ff46c7e381965220d9bef2c2057c7d1990f08bca4cfde877fff2b4aa813d9c4b84fb79eced81ef05
+
+TST: 612
+SK:  c04dc09f119d670fb1eae0136fcc06085f290f4ad1aa1ffc9c160ea5cf47f09d
+PK:  ff498ce8c9db7867f6d0276452a466724887e6172f6681671b8ae035f5865ea3
+MSG: 1e42297f8aeef29a842e0e21f5dbae068e2c9ddaa6fd348e48881f0d42c50bf0ecf1706b94a5d19817ca02d83e9ab2f99d8bfaaa5c85ad39a150b225ad3eafa067815b74672fe026c3ccc677255440b684a76e128ca2ccc429f152577d25b69f40db582d49479afae680712dc0fd1fe1418839687ca60cdde974140462f96148295df1ce43a977351c77f2f0b09a6b26d6fe965fceae17d7b8620371402428544fdf91690b44e9afc2e9088c83ca48dc8576f628724798dc90323174c44996596502a35df8b982c570a6cb51b9a197d431af33f02b80011567fe50cf45ac111b3d556f8c8ce5ae8c9972f2a9936b1a012b9c339e30c97312b65ea59c100f79d795b8a24b31a0a97dc25cced6b8ff5ae145339a048ca12a579017fae8d5cbcb61d52e314dd7c2e72010c47217b1d06878bf2818ca188e8e307960c1689d7dfc0202973cd29f2f7ba743469e685e0e704b04baca4fab5488448a922eabf40be581c1994d74d13a366ce857fb40a6e05da8553694172cc3fd28062f538250aa8c11f68139e79cd1191ba3314b5cea0864437ed2e4b6fbd75b9ded0987b41c202a58ec0254d9d371a795f1dbecddac112be8d09e2d7b9ca5752f406cffb911ca36450bc05f1ec1ca3ca8d35124d1286c55f10f61334e46ece4183b92219a9dcd0e5e78ef2a76cfe9a9ab3795dfdcb44f63d45f5f48ffb4156133ad2e9950884c5bbd2c1cb8729e40a8787f784969fa880c07ffcc97d5c0d2d488085e9116d7107cd5db16ceccdead55025eea2edee93c1b106427618ee09dc3dad1e05676a2368069c8045c3ebc6c67afa52d59398248efcf15e904c7142304ff61971f4d9bf6460c1d6417
+SIG: 4bd19f3d9c5116ec6ae0024d0f246d2ce250d9e0634a232ba06fd3566aed55cbe59f12332cbad65d4349a9d22e7d6e46d2fbdc71d5c8f9da15dfbf17ba225107
+
+TST: 613
+SK:  6791bd74d3b4620ef5f1ff56406432c26ab646f6d5e9dda6842ed69052275392
+PK:  da9915a7552f110faea12d47920a09601443d4000a9c7e218d5ba72b74989fa6
+MSG: 36a20e66bb29155161ad85eefe893b53ac5ade165f089a77190b0c239dec8a201685b076b4ded4a10aa459b980a8cca47d5f8de4d2a662e446d5f7fb70ed9be05db1cceadd130b3346d9409f9d6ef52824c764ac6fb1cd156dbd6a473ae722d0ebb25638c51265a22febbb14967d6dd8253c1d038895c6737f067c8f73c3c1cbe6cda4369632d7f4c9acebe87d0571c81a58cfd72cce4a5cf53a1e75259f4c993e67efc8d9c3576c43af04a5caf33d856f7f2755d3a975ab2b685c6f65680cba9ac879f3a8c9a4765b879c0ade1e4bd0d4a70bb6f92b24d429dc746cc78f84811f076f32c61e3585cc8aade9b0ca15224bfbfe18be10a33643600f6612bf013f0efcca837246a0ee5b03c02f1573624c4a44a90f9e423d4e56061a71d0144f5a887a8cd4a9d6f247904e26795951959da121c83c6c941e2b6b9ab76209ffe9178591ead68230b94ae97df58f9f172428c95067598ac582ffb950840d826630c4625f5deaddec1305203b4db6b945f991ed7cd3d6fabca51e2166adad0aad5117336d52d59422f0135c8fa8cdd0884be73586bf284e5ddddbcb95b411f98568526fbe71a5592b56ad5a7345f2874db1d57beab43e8cc69547520629f0ee76dbf432a376fad28bfc77e14d840f0c02d478f1e2337c23b89e73e5279108b5609b18e80db0de11cfa94ecf7239bcff59c54118e4ede4fbfc0823ae546016f774c52198a963b5545a3489b89df7626fd11ed4658d715a4657994035d403b3370d14eed9718d598db675f042592fea89056544b32e5b9c8062828aaa3cf59cb476ad36db1daa2482227a9b7afbc153ce93253d1b39da95eb96f83128ff2554a547e34eea4a0000
+SIG: b1e8d481065bd5121bb3bf569600bcc26df40c499fbaa954b39a619dc40b9590c31756b8b63f860151694b95765d697b2e1ade0806e92a06c4a559e90fcfa506
+
+TST: 614
+SK:  234ce4d39b5ebabe9a2c1e71970d718138dcb530cfd296023427d892bf88f8a4
+PK:  cb73930db421f6d24536837bd0bff6fa75bbd141c98a405d4244a3c424550779
+MSG: 77730cf8c8f96b9187902acff9ff0b21746ccaf0a382a7b343d1c72027ae3c3168a73a6b8f49bc8798141e15c2732b6a6b3f757f8a8e86c7a4bacb39551c54874d6bf716897ee4af13253aa5bb79a192104f44dcb3de960745a8e6aa9880524a629fb510a4ce4cbda7e2957dff1d62e705606a2cc84f91850beaac5e5846e1420bc91dcdd2427b69cfa46ae38a4fef4146eae35f9c22e967cb14a1af9cabf83b180465bed6ef2cda382a84d9994aad655d8952e0fbb0f96fc8089f2e7489497facdcd656a8a451b928c11e7a4075072aafbf17d8f1054c9196288ded3ae21f9afd5810a100d8e4d84c4a35a98b30d3e18524438dd4402dfd8e7675f09d080cd915f14af4372f7ce58384972d5d111079651b2acf39d2a167c6a00b2b17ce0b268791bd2be5178fe0f82d64dacdde377a1e8be9e7d8dfc82b08644537bdc870c5819286fd51f6792dc5f67b54be336d44d54febf81b8df8dec5d8686db12f164d0e8ff1aa2c16bacc9806010ec8e91196597ef06a4cf1707def5067a04889d8e48a9bc2c0bef664f5acd1b4f5bc2da7da43dcb5f963245ba552fd493001d870a9517a179c2f0de85be0c682d057488e35c7816ff4ba529aefd7c66091f206f5f4d75cac8bd209ec2fa55be74af231e2f389dcc2d668bf695ed267c3594bad9efc00217c7a0e9e7b6a56a33079a30e73c3733f2d24efecdde87f72f948d277d6b6d5b035b4c53180d23d66cc0ff17c15dd468585e389d91a4c97fd80110b218a0bf7a5e0353f4609d2cf018a065571001c7888555eedbd3622c3b1769cd13f33374772aa6c8a8f588102017d4ee4e50dcbbdb1d610c32670934a6d9e6d9b784bbfe71862bb38
+SIG: f6d060ed7d18273f18f7a69cd1d8126e478e88a1d7294ff6040846d46107c3e41a423babb2417139fe587d2910271a357fe5bf57c92ee3a7b77533729d0ac20d
+
+TST: 615
+SK:  103d118c7dd65d07e8d5582e45042a75792417c692001ee6bd9a927b2b3d9016
+PK:  b45cc94514a6ad672496cd4eb9fdafc1d4a167072c6874dc8ff16d761fb66986
+MSG: 5a8ee079186b51cf4629834de0c6bd7334855039a7631d6887652a7728995972e362c1c409f084f5aaf2986ae3f536be0070c4baf459ef60a015ef9d70dfa3ea96711cbb18e92af50c527d7ed457877a07ab83721518c89f7a864191b1e97433b7c6cd634a832e19891e76c62122a49dbffd83498aa416acccb7737fe75f4fb2c35328e6f6ececaaa42e43dba5bc9689673dab96f0befa3c83eb41d4d887b3a117d055e30bb87fbe7c719472f6c7a4cc45f628f5faddc48ca344f77b733c0e3b9f5079dbd07af3a3847af141719cca2f6a766552b45d0fdcdb9868f2c762b6d4933ba10836f95bff71cb88040024c90534c4d7a95a2303b04c2961012af58bc784a96327bbfed039d0802a05262d8e663b78508e92508bc1f2ea2b9be7580bde10a4d663d0d25b0e973b8c5ded59debf19bb044aff1c60c70ea1aefe85f6d15c2c1b84753b59576a49473d65af3ed941a3d514b5c4522c141bdbeed9cb339695b2e02dc07000867f1bf8ed8cfd3b1afe688fbca80e2f9ba5c0b188a19adaff6686ca0ff0edd444661291fa27ca1fc529429a5d8ff79ed2027c60ffe3b2c03fb8a66a3985417ba4ace7d14fd0e2371edf5d71bc02b9052767c7f72c4e6f3f30e0638276b9c420aa4333095d31313033090582e3ac4d9fd3203120ba2514973ab9d1c7fc42290116b51dae9fd579410ae078ed320a5a1b49aa7b5fefcd756395213af8641e29b0ebb5b83e3780e5d10e9d3d11998148f6c6f86c4d4eb252e28c70fa3a55c43d4d7faafcbcdd45ad2637f215e81549eb8a4cde4715b7107207503a79595060b83ace8feb673b997968469dd9b4ad6a7ea81c6e61810033f3edfc137d974209575c
+SIG: 2fafc13c43afe5054372b923d24f292b283afca3aca3b3e432380684961713c8d23e86b3580495dfbae424b767e4795a0f922f71b50f5d7a369ab8c6e880420c
+
+TST: 616
+SK:  47eee2024dbe09953e981f6986520f666082aa9ef4892dfdfbdbd250d2a1df28
+PK:  9f13cd8ebf5080347975159f360296a7164014d8d069e831dab0332607997cde
+MSG: c133f033cf3bec6cd19212ea47dbecb13f2c6018f9e0878ac884bfb575c0f5d3fc5b4999580eb8acbcaac83ae9ac9b443e6d1cff449c3689b433d50900b2e8b71d00e119c8b875094bdab916adaab75bcc852959d8d759795bbd6b360ee484afe47b1ad28391f25afb8d4e3afe0c5b600498a12833fe2a1a5483df940b173ba0d9d8c4d1321fa4b733334b0f6d878a0e5a76f4f180ac119a82082acb1488e49bbca7a0369c191bd6d0c5d445656821a99ccbc945949eca8136cc6e127d9de92ef64f174a6c04c8b5e52495f0dd674bb5ca128a9209968fd450dce319913fd6a30c3382798163e6585f58ef208be4d0c6a2513a752388397a4ae444838c8466dbc36fbc36ae08bec88eeda131c14d06366b673151454100dea1118150fbe441b1e7826e545d9868242e899f5ea53e434c37936ce6fd06146283e8fbd536480de55a16102c44754bc554d5bc2de2f25e19e567a023df4640e74ff3a49e4dd30e0e2558b3dbc2aab92fdd5e79425ecbc4c699fe1f161965f1d0b45d8bdab52ec9bf7a69d8aa0bd171e755ce7b8d0718f7267afb733efca54b213e6f5adab4c9d76c867fcb69ae05c74bd21516cf342c6161f6fc9eccacf970ebce540cd892bc106c6bd563610298b70968f091bcc6e1f7ab4a5b2c6374a1903f4d3ad5e1bd8643a9c2f878c3d7a4dc49ef3197edbcda7bb91e7e06606087d4e981bfab93a6024977962e45262517f338b6857eec2158a297b2aa91524b677a21aac57be0b63a8074fe54e7a9dc70c5a5c3de728b9c17ec1212ab1130eb17622cd7b22ab6eba9185e8d67be6c47a2e5adc663d4642cc120222e299fe134fd7fcd00adabcfaa642fe2e08dd52e2c3f32
+SIG: 5defae0e173ecc18d5f01ec9291be160d5eabff63fd5423f2bc66e3f6408c196353502dcef21effa4b9c14bf27b687d1b6e86b2a205a89eb35c376a3a325690d
+
+TST: 617
+SK:  b6c88b4c90fd19a149d381671953b9b16d428f6361cf503a110477e297f8d2f8
+PK:  8ebfb084f997b2ea7932a2353b2c8b16bd825e1af587a8ebc51a6c45aea343ae
+MSG: 7f4bf4f52173eff072f818d0aa97e6935d8baccf4839663253b2414fe6b1f34cf43ab120155a1a3aea7b4819ddd1031673b8a7a6bd0b9dda4adefe692a56162c646180794264c5122115eb90a6d3054f084302dce3d836ac3de820638bd89a86bf0a4c01547cfdc543d676fe1639ef72c5b845c494e07814cec8a47d03df73be4e33c05afe9a190dda043360496be4cf3a6319da9ab06481677f1a4374d60d3d3b6394f8843c869b0f41a1e81c2b1a54bf5aacbd98207c8dbacb36422a3aa013d5e849e044af928545c046097caf149d970215115dea0b5a85401ff672e02ed40bd0f5a440cd56494053c896c3bd32606349f7cbe7ece2a2230cf236dac59f7817965f3fa80fb48aa30b0b19efa9a96591646bd25e67c185f77e21d6630b288d4e55146b2abc15e95088d936080775618154bbdda115702a2afd6fd5f56b923e188833ec448944d30283e337254242c5812d7245a4e92670bce3546efaed22d274e1e6048b5a0f01efbf895dc42494baf1747185cb1a4b88fdf1e6099baabc6a5ab5a2727b1e248789d170caa2449671a8f6e094c11332ea0ac2afe88132c644ff883d0c499ad76a93df472fa013eaa27ab4dad679d2511b5049c4e98baa2e7b00a534891e290265edb076f7dca8e6fef3f433034a16575f0e53da4577e6b13f0cb0d785870d0d098d5d80f413a268ba84e0431a786923771378cd57b8192258e2633cdbe03cc316a0950970526fd3e09376bcef0d03b7074e59a5a84fc64e795a812156d960567650bb1e1424b3cc9a4d99d57ba858dd1a0cad3532e998146e79264045e28ebbfd75a426b0bb851a244ad6be7bd5765af493dfc44ee378cd04daf3917eef2a6206
+SIG: 7447a20181b02cf1b6ad529569ce437c2a0508116f50205c41e6378b74fe2fc53630aa0dc4b80c31cb26c8f09bf8fab27e3abc8f1f604a5ec06631a84f6f2e06
+
+TST: 618
+SK:  7949a9472f725ce7c68d7ea8fc16e13d9e0e0a58f58c24f9228c88e80264090d
+PK:  a370f82833f88b4f5f5310b918e6af93bb724bfbdf3c02c503780b2c83ab6cc6
+MSG: 955386b92dd6bf92601bf81e84d25144b5fc0bcd7d23c76e7deb5f5ba6316bb61a5d8e74185b012967f0a4438b531696deb4b8101089e0c0482adf13c0613191b977f77b0419814147f5da64a1d3beb1275b9849d1297ba8532ae0a647a8ace395ae0ed00f67348c5ee5ea19b5f1c5bd2e622818e8adcba3c17c27987e4e3d6d910a56c7e5149d3f5574fc06009bf4dd3e37cfe3ebda2c2116d366dd88ce5ea72ab387490585443b086e8aa38d11d3820b72c658e463cdb59c5393011d4a8f4cb6a195229304e76239fa5e8c2cbe0f39dcad138a0ecb3c51579ec9a120a51607eefebfa59a44620ea5b1916087ea338533fc132ff2e4a43d052fd08b6b1b24fb672f73c9b9ba20b7c1c41ea24d912de9b555b6e5682b970608ff229ad3086f431f9be190ec39224ba2ed8acb4c8eac8582e23aaa79827c44e248c5ba092ddac0f2f79684aa93fc061073e1821a56afb9bfec952df2719a9c7a403e6a93f7a656d74b61c1d19083f8d3f19e659fa2b718e0bd04b693d63dafb86adbee5d87c75b7d129122f178a0e669eb035ca4d8eb45397f1851264e2cf0a0cdd30720c5e139cd6a573f1fa241cae9425805ac79603e8de350efdb0b9bc95ba7b085c1ed92c12acf53f5d4a1137598008f2a3672c84e5f769a25c7a4a16579d86288774972606e4e7d85263ad217e0dbcf343fe554c109c5d9409b7939073ac55a03420fec289b114a5c54c20b45ea69938533ade7b3ae85e1a783dd97897c3ae8254183cc54045c2a18ecbe521691f2619d9b8f1fb347ca055a7b0b4c24f64d1773e01416441efe159923217a84874b9c4ec265cdaab643908068497812c1af15c188071e78f597fedfce91c5d4c6
+SIG: e02898cc7c30ee01648247497be8a9c6378593dc8820bf7c17ffcd18118af09879a769f539dd9237e96821166634998f946da65e6dbad8271511669e2d6cad02
+
+TST: 619
+SK:  d68a5e3c47eedb3099dffc804cf19c5e74bf7bf5f01f54d4d91d7574f3d3dc7c
+PK:  46467fe9ce3acfd0d74346be21c46216db81aece6ce0308fb8dc6386fc3446cf
+MSG: 596c03d0873f572f45c3b16f0ef4b52ad2bf59ec76d3c0e534d62c1f84164ddaa425fb85c9548485b7064677e99d04c39b6eba04c966397ba6a5f4ebaa69a241df95a6e44502509d6350557ebfea60264b62ad7f74d16e5d25d45970cfebeb33e7b1bac3348dd03a8e99133b26bbfd7aa722c2587f72d5526e980da9eebdf108211dae50bbe8c65f9abee69a1bbf84c03e40448babad03d3cf3b7de4887d2b47737702796482d2265c566b0f623b53c8671bd3719edec0ffd5f49b49b072c1564a57f9bab6b92d1f068d756639a4331452e61aa7b218a88b9db77a19fb82f13e9868edb798d5beeca55d1ab095b316225f3f6390f89578f0160428747bcd21be6ae1d86991b48ef80d569250858febf3276bd5de3db65a245c8bdcf1488c4825968945786bed63f3d13f1409363b948560476858b396bce588e40b311ddfc22ad622ca7d1e69561464dda5009e638aa5ec9f4c039293aaec75001ffc68a7cb3ae01874dc7f39d75027f59a28965fc19530c0752fe99b153da7c0e542bda76ca1e10b7ea158efb4d821fbc65e7271ad9941095315447abcad0880a0075dd04b1325c72633acbcb261fcb407c264a34d70bf1f044feead069af5a87dd352f4bd8110fa178adbd8dbf23c6b575cdd5df22cc9a5cdd37d9c8faab81a4cb3fb5c4fe7ff629dbaa9fc06b80c1fb691c28655955cfe5ca44149b150b3cf140d9acacb14313a72c84098de72bacc0272d79ed6617f72dec88e19b84425492a429ec6d2ec08b86346dfbf20ea2a3619e77b6ac64230ebe25fa0067abb5f33ee49adc7c44bda7046d7f224f2e7a4895683fca8684ed6a031844f5786bcda48b5042394487b52402a09907788a1e140
+SIG: 896fc3caba7fd3fc285d5eddddc0120cd46da7c6efabe66b150b002760b8414a89ac9e7f1f7b7c7b33598f61f45718e4ff4ac368ff129614b4fe9219f237b009
+
+TST: 620
+SK:  31e82bc1cc5ced21cdc8bfc2dbbb976b08780afc6944af7e88e50e67874d84f1
+PK:  8df977e2b040acebd3dafd67b87f9216e8c371beced618fef3a496d651a5d7b5
+MSG: 69d461b6b7a866e94cd59a5a23bba4a1276602f042baa850d5b29249d6743ada04d3d938219abbc22ada66a1778197f70bf80b597a8b4ae00bdb876812d3ab4ec011df73341c85053eebcc2df0acfc21548283b553ecde0154828ed5af47571985f89767b005b622c9e7c079dde694e49dc0550c7918cc515c274dbd9c5469d2f18ecd90de664e03ca41e53be20b96e25af40c54ab0f7cbe9e05ca3fa5a37c1aa8ebfb6444a32c496efc68157c69f358c15f6ac09d46efef9a685df7e8dd63b304bd3c638ccf532fe901f11cf97c5b1cbed33c70637c721b0289adf6bb6d87c30479fa926e043074302b76f1157d0a81dec493e87a3c643e7a20b7a41525a38db04e78dae5e7797066bfae2cf448a447e9004cce8e41f0987991fad30311ddaa459a2644f4b941c068c0d6c0771afcf42bf9139a684da298486ecf67523bf8509a45ba5cb8b3864ad22c0c6a828c6db72e371de410b47dac49ae9d3b5702b1739b8d760ce98611c07d88df5f04683808a21afc2e61713fc2c025cb25fcc4ee941841083b22f61e2656fb3b8dad41c262c89d2f17610309f2d5c29589a2df61e55149895032ca981e4557e130a237fc0826fc872529861bbb8328d673f39b58b73d060ec596bf22e7ee081f44e92c02a5677679520e2a2b4d22c77f2b212d5aaf050bf2c141e3e28b8571d4321937426235c7a646d647e3efe183c27b7492565ecacd7f43c67a74453f4780e88711ba2dd4a3941b12ddd3909270fb3debd422436ab6166f08c99c886cc0e8e3cecd0642e44285b8864aa416943c5a186974f464535a870a012861bc2e587149cae971624e61c31d8a507e3ad82773e723bcb75df54bef847a407bcb7b1d57
+SIG: 240702ac6c68d597d222da949d0c47d16b390a477d1fb579e9d8948adf9b3b6a7fd4458ae6385b7e2b684a05b55c63fa6cd087bb90113cbab8e4af142fcf810e
+
+TST: 621
+SK:  cc56bc7cdfa611924e72b07f68abc6ca5b85ff8bbacdff406e51ba720d09a866
+PK:  5ffee221ab4d0fe6f4c9346c5e5a4b8a636a6a0badce9667be739f4c9e6733c1
+MSG: 088304f22e1a286062defbebb1827a64b76a14e87015e7f646178777aba79704688d7bf32e1efac97a9fc339810ebd3df93e4ea024686953ed91fa6d2ab6e07ec7811a6d91ca91b098db4725df65846a95b808635a8d0c5fe5ace25f0780e896177bc1bba1cdb4449251c01b482f023862f88e072e79cde5dbd6c1d9ad9c07c606f5df85a6eca2966cbfe0a1673968112f26a317053f167f611af297efa802e0a94b3e1f33a27b73e5597abb224115ebe75e294a1bcdcd979255b0a80265c089aaa7d6bed2e3d0c918f56f4a55f448d863365c6c5846fb9b2b9bb55f6b7c6dff5847b71bfdd4bb5b9bb2e4249bc0243a02ab4d22ba78a43d182195aed78fece84cb1ddaeb9eff68156045b2932e638d7731d0e8b4c9c8c383b0d6d392d21fc640762c87d3692b1810bcc4a42392ff13d45169ecbf0135055093105098c869b68887e934e2b9da5232ac6c9373800f70b64ec64a4aa0ca044c0777ca3a3acaa138c14249672a55b24ddfe4dc357573241e14ad0ac16475a8e3867886d41eea35fe7932ba9aeaa0c86c9eb6db7808049ade7b5cc1a40822c66dea93ad22d44b9e42904b5b83684ae2931fe36c608ff7096f1b09f811b02672804406e08ed9e7745676ce047f0f7f64708e49bb78754720b8aa226f5556abf05b56584645292dad08e2473639a8ce5475e0ce9192f8ba2dd32ce14c91975ab602f7c13538c52952d0396158c7cc6b942be7d923eeb523a73b5b411966d14ac96e5b096a52932a416292eccddb91071c88560e70ecd4fe2fe24d523fafcb98e4021502f4190a0515edcb24019eaca09ec2615a9bfdeb60eb354c84a1f3cec7ffd7e65a5515d47959a4c4ec48d8021b1754ae2bf84
+SIG: 9b86a192b64f4f044ffbf87b41c7ee52f7a721aa320e7bad6425995990315cdd502be4e1116019d131a9218d19614ad95543b1889af0a97ed4d256dc33d76e08
+
+TST: 622
+SK:  7a57f2dda0ad0338ab9a13c9a3497e9c75238c1531589789227cd2749bc6e950
+PK:  6f738dc5e7d9e240c9f4d0c06a5e021747568b69a75d507a2e0be7ea613526c5
+MSG: 8c8575a11d2ff2c238e419ccb00633d04e8b8bd7742901d588dd6a2f00aa12f08ae41dcaa9338f8c47e95312192cf6b245a00ce688a029da56dd1b1deb0d34b5414fe1c21d6b63d06b8534ace8e866c933fd7c5a65eda95a1737a9ecdb17859149ac696951b82c230e8275e96dd02fd455ea675379e67ba63484b6283831fe3ffe52d6ec49b709106705c9d19b859de9fd200887cb44d8fdfe6961fa4ca2340944c764c704491208257e735482af8cb69041dde685241d3fbf46fda057248b8987be1f80b54eb54009f324dc450e886e79f912585b91c9dfafe9012262c471403b1e8b5c31fc5375a1ddf99b68edf9ed70af8594f7d84b2cc4911fe90500c6eebfbac085553550e35bd2e52514e979e7241e9f8e34cdf8513abe72510dff3cfec7e2bc6488641cfd0a65ae0e09ebe99b15b29d45ea67a57aad554d4f8bfce1386ace228839e3a8a534140eec3d37d51be361f5ea1883739f56615f75b055a06a91471be98bc9453783c358382bd0555ae9eb0bdcd66629a611fc1a11c653c82214587dec12ba120e2513070fe69e982f7a80ad159f6a325d977d01d050d116a62a4f8acab6c3d69ff6c878213c60a94845cae106de6c5d6fe2508d94565b7ba75d58d1ad47d76a20defa7568cb7fd66f57cf3774a21d3ffa7d8aa6d86dc284b70e0f17e7630bfc10cd1fc9a8d9c592d39f24a7b5c8e8aff353577e6ac9008690c7a159a7e83be5a6ae8fca9644bddfa37a92b07055f9fac9fa97fb3e8f5f4d917dda5c6dc6ea34b64d302405bc38062e07ce93a1a88aed5fbaf995a09b45b28ad4a6b273dec1413c5404529d825b5edc2e27a390eb7e8c2b43905e116d887ab5fb993dfe150ebdcf817ae62e03
+SIG: 989123761d93563278fd0a78aed64e2de6f4a700fc9a70d2187748ac06d9c2c377d1995f89c7727fe2f120784e4171c42d6353ac3d4e3f620c639c75786c460a
+
+TST: 623
+SK:  32ef6d789a1ea393f1bf9f11de34f57d653c4e77d51e6050fef4e8d7bf183db5
+PK:  c1aa181e620f60525c2b17da8d290bae5d339e17eabceab58cd76ae066f41179
+MSG: 11a9c3c1ba7cfb61ad103305c25886de9f8815c6c21f17a8733a024f9497da0540db3603a671aae837dbbba19e19f82ddfc8af855980a70125fc61cd7ffd10777e366e5e9569927af0f245d4f39b3fd0f45879c253401412855e5761905ed6ef318b6a06ea6e9f906f9bd016bcb694a0df65a016bdfe845a09f23e5086c5aaf375efeb86da51239ddc350bac0cdb03b874db1507e6ad4e2c9f46028ca2388363541493b6cb92c1dfcaa3efd68c6b4e91efb46751d23f4c48a973f0a5c7c6fe2a1269d2a69e9fc4ab8ba3b92f796449ba3dc70245ed505cc0eeee1636647a68c7679d0b6d651bba35c29b81478d17ca3685707ad616e6e5604381f84ee52b25ad02fc0dfb85432efb1fecd090c02ad002c1857fced88fdfb2ff26dd0f5018fb47d813581f6508ca637c7365177c513d1ee05879a65c5b676b3aa873a1935c5437eadcb66dfb052a5e7c3e81d44b3daf698f42244ee2ee4b6ed2b7e6e56e61ff9cb45e719fd746198bf2a7de6d25af3bc6c7b0ed8abe3cb389afd84ffa2a230d93bc0c29d5a9419cbff11b7883329921480b5844655d996c7cab29dfb2a3927b82ba7c306c4577b6f8b5dbe2afaf9bf14a8f9554cd01a69a991bf212828de1e63172e833de06698cdb3b28716380314572bf5bcfd34ef52a6fadda87babe6bacdb20ce63c725cb0ff61fe30c1b51dbda2c2625f99dfeb029a3e58cba7d01905111caf42f27025e720e18eeb07dae9155c55aa300e22eb5e94dc7a0a84ee67d91a960ae08ca632dbb1737fc9a43dbcfb3a879eb9fbffd7299338e264bc1237ab6a5bc2a263cfa99e8544439d96331639fe9408e54a350610ff01de3f85799adeb73d82be938074dea858ea636b63abd
+SIG: 88f3a6e0bbaa3e060bc9d91fe2968c61126b20317f59842e4ae48711cdbaf62c6c0207405d1c4849950271f0aaa7593091109e478d13f356964f7dbab729af00
+
+TST: 624
+SK:  0a5525a4598f60992f86ba1ab9eee6e2675622f943284fc0553e4446ac5a4c53
+PK:  db60d7ea29f8d60dad33d02ec5f42232057bd1c4bd6180a242cb7ab6f4426781
+MSG: f787321b42c08d4052449a488593d885b4e0c34a5d64149fa8b9c85ee54bcbecb50909b2a86b88258a10e07e8f8c2d068a89fb165a6ace7e64998ba57d89d9bf2b8b38a1f6d8364aee05ce3348bed48b88c2473bf5f2665f51ca073a5305358eaad4365d58b83bc9814e25f54c37cd9b68a808a57d6c2d7d7b6deb5fe20f4f96fe725f8de65c29a4f1ccefd7c2c6f2fc0116d58676acbc58691c79c2b006785a0975a31d8d3c949161596a068aaf2226ab842550e9c0b2610a29531d1f3f7f00826bb6c7dbe04e28ae1b9ff6f888a49d82812f452e1b32740b234ddd9642e18f32ad9a9af7f8952528674a2cda25b4f7ba867007ffa7f78f163db8f36914956bfaecd50f6d1af4ee133275a8eaab94bbc0ae52b6d9b2832634232ec0e8b5f8022d3ef1ead9b79ef9a16564277194f2380d9021e1f17b184b8d3a7a34d15139a39c7728c22e1a3a67a27a6ca4b8a8a0636c6054d0f741f046673619fc6b070e62ff4862f59d269007f3431339637a89f564c0db3d9bcfcd19fc25138ac66d474d80f4ad79f6d1e7844408e88034eeaff4a790338d546bfcd7424c119e211f363cb89c888749346a89d32f023bb6b0366a1ede4325032aa35f52e9df938a5027ebee9688ae480dde1a9c9b42d1a9c08f719223dfae1cfcd49dd1053aaa381c24cc9c7abfcf8f6d86d6af72eef05304412f3db2585aa9e0f3a4f1b6d710d02ab11db1fc90ad4de25d04299f3129c212e9cb73c0047953455bf98ec8fd2674e47b949957deeda018badc9f2f68a1b18ef5c583b095e08dd906da5f220da029b9c400e3ca91c7cbd87f3430c742337f61cf54745b0622bcb90762c6bafef87e1ec888c364fad646c33acc22af5438b84cd5
+SIG: 8fa6b0aeac71132ad882975868f1bdb8c11f1a6c1b9c54594e0e46286ea6c9a5d6d5b0eaeaca9ae3af74e72326b3b6f2eaa893c0ec42a49c56ef514f75c77f01
+
+TST: 625
+SK:  2d5ddffa2e58c90451ea05de47b8c49234e26ced54854e3acef11d8ee6852da7
+PK:  7bfd1c8a4a0bbb4606d2e5bc090f56b20d58f2204b6aed831d3df4d406b47605
+MSG: 4f1c5b4e6fac3baa3e9010f3bf293c779e61fd7bbe05a586f5aaf08026371627a209acd188afb2dbe0311547940559711640f78aea9a62818962f445a8e7ed6fe6c5f49162e7435d1b625b88ba39dab0ad56fd2c0ad6512661362bf78afe5a1416b647f3b88a056c9e7289c9b0cc3afb43402198563493e737b1da052506b6c9306d75ad6693db6d1571f96f6f52990c4df19665a6bb63073fdd9f55596896a2e9c2622f2b0c2cc99ddd1b649fb0318058d74794e38ec657ebc82abd5bedf8b3f4bba3bb6c9935fdf6826502b769046b36d96dc695d7c85404284d2a2ab7fcf3b02f68a1493dd383ca6339fac1cde47f53c5e026d0869faffe40abdb98195230f17d0cfaa533315afdbfe7d1afc3a615b4f75090233a503f8861e32374e1ea9557674231d9d737d477b33ff82ac0b2c0ba93c11fb523e613618ed370524a60f4d4c83694c033606d1d069d544dccd3900c37a3b3363efbcf6697f9f762b33b1294583953fc53773ef56726eeb470ebe92149b73648a16161d494120a318bfb080cc38e4996f4b263ffe78c7877fe13c2fc55219f44260e8f253bdd379d870e6c91048b1d8d4e88b88218b2b049fef53b2ae1f8c921ed2bcb434669e3975dcc3fe4520ca8024842f7ff2ba1e22cfeb5d4c9e435eada601ff183b26364eee1faa59d19e6aa4f0975238496a709e46bf68336b068bd80b346f11faa3817a07d1cbd84382b2102986f295a1398077ba291d6b5f5bd860ec6177273468f0ee0f2591b575c4366e189b224e9ffa35bc78a4aa8c06954fe33d080ffc0b23e209fd0e79421f1bde818a86890cf172236db211657d1003119fe91d4e27c524ccc11fade0a25f57a7a1d677e1da0b9c043d02fca38
+SIG: ced9d61010339c471ddf9fefcaa82d1eab3a2e0e60278553b4dd9f395be58149c91594e5618b0b10bf3aab94f159b530f64463eed66fa2ace54fd92572a06a0e
+
+TST: 626
+SK:  4df5e11dec80ecd882837554fa3135b9d5029df42027aa3b3c929246329fee96
+PK:  efd928898fa144c2d1c8334fa2e6b5b6a325a7102a2c344a145541ee9a6c046d
+MSG: fbd6f371b4c8b152c9ce0c6396a77c0fe480bc02007f336ac58fd4addda9d69855ac9e93a45d3e350f41ff502aa1d8fe159ce89b064802a0a1890f6a40a7ef57c6e5e5ed040280df07e7f48fe819be63176710757cb6e440b4f78b5759dce028bf585b3c3feca1cf5981dadadfd27ea124af45ef638542a8617ff49f9470ac2285943c7c3b1163b903955ab99b6eab17f4d49ffa87207abbfc111c4b91f5413dfc9bea31843d115ddeb1da40b45f58f47c417b5e77d5818934e730eba9c4557bbf48cb7fd4e664558af4fb44ee3d94c16e883631f38476f4837db94d54122fa134ca51a525aad5e24b76018fee9a2e8f60e2bb48d24ab8b146f84ffa9820120e7c50d45c0cfbe35c8c31419b078e90712cfe934c3be3a94ff2158873aefe34dc6e36902b1675e1a47cb608dfe960fb4da8d2a8490cc38ebadc73a1003c4941fda8fae944a1de8e3b10ef6d9e67ceec745977d333ac9e71214121ede8892295e27799f206675a9d54ac12159d3a1f954fd0eeffbd30a31904fb2eee77a8aa9dc4ccbbe2851096146a4ce0e81fb9c62498dbd83bf83b55029a5e900086b9531ce3247a98f8654efd8fe7a836431f75daf0868f0108326e23026d2db4a72124ec4e39d4bbf3d846c9f51ca3cc31eb1d02c2ba321e4619f2b659c0bf0fe5c19b213f3c79124f3643f74dd0ff9ce5d27727be6c6958159c164404f43301fe1742e279de9efd441e73e4ea7a842587a79d115d36eca9c03c90ff0d147474109fc20a91d7b3cc22ebcbb8c7f71bd61e8cae47c5050cec1d4849a1d4a8e7a6f845548437706c25331c9e57c2cc6da117f2e5a0f4b368c4cb206265c4178e0655ff675ffc1d4c58eceb9edb4da3ad2c5f62cd13ab48
+SIG: 62545e6c07801fde95b461e2e753c4b6c84c25124eb330a2725989d5e340dcef0c7456d4c7c6a178a221b6328348253db787a9e5510ab9cc278515ae3e58fb01
+
+TST: 627
+SK:  85d32330e2e073a46030ca0ee2df2f8eb874a9fddf5624c8031775111f11eea2
+PK:  6ea7de2ed5ea5cdf50bfffee77f7bd2fcc21d48666bb1f4890c76a69cc7ba4e8
+MSG: ae6107f38ff94ed0327903cbaf6c3e3a3498c47abb2989a8b37b3a19df88c6de790accb4b7258177b9151d1fe04063577d3c3acdb4c929968afdad6f252a67ed4ca89d060f1a4653983f7ab58ddb93e2878fbab0637dbbeb95d25c5986839de2748d9f34027aeebf1d9eb936cb6770e08d45b8095bac9cbb71db14e8a34222b1f2237b9f0bc9766a231a6d102799f7c081d500fbeade603cdcdd7d5b965fbace4be5c2cd932dcf5f6ed31722f41d5a363b34babf3f636fb303824aa701dfe1d3e41263078c1ebbdcb1f73f1245b83e3fa70ab8e3f1413e6b06bdae022b714d60a401d57480dc64e7aac6d3de85fc94d853ca13b7e67415579d5c672123a5af194bee14ae35dc2724ff209f1166638661f881b1194aa4e31b42a527964781591504ba76103f97b7f5520315473ec94bb017a16667b22a8576a7cc2ac0b7756303c756f0ddaae9d0189e6c8de349f91957c72a529e9f7e9b9456524840ba02344f55ad3c11a0b259901439f2655ab9f8c6c8e8e960c057d9c7dafe425c75d4a33b801d4547cd0551a6802a8005dd72424764dcf57e4aa22290ea4f5baac51d7939c05342882ee14380ef2d4704b41949b2282a1e1a3fa7ddea9fe83b9fc51d4eefa2ebac722e4c0a7c599b6925f01b8a2066dc0c26f92196f4f503e887c1e6efb093f1531387bd88c691997b9b89e3cdf7da12d3734183a4b6126be9e0774704b529659b5548f1b87512cc1878ca4ef55990b483c9af6aa97635f4f07949727065abf21e21e32990b1a7d07d74e02d9b07ec639931bf9e2ca3941f2ba6b5ef14dcc2a247d2117e9cb41efa3fcca24716641452beed2f92657c2fb731f0b94e8c892a81bba91f639df43796acd3013ac044f608
+SIG: 414363fead6e59a3438ce5a3a277d62bdd00fa2efac6463dd13fcdded93a7f108ae1f528ffc8ff4eca331dab91ae5b1416e2ddb73b6daf853b03c81e9936560a
+
+TST: 628
+SK:  66590d369984c6f5ad3a89c78ddfca10a0a7657995dc0188b6b57ac3164731a4
+PK:  98873ab13346ee48677c4f8612db31ebd13db58b2b034fd155afa8720f4e93e8
+MSG: 2ec1c6b0829737832c9c798a92eb490b23d334c3bbe627cb582d17a9e42960efcdc7d34750e0b4aa864c204fb8d62b47992e91dbfcfd69f51d937dc06c48c0ad43e8598371cd0e3bbce416bfd44b0944b993aa2993fdea487134cde42277723e0683ec98e69595e9b7b14c8cf9617a1e30ddb8060eacba48d88253b165336108de0cb02ff20f5424b567830869c9b4329c9945f0bf2f3c7acd1e774358930cd890fd9cb864d950935ad8a4a3beccae8f833f6356191371c32633dcf882709b0d98bd807b383aed8d7bb097b6e262ef700c9d768f4b5690e3a1a8f21755d658db2d1bfd2f7071e0caec7c2c5381c5ef5c2c2281c6bcedc867390b90f3b27b0f0f64a33658578a5c0d66e211e6fff6e86488acf82bc0f5e2664b83699046037c0d33d340ff98ed6263354c24273136ff0e4f0f233a6c8254fc0c90764330e3b1057b1e666d5ecd5a2efeaa6a105bfc858431b88ed7fe551eb32ac0af27c66a9803a3bcf87634c66c7066dd0197a3cbd2d6f4e65cfdb8f3daf9f3ca5c4f4e0add45f5541aa18d041f706e4fa87c34e9a223d88572eb50083ee8c7c475df568bc73bd08c0f0deaa374afb1c178d0dddb236e15a8bc2385ed3f52b8761e637887407a20aec3e99ec830dae3167ef0cdb3f3ffd200d83b75b749690b9e25e2171d072ca56f71baecd21f7d45a12c91b2c0fb3fea3b158e54648284bb0095b36244b0b121f9f1384ce9004365e7772fa30828250f51985f1b17b2d2f80a33e8fc6d8565ea15cdaacd42a87bd7c9408b1fe1c770665bdded754bc2ff2ef91b973a86b99f1059c6f227246a698b38541509dd5449fce60d386224183b7dce1b3884f7bae1c2e4eb594510b5ca585279d9041df8817b0619
+SIG: f0db63a1bc7624161ca0063853b2dee45fccd22471e012366f868a4a9c74654e13f1a315ad83916ebfb8dc31a420f83cf645c4c9d16bb4d5d99d23c7b43e2300
+
+TST: 629
+SK:  41cf071f4842ecd494191b8cf28cc0923185ef1b07458a79a59a296d3549822e
+PK:  6dc8e446db1da353b58d0c45d8b4d816ba59e25bb680712d62d6d3dbf78d0698
+MSG: daeb5f0e84f1590bca2b9d9719ef5d1cfa79e0583446332f18e9e4feb0b1f15340297ac9ad6724c85bb16558ea54eb5d702a47248badc6252a804371b74cfe1062d1dba1ec68fd1d4dd029cb55034bbf61068251eff3983636f6debd5727be91993b3e4d0abc96ec196421a47b7893f83986d6c0323f0d19aaf2cde9d3565c104c9d3176ecb5ed5e173fee52b5a0c42b6ab2fcb1ccba9649c2c67c520e9b96cea693df3e58609ad6a0bd522efaaf03858d245dd0a38f84a2fb1020f4dd97c3aeef0e24477d30d256701e900bef26a8a6269ab660d74293a2bf1d20c2cfaebb7c2820f5f5b07453bb69ee769b52391539f0c606d22eb3923ee6f5a1d46050af90f011f851ace76327d3d18c48170a9a25b04b770fd938ef8a30b7bd03391dd36c516b62f0cb78670740e00e69595c418d967253820b754c4fd666e3cce16ee0c94183bbea706fe298e1c99ddb821217ed9008cc8e8b83bc8b819915b07b146fe745024ac3c46116cb4cce5e32ec5d7524a2388d9fe297eb02811af4546fcd5860e14c0d13f03dd75a4249615900078a3c358c5342962bc1beacf68c246821a459ab5321ec9f574f49d10389f40f14ddfc8513ffe3deaa7336035a675fa5858b490c5d247780064adbaf75a76335eec9ab918771b0b1df5147642aef4a166ab172ed601fed210f6c0cffd91869f7490b57e7c65241863e7e8c0a26eba63b5342d0fd8214ac731e1c438d0177115f6a19e0935c7af6bc7dbeb75511d9bd8e63e3e2f47ab0dd1cedd7b180d74a4b44d461197aefdd3620465166a39b45395043ce8874cdd72c602bd3d2eecbad3466b5cb1aa41ae92a8afef2d764cec0c449d27efac437938f280bea9c50a582e57c27f9b3de872f0c
+SIG: 41052bc417b24dc48383966af0143f9c0ba85bbefbdaf791b16a4dad1f570eb80703c0a2cdeb2f7ad6dcd3fa7bdb5c225e869cd8fb278dff0667d38accf3db08
+
+TST: 630
+SK:  a2c8e161a8d9d6e888c3d09b0b972737307a2cbd2acd7ccd804d2431ac6c58d2
+PK:  3a325775886732deca406857a8056010aaea2875545ba6f3df30754571386992
+MSG: 83a3bebcac5f28c5433e3c4f1e7bf5d2e4dcd2f5e59dbee0a83b07025715350746f85675f1dfea374aa7d794287b892ef9097ff6d2e122f0a656fba0798cdcfcb3645dfcfd788c740c0fd04520e7a06a02a05829630a2bf0cdfe2ecca009ec44049946bb1d2326ddd61d7ec640bf69eb44fb23cc1ff478c570c75db7e766e35b7c43db73680d1407a94399fb621baf3845745c1c4ed0b9f0b485be2d53c568545ddf18775a837a05d9c9157b084e8cd01fc324f07f116877e4075dba2432c8a7752e9e939586ad93f0c0aa5edac94b8d82e5449997b15b8c8961589c442821aa83b60239ec5f158c3f5e9ec5bea5115d5fed61918e8fcd5bce61c777f20b6bfe803a69c6fc794ab8c57df271da863872a61335b1fa29f4608ff037f712069809ca642a0307c79aa92e10cb893a29d17201a0b6d1b46a7212b3baec9703c0b0392ba6b76e5c9c10f83599b81ea22283f9547aacdaa7f30896d1ff731e11fb9e56ad06030417119805bab63521496c3bb92a12f5e55afcf60ed4217737f3046b16ca506657a6d696d75a6d8e18e9efe2b08c8b1fa0728238e27cfb322166eee4ee76968b777b50ee6a2b804e1e9b46016620132b6588718d978ca2c0026979c400d3c5336751210f0b00d269ec8f4e2f9559e180332dd270e50cc9465c5558936355521bc3c9560fc19ec14242121e6bb2fff8f50337fc264acf1ac1704328334b3b52cba96d9303b1b5db859dae31d80f1711fba251e10b4d122128f9faff6872d0c0b81eef59541f832b0a9df3a4cdd591c87736b1aecf242c275a10c3fd67839dad4ef399b9494ecd77f7ba5b5d4f2ca304e5b22921307cb18fa64aa3d01c4411c8369ccede465ee369ee637d43d28826bf60ddde
+SIG: 560d01b94df11d83347752ff51b3545ef55c5632ae7c8efb11aadd8312def72562e8f5d75ece10ad46bc96c860deece39e634a5f50654d4cdba84a8e6f70240a
+
+TST: 631
+SK:  d3d188b390baccd95024526146b82b9184e197e46a9340a0e6ec18bf75be7fc5
+PK:  d8f794948aa6986100214e9b7b9024420806b4c67846d5bd506113b353a2ea3d
+MSG: 5e65658e420375433fd7c1f6be678841e58104f10b4c676359d84fce7992f5c57557d738f830b505fa0c2b9eabf8d1a9f81fe8f315d662e2b84ce95299ebf4e503b5e1f7f8cdb668ae733f3d0cdd4c742ab5f272bea4f18d183e8923847662f9a39cd4b14ec76d11032fe573c26201aef66601cec683e34b89afd964e987801c706a85e27bab33701cd109bcf07b27ca67f022c494a04cbe5a9c6d63aad936cdf1a180fd05865198b96f06a78da95799d3aa4df3b170033c69e8fb04288c3546553b579c0ae3938062d3d8421cfa66268529bec0271e53b4ee7d099e7148a802df80fe5eedee1c903ae8ed4d640ead761262dd4014f25f9397ba3f1c08d83a3c485cfb55f89919aa972d6b7e7711be9e30c1eb96a0c3845309fb23dbc75b6991dd6e48cdde90e04f228e8ccf3ba23f2747cfb9d3381a9305f816f26cdde41c0220fad228ff6a8b095c77b6bae8fa3368142724bf1f5e0f6fbca5320c215b6ba86b91e3a8acf750e93fa7eaa65c4f785ef8421a19c1e27bc24b428e08a90242abac9bd4aa03c656f8f46dc40b36152c1bd0def1acfc0da10a2fa1dc3da7ace5a8fd76227bb1a602390fe57afd32efe281f2ea6b2e4d2545cb88d2308d72691c9a52b4ca25231a0107f25d117cc935397621c683bdc8f22e810340f2cbac4ceaa3468665261879f0074200743e0de5f3e58308b98b04b8c7148a4e004e667e832b0084b5f2bdc6fdc959f2fc28a8d31d9a9e78e5d5f9c0b119e5ff1f68f7c0daf0c0f16947cca5b7ced09601e2ebed282ef2bf8fe9a27ed27fc5bcda8aed6c71bee3e7751004472689bbf6d9d07952a242ff870d7c3f5e1ffc2c1f40fc9ab7579b392b554f3dc588c03ab957431fe5d02cbc711ad489fe
+SIG: 16976b267de96e38dddc8478075f6bdd7159e56334b2d2d1920946294f33cd6b7f9c50f8057f496cab5d94bb4dca262f9f0fdf9b1b64741f4b722d32efa82203
+
+TST: 632
+SK:  61917a975cb7ec564c708a565388c57236a66b697dcd5a7f10bae671572ac7f0
+PK:  ecc0f0b99276e528f82b42f2efce8579f83e638c6acefd072828c04e434f55af
+MSG: 6e970e0b1c92a7f496a82d8ae80cfd0ccef1d2c799d41728f35ddcd603b421c2a5ab3b489e78f4b62297de437c5ad1a9683ff87fa28eb3cc38ce242af59419f9fd43fcaa54fc398992f8c8e31f2b33dcccd0ee11ba7b388e8d2a36ead067c6beced5890ab7d4a94f55dab92128a0f814c0e68971df57bd5078a7403175c7c2fdd4a52447153ab37456729aee33e5fc93db8e7f480309875ecf6db07ce7f3cac5de49e361275ca50b6b719f4b715b3e30863cbb3b7164ba9eb96ef3304b19ad4d74dce4bd25e77bbbbeff1ee7d1fb55b9c4f7fc4cd9bd55108afcf99c1a41cd6f6b1adb297b106c8ba24e3134f87dd8efe5cf85492291b94d6600958c28b9122fe6e01bd3e329e42d1926b89f7a8c40a49867e5aa3ad749bd98dae7d006b453609e7dae26364d9172be7283330121ed2b4027e0885118743a6ea0cb7dc27409a9b2820bcc242ea10a00937bf849201e0fb6199421f163e9794f2dd4b332014a09d3ee8071da787747f990f5179919027ddff7cab0f55e9afa8eccb16cc2dd3cbbead7ff7ec818c253393f748741f55407f7408ee33a42ae2d6ecb3fb600a71f30ab630606e553b43678e59854f3a2947bcf4ea0fcfedc314d8370d1266395fda3c9105e975952f60e3086bb82481513d6fe8adb4f95efb9a95b66d480d2bb171078cf40684ac69a789c7fb7fa425333d705db00066755df728de02df25bae34f1d7d49caffc51e9ba2b10b98fe4cd9d22b7764ed931edb5f0b554496e995391e0af0b8d1c7a8295a8d15a7c6556d29cb19e0855ca505ad01d2aa30928a84bc48959576d812d9b27b8e88879faa2806c0841360ecd0fe83f5b848fc12f658f1e7f40e561c2e78d3b0125210a92061c2db21ba660e8608ff5
+SIG: 6abb3e377b5c80b74f77219c1a9e096fba0eb68990817acff12dba7f61c77ccf595fb6608552003cead06ca1317c9cd51ac4724b29f40921fb92843376876401
+
+TST: 633
+SK:  7ba25f2797a2836f379d6bbcbe9abf4f2def5e52f72bd9e0b006571022fac2f3
+PK:  6c2ed4e8c0124d5d0540796d3945d1de71aa6969e6abea0f1b0e6fc429c7046f
+MSG: 171a3409878097b3b22b2c00660b46e542c2164c00bbee54554837940e70f03da9916a40f9bde8288f45e47bef7ffe4e557cd4474045e740fd959d984f4ec81da88d44a373c1eda0cfc6b08e351373d3b82ab0902df8063fd908e703e0cbec410ab5cdfeaae00188ce2ad42b8bf04f7daa5f0ee333a6f9311b4ad9810952d5d5a64b20f37e845415fc3cdd616febec50db296fb3f3bb7f6b366bbe52e4897a05617bf7c981a62edcbbbe5da4c39cafa869aa2b2734e6cfed90ed8be75949390ee44566892455b890cf568b945aabb758d3854be6539f3b86bf01d188e48cf2626a0d7d381703be6ed1290dfb947bc2e0f83dbc58703080d7f5b9ef19aef930908f68f0c80010a9401b303a9f6da805bb8a0ed0f39413eefedf919ffd8ea6391bf95d4229604e49457b8e23bec611484cc7f9832dd95bdc3ad177c050f4ab633dcdb3e691f5902873b38cb0720b9113357fe0cfb98a68cccb5d5f0809d59a375cf7b5a275d43c4c34ff68e448526e8e1aad44e20008a232afbcf532a42b50a025a1b2ee4e077eb0125a593d51a200ec20d872c05838ad36aaaeeccc3ed9ef41f6d122670217d5c08f6e13c172194589acc3c59f7ef790c7c85aa6d5eb69d4c89a72f5e7c9246985c1ac0c5d197f76a73e3774839d4aa2096aca190a30f4aac54057b64f358e0e06400c0df2f876412d34484c4344f4d7c866517d3efba4a90fa7144c9ba5db3361db5769403ec81626a511f93e30f8586eadfcafd9a36ecff8d24b42079ada8e579ac30851177bce9038b0e1300072d68efdd723f6355064843275815a66b9d73a1299aa59a1812f6452fb4115ea2b1f9ff4a99690596e3f2022d81ed874dd67e6189ca0e68b9304e993a95b66665e0d074c
+SIG: f1f590a907ba980eb0d648ab4ded5f92faf7cb851d81d858a78fa6b77cbbe12f64d20df52771a7d5e539a152d731e1903d4211fdcfef9a48b46c8fd5394ca009
+
+TST: 634
+SK:  d1e1b22de5e04c9be4651dd73995a3666cb5352c65ac7b7051b366fe1ac0c310
+PK:  12fe56f1012d5c12f135ed5982f382ae5f1143bc90e8cb8c93051754551ee90a
+MSG: c7f218b5aa7aae1799625a56c4d7d7b02637e572f1411a6122f113791aa3c628e819602fb4f0335a6123013fa64e9fdc4e4ae497bd169c2fa77bc236129717f462886b410893fa7809cbfdc892223b40ee041ebd4ec7ddab55be6081a1646643a9120baa46289acba15b3b48af3b7adecd69f43eede79d9b1957e1d8c3129e0fa0579d3d395370461b0e1255c9caa94e4725601cb9d0e2d60244d15b64e1f7bc9015590ad0991f12f8267311206e9eb5d16add0ba5218fce5fffe1c9ce5ffe1f731132f4b12cacb02f97451710846b7f824f4fa9e08919266469789c00ce0d94d38fa8fec3f51f2f886e9db09b804470b19ec9e80663f155b4984d2bbd0b2ce99302e06c64444b696e3129fcef34c3dd00f7ab5beda747a3fc6339192b740f3569b67dbd6ffa39e271faa400d9616bff86ec49a659def2e7f5d451f2a2b35e662a6e7cc22f1e5cdcde8a59988135b7e76562743c1e6a099901b3ef97cbff23f209bd7088c2f03245279a1dc78dddc1bb0c1d35100357882126b328d3d94e0871b60be253fd1b6ecf03c1db731d9eed0edf2b2643230780a4d66e99179aad1b82402e55f6d785ebc80f8dd2fd2beb09f31035df62c17f428ed0b2d56508db31e6d2dd5fb69ebeeea3257070cf2fe67d42d28816a55dbae0b185db4421bbfdaefc79c08cdc1accf71642562ec70036da2bbafa4a891954c4ee4049b55c640e91930e39e3ef1018dc1647f26942c6dbdf4d56e41eb2c898c821fac17cc273e8e4aa5608a812cf4b82f96019c252d56e7805298ccbe8ce40b0bd0f933b884c0faf97a958b20408b8a5297cce5527b2ca212806e72a3264457a7fac8662b82ca233e1c7758dc6e4f1b9995863f25f747bcee43b639b1f8f2026d2d2
+SIG: abaab4fa6aeb0a0b34ee0d613a0af049edb4cedbfe9d3bebe9c00618b115b9d1fa524ec3495e1330b0936181eabb14299faccc40eaa8cca57ed324b7a6420c0e
+
+TST: 635
+SK:  df294e477b1b91c5ac5b98c330d222d7cd2d53e7d0bc0ca403df4ec75327a274
+PK:  5f0bd22f2f1896d1563b4f6940c7df89efc258c0ff6c2fcd674daf4f59fcdb60
+MSG: 3e42d668409630cbb84812ac7ff1154f70fca8bdff3f1a040fa3af868aa1c4e91508b1aefdf5c3a8b4b077a4d162d2c05bd364fbbe8c5a08314c2e07dffbd6e8dd2e08a0dcc96ea92ddd4c97f79db9425a6c6b34c46043d09a68b7687236a918d21a561610a13ac5e446e0881bb26cc8e28aad1654f867ad82ae33f8f7a78a65be57699475516a1a8746843e93a1a294354624fac04d452ccfbe4fdd92a951aaa07d26676d5cb077a5000d439c124276c0dbcf86e7aa153cc24b5aff677c6badc261c289f4a4ae519b2e2fff312fbf0f5b4c4698f6aedd8fcb1d2348942de3fb73ba27f6db14c2f09180356e5fcae1adf65e22425f8c27f19e989483506e5df57a1b613a22e345038b3ea91c0f78ffff46383f38c72225358a34570d6f664a17454a151613f01cba777f62ec831875ec5e27d257f180b6366cb183107c40f50b01b2b9bf91b3b5549ed931a3537aa41689f72b257a6aa39cdc6fcedf143983be5bffe3ae2b29f82f882122d66a7925f5a710826c0dadb7e4fa4ec079ba2e76dada433f3077cb1ef74613fc5dbf8258b6da7c73c866372457ed500f97f9907e1fc26353c70ba3bd9c36151d46865d2c65986562485cf8421febbe777c73e6cd0026d66d35128b9f8f33264aeb56bd3e4b8d1f5266411ef3b23b76b36d4c9df3c512fd560c2be52ac523c19377ad2adc0e8c309cf5bbf72d9eb85d65a94847d497d8d102424fb84381666ecb1c35a3725d7d9e9284fdebb6b362aa6a9c6fb37aba87357f574c0e63b4497d498ffbb7d0692d784b4b18ce9f9150c146d3d18c382eda04938c69d0778f2902d5235a5652b97cef6d5f60da6bd7ed4ff97cd94d4939caca3b6baa3cfdac04cda95596f467cbc6cbcd9264167743eac1
+SIG: 9945ab73b58562b355dabc4e2b6be7e05f37f89571440ccc32c1a94737095b7866747d21007000a0f0e351114b88e0138b55df44fe72ebe9591410e707fa9d02
+
+TST: 636
+SK:  70c6859f08cf42b4bda9eb62979dffb7cb08eb3dabe93fe94b01384617cf6730
+PK:  401c9e2033e2259fb6383b3e8b9e17b3f2062746bbe648cf484516db0f2f1b06
+MSG: dd0609ea159921395d11fb2da8ea4f747d7f74b58052e01cad40a271fa0bbeed91020f4f0c0846c4f07778a6aa768eb51712294e9e1f32a602b152514f5e6d39f9e08f7a7812bd900c10a91469e47e8a78e54cd4bd7cfededec171ef373f1c4f9bbc2c81402fb14ed0bfac8d043f117d6124521afae0916a510d568acfa3aa3301bc979ac28d551dbbea6ceac4c212aa8c8492b3613ae7395dd4125fc4c25d5b4d99230821d4b17ec2ee6be7d604195a2154333b973526580ca7ef9e30c6c1dd42ef2afe42b11b1aa49b9ccabaca17091eeb380ec5e34ad1e3827cc60dacf144286c7892590bd2671a8dc5f3a702c1de7cd3b42c1b150b09c3e58ef6943b45d89d41df361f1d5c25565591b6ac8deaa73676531f6e5abe5804b0097f8d45ea2939177333cacef12e4b71fe4936bafe00747a8930bcea55b8fd84a01f6df84e7acb931fc7c01ddfd63deec3ad3e69dfa2b73550583d5747eee96c5536368797e247f23f537d79079ab6da314102c7443d41960e3a3d8c359c4a4ec626fcc44e110ea744d417aa850db8ecdbfe340a962db0d8c57dc517be8b40d14de97b1e9e0426447fde0a04e50679c53ba1aa3cdc38c7ede6db6c054b1e9ce7deadaf93ebdd470791535f3ecfabf3416355f7a18a38afe6bfe507ef08c4373a4a69dee1fcb65b1631a0de1488649d0bb2679a9a45f67820b2a4a1e5a548072da7032d172555e788cc9860ebb3c0c359493751b0c2c950a7fcf4803c147f9340fc93d85f1efa57b39081b92d93473fd23516c4950ed4b29a2ed3a042ae3d92a1e52cb709636fc7272fd747208bee2b16d191e4c6deb27672aa34e43914cff2055ca4ee8ba3e1dc58a679c7f7dee2c1d53e28750970f57d85eab1c26b89bb73e0b1
+SIG: 0f03a4f15c339b4f7b88b4e21ad9e3d6bbf3effb7b678ffa500d47383b71a7454f62907b56f59f9b9af6d5b2a0fc1c737a64105195089899f57a2c9dba509e0a
+
+TST: 637
+SK:  c5962961815b57cd162403ce08e4105ddb8aae2d3f533fb49cc236b5ff504d6e
+PK:  dbade72236ba12d4977ba46c364bb69a887ff402de91d47afa9b93c95be71e7e
+MSG: 4ae4148d79ca9425592aa240bd153424a3bf4ae27395872ce5728ac7613596a77d5ce8565d8d6e1b5935b3906cafe1ff888ebc9815e04a624dfc4c6907b85f6f1a0dbddff62e9151220d474462cb9f13d89d3a93a00ba2b60f7e7ca63da17a6379d673551e790b5911727c906dc94f86d8277546c1564a45573a7743bb8a138cde87b3b2f28e5e245940a51e7c458cf8c5f0a70275962553e0d2390d171db44c2f7a5c9e9f93b90f7a5f54f191b0d875bad7e0beb980c2a3365cd7b9208724f4654418117e16ef7134e3e2794b6f9e80ecabeca3254e704c21b7ad30c5dee017ea2533fcd94251e55ae75a8cc6db6674b39c88ca42006043d6bd9b00ecf64ceafeeb402b1f22fd891f2d11c515c1aba6a2d4c0bd2181a48e43fd1c0af91f9b7b7d37f3dcd9e4c0a759748467d348a8b116df6a4eacf178aecccd3066e92dca45da7a3e319f3771eb3490022193c5b652f045687e1705f2e5691c134be4006353d7ecd0e918d5de0f3b87809fca4acfab94e1148ff7cf07f7cfd0c745dd2be01a24a5e069280698bc3f5400a6dcd08e44595c0388e44833768fc49104ee115bdcb02bfbda179d164ce969936629f2335601b56fe8f785cca3805f0403872c62f73c3ce80563d070e976d8ecc51124e2cace7ee18699047cb0f8fb8d9c59b8a60d12c08a09fce58fd92cd36db6a8e89d118cf88a92dc8a2600bd95f5a8e85db5cdbb249ca812ca209c7618051c4564a3a0e192b7e45992456c87d17412c11adead526ab8db21452f7471d17f2ebc90015450edf4f0a44fb2f4905f74d70275ccd89b93a650473c02a7da0cbc67915ceb7a1ea59fa8884472dc917ee9d246339c5926843ecf53fafdc56a695601a276c23a843e4d30f89c97c9eee6dfc7
+SIG: 8101baef004eb6f5ad4de0979ff36d3439b8212bdc928942e431915b3fd18bc2ad67b26f18941dcb16d2c29191421e779fed622fd9f582644eaadb3fe5c09803
+
+TST: 638
+SK:  dee6866c7874c127029e96e025bffd35fcfdf4dc36966c15ee6293368013d379
+PK:  08c94da351bb2bee72e6e196be748807583762c5296e05b1e529c47c6bbacec6
+MSG: f1aa1977f5311b538b940ae442a3abc89aaccdcd0a79380a24258d4a9f1ce638fc2f5ba2e53f8e1fa6176f178d9024a77894c28cad42d629c793d68a02be9411b527acadae7e5c3851babb45b5fece329e29034cd42571083727f35aecad7c9be5954ec64e8f6ecab7cc0590e54156a4e1a45303849f7897e72cf2fbcd84f56c72f941dbb0b09a32e6386fbe18a43bb9bd8b793e4b9edd532103eab54d627117d28139b64e60fb0b81d09001bb2404d925e265babdc69f96b135e9e6ab7febb1ed3075d6aa2abd2bbf9b65fa9b3b7191ef37b633605910ee88f66eada79f00f536d380b82f2f4b5985112de004a56603f4436d8ff300f42bf5acdc7a4bf1ea9d4196c480495bacb0067630fcc000b4f279dd3f30f353276092d152c3f43efdc041deaa0bc5aaaba7f8bbd85e69c13742d678dbb65360aaf7b548a044c0ec60a57af650bc31973f832f961265bc2318f80775afd51f55194c42423f7bf4e0052f98cb206913ffea4886ecd27a4179b13773f947502e181bf1a1f2c62c6f08c20359f06df2b18127043b1070d0194ef5e5bfd37d227984cfb10989f21c71ad0fe3b81227d3a71789455eda383c22f4d2fcc72579f465e066f3d38befc024efef6c2e329649ce434d627367a900d07fe6234235c84656eac5dd0d788cf4cb31871824d66ae4bc89edeba1b36701298453e8da1e69cfb868095c3be6ed2182da1cff4905afd20731ac1ed984164737903c7d8bb0ad16aecf2fae337404fe35664515d93b701e2f878664454c0decd1c6558adace3cdb227507a51606f0a54df8dfaa420205dd57c65242ff24a405ef85c92d602886932b35fabe9c3bcebfc6235639e873fc2dd084c52cd6a7413b831d1cc99931373aabd847620eb69bb0fa
+SIG: b78ebd6d65b175d4bbd3d9a2082a0efe6e991cb2e403521eece00f418f2e956b66907880658b9e8e47699653d159132380d9ce1109af9c2757daf4cdf18c9c0a
+
+TST: 639
+SK:  523623555995baaf2a27adcb1ebafaa802d23ef7abfa9775f2c9bfa07d64e0ac
+PK:  d34deae6523e619dd1bfc8f3c4ca4b78b368c0f720035e144c3f2fc105d4ce21
+MSG: 0553e69ef211652d62bf281bfbdd37be22769d819746361c7d65ddd0fad677cc0438b301d1514578e0da58e55f729fa8e66ddeb7f973a818d24ed8fe027b8491179d07773fb5d2bb96aa85d6b3750454e50de91f9b88aee8aa68e6bb53edc66677b41e601a46ab4bb1e656e7fa5f0179933680a6ec9504275e7adf7a3248e63a0fc9c1ea5ae96cd0c65a89a77cec2b1fd8f4537e82c1c488a69a0ef64f58734d9e73478e1d1f123114ef66085e0ba319cb810b66af96d1308b1a2bd92ba2c265aa309ecd5557d402c3802cae8d7e95007fe610c2aa75fc66196c3fadfe997d6d5998e18d260e9da31da9218cbad103cbfc2c7547765d67e81f24ac83022ef51c6cc50864366a35f6b9b9af94e84caa9fd3d767c831f0967a61462fbcfcc803f12e3739039acd5dbe9366f05a33dbeaf360e2ddcbe5c443f80ef2ad62e03c1d5b70cdeab4a7dd41553064c8d152709deff82076b9071192376f51d4c2c71a84e89f2d9401320c2e459b3e243cca7c26fd098c264ac88ef638921d980b0ae9e512d372037d81adc48126d7c9e4b5afa57ec265d401b9653e928afb7dff9b48e295e470d6b52e88b39d0a40cb8eba249f8b13d81113db1d3e01ef75c722f269488e963cc8182704f8ca018e73dc0714e9a9fc79bc4363c28cb3984374f73b2aa8786e74e0159507a29883fe0ed1c600f525885f2f10ea006c39e59b925b765b1ede534257a1f40f2846584f069746b52f5600430a2863d7936095fbc22a6ada674d41b374e2b8b9a19fa712b5944533bb6d6ec43b89d4971b70205a6acd72a899da12618204db0c3e8267b845791693e0ae6a35f14da1f8f4dd174bce0318fb5a00f672ede42304cf04a62760577590f27e2dfa6e5e2795d66053b30af7f1bf
+SIG: b1871729fec83aea0aaa472b700acd094813fb7d57b909e0eaaf21ee931847addedd2be8533d0c305cb9cfe5080e76c2808b6e51c9826290ddb7b94b6f7d580b
+
+TST: 640
+SK:  575f8fb6c7465e92c250caeec1786224bc3eed729e463953a394c9849cba908f
+PK:  71bfa98f5bea790ff183d924e6655cea08d0aafb617f46d23a17a657f0a9b8b2
+MSG: 2cc372e25e53a138793064610e7ef25d9d7422e18e249675a72e79167f43baf452cbacb50182faf80798cc38597a44b307a536360b0bc1030f8397b94cbf147353dd2d671cb8cab219a2d7b9eb828e9635d2eab6eb08182cb03557783fd282aaf7b471747c84acf72debe4514524f8447bafccccec0a840feca9755ff9adb60301c2f25d4e3ba621df5ad72100c45d7a4b91559c725ab56bb29830e35f5a6faf87db23001f11ffba9c0c15440302065827a7d7aaaeab7b446abce333c0d30c3eae9c9da63eb1c0391d4269b12c45b660290611ac29c91dbd80dc6ed302a4d191f2923922f032ab1ac10ca7323b5241c5751c3c004ac39eb1267aa10017ed2dac6c934a250dda8cb06d5be9f563b827bf3c8d95fd7d2a7e7cc3acbee92538bd7ddfba3ab2dc9f791fac76cdf9cd6a6923534cf3e067108f6aa03e320d954085c218038a70cc768b972e49952b9fe171ee1be2a52cd469b8d36b84ee902cd9410db2777192e90070d2e7c56cb6a45f0a839c78c219203b6f1b33cb4504c6a7996427741e6874cf45c5fa5a38765a1ebf1796ce16e63ee509612c40f088cbceffa3affbc13b75a1b9c02c61a180a7e83b17884fe0ec0f2fe57c47e73a22f753eaf50fca655ebb19896b827a3474911c67853c58b4a78fd085a23239b9737ef8a7baff11ddce5f2cae0543f8b45d144ae6918b9a75293ec78ea618cd2cd08c971301cdfa0a9275c1bf441d4c1f878a2e733ce0a33b6ecdacbbf0bdb5c3643fa45a013979cd01396962897421129a88757c0d88b5ac7e44fdbd938ba4bc37de4929d53751fbb43d4e09a80e735244acada8e6749f77787f33763c7472df52934591591fb226c503c8be61a920a7d37eb1686b62216957844c43c484e58745775553
+SIG: 903b484cb24bc503cdced844614073256c6d5aa45f1f9f62c7f22e5649212bc1d6ef9eaa617b6b835a6de2beff2faac83d37a4a5fc5cc3b556f56edde2651f02
+
+TST: 641
+SK:  03749ca20458a35a37a8d7a26f959f0d59f6dc9973fa363c1ff8ca4e638c2cd3
+PK:  eaeb94f406bde6a7cf8bde2adf3081f8375b87d9335d496c71d042cd2eaa166c
+MSG: eef5ceebd0445e9c9181aff9c6f2660128fcfb63691a42cfa443d6a649efc5fad8c20803763ee97d1dba08e63e08a2616da05077489f2fa2c56b7534f9402619251fdf9c320de7af109e2fd8b2565ce8a7524c9405ec0f8fcaa7149a6d210efde83b111cf82dc0835cf94f20cdb021b73bd262666555e6d62707b46ee42fa900b4f4f705de33d3dbdc68a88d1a4d0ae933566db6c6237ec8abe1024dac4b7f46d407be16594d9046c7312dda6614d9bcdb01fb8324fc62b8eeaf0abc23cd570e304fca08e88c735e5d31592409ceb583862e6b0a767729f7556fa2c053644d36c8337c0274e749202982fb4a171acac196c02b7f16a8da49071c8ab8076dd5d3abadfe3af82ca85da02dcc1c4a6f2e1930bee2009eee0d971e40dd12175c8d00694f0325a3b3133c0d0bd382a5194fb21422ce67c78a5a6e1537e3b97d5e204e5d195696390f77d19024c1bf6b5125a0cdbf7b9880036181c98e1ac2e5165bd496cf997451a1c12102e66946b1676abd4cbdd2c11673f4f2cd5f3c9a434d747fa05b40fbc72268b4eb2842e4741f51b7709b6accc47fcaf70d9c1c4c35867119d81cb3ff1f16081133f1659aed85f63bc901989e2617fcce153c2978d708fd02449ae4d538d122ddb8527c0a76a102eeff6edb65dba298d3c217f6551814eddeece1aef5f371a54f12bffd6b4961819a0f244ff0d7d8694c14422de9822c13179e4eeb81595079b9dd2ad1e7c39bd303cc44ae3f3634881577a266fd6bb7917812b999dc809dc09c3d7019dacd28e43013a2f9e4f94bb0bf7124ef091783f796397f6463bf1efb39cd46f3790a1d9b6a7c30f149b5e66c2937e39cb9744ddc66ab561bad4e6fa8534d69883822643d63d8bd7b181621a267e955e758d1792b44
+SIG: 78a3877e02bdfd015e7f86a327a48cc3a5230bbdb1243f1a8cf227f78ab5e7680de301a915dc11b336fb5f6566848b42500adb5d673969122ba8f0053cd3060b
+
+TST: 642
+SK:  53cbd6f68cee27b9f7bc059b803b447949bbc9c5d5a38652d7789ca15420dea1
+PK:  6116990b5331e2165f82743f01d8e7bd5d7088b30159833fa7b939cfb1cc04d7
+MSG: 306f8e1df0a4ca78bd77e8e1191c94deaa82648355c2aecb7e82fc56d64c504619247e7cf8943328d11f3db4b1dc148e8ef6f6c3bc355969662a281a65576391242b7bd5a62f8fa7acb604e3a344ae1a9d732a254315f31a0464c1e6587462d29212c40e5ecf061e269aa0b90390ba41040721684bf2aa9582d83066221db60d0f7ae2f149a36e16952704fb1f3a982eac6b4583665c63e5a8996f24a566dd506a33d4ec8a02b2bd34b714c745000c0128a3c89d942506d12f4beb900e2903cdb34b35ca9b6d3ad9b350ac99f41db3acfe7fe55a28c0f006b844c9dc4853fd98535ada79416dca5fee5803a2d9f5d68e6b80539ff302e973f24e9bc88b7c4194117ddb9f932b32d5ec74868a13631ece68814b931421dc890249570341f4b423e86e8ee081b22702f649a6c7a0b7bdf5fb756202bd10b0bb2215c7d6597effd852f0b89abec15ea82257689df81e338254f93e81cbf061729d483eb5cf649805d78ed892dd0bd248ca1e252bea51847e1e82d39af58050dc4afbf9115a3a60493e8c0ba2e86e0898cd0d430891b9eb0a40f87431e25f41538a030f884fab36ad11165d267e8dd94dcb05b93a5ae77969430e1810134e157251b982df343dffae6123a99aa0562d5df72408f1a6e29c4059a5a8aaa4e621528fc63a9cbe1f4c0fef25fe3f8e18157774097a9d91020a9006b6c860ec1ee10d521d203a1f8bb82561296faad4b2203da53b207a459b29c18bc0649332b1807c13ca61acfaf90779febbc7f3242164797e6f572cb15a9be5887343455e26b910c8befee42aeb047f9abe6b3750dbd7de99202a0bb576ce1489e61c1f5d27c6792e63218edbfdb9b3dc515b4254d82c859e52ce6bd7ad296dd0e3709d4c466362f90265e99da7d0b701
+SIG: d82504405ff16ba6443dc482367263a8e200360acaaa83fc4e4b72bd249f16103ec7e5a7e9ca17198f888eaca16b740cc3f5c3b7b617a34b9491c3ed76aab30d
+
+TST: 643
+SK:  8b6574f6d7396981e223a4837bc339c3fd659419845a2121bf85be2e695d860d
+PK:  e3811aca70634f5a9ce4b592a17bb5cfda53442422e203cda9504c9d65b263e8
+MSG: a48aacc0495fa0f1259b27865d3d75dc52c2c828ea8c4c2ad78577072fef7270f6a4d582bb7b962f4c3fd149a60a06bc8efd2970ef03148ddf6198b9b695a69fadb5340951cb75398ac51a4fd55430378cd5da8885210bfd2146f95c627632fe8be06de01a7c27b89deefd67efc69c9b5c62b38108f776229143dae660c10cbea3cd4f7ee53dc3692ed01177e4a6f7e424b5666f7f495f2a65602c7d08c5d572234a567cb6c38afd79cab5c4036d62637aefab5588769a448ab4c65e24554bd4158050e09eb58f99ab40777b0356709b7c025ae5ae5422acf87444931ae4d9a8b3d94476881128ba1eb7328fafc75f6b9dacc96d3b6487ddef7c59262dcada426aacb13922935411566235e058372622d885bd0cc04958dcfb17e08fcd7f147e20156c8e26af85530f5511a68db43dafc4e6a23f667df3743eedd71a3f07f76f94d1688afc8463bfa5a439ae311469948e7447064f0b0506f36719c13466a1b98776d967ec58208ba674037303dfc6190da783ff27303b86b5fc3211f01c915e83a6ad0121447911cbe1cf696f618f60236643f2e94e155db657182944c1a43bdc7bd5eaf3481fe1284092cb3789a892bd79a111fd410143cf91ae332860b1d29aa041d177b50d6cc2b9660d328c0f230a3515e6a0d688709c0cd347ad2ff32d61d1e1e9ba76f81e873a6c420f1707f3841db5196cb53f506f0006352c7c44c080f3096801a57a49cfe84205bdd7a9801f843cf26b9558a2db788ef1b237915d587b9ba9779890f61fdc91e03e4f4cdbefe417cc22d522a86adddb53f3747450ab62b576565db32e0cd44276547d9a16653c279659dd4d17ec04827c533e33390fe94f793509256db67531736ab3fcee2a301ac3f0a24d3b108d7e75c32a5aba36d6
+SIG: 2fd0905475a2cec3e76f9909b8afd83beb8daefa77afcda34cb4f11728ef15fc9c1d7f6f6afffc28f3874f913e17980f0e8e3d5ad23951df2b32efaf6219ce0d
+
+TST: 644
+SK:  29b2881b8caadb336e7880c510b80085f4b1221860b301eb4525650752a6d289
+PK:  0c5c44ed29d21bcadee21cbde61a9cdb6d5936009ba2f5b2e777c924ddfb6751
+MSG: 1974a2e2b47949f467a931d1d9dd5ce116e9f5030ad09a8cc728d1aeb148bbf9acf59874da80e708d53c668f2f14d7522071e909808427b2ab5a05f8b94f21505cd26abc53458978c784d479ea6dab105c4f7984a0fb9790e50624f4734b551905aa5ffa60184cd201cf2b26c9795da6e7e08d6a0bc7722400fef94fc21038be89d34bcd14c427b85b6866737196152d4eeb66d05b245ae84bdc7787c14a8bec2eea5360f042433d70794467d47393b93757f331cf2b53c660d71c29582aeea79b12527a28b0c5e110df6f854eead9a2b00d42542ca8276bb8bf988baab8565996fee50cf31b2459c4c50ab475265e83e2285d43fe1f752a55b2dbc49fca04a810f0413bf6bd81b79ac64ee1f89b97bd7d26d62512273e24a6bab2d5f7d2226baaab7b111209bb03733d8a60dfa31a516f4a8c7699d8285c1065159a6c7331c1defb47a30ef5858c50b7d045124a09813d1cfda5c9cc3bb5bfae73c984197f8f857f186c41ab87fb7962b631f4d007cfbee221fc6572784a551194c19777b08e6b596757e7cba7a0e27fe453f90dc59cc08c6472431c020e8dd0917590e79c1f207383afb39076ad24da8ee52486739453a2590e51bfc89b13c2033cfa5f8903cbe9961a8598ba556232869dfab4d56edf4f05e8b77d05871895e63b5351f76cb2d2c8385c109d7306192a25446e4d62dc7d624f0c6673986be0628b2c2d73eb941d35a3433090f59b28a5979d56dbc9fd6973f63647642cd903b0cf7a6acd330d87e2292710de99e0c179ca78929ccaecfaedbf2742414f176b6090c0d59a9db781c9967e28fa4e77d2a082e42f52169167e92d4fdd82e2cc05dd9184c7dfee490a237fdad4dfebc01868e0a4353a2954d090928461821a7a848d1b60817fc3bdefa1
+SIG: 99e996e85a494f1980cb07de9ca6165e7de104d39fe3c3226735c5daa569516fcaf1b6e4dfad0d389b6db0ec8a8f20dd2c602656b5e761c8f3a6558382151909
+
+TST: 645
+SK:  42afe89dac83e7d38996c0dbce0c9874c00927babd77ca8ceac34e564474282b
+PK:  a4c5f5e3803f0a03d5c1c906caec9cc6d2851407f1ca29f72a45f233e6656244
+MSG: e710a163ad2885aeb7658eb374f118b76842ec36ef3b010c3c6b9559e8b160c2628ded0b8511eb4907180da4b621e9aa4a322288888a1c09130f69f890597a9293e74f9289bdaa5c91b6fd24aa044ab9fcb3402f7abc48d2ab7b3880a048daa448645ad2ecb55b3caee2d68a8bedb5d1865d5e211de39b0eaf22e5daf10f7168203aa15b85aa47bbd3cc4169cbc1fe80b4700b625871edabcd4fe74a3e965569ce245cfcde4209cc8abcd6797d44185b4f96c0181bbd27008783e9358a5394fe3a34a06871d379da35b20bb57eef9e5524ee7912a6f41b4a1f684c3919cfcdc00f4580baf9e09d316cefa0f465dca5d8eec514e95e5a57bbcd27e41f8119b264ae14a319d8c3859babf1f4a6b6b77e442c861d6ee28ad12b82362e90db0c3672b0e0d9ff58146fd159aa8fa99dc755fc85b90cf9419279c0624b93e75eda0ef7c09695ae93bd7282419377b76ca8bdc0521cfee6f6d729c3adff894687b177ef19529a6bdace70b685c6d7a5d74a08e2a9e724035975c80d18cb369470de7299cbd6b0a27c9232c7eabac86d5093a65ffe0b40d40befe80b68cd9dce1ea1e657e45e9c499d0b690f74455fb47096ed8c18d1517f90442901a6c410b7f6415f20ae48c58ade8d675b6c058df16ae7698fceae95aa771b4cd88a0b3f22c51f98c71c1eb46b264bf97a300ecb1fd26226ad8e87a058cf3e708e260f566b685314045133f4a5e8fbc34561b9a0f1ff9339f55231076b736b6e11524319a272bd4453a0af1493daa09167e84643d207a02fee98fb223b01a99aa5cef2b7001e470f6f94a5dc208edfc0cb8cf3114a919600f061172f0efe039036bf4dddbfd0d45f91443bf26f8e15ed7db8e55f086a4a4583f4bda0f556284dcf71292fe70fcaa8259b9faff3
+SIG: 4fba2d6cc1b7193d3562f8c8bfe6905c829db265a5427c5c265714785b83f69514c5e30e28b56684c82dae2637581bf3f4ef271420bc7e6010613a38fa101a0d
+
+TST: 646
+SK:  10f009aa887d91ced809afe192d78e4799d9037762f4a9d3a429fde0f39f7b7a
+PK:  cf5116b921212e9b78829a0263463691c6fbccdc0c118be141c96f8c88053dd3
+MSG: 2edf14d6cd56896eeaa770211c4984bed80eca8d6534d5d510884f55f11f99ffa9f89b586ffe7b1ec7eaab6a9dc1a24a3ee3c7a6ab44ade9917883264ede2f1361be7d7a3817f29dec9581c319f18f95d5be26d9118be678340037a68abfc5efbb9a3f3f3878aae3721ffef5bb6a26c7b1a3a56d2bda6c6e860eb41fd8d8371174d91c74c5eb67c3855c630d641d2e571a9a51c6402cfe1842cef38980cb8d0a64bcc89be3189e6811f47e8f4d0063a5b1601f44fda20c1c4c2fc49cbe27a4137dc4638c2ad2d0a5474747229c568e3805431fa36eeba785f7b97844b5e319fa6a09cc5ae8403474bb91dd896c1ec2bac73d2e505efc62bd502b5ceb08d16e832ec5dc4f98b51b9d0738b9fb28f3abe8966bf22375a0b22c471a9e58e3fd700de15c5296373c1bc9d4640eb7816e1dc9c8ce8619a81183009ec974871e8f0a9772ede0a638b3574bf75d8f55987f3cfa6fec68970bfe00b23b59fb5bf4996ea5d7704fcf2effcc0fd7f3d8e6056008097f26caffd5415a282a276a9b2645e5cab12968872eb052f4d7c10cc7c21d5161818bb44cc856b0de769d559c55df64ad9adc16c0ac65838f660da81386b70b93525ec2f40f6f63f8ea5d4830b9646c46183bb4e6f27047bda2a546bd34bd4db5fb88fd8ab7c75f652e15d5aaa6b46a8acf6e448bf2dd64dee3c105647c7f83ad200d8097c444a158d85a54f0e5dbb12b43de943af1a81856ac969f52a0bd454381bd265041a2691d1a4a0d819fa79092c8803521fa53689ab852f1fbabe00c94b7f682d121cff54391322529c8d5ad7bbb98eafe300ab922f1c89240a1e633cf56a7b02f74a29214e569a057bd585e404d7cd5352041456e6cf90c15342e025670f4fccdf98783b6853214cac3fa808a66c27b653c
+SIG: c37bb7b73b1105be086ff3076972077262df4d7332f608c7b2b9d978d474cbbc271046080035f396ee36479b7a6711c68e2561c741c0ec5fc9eca1734e811f04
+
+TST: 647
+SK:  4578c65a7ca48f2774050a7b0ce7a4fd5ad4e696b2b8af2396164a1c7e1b7bd7
+PK:  15bf9dbd3b8173e6f03dcfd575d909845f038eaa09c5d908fef908a97458b3ef
+MSG: 506f32b96814243e4dd8870a8fd60ddef09bb8c563151070d9bcb2b160a3eabd71a044d71ec93fba95288ed6fe1a7b921651604307d65a45ec5d3f2631ace40e58d53c72e526886e16972f6e0db94d57b55634fd39d55e9bb7f212afab00f7746409267e8d565ff5c2257333c3d04152174fe12de6a57bea057dc219e2fba5f191ed8141c018969de19472d6aaf763f19ec554702bb3dcbe13ca9b23b2418c99e71838a88cf454728cf9208a16c84ea39829b4ba9b4c77e176112bfe1bf35f95c4028c7db80b36faa29d2b89e9e862f31000065f139b3da77d9d868530574b7e391ed97b34f878164f6b8d87b406c7dc7860a5175f920e5a62dc1fc82ed8452543b107360d35d2b4c4239eab466d32bfda34f51037a6fae76f6d8b83e8f7f489dd4c1b49c38f53576e62172c17dee3665fde8cbf015af9665b0f1da2fb77b134f04be271e402f31537c2fc05c2f9b6fc3ffe47de3369133867c69d10e7f537bae4567d468e0f2ed806fe335f939c75994f363ce3b70daa7d5bd2317c833851fd8cc97251ec419023d9d0174d84d5609a6918a1740eb1e309bd127366deb9c5ab12992e9902e015fe58d6adbf52d22a760acd63e1edd8f138e9fb0137188601e1978e7d04fb2ada2b2aee12f49f2836c6842d88cf48c866e3d33fcd269c275c89c25e3669ca90de7b67a7e7a382cb7efa47e9c2bf76571c79a25085ef020487152f06bfa133015a1b8f1c0f6a9f0eae1ba62bf104f1c16ac14e1e96c4ebdf061e0cc7101d38da7e9e0994daf0f322aa3cfef91b616c2d000689ab18ed45268dcd275094f656ba3cf515261024741f7444ab7fc4decce16756032a1be270ff0b0317542ba02662260a376fc912cbb029cac54515f5a551364f6a99ffad0b9cbcd0e693b7a521cb
+SIG: a1c242b45e94fd180f054c7101e55b396568f483db6f0dfc4168b69b59d385814c19eb3075237d1fbb1feebbfea50c56813c8c39c22752e02db7e57f3e3fbf0d
+
+TST: 648
+SK:  c21e70c46ede66e68a8873bbc64ba51209303a0ac4fc49b1d83e8193ad46c037
+PK:  9fbf80a42505d2c952f89f4558c3e6d187a7bc1ef446b2e3732343c13b33d200
+MSG: f55aa570ce4fc95f73f51720d254e4695fcdc81aaa040130c7687f039b8ba59ed857ceb29c121025a857feacb4a01f38e01178310ae6e35c998ebf89dd79057b4afc6db340601c81703c87a8c40e5cebb0441df78a6de13a447cb016c65e741bb7df304d83056b72c682c731fac0a0c70b7811ca14a50154613099c2c437521c404b6361de3621f8ea56b08ebfdb07b4f2bb8ba2ecc164336da8efc942766ef0c74dfd3b49e087e9a27ae54a7a2b98281b9af93dc11aa2f09224ab5a730f0218f4a6e1ea4885a77fbd93a1c58277d9e01be73a25cda918fc27dddb453a5da6902ad02ba05775c67e07bea4df86913466744365c1326e0ab5e1254c17967447d591ba5ed1b63a42543b87fed41459a089bceaff219802a87a872a763e692333ce1cc7397825084b2b831e93d80d6737f32980f2f3ae82c62190fe3fa700c5b7329d6d50042bdf831f37548fcc80b11f57cf20f67a3bb651a7beffcc48b70d17eb60f7259cc53bf7ff6080eb2bd0923b0483aa3065a8955f01d23ba80951e0aefd2a9372191572bc52916aa22a2aec393767fafd086839e236fe0460ce6d639c7ce69fe7f9d3aad2130573443570443be6bab93a06a54b8ac29bf33ff9949bc92158e6924b6b68ecda5f6f3aaf42b3d22df6d5e67d5cb3ab71eb8ee0b0e66732e1daca6cd60d9aa74305fcd570076d228d446d5ee542b10488bf8aa988f451faebe74ab669d604d9ddb15106620ea02e8db38ce639b5747812bb9048ee8bf72b1a951a05dffac95417cb43b06dce61ee3da6f2832ee83b2e7288ddd62eeb5893f7f2f6c8090d99e336c9f9069e1815985841bdd505b5f83d895e879593dadee72ceb9765699bf80bd06a5c55331b2545527d0c7caece96584ce3ec7fe02260f20b8a1c0635763ff4
+SIG: 0ae343bb84e3a299078e2434ba220022f3160f968ac04482bf8cad13b423f2670f01fb5f7b32c597520f84607e0f79c075fa7078e6e69d3cec319265d466080b
+
+TST: 649
+SK:  f2c10577f7df77f0c1157a8c331a7bd2ae6386670eb65f0fae122331690f828a
+PK:  0d4c340fc231aafb3b6f74b89bcef7eeaa0b04f293ec8544247bfc3f2d57c1e0
+MSG: 38ea1e028a493d1c60ec70749f14d436eb3a2b2de54f213d01a645b580430ecd8ece6b5569cc017a4943e5595c5ed6e48c9443f2fa5eb2227ffe56d211f269bc8f6fa9ee8cd56f6b8470539208afe29ab0a195044d957b31f93e184a9cbef1a14e14f808bbf589ac7770084f998e1b254da59ca6d3e62e7be1790716d2560f015f399cbbce48cfd0391ead1993446f6b2493977d93d7b09a07a79a59ce15dce7a1da9c646f45af2ccad55ba158e638c4a30c5d30e9ac6e3a3339c243426d86491b2d92dac1478e8d74ff0bf149bdb5e09e3fb6b8262eb0687981554ae2cb47196339079da0a1a57239c19bf781f62fdaf4e31560a84317ef030492cf1bb1305ba8518ebaf2b434d3641672c8f6ea2defa696dc7e4f39efc08d288d1c966a6c7148c012eec439f7e12dbab5b87cfa44c9ae1900f8386f24444e1092b23a274c138e95c661e9377e8ad2d1fcaf1939ec9a632a873f7eadbe687b4a033b92a477f2e02e9ed92ce4f95cf170b3901518a062143e56db054df4e4431544785a6dfa24eec0f0de7a699ccf286dadfad85903612250764f25cdea8127d0078d554825ea6e7371c438bc46f29fb8937f8d9a39cf8849052d43ecbff6c4a3762a5f400c1514e85e91384fef9b40f4314e223a9d68c526acc70227d62b8b637a342df113d318202c51edd3c1efd1ff20b1ff078b32068e794d928133037f1e3a34689e629e43fd2b8e88eab50d7e7ab0647014ab5e4ad582006567eff72b5af2dac536892ccc871f8a80b5cb79d90bcc6b77d4cd08f876184ef58c064ae430bb79a6b9e96b0ad87368aa838a8dccffac0cd8ce9ea0d0ec4c4b0f42673416659c984992cf53b1e445431007640d47ece26dee4a2943aa7097dd356cff4754f21ac07f6b3f73c469055512f37aba
+SIG: 60b703115a322ab892c276bfd18f70a9eb0c7323e2c0a6eb5fc7e330b0bc3b07a578a082846264f032c6191d040bd98e5d5a4d4f076fb9062acd36bea40c9102
+
+TST: 650
+SK:  041a97906b5956b9d340f2e0d7a1dcbfefe663e9bb4026f8cc1ae7e2a14de27e
+PK:  f382d32e88c3a72c7caddafcf8aa699e21db7a6bf4edd6e49a005aad702e6a79
+MSG: 71a75957411544975a48cf103aa1f8e2ad15244459cdc0e336966eb8b26c97f2169e5d78537037efc077e86f06e05e9c1dc3418288c0a2be6ba34b3a04ab20bae7f3621094b87d78a7eacb864d4078cb4efcbac5add937a2c6012ee1a8b256cc276b65d5e92b4d00b9b11fad884991dec4c1cb9dce1863c8b0a210161ae6b3f8bf9cc4dce4adfdc8ed57d83e95ab9dd2d92658dfbd3afa99e3f8951e2ad74a148f6f597eb2c945c1f1b94461ae0745481fd0edf838c6286035e36f011238875dbba2289d3d6a3942a7f9554c644305244ddb77c117cb4b56237729dde428b8bb42df9ce29e144dfc96cf6c6767b1ee6d053ce4f8bb2056ab7810aa1368a8910f2f69e061c19d8847184fed534f98758d703a76885f91eb752a21954a10c6f6b4da10464ded36b00089f662915421bfdad496753689ccd03b624021080761e68176b10697dac878e4c3db2fd0b28c655335d98016f19f265bb0b2434cb4637844d91ed0ce05ed2591fd998965f83f3197d10eef448850e792032724701da305cb6d794669483fc3dc6f686b183e2999130c8fc0058dcabbc9188f26b2d63ebd6cb1e18a097c7704a59b5e187e0142593b7083f7400afa9b1bf0c1cc6c356bc4334af772e67153b45b331b990920c24eede2c6e323703f52ecd60735b23bf22b81ee775927c37e53dad7596ea65a73bb96775f3b87c8b3c088ec695bc3a7502c0c510f020bf9aca3cbb7a2c011c67ff27d634caf1dcfc58e5e397e6658252272011c8ffdd64230a93241fff68372c4ba85382bbb229309652922db68836631e55be69ab6adb8e4335357fc923efe154afcc222d60d07f56990a3e5a214b227aecff2cd1bb6f0c79ff545f70a616141a9d53f922a02443f7d2a4689c35b095dd394d50bf49f9680a5f7d9
+SIG: a23f032e6692a0e8bfee5b2d30b414cb16c35ad08da31f696d461a02857822c4ef357f0ccf31025a4dc95ced30a994f41edd1d087afcaaf3e8e875708320f80c
+
+TST: 651
+SK:  4bc5e05aa003a4492f4bad102a5390f7cebab3d3eca9152142ad5ef7d84030ae
+PK:  6751d3ad8bb6c64d6a17d7e447a27da22f5f0403f437bac9449f13cc853dd840
+MSG: a8f794db1795667d28d24b70ac2200a6239a34e2438ced1d03f97ed48beb4d6bea67c14338f7736419dcd2a2a7973726572e6afe7edfef22c99be8b069f04f6dc61a13b343c6e585abad2214d85c36f02996fabb46bb91b5176ac708e49a0b053017048fbb55453f2b8208d6678d1a8cf6a1ee9ad7a91e380325635d1e236a6ca1d6cc7f6b59f2a2bf184f5ee451d6799f69ba11a0cd6bc04be8a351a80e725b5fc4563e45bd4749ecbc45205229105b9de73261498527f3d4ecfbb583ff532753d07c38526bb482d171a261b9cf89906a7dea8cbd7e726ba31ea68803a6b004f6dcd19e671950463738cca78bb0dffa3d6457e4aeca657ec649b97ee30e97c8cbe6ce43c2aa9a69958e9dc881e4aa7b3278074e787ace5fb601d7faf7ca5103ecbbd3bd554eb1b066f8296d2cc57e8c8a32e9c0e6a926964d6df2d8645864b322c322f1ca8073cedf2b556711a7a20b77c0a1ed277a9a6ca2c07154e863fef5a404e3e89f0d7f30f218ec4de7a53aeb9c41eeaaf6ce749649c9998fd62bcba2872338e19c94e59dd5e2dd776f53719d21746976932ef11abf7a32ae6b0744665d0e0ce513955a9e68531d8ee4de9a8d35ddfb88eb5a486ad63137e8892fd7c689d4f9e7021b1173bb3752a5eecf2992e3fd4642263c7b3d815c29b466ab69285ffe4b8dafcbf3d01d635553ab7575a7a3471edc7be412d3d01e6fe8e3cdc3fa04d2a7599381e22bba49c5539d79c62b52bb0eca33f74255e41a9526a89289b15f1850d9afa87e6b6fa127101c1a6d88d433e0c86aa60bba8fe7100ed61d5a9d00a00764513eb1c7f5f5c3b3efc4532a36b407fe2d17cfb4e6fcd6049cff3a355623a3a41390ea48f42120d897949111be3d169b2d2ef45bdb894fe20b1a95ef66149427a9d8f80a9b2e
+SIG: a24fee11f7ec6da3e9dfaf6c858ac004b4531abd1c9d3bb64f40dd247f00359350e43b2d4b8fbec5f6b241ecf9f1101485cf418735b05f712018335b20068308
+
+TST: 652
+SK:  a3bed9fe2354bd2860149a3db75a85b129cf83e9d73e6317ba7054521933f896
+PK:  5ac03b4f13d91d066b2ce359e9bb1dfb6bfa5afa382fd1ccd72aef1176079f89
+MSG: db853808686d6d21f4c57b541e5ad63394d465e60078643cab1e065c9f306c500078f0cc41ef0f9542b5fe356aec4777ef8a95554c97b6a44099e9bd6404fb0b2e41f91914b074d12237cd442ebd40b51b8bc8bbe437a2c53332d2beb2281bf7324a0cf5b741bbf98d1eb9858be926e915a78e8d314b4144f3d20dfc6cb7f48c23af90f871c6cda90845a41aff1707a87b4e5516f18e8bd7683cfd74070803e888338c9a18f792c8d3a704170ff982bffc9e8ec9ea5d1a62592f1688d4f2b01e11f9f88774c47ac1d58f690bcf288cf8a473d350a8239df9d3a62881dadd338531fdce7615807ce965496d6f35d6c042f0ce7f21efe5ce6425185941ed5636b8ae913a75d21ab9dbdb3c3b6687a45e044938a9f1c13a330ea9761e283e61d4a320e1f559882f34b607fefe32c343174abcdc77b065a92904b42d961db8ed916c01464ffd43f93c1077f1df7ee65031cfe05d780d01d08ee036f22a2b0512193b0c0f3801e0a0208eef245c9e519352d2b0096382f2cba06eb2a01dacf619eabbc883c5d4f2fd7c3423179c0f5ffdaf8cafff5c46b34a09c3c50e2949c06000207d70d37d65a743075fdc2be62d412aa63e363706ca90e6ef44e152ea4dc5c2893ecd08d796d41f172254c3d1d14bb067b53a0897bbd73c9954d9648b2af10d9c2703e38b6c62469f6f958a1ca0a320c12339e90cf768c87b4738c219f8093bff4c2cfd29459f6d3281349378e915a3b0e724c74d2bd7a851ac7c6b48e8afc7124fdcbcab5ff80d1dee30a6c024cb4331972366ebab26bbb9f608caac7e51914df058b9b3745d98c5d27e97105475ec017377e6316198ece4ec5909f04fc27e7b382e66adb62ac8a977f376fd5dae434fb55175249ca1ab6bb02dec0696f089be3454887a0c32361d172bd2
+SIG: 33bc1e0bf1b493e0cfb7ea40480a1423e091f7145745013173787df47a10db24c165d00596fab70e68c94c104e8a7407cf695cd3fbe585b5b176b85ccca4fd08
+
+TST: 653
+SK:  88a24f0df3ae2914df79da50ecf8ecb42f68c7baad3b6c3a2e0cc9c25d09d142
+PK:  12e6603f713b2305358568710018685e141553c47591396fb4259e42dc53b9c9
+MSG: 654e9edc69fe634c2308ba8c46a955e882456286eae3593cae739c44866c0de9edcbbf0db1c44149668467709dc9706298dd2eac3301dabad5bd8e93c5e8a93f194e0fc1d9f376c144c293aefda086b2218f2e9dfd7c2dc52ba33eb229dcf7bb68ce0f876c5fd4e81afd80169f73cf264e5dc0ce16e1b876cd11c7ad89058ee0820c40005d01f119f8be6f1afbe24ca4aedc18e97896827c3ed67fc45630e7903b7fee9c990e361937bf4ea0a4d8d16cf6d9cf0381e9065e3625148f8ae0491a0341d0ff9f727be1f310ca1ec3f0104aa054321784dd24d53c985b28d44082f8e1c108a44109638ff5116edd85aeb86b6ea512a19b602edd9d211070d044af5bedb6c8527ba3491e345bacc130b36960282ae737b85c769274f0f7c588f40e6625b236bdc1a3b87320460eeeada278124b5668874f39f59c2e6aa208c3b6a9b845c4d0a27a0546786fa13e51cc98b73fd7ee327b6215ec6b629f4cc7e4bd3c0a3db78a21fffe24c70438716bc37b8da7c5ff7c3688a90339c22eb50b7c2cd36b68831fd5939175689bd3e22c3881af337ee14435709e351040ef3da955724e51c24a5e2c09f891808393fbf8ef7f1f5f0298deebdcd8d666cbcf3e866c718999ab6b1feec9c47e02e7d63540f89963d542c5d01fb6fc30768968ae81b20c354b4000c132774764d6d443add64f6dd748f5fb5b7f6eba401db4318be993989fcc2577961fa5ad31f6a2a9d6a755285865cd5dc3a88cfb5aba7d923baf78b5d131b4c214df55b6171f45209e21ca6645490d3a3644dda6dc929c7c409576d37164755ef8aaf3dcd4d22775ee7dea0e565bd54727921c649bc51f20c1f68c1fdeac455c67d71a1cb8837f4691448bf0bf044a46f1685fbe22b1e01877f7477d3499408c4c316510ce2e55b98005
+SIG: 1707cc009186bf3f03f7bb9e3cd4cf6b737b7a6baade7fc6c3ff5c1225dbb2baf54f47c85eafa132c31eaca03e6aec1447733facd37149b7c6cf0cd41f611404
+
+TST: 654
+SK:  184d0ce2e9db7f257a8bf4646d16d2c5efc2702ced026b6906d3c8c0118f2261
+PK:  e9dab8fd9d94dc9b24cc79c635cc57ce66518982ba3e2447240741bac0730ec5
+MSG: 6a9b876b0bf4189b3cc15f9eb4fbe7932b5577892a22200ce107156853d6d3ca363f025ad7a2d862aadc742d9415bd8d1fca13c9dca3586044e55a8cf5dee1ce564576e3e8e365540546501b34ca675cf200e0771a818c73d37fcda8cb15e48d5a0b9ea3beec0ff6610b2a8a214ca4f7efac0e71381052d9bf3c00c329593474ebd0a687a0b41d144b5e7ab1412b970a74baba4d274bb0dbfdb02b11f7f63964ba6f3ba0ad23341d083b91a4308239e33d50824396126588de72a2390c1c0fc06747c28772f630bf4d143f7a1159f028c093404894e6d16f634635d4fc330f3d7a7313ef756f5d49d8f6205eb1c792a9495da131b43345a0090c12ca56e6adac5be0cbcac3609d69f72415f6c37f3cfb2cf76b3e65f3c93ac92b63f2baa466249075bca69d4c1d1f3ade24ab31effcb90469c24bb410ab4723e1b7e1c88b3a36433563f71a99aad58fe80568f9c102da89bad97963e77d6622483166f3ae261f32a52a86101ebd645f6142c982e2cd3625cf8b46b9b2891246920f697fcaed397cb922c274945167a0e619b0b506377606db045783b0b88ea04e932d21ffc064a12a40ebe9b480f1a2c7ddd395a9b15efdc495c9714f36fa996f79f8eb8efa52d99a24abfef43b32a237c5bc0018da3b162f59b8d3d474e2ce08fa8024c58acc0a99ff614e6cd7fdd9ca4e8f41a1449aa618d03337e8a374d56055b207a9dbe69f5948f901ca7db0410f01aa373d9e0227623599bc212845b006e942fabc582cd726db5c443eb2dffbc9e3e7f0e5cb6744f7ad716050fdf2c60c7c77c253ab745db9c8552655683ea7ea680aa4af34df1325c29b8874b61be23de4ffba25424f4619ec682c26b3a67bda9bc4c94b79a9fc4d82d340495b437a1cbd6b60307cfcb10026f964a017623e33dbf233
+SIG: b1e3bf5fa74d7e442ced9a98d927d8c45e0e64d874f8ea5920a360a4bf42d83ce18a924ac796e1a77d1b0208294b50f822177fdbdd458c74356fcf6bd7945106
+
+TST: 655
+SK:  d02bbf70d51351e3b47ad8e5ed263dbf556d1498fa9bd5dbd99fb4269009dced
+PK:  8ce4b59f94ced6ec9614d67d3066d9d3a0df7a46b37b4c1725ef1e57bc68a0d1
+MSG: 554560f7a7fd1ae7758a2fce7d780f6b3f043d3af89d4f19ef573c34997554df243faf2aaab65b2afdd28610d4a51e9a4b464db6db09ebf73b7d24054cc9b12814bb29ee99e1a73bd603898360f9dcf01e670836286f8236ed8cef075f3d563312c16c73fc37eedf252f8f42d30a13e7fba3b165238c7f81eaaeb53190f3ec3b5d63f0ee03e3987e390d1d81e8277e9f6c1ee6ec4ec3fa0d720e9f53f9c26f04aa2ed2b5ef3160895999eace29cf5dc254ad71106bb7e8bc29a5b1d2412593d08194e88e1659a73159a2a22033ab066e8d3d8c3bc86b7b01de81a8c66047b07fe24ed240318ba37ba3efb6cf632604ca4f446a75fd8e70c453f0c60ee16ecaf524e703f47df5c282ca3289b3af61dee4709ee085323b1e5c8a6bc0766201c635031446891f3494e9db20dd4e9e0838249a67e138d13ee2c96f61e771061542aa16ef20d81e3a0f4e4521a6cd6c92fc26feef03b66c70e035cafcc19c96fb9d82918fe197780eff0eda6e2512c56e2a73d77032b768919bea9772f5989c8b6c65c3d1e97a2180cc3a37579da70ce9806ac1285a3eab415c0607d88cb86542eab90b9d2d67fafffcad23a714000ee59ed68c956e81c445428882f97af74db362e45c0d1bd8856eed166e4aec4bfdf95eadb251e2a1ef804852a9ea77d34577fe70831a928b101b60ac613e7ba2e6ba0a94013a64c2f8219fd30bff409099667a786f99327bb03e2f2187f445b46beedab6d325afd904e39543e93f4b6c5443249d744b2d1a43e141e4768bd40aabe4057244e1eadd9daec175719e51a093ace32fe82b2eacb5ecb0da6c1ffe98c8cee7886e301670dff87113efed4282471afb6b8a0fdb505e2e8e7dbc1a08a22e9680bd098bf1275802bdb459413a3b237d7713a1bbf597e6adf2b60eaf823791b3
+SIG: 6e7c66acc954ffd9dd4c1c6335ab4fe79dbbed782c4a47ec30d848d8bb2b4f1069dc62e522a1e8017f54a6345e1728c073af6447856d8c1ed35878b571e5230d
+
+TST: 656
+SK:  aa0fdae2a5a4c9c04521913004cd89efbc88b2dadf5abb246f3ca7f6923544af
+PK:  bffcb17c35c1304cdd9d624ff69bee60ec7c9ec327d12350d70fac12b47cc25c
+MSG: b14184cfdc4a5f0c7f83f94a832f588507e2d72a89329870078571d208a0c4960c2fdc4c236cf88229981d12b10a1b6884c8650ddaf1d4b2eb981575b1e019fe3f60423676f8856a992cce36d6d0a3d026631c8c1e1ffe34134b296f40842b6df4f86f833e0175bae50e86bf856d1ee79925f434b8bf2c84519f1f5d25386049ce3ca61777e30b700a602d395250b60fc64ac6f8db027e8da8b9550f24ed11a11d9f9f9c5e0af145b8659751ac6b55861f6388a64336b31efe45c0802d76a53486a81eba07314b4d961c141ab34e2f76edac0e6de31422df792af081e769c7ed05da9a5af2fdf36f141769908b700937f0e1068c131f176eb96c67afdbe78f40d86007fbcd47e49e2e4c4ce049936adff1ce3eac42b96b3429b5626b1aa62acde07f45a13ce1bd211f32bd7efe4790c8371ebf87c164477a5c9fa3e78c2f88077b097344cffa031c4429c7f42dca07737850ee7a769b36d0f0625adf120ea23ff4e393a4fdcb6558dbf9b266a032e3b0599b9d6692fcebd815a3897607856325fcd0115dc310db3a8792fbebd399494c8371e585727b3d632414496893d03813ba1f99661bceb9dc18ec5dc27f52670318687769fc678ddc7e40227c200522013f5c0eec0e4781e6fc153a0c2f4f3f95e517c8419924ab39992af8c19465057f134486696ba7fd4651768b4e749ef36f02444617cf97f0a423e4c13b7b66ba2b6c456878b0b50ce2ee5ec564ed8854f782aa1d1c6aa760f2522c7d97b9b1abe0ba810959d7aa403a99375aa3e39a115d1fc6fedd002f3830a50a837dc720329ec0c73d5bfd500385c736838287e19201525d189c3a084cd5a3f359875e3b8325289ced18b63b00ff9cd070c3e67444bd3d8346174085cc45135caa0c67b3226e4a52e9a1c55aed7ec5fade6bf16c19
+SIG: f937298969ca34d97584448907358b0f47841f3023afc7ef7681521c5be0f5e5628a8f607e2f31636ef63646b0e9898a72ad355706d2c8060fbc640efb3d6605
+
+TST: 657
+SK:  7162fef0aca4974b094a6a08054395f877ff9433f1e33e20e88eaa90f938997d
+PK:  a280640f139f45c35a4871537eefe6ef9db02de785ee9fd54f805fb57d3746ef
+MSG: c90f450bda1c6efd8d1278debd7ae03e2eac2740a5a963fcf96c504e31d4d6fcc5e2b52a2518d2741c55e9591867b2423228f9c19f33c6f38705c62036d480ff53df12077e38fdb073c673105da1e11619ba5321a71b5f4993234a11948ea110cfa242bc23fac9aae462606e39641ca7147eebba1eec553fce94e53e4e01b073dd780a2ff678b31572ca11ee0877e756bcdb6653e5e1b4cbfb569a9d60e3ee336182dcb9b25d1be6dbf9b5c7146d775585834cabde0278aee5d57c85e983f84d8833a9e15bcc11198e1c1da6ba59282129f1db966f5460c8fb6530fbc3a98a31fc0f4e9b337366eec1dce108c826d49045abfa12ee88797f08f0683fef77edaa3543b91cb118e424d9c408da547431125107d9b0744c2443ce9917e1e328d81850babbc94d920a1d06e524dbb6c23dd82e1787822d71c4cdc409ae85ba4deb581f934748f75e7a769b9d68c4589e594e65cb6c8f4903ffbabd5a326e89441a542f8ac264ccc64e95a8982a710b6c56ff7d10916afc409ea8a41b74679dd6a766f59c52b9305ba733b13c9e811ee13083925f4200682bd05dea339532522970aa149d004a2ea20ff461e9ec0f3b62565c1a106259c836605cc27cadc9515cb9979e89af287c027d75edbf87d5cff63a7fec9bd10e7877ab9bf868d734bd3a2374cef7025cc4dab710e254806685a136ecd03e36770346513a15145b890eeef47b80ea08e46c81d202e533e9a06a38a6f76ef57a9c736ec78d00b808e3ffd9c79b9dc7a2e589907656c932ab8a8b57da1a495ba7452015e7924b5269ab1f67bdb43a35831487ab9002f52d78b134cd3751925aaab0b45c8e6b0f2bf0cc9a4659317108fba9136aabb0921a58fbb9b50e51243f9b531847dc9657e96fbaf7aa698fe6fe44f90590144c70337250c58bc5dd
+SIG: ae161cce95403384b65c6bc9b393eb072564c35f3a6c04fa517ab068bcd23767cc0c8edd92b1a13ae9a9ce4864137fb89c1f37b748cfc9134b6741ba1b22280d
+
+TST: 658
+SK:  dea180c91b533aaf736bc5d3c8e474d5e5d475b75b92cde6bd1d10f3b8f55ad4
+PK:  30b20fb320b00e77c4e0a8eb3730af3c0b1c5f5ed9ee2b0562707e4f55c4938b
+MSG: 606144b7d4f96bef7f112b6d41bcb500d2136c134ceda220e24d0f1524eca12c30f2b102c7f378d6bba259c5b4a5ef8ec9309d5c8da7e8d2ded3792aeeea2108f77d66b23045938ed64751f20d48326be2fb99628cfb1873d7dd27581c105ec13249a952a50784b8b34cb3b2c1a004fa8b628a0767fa9abf058d955df85d134a0fc7f4b7d7fb0c8d31bce345dd0a4282145afb2ff19751f2cc3a1caea242baaf538749bf388000e3dc1d739359dfebae64ae1e10fb6fc17cc9fb950535c2de129587a86859b7be36dfe9b6c1141b25e0915c8d4aa1cceae7046b3d7cfa940bc98d4d69fc5a30dde1dee42fb5272281bf8f8e7f3e1a04397fb4f3adefc57532ddbde36833a676e6f39c82aff6bf4832ec971e03be3829c02a203c82d9eb8c1630ee9693f45d26f5f51a3103ca64d468eceac1b29af4c42eb216d76ec8994836b4bec76489ca5070680c2c2eb457210a77c47fdcbf600172073a53f1453bb5c80439c882f0736de40637b4f5ab1f761ff355c6e9bd4abde7560d5fc113c830159a1b77c4e87bc2c69880a40c5805ecc8aaaf57575bccd8177fc6b83569233c0f5ca223ac4013ca106cac2854706aead714fa29f2860a5f9753268a3671d9f59cde6048cf0b8986050f7f549e4fd7557f2fc3fcdccddcefda586a64b3006e5825f27ca31687caf663bd90a05b1152d7c88d7f1051a9d791748651d888a6a12f22d6c8c3f78c2b86eaf5394b4ef7eefb89797b25e542dc93102d021a1d0bed6a7dcdd8102b8f0430a0bc21d904a3c9346c018343dd9937cb35250007a284825db08e9a11fee31cff7a314c48c42d8b314acc27822af03d1954c7cc8bf9ad4e9e98f4ad4efb355288daa8c90de9037e64a7861f5ee43ada9f0fccde34d0bcf50288550f700f215a7944a5380e2a8e3f04f2b4f5
+SIG: d083333fb84e79c9b33e55e8192d571ffc8dc50745b6b5fdd8c44d92a63fd178c4e57c2ab3a1211c0ba2d39da30b06629d8d1cc1d9f2593263d524fa5a2ebc03
+
+TST: 659
+SK:  9daf6dbb7f762966e7a57c2ec1996e9f5b555b9866b8e31deaab4356eb13816e
+PK:  f021b55a36d9fbfbf2978bc0df736b289c8241d6435309841a134b07d47ce4ed
+MSG: 544523900daa6778c0391ae4044a51c0c4a5e444133fbd7747d539a744fa60ab5dc54e1819dc8e56899c56efd7ef3da341790ecc49645ef325c6568ae971d30d21bb7f23464f46a24b80d49bb93c6e91de79b24331d0707f43d0665d0197743adff690d615a1c9258777fc47d0217142426a4734892eb622ab8e50bb128ec3a895266a3861a39768bc76096f581fd082df9b7223e85a8afbdb5caa4922af2a014bf8a5cd11e5c5ea93e91cd46d5a1b99b85a2670e321de2e32255afd67fe2c37fd932caca22d241faf4ccefeff58d6bd04cfaf11dedd29c8719ffcb02ef65c5d3eb78b4fc0d170a2e3432cc812f0d041d9760c13c12f7c7f2f84fe5e0f700c10b1a69ca466a70bdeff8dbec7d318fb09ddd827ef61caa6910bbc061cbda2b527ef2e59ed4c17229972f89567d705de9231924b41bb6e7c01fe854264474fa76b1f88cd57eac311171af103d23078424a12675f2fa36c2de0bf53c295feeb3157de958922986e32513dfa33b35e15c394a11c0fcc55b82d6dd0597cddd27ede7de12985a616e64026befb5d690482b3ff22c0dd21f27a086d37a0499ea36fe2c4b5a959d10e9a610cab1fe0d28cf1013dcae63d8fdee0ecbd8b4e19d5d040e2fad7d0413a38e8c4e73552ad46047b5bbdd15c09cc0d34e48b91fdbae2a9d162d4b21ee20a1ef535ea883595bc4951692a67163454c7367f134bf645d48f9969e3d4f0f9eaf4144ce980a0a2e3342c746c2bdc3ccdc2f8a7da57a0e8028782d30af5857d9efb37666df65d7cc384716661e61ff5c09752595e94112ca1a840d6e4f6ec0e55494c5b44f7c0f0d4a99cd70905bf8485561748f4dc0fd7a44a1b139113c38a1e8eb5c7a20f3e952eaea8ce38b207c28ed972718f031f477c6207ce433c515f5ac2840f4974f1f16989626c76bc98
+SIG: 49b6bc46b7abb5694da94215efc4b30eea04ae2e73eb2da8e8c9ef9be2222498b17e13939646c29e32d645584640641590b1bbdbfe24f36c6f694bf87238ee04
+
+TST: 660
+SK:  7186f8d168d9ddf17edbaf0e7b1abcb26da3e4c0272d9879c7fdff6421c4ea50
+PK:  96b4a656232029fc1b8364703cbea7a5d7387518a88ced1a915ec8d886848132
+MSG: a3e6cb6b84cc5cf1fb1a848b4b8ea7cb7c87e0445750c61f9aa5d77deddf949463ecd39bfc71f2610c2a9424847fb76f84c5da1fa10ef718a34566cec1b3e899e7252e8d4d346016498ff119972750061660baed312827583181073d1dc74b76c430ca30d409e4e8439c0fc48c00680629d43ae2a77d69228f7f8a1253af15bd2cb6bb1c1696550c4c790f449869630ab92b9c11cde1f961aa2103ec23f7d9f0fe9c3c4132582efa79a66ae3426e5105b80bfe5e04dc8bb1e38a3110cd72984b3ef02a0ca62ab638cbcfbc8a6b593d2613dc06ec86fee34f6518d4a3fbdc157237174564daeb6674cdc34f4d6537cf81d8aa9bddbf3aeda312daaeee336f9ed8bff81e294bc7d44d25cd787072e6cb414b65fb7a846fc065367ba8e37beffdf0b7ba8f98cdf1eb870f4e8b7130fa3429d2e24bce5994daf1aa65e5f603b631053dc510b2f097e86e9b9b552302757968d0136ee6754c42a32c990add9cb529bc89751dfa4e5e3a0badaf4cc40b6a09507f9fcd24c3ca72259599c6ee58d857b3a189e048902e885a3607426093cb0fab437c0fb0ed2f1e96e9441a7e954fe3ef7646e26a39a07033d0a1555dfeed9a6f57794af3a2abf0057e9f853ae5c30138fd80e2f29c2f4a93ad3145da10a3e31ce9ff9786ac65d86037d98b7aa6d11de8800010e133869eb67a5039b9b8feb6ef903d0cc746412607da725ce2dc6a352109dbc6a5e40b170c23050bc4fb1efa0c34fec00eae3219c29040e8f5978c9384ee915d8c9398dd120d5c3cba38f8526b06197cb2c261dec7d726ae130f9bee17261700e99931fac4b4dca0f758701acbf3707d47df5321130ec10bb3b13078c4dc5de3470f158b57dbeb878b3a8524e0ed2c9547545f0fddf13125e45bb23d6a7b383a187f4c5d54a7b4c83d5957f2cd7e6fbc
+SIG: a9c0499fc216a14532d736365c6355f938f8d8194fa1132848f83e490454d4bbf69269f12259fc6c074c1015e425e4f4f27c029c93334951361a35ad1176540e
+
+TST: 661
+SK:  e86e8c62566e15753bd5577eaae7f24105b74055a25629580708bfc83aebf06c
+PK:  8c8ce882d5f76586d8ddccc5579bcc1cdf4cfd7162304cb10e7696026e707f17
+MSG: 12fa631b0e482e9b9d633e94b82d8ab436fe548e5b95da92624623d13f2c70da775ba136c5229c16a0c7a6fa914b2feda564e17219e47370f9515bb1d59de6e9586204d943dc560d73e2e757f7eb39bbc7111bb46bc643c13f602112739bec778d7d4f49d092563d68f5776e430e3b0bf2dc1b01beb3040196da6302908bfe91e0fc38e04c150ef907dc736c445ff21fdbd2dc1eac0a0f5d00a30af028afe2ff61162b758c7da9a776666a112359431c48856a87ca82d3dd1c8af376598635432bf891becbc33a8fda44ce883ea8af4ad8b91a9261ce76b9e939c461fac53ae0f076e82d879aace8f38f120bc9b04d8125ed24bcd779d9d24386b1dd2017ebee8197376e8c36fa3aef8c1e713e2b8bce4966d84888681ba78495fbd1d6cca58626e6854cda606b83d6293d01e8e3e13bbf4aac851d9a1e00d0024e26993b0b3091be7e8061bcbb3cbb2302ceab96897a8e1ff367ec8625693cf31534124a9d5d725bcae001d67bc2111d0ab8111fa1d24e4ed06d63583ce690f2a04626d791d29e3e315a415bf2e853a5f2974c833a3fe2e2909cf669c73c1f59392d30c37f3b9c5a3ddcfd75621fda36e4ba2f16147858f6f206b9a140f1ddc1466c9a53ed73f82490bc95322c955f61d11cb51d5e8a58c6b3cb0fdf0419763201beea93a8512b1405245bfc384155adc5ce778aa74d00a322726465119af79501f040dd0a7a84060001ca89d2fe5e9cf9779a547e3ebd3bf8642990a3690e2b2c3e54cb7eeeeabc242b4dd99274c425a867931c929ca70808601c3908cfd788867d687dc366e976350c9e70584bd390d67eeb7cfea26c42686d3d9620f62f64104ef41ed1d130d79e325938486296b7ab2d2adb78526743e400acb2b7af09628d68cf9475101625c20e1dc051d73c997c952e12812c805b68ff
+SIG: 54d2fd44acf9e209bc7e433372bd73074d07806a77c6ce228e9be994418b00c7ecbcb7ac006c294aec9de668572add517c06b4eb4fe2ff3523bf043df44d3d0d
+
+TST: 662
+SK:  a5cab2727e2f131a4d63facee799336663930aa07afda6bd5a8e985a02deb1ea
+PK:  ac355f95260fbfea778c55b5af8b3fd1f24d2693da35de4ee508a27ed350391f
+MSG: 483439154dd5e5d109857c24d1c4e7fbbefd2f38651da81289f2ad3d6154306538b82ac7dba9210e740776ede4ccf51d4f63094b03e46ad3aa3c31947d8c36ce6f94e85296bdedcc1ead62eaa1441ecde0a225d0bf02edcacf865014899af66d9808040c2d02000a0f5ce4f1683c1a495276d9c4d728c9ecd6f078db8a0cfc267187238562ab1a1ea2813fb4f12e878e1ba143f4d06a3bc8100c3550118d69dae67b55ed692acf9444daa5c3e3c0a98ee28cf172de0c584c9f2ec9bb6e9b57f572a86ff8729f65f4c65b7feaccaa21720ed79e90618bcafbfd9533da85232b450883aa919f827f04c4a97bf51390d4f8569c191726f44f7e39fb3db73bfc415b6ffca8b91acaad69238572f14b49985ea03c98d7b1d44b3a6554765b19abf9b25274e97e4634e4b0f9e802eb6f743fff950757ee013a6988221881a7443f1f32bccb007e99379c7ca4f906d5fe11cb12f66b53a3d21ac947be0c8150bcd04f1c816b3f0c07c5fbc0905a7136956849da03836daec25c3e1a06ec3aeb205648176f89f4a291fac4f1d3899f56c9065eebb8768b84b31b7cc03108bd0888338d1774994970292d935031fea335d9e7908fe0254889c0b171cfe0af2e6fde7a5ea3de1fdcdae537b6313119c27f772024ef36e45c8b89f26c93d9eea13725e12d810cf9824aea04cb802da7e458e842ca375e3671346e0089dec571be169b0d90966bf368fe3698fd3e72bf16249dd900af6d29ffa48351360f12241714585f7a9b4c7bafc952226735de1462743d78abad0f6711f2495f3313ad4e0ba216b0dea5dc1516a9549f7dfcfeb93e591abeda5ea3c7045906523b40868ca5735d6a3371c3c294c11126d097f4c708e90464c1ad9142fa0bedf07dfc5f4cb67d6ed80f1bfe72683cfb2ad66530dc43d7023f3790ff42d95bd8
+SIG: 138c7a8eca5b5c37158813843c9a904e5f530ad971ee432a44f344f8c64bbfaf102ff41daa5cf722a4bc6640588759b8f36f9c059eab936cc45ed4796394a002
+
+TST: 663
+SK:  cb6319613779a4ef66be14144b2840ad0167c03f3b8d04ff592cd1d2d722e330
+PK:  18eb03f0a334b080e1af4399d8376d83c533316dc687cf341f0afab450965299
+MSG: 874a6c81d6db7133a79169760c84d36eea3d42ea0892b7c8dde844a3a6b60aa9f2660726c9c4dd26a01f4ed0dc1c53ba6005463f7ea64a1ec63953bc3d81052a2f1084389a7706df74ed4136082ab5c6e8c7f411df9d3a0f3c40f5a60e2d21a8548e7a25dee34030b3c3e75caa93ddaa9c190cb6deda2413d54e373d4353dba43d39491a2f56c8b36d45016f77d7471691634539e76c4fb41913472b0a23054f548f54b1e7109c8b6521b57ae981d050316a33c49c7116268dcc4b78c2bae53a3ae4dd178bb8b76bb3befe19e41a2cf12cebb71168f971f202461c63f7d6eef107f5b1030edd4e75009e9116c3cd0e8bddc299b41f1a45e784efa646dada64068e9248ec988f232634ad3d5aab19560e830a5bd665457c94295e1af0160fbce272ef4845ddf0c4f24d976f518690ea1f82ff4dfa4813641a67598ea98401e0ff10a0e582e2b90867b4e6232c34ea499c169909a44126f377d8cc1c11905866340efd1e7b077dc7456d59c9b96a124aac3b33bb227441bb7a52e6c3140d7a4f67ca05bbc93c93775b929119a224ed8f39005820f420cc6c530e61e20adca01e939cc031df49cdb1ec8ff493c9efbcad34c57108efd764558966fb1470b0745e6966191a9a9e44581b09faf469f951537203d926bc8a55d080a805181dd7296ed20a818268f755eaa66b082242f4d020f7cd6720890484c01c757fe35d87b5bc906deacc2e3071de4601bcf0dd6b837c433106047fd8ec9bd0e98c9ee806f7ec8c5a10ea2136f1f90f900b853f953f00b076bd1ebd929d08a38bec68d866435047bcb6721e06b64085dc0558c1fa85a2c83b0caf4c816084f10a4c5885295bca15ff7c18e596c62c92ee9921a27c29d195bd282213ff3660b6e7546b4eaa777ce39fc5d20484c71ed6ca06f9b77ab1d872393ab2d10255
+SIG: c1b399cdc198e9a159e684fc26686de660da54cfe312ca7345df0c7d15a35743014410bd2f6cd11eef33a89b3d15cbc17c7a358937fd997205051f9257c25609
+
+TST: 664
+SK:  b298adf38a6708f8d18ff1ed96bfbab421540d096c4e4351b92209b5e6aaab65
+PK:  770edf42b8a039c6cab9ba65ebfb135abc2da314a4c309f46a8f325b52d06593
+MSG: 9df4d5d7565d2c052262dd34d6007d86d9c0f07c7089af6119e304f4d8011d7eaad77b3ef70cc280847d59f297202b7e1861aef334bf38de14740e8073c955a851d2cf3dadc3edce15be490eaa845ba553fc6e8746e52915e655af4b86c629d4c522783635d464a2825777d89d7097677ef0e5eeae38537ecb656e3b28dd07358fd9fb2cd462517286659aefc79d374d1d13ed93967c530cdea4f314a0f91d6289b4c7a4279b6f4c4abca33357f69ed84b9119637adb7c18e694cb3c56e73637da910735d43c38aa8086675a06ad370e5726881da5e1a1dc6144d6a62aff7fb0c352d88dc971a3d72d3071e14b47425356af1b019233538261451a99a6cf4a07ce9ab1c3990de6ab8de2116c756105c512b7a3eeb3157b158b321e444e806d890b3890ed9ddc869f1711723bb99a72bdb923d131ba4edbfbb6dae99a5c7b328d310df9a6d1dcd85918962833e89e20f5c5e6333ac861094ae9e799c8641b9baea11a2e0ec234be5930e02880859cdec0d978237cbea5c7c32c111bafdd4bfbffe4fb3485effecd51bd195a71404ca5b59afa252d7b5ff9d030f48c6faadbdba918f21a0cd39af56966dccfa25fb5a5cf9a4b26a7f5441df6e320e34b27393de2ecfbd69a1594909a6c685ec645fcf3048d0148fa38d3e8a64dc3c21ae44da7e46a5ea7936c2ba083689a78ca3ac60b87be6d23ea40f5961583742842e37525a49c5fe8fd15d7b0c9e8fccd07936d19538212f7373dbbf3df7d46adf9d9f5db09524c65b883ae6f6cefa24b19ec48ce28cfa734d9bd6e77837d1a14d6a19d345bfbea559e7e6bfb71ddad83cd8deeab687fe73c057488f8f2b3e2e26d13009f4d23e6619a23c0692af76669217d5ebd46085b398890e5c91fdb4db5ba40e7773d518d3cf00c0a5b5a4b0f1b85d62916a59e5607b7b1eb80
+SIG: e55f8d304122dc175cf0274674fc9dedfec2b5f8a2eeb1e3e7f8e0dfba0dac2d32f4e704ce91cd599184133c3bf1063d2fae63d73acc5772d718d81183318602
+
+TST: 665
+SK:  e9cf16d696f63b59e5e25c9ee2d75bb05ed2baa591a7557f9fb129cf983de0ba
+PK:  6d1ae385e80a3955e8d0c593a81f431cd432671e78cdbafe83fe58dbcdb98560
+MSG: a10fea8fc93eccfe2a6b7826079563adf8aa9a666444932200cca9447dd027c5c7204ea62bf8f5e2e39145ac3948ab3f3186887b30bc60233024b483f3f519036a3e94c8d7510a853ac6e20c6e526ee3cdb76de663f67305ad80df2342c8501b4f4a8ee3665a798fc437dd814e4e47e7a466890e0ffa8f510f3e6e19c9c969f70a76e5cf3054d17de459ac8ee99550bd38319f36e433434a926ad68b961e0ca10add4ba992b3650660a2c3c26f5d740a31afb7763f542f723b8a3c92d8ae92a567764efc70530312baabdd3fbbd527fe0fcbca3f6a7064cdde1856e97ab786af7d7022a9d46a338e8e1754afd9adac856a38de2a4c9766dee8dbc709b0671a6a6e6e1e5d12074d22245cd73beeeb1bd8ecfc1e85a21bde253f7c465abc1feaa961c0ff5cff2d896472ae17ab8488e33ffefdb72c105e204f944ada51ee13981a136c0f38426e3e49b0e91841c32794d52f1335dfa637f151c7e40f9b830aed539ac5731b81cde3264d22bead31a6cc68d1a73143b5ba4816139232f3f7f97983f4ecba64c49553be9d6d943f91dfe03d1ee8618cd40d2fb7238a31d1bc38e76a551f9eee22e73a27d7a48b408772ea72c3ed637bb4b168f9d7aead94ea03bc11109901c889927d51cdacf962125962559979d3e4c8e3b5ae582f2dbad4998802856c4df69e8fb54917e2f36bb67a19a26e9a9a9485bce98dbfff0d2b02b9377a9137a734e57b5ce665053017e992677a1aa079240d2cf963cdf9bfea8d460091232daf89801fd75171a6195a5c046815914be1f62868783d6f2cf28af9378d6c6893e75de641111c684727effa31b8bc9b0a01db9c9e81ccd8f4d4e875d4bd90d253f58989a8a52a203a77a496d697986b031e9f699bc6a16cd5f9c36018ebdaa36bad0e014f4cf3b4b746171bf89314e8b72cbd47cc616a
+SIG: 8112ac37eafb749d3f4a1ea1484379df3e383b019c12de8515e349e4f6f998632e30968347a1d15b09da2eb800b03d819d202bd10a6a463bb02b366d6855fe0e
+
+TST: 666
+SK:  238a6d4979321a14a997236f4585046cf7a05c0adc6ba1fdb19ec2a32f62beeb
+PK:  0b4ba674e401665b6790cfda080704cd90e2f3d3efab253ed8dcfbd18e406789
+MSG: 97cd619a2251eda916646431d4cd1598c2d44d06af3e48bd18e3de7fb4bd4f78e00a69eeabde3f82065cfee6cd711f07d22637161ff685f65a7ddf54553197fd31c5c6b71d9e365a941dce4c3e225d19cc633a7e12862cd23ebb7c74a704850f761ac0241be517ce7c360936ce07250d9f2eb2787115eec377e1134dc08f44eb0a2a2a2716f00144a49f012a57b3cd06efeb3fae920f285cffd9a401a0b986594e17b2c9c8fdab835d9f3f5d474be733c1925ee6f09386711066c3fcd645eeb0fbe7054169eb709d4a3f0d16f28a1ff5066c842bc63e359e92485b38757ff46c27f79d0cdcf0e16e97e3c7b7e2178dffd270282dd61205d5854d841f0e3fc0e482cc1ee48552cfe658935b5427c366230aef79aef4021d6fab5f1875cc849e321a75500e9e1ba5dd596b438cf88b235b01a67625c4bf84d0724ae6880a3785e33bd9235fd0f5981804d21cbd633cb180f34456460207a290a254d9fe61063d40634ca3872f0935fa28328795ca41b006a2111fc5932b1e779ce966cc47adb7c0dd987333ba7529a1a4996ce9f56e051981fe1f553e578f43c3ba94beacc93c3e739667c7a7c6fa27e1e081695d20ba705c3f10b20df530cbb0ecb87456501109687019318452785d38e766b3cd35b007d7e3cfe0b2cca8aa6ef7395599dcb9c4d28bcc35c76dfc35343cb1348ba3e962f10ee86f86f5b6d4cae2e8c2b185e3eaa1aeb87bcfcf2fb76cc7fcc6895071b168e8b7f6caa0fd6398e778cc07912ff5d6e61021a8a59ae0352160f56d5488fe2f2acc9403da9a9ffc661c1e9dc5be88c420db0fd77d845dc8dd9d8e58f9961b79afc68624baa86aa643a8a3c7edf71d553cc0d3224a6069ec674f52da29a1cb60c4192301a24347a8aa8326269e0a14780c9583cdff515927fd5bef528f9d23787aeb803d70eb916b
+SIG: 2942f708c0ede4cb0ddef13b85d71d7213e0383dd294f534135fd69cafbcfc0e33090a2a0ca3fa572c72cdf5592de903b1584495ab63998150f2b393a3b3400c
+
+TST: 667
+SK:  59d501393dc5999723810706fad7d6efd163c44710c741c185c27e0425e3c05b
+PK:  8265d43cfb0735b5d7250fcf0fcbd154bfc0eecb13b7ad93b6b02940588b843b
+MSG: 564ed22c172f5c3afbb0b95ad2fc64e4be6d4db1ebb8d399c43a5e16048e7f8732181e5d0eed8e638ef2a55aa0d7b681fe02bb5423af94bd352d3c2ddec0f84760a4112b4fe017cfbc502f9543cfa41fb2aae75a3a081f8c499033d1fae5d9c50cb44dbc63605a54398fbf079852eba86f2fdfc272d0c4179d7c13cbc1c2a3da0b82845cf1a46ebbe31e79b6009733c7bfe7aa4f9ffd719c77dc7d748e492e14ee5e4179bfa9e649cf0d89534186385ee99410051d6656e623438cc7b2e707e48c84915549ae8d67a306c67b106b7a25f45f8e10dd7dd3eaac31f1052257eb6a7576b685cb9e6c1cd0d73c7a3ced5a8dd27308ae00f95eabdae9d1c4aa8934e2424c9328a5228f4f82dd4a66556d8217c5a22b2beb86a2a43413ee5e10f883f2cd6c2e8749b5508842ecae5ffccb796d9633e87ef4a96c0df7ef47b283d096723ba3135bad75b2e19ec04f70a478428ad5d0aac0dd2ab9905913e7e5ade408801d5d3c54d9cf7b8f0f0c5eb054c1475cc210a2c798d8bd89932ff9f360421858053a707b8bbd32055c44b20712a2678a9a6af9e36d04dcff44f431cf1930cd18fc935d2267775c69096725ed89a291dd60e21ac0b0128734072992823ef87b5efa6cc5b050177f55f4cec92a08a65bcadcab9a41c36086370b7b9dd6298ac7b0ae6a09c9710abb4676a8fc87a3651290144b6b30ef4f6fbe5b9ad25237fe0605e3b9f18a7718ac9fca6f325ea55f49a807fb80a2402ae13423080d327758649023798d5728e0dc64ac88a6e2945dbb3e3ffa9fdb4c7b58fba3f5fbd67c686b2971bbd8ba4d275d573eb796eb9146775d8cdcd5fd3eb5a88ea5a930ec3244e6a37c81f6a2554e5ba787f0e45319fe4b8a2ffbfed50770e7827b3e7bc2b44ce512ae6051b6f9f13931ea6acc096b8dcb0196be422484db5fcb299d
+SIG: e646f164cfed8c2e060710dcfbc3e9fa5eb396376813190184e346f52bb0ba5746ccb6b59522b1aff9830f2f98b9e5dafcd832077883c44e8a35388f718bf40c
+
+TST: 668
+SK:  839fb132e69250ca1ad94510087f92ce068769213a19b2a6c89490f1f578807a
+PK:  eb586619b44a15379acc4621a2ac71ea58970026c28e2409fc1ba2bd8b236d1d
+MSG: c57232fe32f11e894b437d40456207cc306db48169b20e0781103affe802f5aabe8582952ca8e95745e9940d535e00ff65ab3c64bed3d1173a0f3d70ce4ebe2b50d048bb47164d2a2cd9d95a10cf0d073ed1c41b3de333528ee32968223a0d847cadbb5b69f382164e9a28d23ec9bde9a828e8771c9eb49220af54185508aa073a839195f103bc2f32fe04f951ca45bfbf30d2fb8114056a736addf27ecd9af0f6e5e97e5773c4fa902268c32a151410955f3c76aae255549e0f033f89e1a78f265cbab6beb7516d4badc49cda4588316225b4c85ea9fa99c7d6766e9490c49de59da717f667653530071dd2f0c53e31d8768156feb08faf00db0a04533df97957a84aa46aeb7e36c0b0be69018946f1538a6aea71df536f1442c2444a43a043d046abde1a782b0f4f5c6aa720aa60afed947c0cee477dbec00557b37212d93357ca2b6b6f82715ba0e484f6daf2d0b7a98c033519ce38263586796d5d31cb2bc3d1125bc0ccd329a5c21fd27a218ded607a0e7515b571f192c33f5fba514afe4d458100f3ccba3f38eb430b4fc88faef999fa71eee488228903be29f24df81dc911044e924cdaa017cc7d87e56a6cba8760859bd63dd2d4f581b955ec924a49afb47ca0d63e7826fdc712b4943b739e1857755a33c6503675fddeae062706e34f744fd932648a5608ce608a61995783f3339ca3fe107e1972744bf6d4edafbf47ce021e05821fb124c7083930e68e6f5c32d2d9fc4a884c0bc88404e4cfe3c1a2420d41823a385fb3288db65c89545f6e73f0d8004b2ba12a4e07727523ef085670daffaf41c28a4c1157bdd245e68750dd200e023af90c67561e0fe4ba340c433f755eefabd4b039bfc323dc11adb75aecc448a869c7f2a58b9d8617c64b8f89fc583f8c948e2df0251a6c7d8c738c3b5a42b749ad5e8e986bd8
+SIG: 66437b6bc05e75dd1626c3c4ff1f72e6db381ba1590948f8f16ad4d66e5991659aa84405568cfbc0a77c025e59e43fd53ab9ffabba7b258f78796239f90d4501
+
+TST: 669
+SK:  adc1e56c3ac94e6cda0411cbc3ce2af128d185a2a273bdb2af8d7e50fb96b526
+PK:  5dcfec1f9112751564ecb60715ebb2c517b5ec37b2534fd6329924429b7fd5c5
+MSG: d4f959474e0b89e2dcd02066984f88d739dd1134a33309f0a8b7802eaf013303c13515dfeb461ea3d248e998b9a4e54dae5b00190a45e70dc67e98f3d4cf906c214d4f636d2952925e22b1a86a1aabb3a892a9f8ed454f39c63d35b71e87a2da55a8e167ac83a866ad167a17aed183c08518c15e6be34858b4cee2b8427314760fffddd5923854b1747f796e1a5249fb3044894ed646829f654316ee52f4010c8dd321fa1dec397e50145ed9e31686fd5203f7233b8da780acaa91ee0b5b47207866aad85f837e03b4e6f6de8c04acafd707bdc1dd45500ab564801bee9a58ece360d004828baaf523e2f5ab69326a03aabe010878fd43ffaa56872244d7681f1618e623e3d474c73af8b080a61821a574ef2fd752d23b605ec521c19c1550de980c094d05e0238f3e008e6b195abfdd4028ee1ee1d6c66a76f178f0b431e4af44ddccfc5290edff36ece63e8385567013f43a2aebb67e3ef406308c20488a76d58a214f3139d983b19afb12e3283607fd75107bd31feb6256174b7a18aecac9f8562582018b0e6de40535e35bef2b562553885129397562900d3417f98cdd1e29d731ff48933f2952958163ba67d59561811b83772bd05710b6e3cc0434609937507223abb71a6a8c838fecdb1d2d37c95dc806f65f3f9663d99f06e6c0f3c32e95af1dd708e81108636a26b968e98339c74128b6cf671335884ac72f75b637195ea9eca053608996c32ed445410f67fa104b39f0fdf3c9b5c6157b76803756b27f4c3ba1b47f328576248e9bc53e7b8ab0b2ed97c2f9998bcc7dfe39e264aad30c6cfef2b5553ffb5a699aa4bd0eabe438ce0522cc91fe4e72bf7eacba4771ccf63a37aafcadbfbf99dd76b85b80ee075d3a7d1a90a55b7729a5416e5be696bf9fb7f3158cfdb5cfdacdde8172ee1ab9486e24ccead29b457acf43
+SIG: f02e5dbcb68704afad03aca81061dbdb998570049f10ce650ec7a2eff15c793ddf5a272cb683c22c87257c59bdef39efea79bd679556ea1505ed0036cb46040c
+
+TST: 670
+SK:  db89df6a23d890b7f00260e81f4ad98fd09440365131e85e22c7951a187b0218
+PK:  c96763672ee4a2cc5a93b6a683df9b5de4d9386a790835681d1217d19296bdc8
+MSG: 54c1c5111e08c98245ba4f1318ba1db1dcc74d14a5c98ab9689cba1c802c68bcfc81fd87ffc61caa942f66d7e5157f65538c7e7b33170484b4b6543f3620ff29638b64d4dae7b02221cf7783f187ec4231e6b6946d82762074f09c32781c2f3846de3e8217f6e1b6e0d2b5595d742e2c4e325a2841924044dfcf12b479eb69f1bbd40eabddd1ff54a9184d366dff9d8f2d863e378a41f10cd1dae922cd7fbb2a544e47eabf47ca0a38abba34454919bb9a4ef044bfb97b708c2f7428d68f9c57c0ee7e7925f7a2b5c6e7df82bb2680c862dc7cc68b0f54530e64afe2763d9c7baf45cc6fe612d1f7827739c4411398888f7367c3d4377907acc06a06f93f887226798f48aa5464f601c2c1edda77edfeb9b9b5d5f9cb6fed37900547477fca1d09ab52d63e491feb12fd6dc805a78cee3baade4352982061dea5a2653db8e7607772e834b3a505c16dd6e7c71b911e842eba925d77a33c5c57ce1184098078ca2e6a3f69aa6a14639dc97b4b30c99dc4fa3e2cf63c701c306c5e253c5113854c185ebc8b4798f68d1fd780054d3eed2f394c454304966bddbd12280834ec9b40c1e98bc2d98f4845f6eb44f25315eedb3b79ffca4180c1bddd97d0c9affbac58814937682680076fe5a3babb65d28f2517036c0cfb42f0293eb2acb13949fe91e0ad0678aa243d7734a89d997870bf9a6a584ed6e628163e39d8aa610d46b9285b9e1dd7e8f807fdf5ca2bbf6de5e5e68af7cb7ebd43ecce227cd70c7bf4ee1433edfcfe886614670cdd196343fb91e15416d2f6acbae3eadc030231ee9d2ecc52a88ce8dc7d098e7fac77685b4eb540e3019307143221b8ef77f3632c893d556e0bb743a1963ec15886c8545e87c95cc825f200d0f3cf4f55a3d660a536a23aefcc428a43203485ee84342f5c001ee8404e759017006282ab8ba8903e
+SIG: 80b7fc8b6ae6eece8166b7ea534cb5b214c9ea9973921ed05de40c78e14f162b09e978ca6d86ee434d984b8b0070409dd2ad11b53178e239dab5bc39c7ba460d
+
+TST: 671
+SK:  00e6bb17af3c2df652b34f9abe19f99019074233686c7114e3a0edf08309934f
+PK:  7b8232a66cec2f915aaa7951d29d2b9ee93d321d15b203c51e61e8ce83d187f8
+MSG: 063281e41e8ba9703ed09ef3bf0ea46e4cabdd6ebd769d05dc045d4f990d69fc554130a4e61aa21e2de4c92db48a20a37b1747a7eac5ebb2735a8938197f139fad1497b351ad064c0f18f8faf1fe11f63979a69968e24cf91e58a3ab032669e4efee274f96b58be7d9e391f36fcf0709b2cb2d22694a6ceb17246945ebb3bc7f0f03bf0b08dc9626e3e715c991671d53ebb9ae83a7d08d44f63635c40f8d4817f58de9eb77cb25b2acd6def969ab569e974a8adac11a86b58fe6c10067499fc914dff56902cbc393a71cc25e8f05c03c94f13b84a2b01a58c10dbcbb60ebcee487f529177466299925da50e2da5b5557f0aeee3fd7f47b5c2e3f84cefab4679691394dd122303bb769afb3adfe8358b02b679273b35abdc6402576ccce5e10442a137ef9456939b289ef4e417b1cc6239f7ceedd68f1a8264180e068b4966fd67f2bad6edd8b4a1e8d2b542daf26db831f1fb51eb86ffadeccd9ac3d664f346e7d046c33a572841ea8334e7f2f417a05712a9e334e487fd3ae175455162fe8f49cc026a640c6cf93cf58875052f41cc9820615653ea2d084c896eafe5ad4725579653084994f956d5c94590a2409581b6fc86e40aa58bf6e6057a6f90af3b87aeaf32994a55a54f79bdf3dbbf5ce0ff812e486b0545d9e9c2b0bce0d4c3647b1827262498834e198a3ec70f3b03d6aad2c49eb80b5e2051439225fd9ce9468d69af70a262ee3b8b62a8e5b41346da3012ffb45816b7becb0e79a60bff71636a3e4bb1b35caf195f55117280f787217b3caa2e793726fc5a74d1160dcad868904c197381134ed8c3db3750b7556f69ccce18b77388b58c5b8113e590ad6eac5b91ece5a6705025c80353ceb1ed84aaa1cc48a416bc016aef173bb80b2ba28c57960c6b011b6b495a3f3311e79fe46bdb6a4c381fb9dc4628b0a83023558f1
+SIG: 04b3b8501e396c4a788e14ac49f6174cdb5c855e651203cf68d1efa89aa58678d4d1f303a9877a3786d203c355b09d5286c1ca0df04a89aa06cc3f9d0fd30504
+
+TST: 672
+SK:  fbddf6e61e20d806e55917756de60d0c9a99976f646716ff2ff1312c54dd971d
+PK:  ac538fabad4380e60e977126e7695eeda5417d85f7d23db21bd0ad111116f05d
+MSG: 3e9953ca55d0cd233b98833eb1bc79d3b55f18c8fa1c42027bca25579153b55da0c5a178b8386956d9a54183b24c91dc4be994847237d3666a0a0130fe19924bc0ee50896c35a2e16a29e2e2acf180bdd9379354687f0ece6882d26e980e686698043bb1b01213aa644a4f8d61f9b613e62eaa3576cea0b0b83f05ce2558ff6356495c45ede4a8f65b814ab8a7309403dfd43cbea90893939b7800aa00232b5f6b7714ebdcd8bcf34a5a7e822ac7b1b099ac615f135f8c351dc41ae5f66d5f9c2600454ca01c009ba6de04162ae5f1f270893ca3907aff7f78e03396e32b622ff340537bf123e55995e9209609330b2eee51127484a40e250700823feb0bc97bb509ff732675dec32ecb635ed92c7d78fe3050200cf1d941d6b388800a8419d96a595eced5ec4efdcb6f987f5472a5c43058d3a3a7bb56d7980365ed43dbc2be48f1d18ce76a89185426fd5c69df7e9291ab7823c23a76941ed3836aac7b58c0d5fb6b636c42471a4d1703516f03e935f31f195450e537b2a07d545ba4b68afb0638c65bb0ffaa0cfd69d7104819796619d483a0245b4fd9017f62a7d3a5fc3b7289d75735f287ca0a951ad58344b2ab7d7df8dbd7922a5abb8d7c2e79147e6d36ee31f930473b0727dcfd58d644d7d70a0ed31ca6a13ed9dbd224492efda19e4f8eed46180fe750f07bbe8e99854d13f58ba968ce3859d61189cd2b667f3b2d0665b574c4bac19d9e37e5b7a80eb334e36810530aa5d1766393f8115a52090c91823428c897a5f35e12a8af2cd4fb13907ca6603a4f76f5c2e02374a8dc3a47c1be6f1d1c8ebc59b36d1cfa0ab23e9b0ae9b0e637eeedb9c66bea62dc630cdefa718239617e3118e5b6deb7c294475282e8abe24fd5a54b786fff9028c5a033384e4bc8014dec8da100a94b178ef88ec357b66d2b9098ab64791696b1a66b
+SIG: 8c9b77aa0f1cf52e8f7a918b21b468e62335911bc59306b30ce77bf692c11059b0ee9c5daaf6839bb81373c61d28d072702b595e4dce28cb993822b24813040b
+
+TST: 673
+SK:  8a55e77bb0c8740b8c2e8ddfdfdb40f27e45fe81fe457111bf1c8730eab616b4
+PK:  9ff1fd0c50eb24f99fe2f7711d52872dfc900380dddcdb86fe6f4a5f350a8743
+MSG: 20fb414e264a954784f112bace7e0474b39cb3c9e53dee0a21f4cf6d4a99b9347ddffbe281a6c230a75d63a72fd05f6db53ea7014ef7709d18ff970f485fe83ba1d37147338aded6da4cfdacc1e69d2f3e0ef362f47b5bcfb78a1e179eb5c5b106c8d82a0a0b290df075ab27436929cde656f02309f95750eb676583262e5f2f69f0ff72a8e057266382269205318740bfe06bf5c2cb4533908ef9f9f2869a75b9533579820e3bc0caffd646171c8286c3a4aba1ff0915d93611205e230f39ff4c4caf3f333e753fce2b71213e53d608415ee17fd48212eedd8840f337101ef0d0b6f7be4bffc06eeefe8066dd27a0541a468831acddc4902e2fefefbed19c308e5621e0bf46bcd538aa13faf04d380759c0e107e912001839dfd0b635440e9638f5377ca8450f350c01129ee33764415c53cb2ffbf968df78b742fd0665e78a34abf4decd1fd386289a1364e64555eec58b0af9a4cd6b36d1d5c611a2846dfb5589344bbbb02560241b74b993a25bef50fb1e7319086e6a23986300834ed2dba98a168721c2f784dfb8d3800d06a054aef14d1772b6c574af2563d193ef2e51bdc62d2abce2eebeada79203498e6686c287f37bd88aeb166f7dffc3e6ad0294117ef6ee9da8479ed8a16fe9be246d266804f29658db75e7a0873be71dc7d407e39fabd66f988b457477427fad8130f09ab665f1597c9046e7373af9a8352a86830cb92a804488700fe6891924fe2a7201733d95e591ee0a1fef1c2636078d370e7ad3b6a944fed2cf2b30aba2d56f3495b2849c03bb614f48bc4e507c395a6c35d3eed4c7be8e680f2d45a310b187eb88cf0e8ed4de7d37246a50a6367b97ee3784322c0b71131a283198da4804de751dcf70c4bad00dd98d873a69dd1a09cf69ddfad7ae603500b6a462258098d8b66b85293594e208829b5228fae2fafc39
+SIG: 8aaeba535c511c31d3f8e95cb077a9a7ec7d08441e5342a6abe0bf2a5d7fc930b43dac3d1e8ef2cb034552eb4d0839bc8bf294551dd2d80c53fd6279351ac20c
+
+TST: 674
+SK:  163b0cb6a12e8f07b0c29d6a63f6a652ce497270b5e46fcf833c99bd843f8c64
+PK:  68a35de4ba6f0f82ecf4b1e0df8e24cb4f18f2103ff04dc1b5333991b6d314ba
+MSG: 56a1603f725be07613058cdb3acdc52354e3bb1ff2bed13f895175b15c8c5a90ffbe46b11a06cfe362dadf7323c940417255aa7aa54312103e71463daa0b5cdaebd0be723c732273e3c3f5bf7aa3519d69df6f4770daa1df8280bb3cd2c714ac030200546579f56c60b91ae11f4cf874a35fc59b354bed80f56e11a6cd62a88ce6b4f6bf39d64ce3d80409825f90162c3d96d10e478607365f7a241e71af980042fec2d68891e0c8a37c58ec4e600fd581e790b0aae8e09f35d4cc1876df434b80eee05369f848fc4930577d1684275888f3259cb47376c5169c9937f855a96a9e748ad0a69ae4ab2f2f1744a392f9acc6209975b784984cb12f98292c36a53221994abc56f9a66dae4560b79356ff47e128c0796a7fb0e0bbc9600af48e49eaa9427cf6eb6620b10cd2c085b0b342004d5b0d3edc11d29242a4638780762c9dc6069b66bd84973b5011961ce56db58bdaf48e6be12ab9ad24416297004d02914b959f54e092f8cd4365fa6ab78ddbff4ce8dad4e2f53a05c0cc499bfb47814a2713551dcd19d447f627576ea4ea4bbda8bae18a6465ced747ea17180b009f01212160482b0433aac68e67644d00f41fdf9990b9e11117634deb139b1a40ad3fce4299a17fe1dd225301c7f8d8010a796dc79c13307d3ff992a88be664d4c886d68ca9e4470cfbe63ebffc424010e372b6922aa95c801d1e9406da4bc188ca82066405bcdb3eafc937629b3263dc7d50ee5278ccec6f11d5517f56bc269c873691e7eb53faeff07564ab46b403f15d9e0e692486ee098e7b51b42813469b8235042233ca3f9c4f8ff24a571f47e0adf9144aea488a2d2dd001e31fc961e05c3e85f0d981407c873158bb0d35bafe4b60422e67551e970165ce3fc599d0fcc92b16ac36a92b2c1dc6b3f033fe310cd196da04a4e639031177cd27d7c2fbec65a00b
+SIG: 17738f5726550780651d60199fda39d9c4768db5917e32393631c54a419d59f18ef960ddd439380dabc314761bd0cdb57cce481e6109fed095dea6e865aa670b
+
+TST: 675
+SK:  8c839381b6a7ce2649c1ea464ae3c2d3fdb1ec666d7b4be4e2a941ab6d6557a7
+PK:  5c724a30c6fb32815343a80ddee6eee544516418ea95e1bac80afc8040d63fc6
+MSG: cbcf89c3548964c38d70fd8f68e8ece36cc39755c971d14d7e056f39b023ef166d17f2438522f010d6d835d886e71f474c6727a4221fd03a7574578289ed5493ac4c0947e3f428d8fe064006a256cef21811d72678f5dfc6ba66ac29ecd1b32ff5557cb08c5f130559217a0413b759c24d83388a2bb9b29b6b91d1f3101ed625211e4d73805193478cf995396c10b1c5affacb00899da04e3cce193b494e2a933c4eebe0a37bfb8f1b8371bde5fda09e804e940f344896a529467adee45a8febf85ab036cab880143be4f59b7741d8e450278b06365578d40b19dcecc6e1ee3da34ab29013fa3af7729272962110e385ab9a022fae4146f89716f7bab9d3dc682f4fac7736d3e08973c685bbb275bbf8f217419e5cae0219eba5166a5de1b11e3f9a908b8ac7e65bcd623f8c18bb024f605dcbacda790d8362957444a95c130a37ee9d563d0cbb4cb2b0ff71591d9390b6c8fc28753a0e402d6487cfac607135927d89267512b34f877057d9271bccc024dfedccc6c32edf75c8b7551cdf80154ee8e08a0cc43044e1036bae017eb48b6502c7a9d60c8b370cf3799c464f964a69ee659501223e789a6497b63496df1ada2e808d2434fc8bb9794e5e2a20bbf4d6925cb3c5bb14842f19200905ba9354e00dc33cff5b42d4e9d9668b34e661d44bef76fefe2ed51f94423a933ac94f1523bf37823a238d616c6b17973441e35f9405a04d99eaa8f504534c8b5fa5e8e335c743bcf21f5d492b7112e00fd8642cb12bfec849df62120dbb06bfc2946a5601e25be75011c6f00c65d35f44a46af9e4f7809e5789a3a61ba0a3b213890497296c81e42e88f0ec0f5defc1f5d39ff2a48b7e3026c9e547202edc7eb738c34ad3a15d373ef82a4c1d181f285a98bd3314c2c1947c9e2c60aca51750ee7f943caf0c4e1e5c7df7291e973b1f936b73707619
+SIG: 5d2110d1d2f3edd683bdfdbea3ffa7cf5528a40b8b3d8d8c9bfd22aeac28bad471666e062f7d38ceda8bb37397a1c5c3f733b537967045706478437d4d187a0a
+
+TST: 676
+SK:  aabbb2efedb599424a5f3e08f90fa8826c5c92170be501a1181fe8e8df974e0e
+PK:  ce7319ef88b242420666ca697ba8501d274ec4a5dcf844596608b9dd5a8a3acd
+MSG: fcc15cc57970569e9ccfa5a778fc7aed71978a3f5624577b6f57fa3f167ea223ef31764c488d059d06531d016bcb17d544d46977aa241f8e07af4787a0810f98d766460c0841ad81b88f4d5d8164485a1258a94622c5492428d6d575943715766c2b0a865bedba167d5d340edb579c47aa32459b8fc98a79bb0bed1c960b4ccb7f2d4b5681a2a70d505b85b81e3d99672714e4eab41f3ab0ca874f417186feb69ed13fb911f49d1584758b2d18b4673edfae495e68dad513a7ac0d47b2753cb4eda78fb431f04dda8fe8030d7bb4e8dbccb969d7f580d9c1ef935d074d7a41d1f8b9dc45c9a2e4106a5529a98b95529ab0edea0b5722dd686f5a7f3cd8fb2624ab26c42df11f510a103d8a929830ad85f52124e3d5827ba60bfbcd736cb6c590ee777ead7aa2224d7ae46d257a90407247960c9cb03860aeaa7f54c1a8e11160d11bb473065e19b70721c8f072e1909d539e9ac94185904bbbfe54873754ae1ca7bced6f40561af4b505f03ac972a6f0bfa73b5f832fe23b898b2bbb0574a6662ee93b3b360da1ec7e838eb2c77c7cb7fc164f7c4627010489c858900752c92d9d75ad547167e4bdd11a07d28b651aa30f16a850e060dd2882fb820919a398e805eb63699f4ff595f991524731641ece25fb3f8e89ada501192b1eddaecbacc8b898528f2d5b3312694f5ec2dc9142e1513f777a5c833409c171633ff9fa2609d0497f5df4fbf48ef2b77d55e25519d2ee79b5fe9d8fa46000decdb4f25dfb3f2bafb19fbe2cbdac002a359a954bc69bdfe2fb36adfd9a1509f3e3a4c6b1f3f36e7cf80d583d440ff2a144643098974d71493ecb6417c0b8065bd2c21c1e34af09243fb49e9d35297eb0a52d56dd270fea6dc5c080a05599f78581e90fd8cc4cd11a505edde84b892d8953bdbb2379d33aad64658ae20607dd35b0bf3a2637d20c3f86
+SIG: a0b19cfa6c80de77bfcd321030bf8c03893e2b21ace6c6ba1ff7408e6ff07d847e6b2b688d4fd51aa932701db6402ef22322e6e9fc7e320abb4d24e1acc6cf06
+
+TST: 677
+SK:  c2e074faa234e99ab20adbbeae11b8109723b708c54586df652b402c35cdd127
+PK:  5e524ece1c696e705a3514dd0082b840795a59c36a96cbc482bff5ab4ef515d1
+MSG: 31290338e46d1cc25ce99cbacc40160341b785823c823c4ab9baee3b612579f1c011716796e56e2693f6ddad43922aa7847cbb4148101651bbe62d50be90825e8eab777aa4b8026dc5385a97d3df76160191f922cdd2f07ba5f85e95f45db22928f90734ff520c44dc8fe3903b4c51cd23e064f01c829ec74fbffe25fd0d369d2765740f43856bd7398a1911ad749836160fd98d04b28ee87e111d40718b5a166f05c9a471a41566557069f7a14de988bbbf6777521fcba6dd65de4c06674a11853af83accb70fb328dd8fd6105a7df5269c9faec8d900147e928d970c36cd834bd6054f70650dface94b7629d16e3703d766ce7638d0ad1e17b77469b958d2ba2a1e631a1635efdcb006ebc6e5d8b9faf7e5fb989dc0896c561a26f3c25f055716b367138ea5da1f81dc72cff7a55afaee5839ef5aa822b2970aa18a8982163bf5eed1b677ccaac1224ff6c6cf256374780ae65803bf5c6e23c80bacd76ec3e2ddd3ab71997506448e19db198efadc9f757491f1b0972c82db29410e1e8bb67bbb23d53563b8807e5e0c2e32ee596b5b4402328f9e179e9ce856d3bd199d58de6c5c252e7a6124d81fc9eeaf23d347d2ab88917aa684450dd58303516c1a4d2bdcdde220c9ae3790f298d7d384b70c2fe258807848fc35320b578b33503b75f38a1df630bd33e6a85a4dd4df9f6e55a6e6867c73801e593e1d591db89ba9a9af0fc292e06fb515ac8a5e8e343a821335575ba48fbaae3fb12deeaaee60f4b3d317ec0a554ddd425c84932c27a7a12f29d6371510783bd75e60e2f6da20052069ed71e695a943182193cb6851a7d2fa3c666c193028015ac8b7e7daa6c5204f77a6232b88b4abffc5362fde7dec36b9d454880849283b1156339ea2e8c3b10e51bfabdf72578c726419a38542cf8649df9a0909f582debad5fd89d8c81f83d9e423e7503
+SIG: 657c3826b3483fd42ab6df869d1b77a8c4df67a6a590c7c6772969e3df3312ae0654fb83847af221935a0512291636ec0595700879ebdba8a1467c53d40c2306
+
+TST: 678
+SK:  b9da4e6af07e398ab4d21752a32c8ffa9be0c310d35059fb661bd73afa97e2a8
+PK:  f862803c96cc42adc8252884547230b970047b7e5da996260ccc0240ab71a6ec
+MSG: 6b95af0eebb6a08afadaa19621f76a839be80851c6dd315e8276f501995d4ce6d134df5e798ed517a2f0e62aa1d6c98c36ef14bb1e5ddfc98d5a7fcc81140a13c20d2ca0c4b40e6e6a03eed8c899f9d1f792468152199f4b95a432668947a51d7b8e104d8d1f12aacd967e08b08c41c3c8ca3feedaa5b8b63bcec0613864d953d81143ec81425bde29164a0876f23f37ac9ac9473672ce11a08bd5476f6f66d665e9ad617e34eb32ee56ffa459f20d1b9353d7821298545750c6eff3e7d4073dc3185ede0391cce0575f8ba637d800068d9d7e5403ba7038d2db77da144784f2e8ea76aedfe521e7dc6a674ede35579595993fb20d44b4052783f56c8c0bbd0440b69eabde84468dd13c671fb1bbd5cb022c2a4fcf3542d8b3bb518e5adebddc84e714b13be52c56b282b42ac0892a5459281be7160729f4112c7d99df9be5434f823a9ce0501789de1d550ad50bb18c8d89a33668270bff7b91ff118f5cd9909addde90c024a3ad713915174674f28aaa9f94a322baa543738edab4973312b5bfa12155debcee163cfe2b04ac9c122ac8a4e1bc418c14955d9610455bd945e9793b916267c9c5f9e53ac04518926ec98ecb84a4f0445dcb1236c76c3a678c69abe4e92c22971d62217201a1bdf05c04df8420a3de6a917a85e71e2b9725e77b522915d4c9946077637c2d8813f010b9491cf0eddc3d4668cc0f8bc8a683579be543934da2853a16f5715724f779819f44439e1debcaa4270d9b8594ba4c86e1063b3ce479d71a5409bef27ef4e5c1d1c96e8be13865af7bb43f09162ccbc83a2ca9e9b8a2324e6d996575eefed37ef49908185738b8eae43f8adca330c99bc66cc1fd52c530d7371c60869ce42c197dca0ad128b85f61c8758f0d542f3d3298b65e93c6e8a68fa0e9a1d5e8c5fec805b83aff4390e115eb64f3f078a0b9b66c273843fc6c
+SIG: 625e1f42c87434a25d622d80d12532806afb2509332449e696b65e1e5888508f11c4ac25f59b8d94d0bf27e4c8d1867007c408da573082dcf19d15a9d5cccb0c
+
+TST: 679
+SK:  143f7b4247d549f6b7c0917266c50f962c28a2ea24762f537aa06ad15e40b35a
+PK:  c9959f90a2d5feacbae2c4c803ded5deab86987637064337aa2a0b0ddef2fd86
+MSG: e274202347a0d057a48bf2a1f6e9f6cb4256079d800374093c020cbf520e5fa27fe996ff07f33ad3b21f74ab0cd93c86475ff37cf622d3f9fa4d13bc99f013e8502b24e46cc87c47e6b2c3662b50e979a0f345b784ff21a8a4d92adc65e86e33b4dbe17f528ccdf5b4864664ba94ffdb7c7d2412b438e6e43fa9668147ee3328224d1f52a3f5b54359b4f7fef69af8f867b478f130a147bea42ed39803bcbc2557bca8c3999f1d24f0a6b03c98846011f9ec74f666417b95020eb1fb2fb88b6312e5008cff03e2d77a26aa532d1780b5077f9e8b828674455d6bc957975f7b2a50e7fd7c1612ce02362efa4c555a1eef68ec34a5c006a6da008a31d4193dc2cc647685ad3cfa3bd7c560b7aed45f0f1a3d1b5b362268de532857055ab9d1d5d858d9ae9a759a51bb9478e8f0ee93c984b576b8b4ab460280be3de205a32f1dc3d572923fb213ac1512d80eb5ad5c18944be77fc17def13a61bbd31bc71acc23d250ec5894ebc214cfec0c1b906516d32d836adc838802e8de30dd76df6e61c1bc438b68d2b025a84f211facf3f1384d2612d0faef5d17131cfe0cfe833fe950e479bc29cbe7fd6da0cce307cf0b1bd92c80e878e432f636ea0cd42480c07e8b8e57e69b2f938b78120f6af4abebf7d4b05cacd6eed854491c029755c4e66338993ed2ac25d19a0c5b40f5e32c8a8b1bce369718186c91d60edff24a8377a9969757599067dd31263a06d6a61154781f29611ab812ff82e813739646263704cd6046357a23c045e2407b7a89508259391314f2fbee49aef0855c6e5e63d912a19df15b11ece34e276dcb88bf2f2e4756358f34a0ee3952b686fcd17578a884176d34ea2916c5d9fcd00eb9e0aa9f2cf0f16e2564bfd28b6ab5968b8448f068320e4187160f8665781b1e2ed9d049e1b54a7d72720ff9d4f073051996a9db6f0c6821c424fa51d
+SIG: c1cfae58515713ea728cfa09090e8942f8df18621ba7090e3a3376c3802775a1ecaf436b184978041ebb75226f970df71d6ad353c0fb465023f9e298f64a7002
+
+TST: 680
+SK:  0d1fe9d8b9a2f04c22bbb0edea3833a0ce43339347531fdb67ed513a13d36b39
+PK:  67c49f410f4853293d0c4d39f4c1b3d6c6103c5cfe20a9a59b53932043517369
+MSG: 64217ac841fd4d6459bfc4a49b8801d6929bf19b408e8a53790ceb51ec341f9b46a351e8c2e59d887e1eaccb914231cdca1d3e5c47d166b4cdb9b58c013c59a3bd283ad10f6bd62c0f15f764ce14f3b265f537c63e73b6c4fa65e06ce1e1f4ae0d11489dd2602f95fc402b7712052abc84bdc778c19f10001b4e0d5fbe463090e83ef438fe068f3bb6fbc2c139af0678ed2a11faa1b9e49aaa4620abfc08439fbfe2c61840769e5fda2677f8e2f0a14564f9f504232a9fc0d9da471e67fbc574c3d56d2aeb937a586ed5583556308a998eb1dc476a014f5a08228dbed95a1208bc1d1f5d76b4e8d0b2434b995ad458e429ee6142a0c971768cc40c40bcb08e9603f09611474471b3859d7fd584219f02657b430e9e56955b3467ac56ff2eab22cc498489036a574120e2db769a3b21500389142c78a87d069f0e2576cafda8cddd7915a9228773d2ac9a075cb387f2a898617213b2cc5059d11941bc4fe58641e7c1750267e53e99c421cb4cf21d098ca2d1f41644f7908983eb174a23a781cf15ef38eb9116eda4123a1522f53b81fb7368e8075fb83859d2cf98d921535a709fafa9873c4a039aae682f7e6286b899257c0924016ca5bf6d3169099211a9a4a6745cdd3198f1337f60928227ce3c7d60960b53dedf011a8940f5c468207a3894bb0872b333ccdec9d5ecd911ecbbb96c9bc4bd4875320e4d3e9c02d9dc76109ec45e61d1cf5ac729f2e34a9647b95bce70b0c633171adaf0dfdb5afba4035b3cce8cb7141ad142bb7add4fc3f961d42d7203754a4e313221d487831e32947da91138ab648b5952ef6956e27aa5d2c175794bf81ef277faa6b905e14502866887d87880606e81b27af01bb263ecf2c5820585ea6ce8d8b391d86fcedadcd11fdbb566fdf147f402010fc35f5157e036146b3736c8a43359127c261f6bf0cad3bd8a34cb1509f7
+SIG: b05725e7371ed0a91ebc89f3c30baa99183763edb4ce34fe901af3731e001cc54f287118915e90365d91aca8feb1708769f9f1d6eef5aa113bee00b5efab2704
+
+TST: 681
+SK:  c10b5ac6055a1ddbca28552e5c72ebd05278c92239b2fcd0c1353651a8e559a0
+PK:  b2183e1b00816d29305f7468e7e45eed3fd8f23c15b305f9fda93e812d65bc27
+MSG: 3594905f9ea464615f41b87abb9d167337f29d45d97f7a1464ec9f2ee50f90f2e67339874d3f2093be9226107701ec1aab941c4e059f1bb26ce86e148d1d9f0da2a2a0f9829a364fb4f13f58b960d0f8d72323283c4490efdf57878645890ff7bc5065dad6e51dd1e5b9a5075150978b3367f1ba84e45ff1f1276c576e4bc72be8aa8e405fc2b27f8146b999845faaa0595d3cb70e5d3712ed54a0fb3e322d45380b5de3609b967b959bca5a583cc520cdcb7bcbb829aa25d7932095ecb303923c2560afc3fd7324b7b7acd089a9f00c03a73d043dc0cf0ba0d8411e2b1b18d21d2a32a726a53059140f784f7cedf2f33cec66fe4ad5cc9eaccbe4ae10036ac3523bac700a113a98b598e6df0304c6fa3212acc04c4e3c7f6687362ef86d617c6dd483f8d80cea66d1951127428a61c1e155a6850bb2afb7f91c82d73eb2b0543ee8fc1f38e1dcdb3c503ddc9ba0812456a5ce2e11d556487a646974a7bbf86e806c58c68c4269a7c9bbcac0ffef9835b33dc449a75479ecd23f6d149c1e5ea8b69208ff36e5fbd68295550318bfa0d3b1d6c1ad4270bcab0904ae53491f9b1ca502e012eed77c427d49a0962f1055125dd7b53733d8528934b5580dd5fd5bbe854978bae3d25bb4ae944e9065e8e2e07946518a6f548e36e056be824d9e02a7a3eaadd37929f58101cb1853be3d7547f58f49e38b018a748d3f19c48582abbdbe953a8a25ba9d365dea835935899c19fb0b51906aa972c5ac45e99c40b3b76e35d327e321e8ae2306a6eb3d8cb6ec2fa5399add19ea0028a01792c08e27c16cf4f85aaaae72f986b099f9ebe4ad0b25d06d3de44a8bfa52844be4a93944833ce2add51bb554b356a7dc49748dd45ae7ec9e8db426c97a25da5edd3b621e4adbde48197a3314de1c50f4d6002027dd7519dde3e15729e486955ac40d9d66876f90668c689d8ab598
+SIG: 8a9a3217fdf0643aaaa5c8fb2a88a556398859b8feefbcb48ccd88e585a167c94dbb5c0cad24d15bcabbc1edb21f02a8c457c56120a3234ac33577b9af2ddc01
+
+TST: 682
+SK:  061bddab280b0fdcb26bfd9a0fc721f68f88343b5d3983a16b6dfaa5e76969f3
+PK:  815578bba6e7070ebdeca117568bd77ebff9e14cb8bc200c32bd87db1fb37d6c
+MSG: ee76b40cd429eac7bc12839ca2f7cd31f1e0098a39c5fc19805be0331f44799e318d12571f06e2993753a3685cd2a96b2301e20024209adc5adf7479ff90c477c3695abb99bd28579dbc7831a192beed0ce17b038b20764800653af7af024e2a104ed0f3e52d4bbd3e109cf126291f49b0a21be433c1c5a2589ea572997f63d2bb3972d532be35a0471ef0573d795c072b6a8685b95e47b09ea9f475d93bf12bbd77b7d2bf5d5bddf0ae02375371d1d799ea9204be389e6a8e5deedcd49202e92df7c3e761f92ef8d79fa738d2c5bc280ed32879832ff2b026424589cdbd52d15b60f2aa3526b898849a34a85ff1c47dc6554b85ac76aa7935cbf3f7bc80ad009192a875ca209b40feb047cc446968f970da47b8cd67da7eb4e54a0e5ab20cb35bc6fb7f13307ce67eb6204a67ce9bb1d139c1b4bd5dbed58010c87bf831e6522ee182dad945804b767c4df2554f15b9e9afd2599ef258c67a22caeb92a57988006bbc72c104fac7e5413cd3d3b802c83e639eafe212a38bb7ef779af1a94ee137f6c60667bc48f27bf4a22241bc44bb6033836239bd6eaf3e2e223187841e4641b0f4e9ff8d5a41ddbeabb4138f6b585ace0fb6b53dc3c9edc0373b6047f27d835e8e246644fd832ccfe0df25c3d7da187c9fa05420d43455f2d08b571929386b59c6e0e10a35601da899b1b4dc3d95b67dd9a83818b0a318bfdda06464b4a42d3cb985f30ec97d6a2af13291155d60cec57cbd58d5cfcb35c18535e8d299b5b007590892ea949d1b137a62b39a436cd7e5b9f8d1b6938dbaa62c2268d459c6220a3e6fcbf80ba0118acd2342563fbdbc1f7c9dba7ea2c072afc8ae2128e3ebca0644ffd8163e80a1a557d9d39034ccd9dbd12c8855a6f9165b0801839cf6e07a9fba4c64d9c099e15410e290e677031b65cf7deb0079bdadc573cc056d7666d95d033a0b6bdba7ec
+SIG: b83297ccdd6d0098ebf5d132d174de1958311a766bcc4da15f864d801f38e09d613e7aa8c336302735d75be4166d73b0184b0e0bc5ef39edbccb6e0e61afeb0c
+
+TST: 683
+SK:  2cab5bf55ffa914e9ad07622190d343ec55c13cd91b388cb7500ffe06df7c180
+PK:  b61e432bb97cbae388a2578a7484998e00e9ad3ddfd6cab8d3a5fc5ba04307c8
+MSG: 2c2d04dc3ad1982359ecd5bc3ee035f3498eedff6104a93c602af2179aeb2cb1f41c5cdb0a77b124f946aa8a824aa3076c2e1acfd48f68070b26276a656b4a4758ab151a6a9c41bd74e09bbd9adcce1e87a0a80d17fd92e85e4bda472c988b6bb1183b7ee59a09d80570466db90dd3749579c4eb19ab75fc152ecdcd68cd1078ef06e593c73516fa8291481a667d3f95bfeb144bab59d6ddc73a2795c1017e09536b3162e4bc58f8ead38957018cfec72badbf22819ab0b406c64730fc73fd9ee61f74187eda91ed4e7993e66884af43ef4c6bf7f7c379e8f0f63dcb8041e26b8b8292b6b6d190e4adf430fa82dd74c57385b919c446db37b5e8767e4a0c95013be89b2bc4e9fd62754a844418400968aed2dd328d7b1dc91e1a2b3009dc7ad140a0686f673168a60e88d80c520fc2dcfc56ca9d4b0c88859099230714dec83d26b4630554dcb9c4901895f78f3834b09766b67a465de8c9490065bf568339243399fdc9d5100324667c5ab28f35c00f6125638e61dab70d1eec48951de0fb3f7b23d3cd982437c63473415bef374a663296f2986b1ae9579b9ffce71ec35eeca116d194f8fba9a45a91bae27ac455db71a6b01a729d0c135fcdcbc23e504a2943c00aa42070519d9cd77ae6754f31eb46a3e5be9eeb3fc8d31ff182da9b087be3462c8459126e862909232fd5f2d89c01815957611e6ae7caa98b6053776a7715c2f93ccf030887030c56c2b8226dae2977995a6d3f1e9d7911a9c9d2a303f0e01f32338efdaf8ee63fc41b25399cffd0b35f7ee5676bd8fd3da2cbee4ae2ea9808d7e73583d99433993146674a4040f42f63d1b3135cc797a8d8f0b88573a32890696cac9439d1e15d196d9090b62b6db7e63c96472d946e668cbda1f4db889300cdcc25e84c9f3857d1d9e53241cf625f3909af1c8aaff4309f68f654b7a15b67711c5b7f9de76775
+SIG: 4cf08f4fabbd06dccbcce2a7a5941fe9afddc4d2d0bc80802e93b12cb135d3acf6511e0fe4113c5e3c5541b27d3a2150a757742ac65f95a9ce6673ff0cd21c0f
+
+TST: 684
+SK:  dd7b59a33d970bef62e0e21a7b6e4c30960686f17f49afdb4a9f4e808e355c7f
+PK:  53a0e57277d9bbeecf99c4d138fd66fafcaec7bc5f567f8320800c4e584ff82e
+MSG: 75580367930518168b0a764d0958bec4fc46cf591999eb3737e42a02ea72d210daad53e54a7c2c134a6d478337d2633368548170edef0d85179f3023e1503868a6e5e2775e412ac05f0589d42a377e75aa6b8f5220a7699ae8aff01094ec469d6361d3e8f38615edcda4d2d5289acf73db6456985780c92e07f62c77a909fb6ef598822062bd572bf7058dcb835ef3443d3e47b5c603d92736dd1df26be4b9283b76e321d55ce2b638cde22577ca59c963c2479556c575ccb0d6d18c804e2eb01ff53581eb040ffd2cc46760737a74672ea6bf78058a6a0a1f5ebf56decbf94b54afb23c11d34179bf0976b4158017d407c95a401fa6f9624d77135eae8141ebea9f35d5f51b3ded995c7f70c025b094adef2b071f971155d7796d613a550d09e7f4dfc34517b3f8fa4393286a2b228017daf2e015387e13527f63661d3c13e78e90fb2955eee345739119b791f05b07c8f42a436efcad1ec5ea10f308f8e23ca98bc65a5fd9393efaafe5cdefba81058170cc5493c00cedf254097435d2e2fde55f866bb82dbdfb9154344974866359167b466caa909b91530c9c7ee8c53fa90164bbd0b1fadbdcd08127f19be5033071518d3cf10ae6bd6f9827e1206f5ec095c1986170e8d5d8e72e57d4228701df2a48c954873056cfdfbaafb10e46a0c1f144b1a0eacdd2cb66bb912ac471787dabe48353859120b03403567c415ddb88fc0d7fba4069bbfef406eed724a11abc041e8e7beb663d0dc99dcef3ac6a149007b42dd1f22a77dd52901814325172224a2778f366fb9eb02c812b842a42842561c68f2ac231c26ce9e8b19ae91ebfad3c0e9f66363a13ecd8b897a3d00a26d257648d56c6747441ca1c6ee99f08ddad25d116dfadab0383000d3d7225cf2eff7076b2adab9522292555f3193206786000d42ca34d708dc04284a94d174cc92f102efddf3148c2996916d4
+SIG: 87294d22d4ad0d0814e2d6d5faf55749e9b39803b4d4b7879e60b777c1fc41584fe15135ba1123ff5f200db35a3468dd4d58dad77bd96ee2b888a5a8b18c3204
+
+TST: 685
+SK:  d880d2fb06262f57ab8778e33d16b473060978a6549cdbcd5586ba8105f5aca8
+PK:  0de486d2115faf2d547266772e430fd9727bdcace6ecbf2fe23ab60f7b5254b1
+MSG: 114743e82a0993cec9705067abd77c168b53677ede5c159fad36f06fc1a14acd77f883799ed9883f9915aea638ec1741f3f4215855fb5b07df3793bbe5b568eb3594391a9ef5727fab93e57469b37de125b1e9f2e6fe2c3d1a10ecf87b6c0a665c6d460a170eefb9bf716cd8faea9764f579ff34ebfa9c4cfb34706d8dd7c9eb1d10b2df460a46bb5789430bf449158b5824f2a3a7b918b33acf2d9ebe90216d1b7cbf4af770c5db95fc62ff3a3c385c3a8217853b7346634aaf30607288db0c483bd4c222eb332cb89dc4a217e6334a268413a390bb371aec355fbe4c736f7da75f9c887541a2b7d0dac018b6138f021e77266ddece8468452ada39f5e63d0209b9d6dabf975413256dcaa15ac14b6068e177056c7bf0f0f7c884a3402032298cd559a6312039400632327f9c0e763e52798cb177da4475e4b2405c157ca427741108d33ed0b7a3f53438ce6b725c6dd5814af51cfa45dbced557f726db130d55cde7533bc2092d6b699c2c870af282731e18d651ae85b3db4ba02853f8c87fd5e3ab69bc57b08b81f83c239ccf22e817e2ada4d0ad14487ed14612c8b0973ec0650a55f6bf9af4ae9256ad3546a3f67dd35d987ef21909a94c50f0ef0640e755b1c4e1a012af0d31766eeb5df31cd104c64eb62eb4efb139cf305769401d213f96a488d5ee7e3ce32b0192ee8f0831bfbe8fe95de956886b524d3319b73fd56dc60e9f1c72d78155a97c6f43697b20466b3e7aebd357b91696e7348f4599b34f3591eddfce2a7bd849ab16f7b43ebb16e23d6f5210efa30ab3ba8d32c40662b8662fd911544bc2458c6569ef75a9b9df6a0f6d80d658ba86b241ca19ce9a6fcf01d3daa95afb59c3d89a18b948621394327fc5e920a75f98f5e2b3d6c95fd852adf567b6d37c54d2970856a599f749e2c55dac7c23e3fb1a63bb4cc47b8b94f3d589ac4beef0aad4e6292f
+SIG: 4c00a71668d3213c29c7041c5a037edf13c6514bd0ebc880c909caff1506a45d27809fb74e6602ea2aad0f842831b74fb3d6900ccc520652da28368fd90ca30e
+
+TST: 686
+SK:  585871941cc282e333d57bbfc3d4aeda862cfa0a375030cd594b3692848c5f00
+PK:  4f343816cd48050b678d3adf70008877c9fcf5cb662cc4ad2b93864c02090707
+MSG: 651c101b3e2dfef0783ce9f61bd0a8bdc9307ac0488b9dd70cd90a7ed8f179a78935556295b91cc2b97211e3b981b8dafcb3d06b76d0b6eda7fc61945c0ee2652c5ac454256496cb82f98cc1cc92d81893b1082b31b47e6d22a2de609de4ce8d7cc4f4a152c47f410d7fc37d38ccd629a4b33e6221896081797d0753dd4faa8a8b44d6c4677166dfb4d5215446360a3c28d8f68e38ab54608b98821b83c187b5393ad874a76f4f5d729493a1fd74cc7719caea991d229c5d0c8c4c5f89d8e4345f4f52214313410b8c06b3315f45ed0c2f9138ab966aec0a645b6dba76380a539123e0f33b97f3d060394a3053581ffdef3e6d36531166b553a9dde03105c04af697d95e95217fd6dc968bf3b448d5f3a8e4f5ae7edc30ec78b1aea4f0db189a949a122138cdfb5f9693db004baed1a421dc44122f327287f727cf989fcae3cf3be3e3dd9b9f53502cf5d9fb186de791d310d122869c9fc3b695dec1607477f3e149e52b63cfdfb0d983e89af2f75a8f489843ec05c5ea5f0e721acab387c68025f20abe0d27b4ce29f4a64fb7f8e8a332873d3ed121fb493414b8cb0c00ad3ab616c5be5241471adee9f8f46974eae84a4a8ce6fabb7f5d9a6b75a7e670456fcdcd1d982e8f827a4bbb69dec7e3053dfe835b70301b7b763f0004bc906e145542f487b4dba2ed561bd1a20306236af4b36e4068e8c007b9454f8741a5f8f079ec1db8835eb6544290d6adb52a70d7675d85df4a9a1255bfd936c331fe51c0977d124b5a506d29c6eec33caa25d8eb28952d6ffb9d6e3da890382d888796d374607f6643b89e7326d9edc49a0f53bdcb8cc76ffd393a7706522d04170036ccb66330dbac9da7e6168caa88cb62181e55a7b6d521a2115e23e202ee2480b587be4501447979a8d736f9012ecf00e67b31e8104f6e7df08a9683cdc89c03a4e37ee22928d45fa19094e0d6e7b40b
+SIG: 298856e570188aefcad81bb970f076965770c26762fe29e6554dc7afcdb801723bf6c763b4ccd65f4e15d7d8ea38fcf67ea9d28590c79255c1cfeba7b5e45a00
+
+TST: 687
+SK:  0588acd4e09ba90274c8f3d1575b2bf364a776884a9aeb4103415e163ba0bf81
+PK:  3ecae697b425d87e34a1d944098e3d32e2c1ec56c3627df80ba2b8a43ddc1903
+MSG: f828f8c9dad298c5b719daa852b17e762598a70f4ecd16a2fc596eb0263899e983d44edcc7bd240cb07610600ae96aac0dfc3be387b616850899b5cf44e1767ffaca3df38158598424f8071414c704e60b422ad77377fa7f6a8c5d0ebc0235e2d43a984f3adf759eb10447f3c2f6b80d5a11ef41d3a09852c0932a1b9ac23e6f40a167de21041bec8885f9433eb80b95c9785958046cdb7bf147a79947823b4149ae0521d7e5aabc1564fa4044106e2e392e9c344457e9929376ea9b4229c6e7738fe79008d554c429396914c36387f579b46bab146f6a9510eb6f8c85551cbd84c7dc0d0b1c010ccba5963a7f39f181e44dbc98e495aa63c01059cbe6a99b07b449e7759c9af9e0f8d9054a67a348fa19d7f91ec0a4d4f2c7026c3b849259a350417fd86cab2142e4cfe3c0afbf25182a2d52bd2e0bc920e85080832b91b927b62948a67c317eb09091461d493eea5ffc47bf085582968258a3c8dd81a858270bddafe7925684a15ffb51bcfaab931afa465e3090e86be41e3547cba234b85fe7db700496a505002df3ca4eaec7b96278c7d1a77db834a91797bbb826d092aa28b49545ed3b1eda23be11a3f528b955cb0c4fa66e16e957e5704cf319e5f79cc09f2d054e6daf19e2926b11e1e413ff822ca141f7c3d385ae95dd20b346e583cfb0c229ec39cf889a5419cd37bc184ef5fb144622080a302d9d7745c451f7d88242cc26b916a3569abc7d1f216d57797a472bc621761758e840eb8e29bc8efcb7aafc7cf8f4e59330d35ee107496dec6e714b1fa4309837bb47eb3a06b4604dd20733cc0eaac2649e18c07342ef55d19b8d039591ac2869acc34b6c3c1ca3cf263ff84ca43a5f6465ba34888c109013b32bfc0d0d15f5a76cec270ab3ac9a106331312f5a0a84282c3a3d4aea1e7cf53dbf8b240bdd111c34d2a93dfd1258fe9267133f7554dcc21a8f439c165d
+SIG: a111b9706d242cd36d6e8741cbb097b9e2fffa40f43fd6f2d3d91693667332b5f2db5ee3ea20b83291b8405795b74d633d46f475ab7c47617118535b8051d907
+
+TST: 688
+SK:  7d14023eb48bbd437649a241877905a3c932f14640f29a0fb134114e8f33f582
+PK:  ea5c11b4b2c5ef4ab706cca3475043c95818eb565a797e33688afeacd68adcca
+MSG: 9001db31f279be505319b8e72bde1199512980df65f0d8a9b4930467413a997b97a362b572a4b44bc940487f18b208ce6ac5c68716d3af1bcef170383b5c4b5c47e44737726f9383bc4f144768bf5cafb4e9dfe39761e6ed478971d1c70e6dab2fd0499dff9293b239d16c960261c68218b9f5b1bee690f0d240c1b3db711f9e821f0809bbeb9aaf249ccb168c67d965562d24f848516140bfd9fc050d4f20da5a1794468a9c0725ea5c669d5c630d9310e5745107dad37261b5d91e38e08512e6f373ec5dcad5ca09072907c8fb7bf3b926c3339490b3f51f7644e73ae2ec01d61be7c6526536b4ffd1ab6849fe0c2f40d3bda2a49e5550b8df979081da85168d0f71582b903677526d1f1b1511e138b684fc46aac8bd80c3def7ee8138190461807c5536125cb0e2c3d083a187c7269cb531ec3678787b32555cf04ab093c9002e7d792b4d933f2e3070f39ac8ccf8d5f5455f12109d8a8aeb4e212fad4a70b147c04a7b918460b1316376e64020859517eb7ee30c290be8b8d6f9673915256c3b04b9d9054b52338e0d360785e46a182844c5c3766aea8ed311b2d481c0b7b2114e418ed17f8debf01a83ff37517024ee9e28e0c90dce6d059ffee413d27cd62783a8b8b5016ad276e39dfd8f8f3ddfc428101818ce507f003eb58c9a5cc8b1aff05aab8f0d7f1d1f6d4b871dbced1f3d2866239752fb13f6e18034bb2b5a6635caa6ecc462e058ebe2fa651d3d0f36e20a31f765e4b958270bd825c6818aac1ad7563135aeedf14a2b6d398b6e34008401b218461820071c5af77846cb9c328190c061d5aa6e0ecde7ef5856b0e6814f833f704096df0825fa4b46dcdacfa27cd87bd7bfeff7f8cae166a3a04d437c7be716c49045c7bd3d1349627c9cbd04c15f00a696e3cffbb45af29122627e7ed33b4249913bec00f0e28aa11298cce8b649081fe3b169b4aaeaca485bda
+SIG: 31339dce23336df5b2b193522aa3dd2d4114a66af1656289c952bc11c9b210f77a54d46161f4e0c52b3013e40b9e9e8427d851325bd71c4d99353eeed751080d
+
+TST: 689
+SK:  e8306bada6d55eb188d9f75c815cc914e93c9c7222391c15bbaeaf9354437935
+PK:  bf2798b8e554f51e2286c3034a88e577ff23fa32a67244ea8245912e8bf46da4
+MSG: d7043809c3e3dc00b17efd52c9130b11b786f1e257b5e22f81a7faae600bbcdfd518537fe852c642359762fb75e8ad859249e6ab49ce1bb04f2492f2aac35446ba6eb03e76de3abd2d5fc7e6146843add042860a4a16b59bdd7d038378a35e1a04b1217a55710d937e2c9032232ea2cdd1d25a0bff71ef5d3e0c056b29cb92f6df692bde14dfa50e132bebd89e9f1833880b657a781e94ecb603041756e5517d4423c56fadc13e2b318088feddf3b5c83c20b46fddbba92305e48606dab748ce3848b843f4711f370c3ec7d5e19ab4c0ac1ae15aaaf23d65fecedabc08049b9e29113e5761ed9d1c62eb075cabb2674cdbe1e3a889bae4b1dd31b6a5b2ea1b8dedcc3c515edc4467c30231176cd44bec8a057951ab5cd39a9623f8af8473cd27d93302bf8aa624c9c3c5799da1dc494494ef8ff1dbe0187ea5162670b8d098c3a94919398dadf79e6c2491c444392c29cd50d57435063290842bfa0e8530faebc006d6ea7801117e0a3f019ee28fb3792235402e2f69b87a43dc227f9de316029756c3167d64a3a3f6d73160331d5a18eee5b0e6e22a663efdcc8d67af3bced041ea843a5641603ec72efd644e173d199a8c830b2ea5fec0378027c37225afcb604c4cdcf409be1c509c9a377be0d0524107c6d92b5f09a29efb7109295670bb1a1dd3ea008bb79185f09b98f020c43f1439685b96f6199311a090870f0d9b10d495cd410aa95b7e53749be3a6c0fbc729f96cf8564397b09c13514016825f72f14eb93294d7010accfd11f17a6ac8f544263d6038d5c7db29486291b30ea49b6b54cf88826dd252cd9dbb57d841b5a4cf702a3264faa4dccc86ab14daf124ef3d5335a6878d065c6ba29991045765ee5542cc9f5d9f354dcd2c6e0cf7ff3a30f649b5912d971d633578f1e9f263874d0565c247301dcbd15d76211ae2d3d506fc64deb7e042565d438e2bfb249243b7
+SIG: cc6627308e2f424383fa70594f575791600540027a2751619b283affeaebc9c9d29ac6db286dd2c1b596587b878d1df4781d436bb570c1c0f0d33368dc66520b
+
+TST: 690
+SK:  363c1ea7c32ea328a055af7bd8b3bfd204fb0bbd4bf42ffe262f3a5ebd54da55
+PK:  7a83ecca51ef6e5aa043a5ce04d9288add49a277548bd3016b693ffa79a22edc
+MSG: c41c1e1fb75954a0ae0ebc29090b9fc533e693e7c7105cfe40ef526e4e12a7405221f218c7ac019e1d4c92da2853f2d726aa62277924df0c343fc3d47cd5a99a3e279b26a1b13b1f2aa36f7ccb4b54fbef18bd87a55f1bc40ce7b2029145ee7aab391795ac68de6199f50594fc79611b85131c143021f26fa358da0c7c6a65dde076dab488675b722309e5ed9746d18a89309906a7a9df237dd27bd590ccc77c402ef6e19ca63cc86b85160330ee6e1f1f47a2ff807eefadc00963520a1c600a3e45aa7fb2554f47d897bd86d81c3b0877101222fa7850b80ce3bc06c9e58c0c96e32fec8530c9fa1e4163f0ef8456952bf6dd58045a363d61880e9ac976a3603ef77a4c395e6a07e342f6023b8af10225cff240efc0366a799fd86e9d062060d8724033bdf67588cd73ac284de4c6943cf45ee4f75f5937d97d78105f0bbece04d3dcb5e424eff89b773e5d6b4f37efa9a0654cb3ef345278a62d876cfef9a3dcdceb7081441877ebd5fa30c9d954e3684fa476a4f485d426fd3c8c32bea0f9cc20b15e8fdfc3ca4b302c074f508132d15de625c10ae0737811463dcc55fcc4014b20208fffcefa9dd452119b1652de41348f69f2c488f5cc1856d6e78a5cbe3e373dd4598e2d39f876eb94e0b01b21fa9129ef41b639f4e05e69deb1835ed44b9112a6862a5bcea072c6e1b8f0f058f46bac2a845a582d148f17760b9e0a2ba60bbbf3884af94dd4c7ec9db08e9a5bcc6dde1346442ee1f4707d1f79b69ba867f418dc279173f77adbc58ab85ea393b9dc68261900c1caa82d2f50474c42aec911314278c0affa2a6b6c36d1ff88f3b49fb2b7c339d2a7c2b3049f8c0a08d16a9e8df93d130da484bdba6dbec534cd51097a048221106bab48d67f951b7505a1484892b85779c5a3111702124d957acf2dc352ef9ba247bc80e2ce96269ce85e78b9ebda989076dd5ff73e1eb275e5d7
+SIG: 5fd1e5f9922a12f636b72a7d6217091f948a55bcb1826b8fcaf99d26416c7ab1351c10f4093ffd8a2af86914a0a98184ec7e06d2dee87fdc0f4a47f8c63cf501
+
+TST: 691
+SK:  db2228ffffa9d2534aef918fb85b821ad360e2d39dec5aeb2db0df02497f9416
+PK:  6d0195777f8105ff523b79c59e3c3081fe89db6f87033f094fa5a940cef84bb4
+MSG: fc07cd99040f13e5a84f94746d6bb868f752b448b62d99593ef29e43cc8245f0470f65552d643220f6719285e15c37a6d174aef76088ccda5f88685b52dae284c65b380da345a2e1af2ed76480d269cb934b4317620b792ebb39b2a678247d6d815f2a5cb9aa560e4bf6deba4c0a0ddc82d0e5a5a65acbc478e1ec6b064d7bb7388a73f6eda30b0b6b73dd8f879263ad1a0348671dcf211cb96ed08ed52f3317da68185d6bb2589dc11d755d47a3b6f6a0386a8594d9570b2e9b0d4b5e13dccd9bb7acbef0ab276a7aebe12931be67f10de267a029895301f5662530ad8ab3d230b3b6d7093acdfbf274757a9078e20c23bc822deffa61005486102c01ab82bdc8cdcf1bb37f9b56d39e50fd5a6895416e767f4e36c1a41778908125b5ca3f92a90da9addff155fb1fd7768808a80f203ed737ef007763bd2fea9ff28c84b43551c9fc438ffc47fcfcf64dc7700613aa8b3af8633ae8b6987437c0aa4781be1e821396c536cb3005d05549b1cba70135afb7fe3068961cad3a1463cc0b5560684e27bba77aef419d823868e0cebad1f1ce0ae902744a152dd29451a17e28a89a7158a1836efce4a3e5c7d1faa4c3875bc46c4d9be22d66d366ac6f59538a00b275b02fac6da755a854081997d5d1d0e6e568a5958cf334c518cd517ab9d73c48d6cbc4ae4eea4353113e7e4a7c05920e686bf07afbfb8dd2ec4f18fa7138e57d332cd7a4228fea73bc09252f24427294ebd3645ee0996c2e851a8aa51a7cd9fc2eab47c0ab213f4f51d216091ed089e4592e9bb0828b858f84f60b93ad84a0a22827cbd27414b781322a04d3960828f638df2834c7f7839d70db126bee5af2ee7559a8ac4c01a6c391396af93fa0608940297ddf8900c5ddb466340ae51c60c7ead762447e76d8bccb573997cf6614d188a0b9a2f56eed9b0f9d463a19787f4092581a65c6bf781b93c56087e54ee1343aab
+SIG: 82189d340bc11ceaa400410e08bae9d901af059125e953786f8a043ddf11f7b2f8e3b617accd78e2939adfabf2d2471fafd6f5bc45b14075b328e34d8075b207
+
+TST: 692
+SK:  66b50f692e395eb83386e027c82ce3fdee3bd899b0d3179db086fbf524f57459
+PK:  448536e982408437ce89674053e3c589c98c095c60021a118178c6261d8810fe
+MSG: 7428a964212bcbe8df7d59e48e923480aa0ee09b910d04efb6903662efc3107ac8fdc0c5f39272740cd877e16cd71c549238c337220ce2f6b5a1fc6f7b0a1cd4ed21d93889081e34fb7fdecf4178bbd431e611e539d900c3d0ac3dc7107b36b41d6d0d5d32c19727f908b6eb367febb352a493581ff128b56c4caf6fb8e09981f0d37957d1282017fbb807614c20f465dc02b0cd969983bd5ae1ebf6578d7ff3ceff320e25562199dee934757cc1f58d5540c41aac1ce4f211f0b8ec4107174030e702bc6a8a9c85c505c9316aefea3e4372242de019b35e2bd3c5a956521971c106a3adbbc13cdc4f7f9d3c58b96a344b4ac3ef6bd8aca6ed9876b43e6497faf7fa4cf27fbcb665730c091e13aaf7e9efe7dd10e14eb19a9200424210ec8b8fba7e69444ce1a9e3a7b26c11f6b7145b6983a7805776484031bff52e81ae769b70a282b094ffb5fb5525dc1a872e207e827a2e11f4ecf7b5308c748a9278ea7bd66188194400430c8cd596ebb87221e536f6afe1f1505d6a59f41d16a2f014e1cfa513f7a69731d7bfdb2affcefe0537d42c796e3fd27e41b7ca72051bef28bb7bde7010dcfed8aa16ef676db6e520c3cef8d6f58a9a2813cff0f7041f87fbfb8431e020ede1d4eaf19e23b983445c5915b54adfb557fc20d0058f40f5e09825dba8d8f20c00f43b3aeebb6157be32ec54627d5d42ab813cf97f095d26db8036c12e82cb963e8001167e61ab393b4cca755ecea869954e323fa5262c5fda3e0be9a51e5af51fa6444824fb837cc67be537a87569c30cf0114d39a03942de4e1cd523355dab1af36080a9a9a548be1c2a7fbe5433772315d283e5156df648bee4b7dcda74f15905d542be54873c15c53ff42acabf8c56f257d764722db4e9c718e12098a3457486a6c947ac2de0af53e82cf950bb37ca29c8dadfa3646db4982af572d39b268c7f96b03ef6b653c87945f29bc5
+SIG: bd13f6362c07078922f30c6330751bf6e7cf42a76916ee653eb17accff1fbbca35258c4cbc582a5e8cc94fd2c7edeb53762f1fc23123d7f4f145409b31cd3802
+
+TST: 693
+SK:  55328be4b370822733ff3989a6a3282d65fe8f207ab7270d7c2e727ca3cfaac4
+PK:  518e02eef52f5aaebde3d108ea79ecadfc4d994ce1953621e54b7b3b121ff8ff
+MSG: 6c24c9afbbf12dcaee6f10e4089252f2c60b2ab93a02c1602fb5de4ce3bd923eb02fe1039fdc15996a446915e767dee0176dddb78e9d6bbf069675775a829dd808d376b0cf7920bf1a66e1303ba52419785f25f28bb33899ebde840c0ab14b919a6580cbaac3a805627b9c4a77baa16f825a9eac2d6d3641651493370e50eee94c74049764365605ab4dac1a030227a330aa178f2f8da377af73f0bb040bac12366e65e0591055f9f23eaca35e9688d837a3c0d99c168fd886acc922cf37a7118ef8a44bb0a4fa4288049309a7dc1bed80621e1063e3e592c0fba42d7398eb15f74028ac15d7ed65a6368a13b7f956d19547eb506ce7ec90734eb949cff1d98ce414f10adcba8c007320018750a71bd36d3b6bfd6127054508e3ef65d99848514d33d68b58e3a4b224f79b6e34dd480340467fe7f025cc88213d808fbb5b91e2e43cf9d950640798659273d47a25f1f0132f6882faadbafba28fee5fa17272c1a9001172b3ab6ff2c315f26c07734405b5ee8b5e4f08e1e3b8aea019467fb071887f191901a21c5976c1ca8aaf0a1d4a2e698e7623e9bbe9ca2a67a153a16f895e6dd9ea924441b4bd0b674552e398b8d970343a9bc776a3a3fc1a8660c5625d6081b5d87f0f8ac9f07ab5abe77cdb8e30d2fd1f6f46525c75dd0dd1ca3281cc89346fb3e6d7388ebee154cb59bd9e95ed6a41d5df668b59ea137868eb120b8a2cfdf4674414fd279699f28b5a5ccc2e2fc802a4c9e0b85b76f20f6bce2a4954886fc402670a71efd261f5dd7bca16884a287c622fd445f68d44151cc0134b229da38daaab81b5c960d57700ca92b26d0b142134ce94b7be6c18610ea2136f8ba8329a2e8c000b8f02fe05bcf72cb71f8c72535ffcd818e38e7992a8f0c32ac62177d1522ae552c60c1ee616b75e4b3442e79657e4a333c0b3d744eaf260d0c336931686a6d668c64fef440052352c2b258cfb65
+SIG: f58db19fd834e15194c3c0f8a6a50ebc4cf074e80ea2e70cdaf1e169bd51ebd0990bad77c4fa208b8dd1e2c8574c01b5f596c8dfa6bb8e6ae3a47ff412e7e209
+
+TST: 694
+SK:  7da05f04e5d38b989b83f72f7ab26c138776758f4f577e49dc73d6013ff43759
+PK:  b1de5167f4d330804eec9eb565ef4055f1b64dd95e1c9b27c67ffef91482cca8
+MSG: a6a861d8947c5cd6ad0819602e32ea7681c8f73010eee553e5defbf7982098b5f7b39924bb7959ad64c30326bed560bf51e9983cda5dff4f311eea24cbe68c6106ceac9b843aa4e2ad1b6f8ae1e4f96871fc025be4a616385ff2d4b7f56829abefaf6aacbb780d6cbbc951b6e05a787f885e3325611665ecc924274aa531bc133f62c76cb3ad148f3c9579a815a14200b7648dae0b07b327d3bfccdb6fe3b6cbd70ea65e6c0cc2516a896696d07b2e77713b0bee3b92fb1b6f75b0820a5cb62c5fe6204003943e24857166fbdf571f115d45f42e75901df8b12c32618aacb0d24286c8d30396051fc272aa17f4d2d47461152aacd3faa2b7b208312278e809240592d1d1aa585c56280e66ffd92b5717d0cd1eb9fb7401def879487c374e5c530b6febf911122574d24fe104b4f45c7c601e6c917d3c1882c1ad3c555d8f2ce955b5a10db0d5a8b8ac7a6266b2e6b27ad0ee34f47ad857367d52f7096d4bacef0e46725488424b93b89acd429ffb5ef33a0b081dd09479679196023c3967f44ad41eb1a2395527fd3b79768f1b885f0429b495ab60525691be84650632a2f66cb63ad5bf2f6ae70b668c5a193f7499fc4fc42cf8cb308ce5029a5027babef55d1925ecfba9f27eb6081619ed0df8569fd80e9da104db39b5b8140bfebebd29085440065819deba8d469ae8b3ea6d3bac5891f9a4ddfb7f1f06d13c31a07ee53fb54bc97bd08696394c38e7f3680c0f02f975f469921147a409859097813b4c3fa43d174ac402f1a528cb5fc4b807518432eff33407a111ca3a3d7e9e84135abac8a8f52ea631c86d74a1c6e5749edd1491c0024e7de7fe52856829b72fd13da63a1a2343349df662ab3163536032346e5347f043fff528bf67150922fff2026bab742db9cae7cb2e3c74580719652c28447c5e2098231797ee6ef1231f5792054bc3359a32c86d2f94f85fa7d4a7419dd241ff662a
+SIG: 05f117f9bc3ea55d455e9ef135e92e7665d18070d8f5e375df67be1817ce14357a55e70166f326b77d85243227cf67d8f2e0bf8440cabfb05275b373f1e1190e
+
+TST: 695
+SK:  1b8ec65880edbf039a13e970b15aa67e192aa02ca65cff9ada17d4558f40137d
+PK:  12c1191e4de3bd44d039070153adb7b581f600e9a1dd69aa89f277c7069e76f8
+MSG: 37f18b7f64c5133479d6dae3bef679cdc21ece3f5b579a6a9c3fa2e59e9be87d2009f74e1cfdaccb1ce37d00702369bd169d94fdcf85af9fa3217d27e6ed6d1d8e5df7615e8e37ea55de1fd0b06d77b4c83b929d80586fa0694be72ec8b365ad2cbcdd2b1ad8cf7f036dfa4daa1a9036cdb120432227b1f07b8866b122120309eb914ab84cddeba1dec48ab92636728588fedb3aaad7e7dbb2ac30e63c6f5f90fc6ce62d6d3bd88b0d5aacfa61de9f3267b300917b57a48036ab20c9a05446b8767494af249e7de7bc507a2207cc956f7184555a7d5d8883bb4b3e93f2dcfc57b0da8638658dcdce885d44d9cc68b1d8170a3677cc5e50cbf33d543ebae4477d9239cf83384ec59b4233e8ff3343f06f301877729a53d420bf01c62e66ab7fe55dd87ee823a58fcb87870e1f52e879177cd439c533f5a223e5a3436fe9d6426548dacfc86a0846d3ed23ac042563e887ff46aad005f4e1dee3ee0ee4c27a7251709ae40abc5e256864e4785a4edd8b2adf1bc5b4018e28d0b175867b02d052a6e17e411a3d8beb2a4208b76cc621fd18be148e235d55aa7127706557dec053a13f1a47dfda405b3fe5bd28ef5d348619f51e595ef5055f839efaf110e4901631ac31a02f4f7ee424a3a2c3e00d2602d2cc1e492906eea420a9268238ac6622a08974e5730292e6ed510256efde667e0d9a0ff2213f54120ccd81ffaa6b7cc48141a2b729852af583d26aa51fbde67be4df14e520c2257a73c5c2e3c3d87dfb25361175fd18abd7e99aa09b85f88f19c8d82d45858f3144c5dfb7a49ede45b4efd8710592a3720636e7e889c7e22ad13b2d44bb7e2b47b2963a5fa3f2557b85bc0c693de3d22ef9464f7b814a20a4676ad26fcaa03544c6aad41283095fcd1210aa8cc029ff5a26005a891226c298e94a52aa7133913ec9d22a5b2ac0bc6f15b251d0b93889213cd1b1e5c6fd08f1a8f5cbd4215329a3
+SIG: bff269a35d6c8e552ce716d1638181ce8583b45c0ec593b4e58c40ac76e7f85ca1dafffd68541e623a1e35a7c0972688b25eed72f4da57eca16857a8263caa0b
+
+TST: 696
+SK:  e75388026a6a6d6c6d199e362993a5b1044901e18a76c2fac7261a6d1c19a4f3
+PK:  b9ce14251c0cdf3bddb206dc6b8b2b7f5b7e4dd1be2ce1863ff18806ae00f1ee
+MSG: b99cdc847211c06642dd111bc5e0beca53a74ffba2e3ac93afb4b0947518e8323527330a4efefbe4bafa00bafecb434ab1e5b7ce65656f7a4fd856aa6c385ed8d7bd6285580d7dd60882e69c19da076909d647de095a80e98ad89b814aadcbbf6f033c49202f656c0910503959cf97cd0fa82d5f6d22fba3389951294c4f7cdc21eb8244bd6560637a5eca62a8eba1f4a933d187a75f86711643af358831c8c16a9a0f09e253b2395e9cb371611eecdd66b4ab521aa94b3f20237eae41cd10c5e21a452d48e748187f354a67adf681b0fe61cdaec94a5eaf01269fceb570d514ff3c55ff1dba2fd2df17f86a8aeb747838113dee94a43b1384cbe133cdf6427e8d122e4e933704da6e26cfcee97fe3f629b60b91b2dd863867fa79801e2b916ec4c0fb62e07159421e657974307a1d02f7f2ed4724a8b521a861f55f35521e8b2e1a84904c428cfc5b6014bb0f8ba8434c2209bd40aca31130db97743333597d2351d5f6811741f62688973bd773d30266fd1efbd89d47a964f9d01997153d087d92696616dd103a934ccbac4c1d142f2075d4e22c3da4a0e973b23863196287b79174fa29755fc6d9b5e100ace0a45975e503b254d3f195c261710910fef106892c08bb296d230cdea9f5a11f91acaa6e7c05e92c281d2b3155fe4480b0aa5e0db41d10e05cfdefa4364051cb755dc72ffa978c00b94a5f212dc691f839b49de97e0139d65e8d73b2b289b26a12c6ccd8edc04adb452af7ff094aa901eaf57651eb1b87b833d0a09b4a4a6462f40664623769e95079f3c962850cc3b401bb0058b8475b10c862f32f300a2b143b3dea269ddcbea7be7dd2426d0d4204eb66a39f1318822dcb9c561398637f4ab8de196768ace74f348c012dd1babec17f5300ffe0d7aaaeafef7db650a8f2f309a9793f52c685c7e1d5133274915784899c481d485c9bd30e99fcdc97d96ef07487da663befe68299df
+SIG: 6d0f83d9c55d84bcf9a86147d9b6ba9ad537832fd0f99dae7e72c8139afcb30c7b24f6b292e32f9847097551b7fbfd510c84e89be98254441457bd08e5f05302
+
+TST: 697
+SK:  5b323fc01a16c45d1064667d2ea4a7ea59d20342562d12fbc598d5aa7300688e
+PK:  d4141b455d301642bada2814afcb1620d5eb56d92b1185fe5dadef559625fa71
+MSG: ad24669ef55c540a8ed162ce1d28f01760a60719a0377336eb00b1ecbe6f61601cd564f92c956804f9bed4e1476b94e5ea8cca80cb49a304ef851f7f675abe58e6681dc012ad55e51b021d9828569d0bcc9e0527a3fc03c891d17a90e6337a1ea67f2f08810587693837081e4c08a3d72c536c2140da200ba456c376f61d05651f0c5f395711f41c0d6eae98c906764d1ebef3f9046cb7c8622640fcafafbfb8f62e1cd32c66ee1c55509489a538ab612999e7997b779c6422eff109da4df82920930d8d363d7830908795a3888f25d667e14d155ed44581be430f7973b574e2bc0b134cf139fb4bb01dbda41b67b98147d8012f40677f4b80ce4a534c90adeabf484b21fa994b7a175f8a8b8a4075564478ddb05024580bab038cd9eaa1dfda552fb31229429b614fa1d80c52614e84faa2217f260ff7ccea8c7b06e3d77ff874eb81fc8597e5fcdcec951b5fe64a1af86e73193a882469eb3ba3c382734b2887b419316ea448afc282478c25f7bca18429cbbffd8871177c5ecc7d8aa9a1b9ec87192d29a52539c081c3593332444cbe66872cf3d0e197292b82b0be5fcd858cd6ca48b53ee5b61641bcaaf31d819c7e1cedaf9ee6b07e09caedfb30b9204a1d4ddb70560cbe1eb0c0ec43f1d178201b290819fcdc92c63e0db60fb87dff00e512648c8958a847efc36346073f1a4f1f2317060f1c543e6f01b42485beeb56cab3bab26e6a0ca6935802c762b799159e320f36b5e83d4aca8962aa2c3c2b7a3870e9e04731f3948cf941e21d50964e5d635a35a53e299811b8cadfcb4416c57598a3fd05410910dbc0ea2c78fdb92574997d58796279eaaa78b36dcef1c9a129eeff82399a26d008ffa3bf0418ff7d39b6427f341895024d16e22a0c62a82beba2e2bac23dee18cfcd5db2397f378c5367309082c44eb43cedc15220253a62320399665f71349cc1b944f58c73a10a0bbfd4caf12891e3
+SIG: e2eff607f0227a29d582d69f3458acadd3226fceaac0abbdaed52675c51630073cd3a901707ecf05e893f2c36daaf0cc4901116946b5770dc038125f6d131b09
+
+TST: 698
+SK:  be1c112f78cf13aefc5ce7e33764aca4481f9f88b018e122db9f8dac14624605
+PK:  ae389936bbf6d16e3c1eeb6474298970866e12ec9c1d6aea2fd9db6b56aa59c4
+MSG: d77f9aeea0fe98ed7fb74d582a402bcb7931474b4a95d523f3fb769fb7097d2be4c6ec1052140163222553aa8f4f89e421730014ec73469720cea967f88b6a48d02a2ddc1a121fdffb8ae127738e293c4d6b1b74ad03844de6bfe821506b3a7a81d19c37a7f01ca481471219efe2a7b92c4bd2ac07743b4975696441714b84d63c549d7a6fb61f16fbcdb72b914d7882d091f9706da38c1a81a1c6a40fbec0d8e238b5d56d460e909f85479f7ad8b119f35455e34010caa7e5d01f38e301ad37e8005f6ed29e4a102db3f61d84093f78c49a9648c977bf4d5b689f71f406f8ad7b9aeb1ae22133a84ce1b278b2cdde465901b23a179d072a80879d0a24d2af197b322a07bf5d40eeab3af12117f13021dfc1681aba5c083f2596e37f1123422bbdca3b2c32cb594f56c325e0c564a1733288053459c62488925cd80e7c944db998c3c7be546bf89d7a511ccdba4b809eee0fc2873dad72b4cf3ba051289bb3f4e9925732e45ae7741058c8fd11599dd843927e3d14598bb83052d33569cfb02af0c88fa7aea4bb46841cd2ddbdf5988fcf325ff104a5dfc4a30d269d2a949730c3613bddd3673b42f6090e6a60e4a253062463a65d7e7fc0030bba769ca344bfa9ac823f58cb5cee8a5fc0ca37228de5a4d93e0ecf7f10821659a2261f7ef1596eda4e411cf3c9669d81de74547ce4bf833eb432f385ce9038fe848a8c96da7f01fd95bea06d1d747c8ae736495bba2285be5c32afea449520cfe8e1ce25f9077ed0ec0f6598a9b8f7386f15358170ccefc3d5ffb009288154de877c2409ae5fd8fef0093f1c36b3a8f547432cd0f62c4033242ad9921a8f11c00f366da9396930a80c997df429a4f5f4e45c7a6d7e02af033186757c73cbe64d2d4e78eaafe27539528035f2cfcf8eaf0a42bd25f88b2fc69e42668fae6677c9ac9091d9d15a41f3ace65d90a0229873dcf254256cca449ed4c17d5435bae4
+SIG: f5fc5acb17e9957ea304f123b650e144c9e4377283509d431da6a2bbd527beb382c9f58745a3e56dcc655bd2ebb7aeefc93edc3f20d8d3c37923031eec0cb407
+
+TST: 699
+SK:  bd8523eda899b984230e328875b9672edc9fcd24ea5cc12d7b572da4be01fb7b
+PK:  02b734ebbe88c13bfa95a5d964fc7ef9d395bd6303f065dc4ee17b3ac1548b7b
+MSG: 16c216c9be9f0d4b115410bdfd1593c8e262221ab97a2a395a12198f95c30205b08962d4893118ba9ff99ab1c7a6e1f2f175191070ac945327ad6c470babf7928b07dd788c85b64b712e0aae6c0ea20281e42fd561e83e3fbac67f14000ee56d981d2a2f0b9ca00a9ea47ca2f6fc8dca1035fceb142c3f26f20e3c732207ffff11b79695bdafa415214a4499302326605cf0b8c82f2b11392ecc90cd74a7b411b6d907a3d5c130c879b7cf880f22bbd7f0e95933718e96d7d16caea9f2c39e89b13cd52266273604a96b51d6e34f706735ddd9fca44d09cd86bb7217600e0d34d416ac249f2e41bd0f4abcbd2580adae21d7eba5fa44f39d780f17eb85ccbef58fef903a280d95f8f3210789fa12e120e21b6e8cad917835bbdcc3b07e84693954e23a94f99f937ddb0d4a18d42c3ea8fca7d1ea6ed53a00246f99ea520e6405bd2aa549b06e7da722c1ba74aa1c136e8ea58baaf8d37658693f3e0b44f631dd6d08ffdf4f09189d3035a3f03468e29696ef05e02cc1aabfecbda2301b540cb0eb0a75bcce73db9273a9161a98ad898fcd6579fb7e4b3279544f2e0bd774dd1a8157daa88a70321167703c60a608a4b54216590375e597fe21aea97b52185d0e37a53b6388a707a2bc24acf94425f84f3d56bc9f7ee7412a9e1833ad55b7eae6da581698166383a2eba8b6f53920f517a5c80bd3e03faad4087e3ee8fec9a79a01c779512133d7b6e5f1dec766300dc405cc21a8c583fb73bc90cf24385b086049d3bf20c300983c0b351538dccb227a14fafd23ac4b26be81a2b120cf216fc58354f9dcbf05f66339ad6ddc2cac14677b90e247ebb6c5c229007dc60f374a06d404eb23eb1ec49907c6e881629e1867268ca6fffa59aa3ca8f6c295162b9536c2be22bbe3b72380ef11b61b357a6253100e30a586818ba003fa3ffd1fc919881c05022f94848598f217fea222507220d108a28fc7bc39a8a11c
+SIG: fcfcdb088dcbd0a51bd301e3e1561671935d8b6f719c5d92690640d3c91e775bf4054132efc05a2122fc209db3c3343233ff8aecebd52daa2b3b21eeb15fd102
+
+TST: 700
+SK:  33a85ae150bbf552f41663b21521c296d246dd6cf8195df851c695bd15f4a502
+PK:  c8c9c42521008d5efff576c7e4a56083ced9a928da6fd5cf93fda572a5a2d0c0
+MSG: 937e05f2f1fdbd41731553e77cf181b5079758940aee8e92623fb1d5f07128b7d7f17e4842707a562c45ba69264c0f730a821c7db6bf82990dc651269b296c335179113053d6f85bb096b2911165fa3900cb102416487ba8078679c6b336dff38763c08dcd20fa66dda45c575df150d851165a4804973830f436df60b81319f9cfb564c0652896ed5f1849cb3354f50f0012f286e8a30c213528693474004e8504012b945560c074a6a163432cf4ac4ba7175cf26005db7199ee96d893cd1aad3fdf5d57460ef02dda6d3a140825196f3f8e2f37da36b6fdad184f2740f116de758a92917030c5fb80f0262496d2df93c7e276f25da7dbed8eb8dd4c563aba55b82af6ba3a70ca5f858b44a033cfb795604ddee746e7c8ae79d272fb9a2341a2a202df5eac08de75ad80c6580d92b169f2e1318857b1b1421c30f3dd461093de2d345ede7404b72a450de07b16eee68ce62887b6eaa436eee684be75ce0e1f96263e8d8736f9ba000d88e9e5860f328ae1e2dc73099d32fceb1bd2c0123698a49bead190a00ec9a6f87133eddd45316f65eb0d329b07b9a66bb9fe42588bf7b8d06efec1986b82a081ed3f6802e9be73464784559a4f2c097ba14b0bfd5d7e0aff65cb69abd03f8616cd7edf7ec368219edcf893e9ee71dad9f18d79e568265ddc6716223213235bb928e908dea827784cd1af396d590c81f4eacdfcf89c5cac96fa050064a22841ea715f8c89d6d5afbf597a4d005dbc6b13856d335b42a9a82edcb949835cca20b0a23de51cc3aec35566eff0c5ae1ab3751320d2c310495238eda383c38a4163152b8815690b8ff015035d1d00ea4a0d6caf324bb71a664a1bed31480784a68f438caa359e8d2673c857d4b8c0b6c695847b86800ea3d734b5ecc4d52b507ac69b3a6778916016ebc2315f44c90bf0c3e7dae01d49cbc303402bbc634ae1191f3f6fd63d303b0c0be033a47b90f8d3a77f0a44
+SIG: bbe4cd63676e26d675a191151d30db72b5b84d461eec6564af867ab41bae9931147885519ec9d7e6c818743c8ef6d5167b35b421363c09b357367fe8de443a06
+
+TST: 701
+SK:  ba9e686204975c3bded4c1e9f74c7e4c7a7e3c9981d01bfca0ad0115c3f0f5c3
+PK:  4990fce6952e8b7d0afcf4bf9dba9bce1bc4815e37511da7c2ad4892581de03a
+MSG: 46bb48952ae58f2bf58f5be8df4f316b50f363ec84eed8f82ff4c04b0692d03aef26e8e1e6c9549a2247d540a6e22feb11e57f4b808a2097e8a7b6b3b7af3769e6d81d64886e6962372f4f39e49cd46c1b5f735f380f7c277d099776ed1aeaa57a359c0aa8c72f40eb91a1bf07ea157f5ddb30409d6e3af98990ce7f30affdac5e22010646dca96a540060fc908a3125b000ad1ed3a0f255cd34f15d7dd1fd681c3c35a1cd652056ecc5264d39aaf72a9bb83a551cc934887ae107afdfef063217270d9596891418bd461bba63de65be067b1b7864fe46484c7c9e96349a7c03a80fa055050aa18ace2a44b4a03c947824172b30e21011159443ca3cefaf696a7aa8f98011260c9436bf48991f41d4d507b96ce7323e531adcf66347c55c8855673a9f2ec89b5c8024460617ec7271773b36d64fc14eb5d82652c53a3031457227093d118fd8eb9384e80229041a96a6493450f97e6736263abf1ecd9e9fb9a4f0f6d667fa824151485edc37b34acf3d8c35f9c1be48b5e96a12af8e2d35c23a03580f211da6316b34c56bee872d47641bca77da640fdbbad5a9ad8ab9dc7957913da734ad37492ba4de8cf136cccdeb6ba3f1bd3f003be7263c4f2a40c33f24ca3339596e6c3428338100ebcc0722d4f50d30b33b912d4e7c1a9fe65f6658a6f239140a62c3261e10392ed1930aa917652d3bd2be4e8a08ab97e145b920abb31ee4bcd5a0d71f638180f61c245823a399a734a4dcde0997880245ed71eb9bc65e3c6fc95ab920b8024c17d44ced0037d04a133c2641782f1d622df45269b491d3fa2a1227579eaa386de3e7de7bc455c6a154eee5727fff0437a20076c5c3b0577cac5b4b6934e269380222461a60f954e48979c0671217f16f7027983034121093186c78705fc27dc92e2eda4116a6bf7d23e0548d62b67b25c41ed06192bc26ef1397bf1601f3a6e2a0e7f661fb0505ee382f27aec2805a3e2117
+SIG: c7d23a58e2fb2a8d4b8ed1e9eae91e1129c2af8bd05f0bd572abebbe0f30825925f0df71cfb7218c686e5548d9427710a690366ba85541c79101a58a10e8af0a
+
+TST: 702
+SK:  5907a8c084043875238edbdcb7832fbba4c05ea3c5f88a96f1fbf950401ec164
+PK:  e2f49509d1007f618efe4f1fd67eaa6e2ab18afb2decced5a0b2ba8363789260
+MSG: 433b2478e18fad5cb81067061d225528229778307885475460fbe3137a5b44024894ddbe56fa6ed021496f0786e42bc6c2d2797ea0a6bf355e88115faa55cd92ed42133d9dcda6b9ebf63ce4a994d1a82d2a49267558be54182a6f85112bd12b247adacf1405fc7ec7a015d43ab40b82c677f7f85a0e48197c5b96576199f4c3343ff7654d523a30c43a054c3e464451278034b7f196c366768c628af94fc0ccfc9a2955f9d32338b944780f8e327085b103781868e4fb79d56122d7f3f5ab309e5d634add15da382c0d2358e647182be4de6e9a9e43e6a3a3b8215b204d9507610d461621000fb1893707af7d2595bfef8a8c5c5cd08f309a5fb55e45519aea9b84748ca5c672bfecd30d25651234a3cc319b43dfcefc1a07b55b4aca714c2e7ef9638fe7884a77b22253a01a2229500e9ce10fda73a843c19cc09626d2456c22a9c901881d521f4b15d2f613cb469d304d579223bc5ff73804df6371517ebaa5b677ea910ff1a02a26fafe48fef469ed799bed6d56ce961834a2edc2e23c0d9426eccdcc934f4c220e37815f7c334b7383607d430520946a881a08325b4164979d5e82cd8134d78cec4861c019f6de301c1b9aec52bb982033fb79b2e9731bab2968bc3f93fa5604b893c6028c204c36bb8c6b074be28c964d2849b5bb19d7e0ba24e22a204d4fda83b10131d383f10b136bd0dba39ec26af30e3ffb4dbc0c921f0cc9910715d51c81fe4c62950e855549a17cd73a09ac91e06d461518376d0fcfa123df0a837103458d9ce221808d1f9ef2edc5cd2e6823145b524894ea48526d985eefd3f60679399548e1edeadb5395b43d87044b2bfe7c6037029b346a402227eab81f333e10e77f1dbc06a211d43b82558676c2dcff9082b1dd53368df002de1329af3000b171a6914389bb80ec0c9f3e412a441b800afceb0486709adac66cafeef248839331f5d892197e25420f1e37d7c0247f669f5fcbf0
+SIG: 8c4912c0f885d76c914059505373a64bddd67dd468369ab918f23ea28e04c19177a8d461144f0a8b51d215176cb08bd65301c3c46237b61bb1498ca79d4be70e
+
+TST: 703
+SK:  6020ae273e0e0537bac881d7549d923eb1cc200d49ca65d4be635e39173df9da
+PK:  daaf0e699a12a92c16e0ded3eb3450a36311824577e361f05696603300166297
+MSG: 6a8011de09aac00db16ff7e55c2de67d8c9883fcb2040dedbc1e321caba7bb036971530176d1dbbaa927520bdfccbed8840126043edc44cbb7fa3528680e5f1b5664951dc90109aea4b9c336ca043d8221a4c8d2011656bf944efd36ba0a10a4b389196055750b0e388fb52870bbec8c55198131443945c09f3aace3e6915014374073266f34887442d74f468f8d7078bba0bd814cd6dd423c97b56905587b152d1fcfba0eb9fde2112691dafaf4f921562f241b62841001834f6ce36685f82a8faa3b7afad73a5e59bf5f9e713e59163f31dbe696118af33506d2ffea3d9c1556fb152fd2b321c31757d0c3c0f60ee113edac02d67efbb303dce6fa88f7b9746ca110e6a0cd099c0831f53c55c28b6c82af446456b842b2c950a553ee2c765e9729e6b0c546bfc26bd6d42d06b2ed5d4c8cbbc75f2a3ad8129395793d979c031fce7e20b38bd89c9b624748b2013423cebada02cde2052da5664c6c6426cbfc88f84ff602e2e20df9678fbba577a4c134517ee050681151580f7c5c9787b96e55c4075a26f4f8ccffbbb6ea18de1b2cc8c4496b16042770b7ec6eb5429e7ac1891232aa4e47467f4e9a985d80547ecc4c6fd9f59763ede91671f2aa5736a5d148e3a8ffc88e61253a85b0953654958eb2d69401cbeae775f8cb8c3ca42d21693ebe298838df94c1d77b126a1205cc47d50d5367b6f276ec8db6b95324a31e8fd2ed2e43420c4ad02ea277dd948a55193d0f0b4d1cf28386c725975ce5c12d2a6f35673cc22a0694cca4daf6afbfd326d88c1850f834c42ff0e292ba4f13e5ef0774a596d33904c0262d31df2c584a0a4f453f6ae4a88a275f7de79c13ae1a73115be02f425c6f177a1ec4639c42a792809a2b0919ebd321e316001d5b2f84894fcebd50a1dcf44d702b924532fc0e4d3f9ff8486c0ed180eecc3e09e2272a94dc7d24a4e87a931fe2495cbf992c0aae9201e0796298f9363dbac475e8ed
+SIG: b1ba88fed7e5f4b757f3fa4d1ed9b19e498e5d2f5e6cd46e426fe8f039882f1be77ac9e5a9265cbf7e3cd2a9e9926c18199143798da5be47a4086440496ba00f
+
+TST: 704
+SK:  932a200ecee7223f24146283a4048c67a6a2d2fc4ba0f9248bdffd82c6cce3cb
+PK:  ec9bfb7a6d04e726fc1ea0c424610dcb7967bf15d6d6626858d411198d40e239
+MSG: df953207048213afb8e2af452c889a21ca136a68c929bdc824f9a89ac596dcb90019a46fb682bcfd962fccb27d00baf8eccaf9d9a7d8183cabd7dfa506f7bafb4935ab045931ff8faeb71631f9ed6bb8f8473ad6290d7cf519db310a4442c461118f67d1a6d103bae6f2697c94b7426d9e02e3cb9522fd0b44aef600c962feff5873d98c2790887b8e88d160824f1bba22017639f8dce68f743480deea1f92aa1fd4135dd06457a60f36b7d7f517d40c94c0dddc2e465847d909b9f68245ff2b421d5919001aae5aef24e02c002da907e8605f160ea6096b580b75cea022d402f7f5fdc464f87f78c7906a01e8e48fb5b35174612b48ac8bc750e0f3aeb0a12f7dfc09b0842c1780a5fd9c54afb9399b9408baaccda20afbe3d682248d7bf1efdef4905a319b0ffb108b753b71cc97e9e21ec9b3dd28cee039d9418a1135f0add092aa66312ea2913300d1cc8916524302bd3d1b09e6b29c6857cbdc56ef4b3f35d8ee677208effa846fdb066b05eb717b4d45120cab72a7db7a7ca846e87b16b69047eb76d8f18da8e1399ec0a8c9c328cbe60e0bf42044d2ebf2818b3c047588452fcd2b3efc1e1009ae07688727db8fb6df2a2fe75d1cf22f32bac09c82a6a3d7eed7d00508cbe5b72460ecfcdd3ee911efe5898dbd8e4ce8591326dd1522f9d255da861bf9eb2a1d5725d7d5d427340341945e7bca8cf2ff8a997450953e77d203683e4b0dafc330e05672d2ecd13a3f442df137044e0f556ffbceffea26cbae26cba6f2568cf39f908489e1a92e76afbf297995da4b2cb1abc9ee1fe4dca5aa838b2fbdc109e89bef3ce5a36e5b2f712ac4c889438248fa5a2150cac6c977b5e0543f4010b7314732fd18e7fd5982e83276519e78725e5a5eeb86f4892084ae52da3849c228c809edbf69a2cc47c478d18719f111d737887c7a2eb3250898db34e5e5076fab9f4a9e6e1929a3480836dea07ba4d63fcefce5543430a8
+SIG: cd1e4bdf4a3e4a31d65254333c8cc4087e4cc40b02e2a347d09a3dde698490c087d7109ad0209c53e987589cbf3ce26412a2b02cb8a3bc93fec75ab5d2c38703
+
+TST: 705
+SK:  5c483e837eb01ed5a4ad5db3792699824df13e576be967d12115c85e0286e628
+PK:  fe1aa8b069da56e676ef3a57d9bba88305ea032808ee635273b37c5c635def4e
+MSG: 58d5e2cd899ba985378b3ec33e9a869822b23d5d896a28f424fcd6e4cc28b80d4aaf2de804367efdf5e423b1234d821d63ac05eaed12c73e8e3608af0ddccc8386b7d842b12e60d30cede32553945e7829e9b23f5ccc2e7103a08f2cdd9e75a7b36f5e63720ef0d49b2592bef3740268c89c86a6cbdfe201de0db9985ceb19399c9a1d5bb0586af3c8cdf2713299eb0443a541a47384607243c54a05915058367d3f2db380ed317a8c12c7a63e809c2e84d4acb9d9eef54c6f5af7ab59cb9168b1068f9d2ccd978fe721bad68a669ffedea3e92c76b32e3166658ee3bd0deb1b084194ce35d9a741c57fc2241e68efaa65320b23a1dd19ea8b7ec81e76f1e9163f9592eeee5af8eced0272f33512d0d4ca067f05551b265396e10014783cacac79437b19842de6ab91b9d923bbeb503325bc54869f663e6ea4ae6897701be7e11d16cdfae0eee861862000e7a4160781547e42526af51ba9698d234aaf510da81a0dbf264366153d7a6d5eb3fb08b9bb5ea065c2f5e5b6bb679d2e210b5b40e2bc82f78dc9ab5824b74aadadd89bf8a8b73a0a2f43ac748378921a73a252704a4adbf740cb99c1e1594c37ac9acc19f52315c6a846a57b36128c64d767af44e9c86305bf18ba7cd52680523a3b102fba6fe55567069d2047cbdd9605ea12c8877d399c1e66e33817731f50b84f817d1f0760a40f97468618934105eb00ec50c76db3c53fcf43fe1702907d9a756bcf439f8831d0bfac92e7058fb157be3e591d37eb34165e3c6fc60e72294c083e477626f9001c1d737c290377dfa58ea4ead3028fc762ce8a3afec2e6e132c662df6034ab554f93efac657ad34f6107d347fc5c5e53f3733e178b76014d2f9bbd06ef2dfe60e2083d8865f7f5b2acc025d912e5cf6cda6e798143e9dbbc70a0211d8e4003d78b383d66a6ad29717ca24eddef7df7cd3a7ef652aba5487afe5d026c9b102807294eb27d9824eeb6b40f083de7
+SIG: c17c2fbf8c00bcea3035bf0a62d30229db742cab1199677c7eb4eb0ef5c7b51ad487a4971b631e794a58bb0823cc0fe62610fda6a9e03f8c4c3381cb154cef0b
+
+TST: 706
+SK:  b0d0abdd8444e10f293754ac9f16e31bdcdd97b7067128aae8e4d7f11289e2cd
+PK:  1c78cc01bea15352b63c5697f1cfe12ffdd16ddc1d59e77951b6e9408ee228ad
+MSG: aa276cc543fcc62d70a704608d98ce51b645b5c24a640a5df10a5591417d108926df3f0ce1b921033309eb8d8659f489fd6f79aa1bf4882d72ac69cc58d3bce0fa89b16411e9753eb40c6c4d598dc8f4abb0bc48f1370371326c9a86bbc2ac6214478e78a38408bddafaa9592600c49a129c05392f8a7d642b49137a20f3fe9f11ee17cfa3afd2af71565e9c40080b60cd0dbc378eda062c7cbc7fe972bde4509a1de95f14df482f48aacc463cd594f66d648d3794738ad6ab496e2da50b0db2ba7b659185e4587f182e833de750faacddf21af5e0cf4c9af385b04f7be231498ad0b742d5a87c06115db230973a51427f202fa39afb9828b5f03fa327cbd52dfec66d71ea319865dcf6810f1858472d8bea3e447adfb4b60758e86b48133709732d2bcf51c76caa847b6537fcb05bb8c87dc5e9fb022b3260c1d71b149859c9663dbdae6a7bbfd6deb9d123809c241401af10719cf91a6bed16084c444607359ed8f018db111511892b46bdac6c9c613841ded886b9dec06c01e80487e48fbe778e9e97508ffda0577853aabdcaca8b0bab6ce41557aab9631c96d60977e35718b60595273fdba140f5500a8d3576f5a9fc8f3ca4c02c167af2e03d25750b42adb03b1417f2b6d219be5f8429331a26a449b5d4db2b1a09152eea2b25d2df7ef6fe0a32e25fae79360a9aee1511fda8064550937a7130971930c673bb358e5f55951f50b146d85d383f3e01c151ece6c06d836701253280fdcff4e139d3319ab2e2ca71bcc3fa0faf7c702c9c604e5651de4af5700e9ede7258b9bc148d5595cd34170e3e5cf292828390908fda961f2230ac0b8cac64739732706ce2d5e59abd6d5e207bdafea74d28d7a758f2200e4e00a0bcf0306a3cabda47024fabeae488ab5c323715cf3ca7720af9ebbf8582e1158a099d736b569b9d40295817ea2554068bef32442c111ec814c6ed415919ba73526334df30bac666084e5601c2281c
+SIG: 64408bdd2d0fc892a5b62b5acf8e3b3c73c0b5c4fa2a72e39dd608d4937f9332f73e14d08badc6270114d1f1a556cc6ee8488abb907f79ae175c352e9f11ee05
+
+TST: 707
+SK:  498497fdcc6a105891e023ff32d75f7c3748d8c52d87dd3b2775aefd8160a143
+PK:  2d79ae9cee4ac6275b05749c438ebe552b413d873cc07f14f5fa130177214c54
+MSG: be38bc8cdf46190e304ab53dd29c2bc40954fd4c6d2bb990f93b2b5c691fdf0527c260f5066187f2d0f31f43a08b360ea1ed8200651764b8fa49595a1594109e496759ab6623fa33378d800e6117e079e13fe85c81b63ebe247b3df6c1584bc7cffbdfa45f2a2ce7c237aaafef8cbca70bcabce0b847d551f46a7d15ce2a0d3d545abacc5930010c53648887d476e0d13a34fc1c54df09d106ed758deedc761d557a73b2bcdddefba4ed005997b19279b9d2de37d041fe013eef05a2e11c9a234e87cc0e16c0c6da42aaa5bf996417bf64e5b785d67dc32547c1f052178d694cf20f1698589e7ed49be29dd59fd5c01ba1d9f5fb06a75895b7b1e15895097ebde84cad6303aa0a86dbc324747d97245d70c5203be01b06cbde06ae037204d23730cd696189f7ac267cf202179929ce5410e0e3ade513d2201bfd20fefa40b4476f27bf907c762eb7262a5be13cfc047a846d20a9f2311b6469b06ab545f0ec9fc446ea250cd3b73a7b6b960c10ca4c2d6c64a156a18c9fb810e49afd0c36daab8b8b856643a4ccafa9ad886e91e544535b8edda27c90c06ab6bcc53628be18d7d6369ca1801f91c2e0b95f36d702f77234b4100719c059951e45b1f916983934e32b4d4d8f29c0a373f8d8f0918b967865cd0e4beca01327c99d5fded4c1a69ac2d4d9b78ffb8305670021040250cc27737e75df75760fec8b8d30b245654f3c12f1f7cea0bce78ab3693578af3ea61ffccdf9baf7c3ea65b88fc854128126476796892c663bd14518c9918629a1095f614e0492446c3d84b16ec94f7ecadaeb6b659bbb4867b579061714fd5bb0faa4ad6be0ffb3888bea447e4e3438c8f0eae644fbd45a3802dc40ec451b212bd592dacd4da96686dc8b2024257f25e9c830bff795eee85d87a090c1a42321e710555764ed8257c9415c7f224b537558cefdc615129f28350267c01ba0403e07f5c6067f91c85a2c50c866dc4388af38d2160203
+SIG: b0a36a2c934756348eb47c25a32c3f2a5ddbd58fcc72a08c3cead1a2d900335c3001e35bfe1f3fb5a555009ba8e96874494b97e8b09700edcb1f2584b9d0fe03
+
+TST: 708
+SK:  d962a6719e5cc7724ca4a1d559536812b4e22aa7bcb13e4fb1722d28e045217c
+PK:  a944592dbc7d77039d720256c3fd340d34db892ab13e4812d662e2840c28b6d0
+MSG: a6aa7a190d003ab175332b8f58e7caeb690854d9db56dbb6957b3fb654e2e0da991f3154214204135df1e1104317c9e3c58eedff1fc61aba57744c0c7ef486000a70b2c142ebaddc07ab065e2a855daf198a6803ac24ef3724487c1351ddeda0513913457d76860d78a9b6bc3dba66c40e5fc349a873ad6065ce7d7fdc2cc483b3aefbf2f03dd669bd9cb8f63cee47785cacb09d872c9aeb83e9868405254324037982e08613455d9521d88ea2fda020be730cfc8c07cb0b37614ccba2fa3ec498b815bb5adb996e848b38c015a6a5c752ebdac7b9eed8b69619d8c846b66f7816d1df1ebc21071cef0b251e2eab59827f6d6055084370fd27c203e86a189f1ee11e8403abdcbd1f45341a820525d8637dc484a5185d6551cb882a96b9981a5f1a821f27b656fff90e7f69bf286f752f970ffca5c53e0850b20b94f9431627094acea912a880b749a6f80bb206ccaa746fa70c833c9f323089ce0558c9dc200d5739d1e499634f2c16e54b7f6d7819c47071b60bd54dd0f273a319750fd3c510a49ab56f630c7ce6d8023d97862346859bc0b4d605224969708903760301409c60ab25175611f0be98b23a8cd8ac535e3513bc77e1452193dadf4435e63c3629b666a5ea4c4bad36eacad2601404eabd8d9a07956ec2b4b7bb6336ed75b8df8f16de42c0fcae93652e3c407cbd45e8d413ef51e8542df62512ee793e41358a1de19246c6586b3c1407410421f6e865c75a9f4a6a4788f84a9c781d8f8024bfdbe25bdc7d4b69cbaa7719628c0b07ec2c4a234fff4ac3d4935b9ce4c8a16947abe7951ff8d9ac9215e338fa0fe9124176d17bac1e05592c439868ae5a4f75fd1ea82aa454c20a939deda729a0e19646cebd822049c825c7e31c6efad45e306f2d9f0569e0717331f48004c26ebfe68f3843e90f8067032d21e786c8539e01be3ceac5954a0546c84b734d999456a7c45f8cebaa478e548007f9d3af836f754de4123f2f
+SIG: dfb9b635ac0edf83b7b59d0b8409af475f66fc9946af0b7c63ab8cf5929d4701a1bf66959cde62fbcf59a48ab3bbaf0b9a61b6e00b2181eb934282070a5d5300
+
+TST: 709
+SK:  e1d1416518921d07c8c39e2973d8ea1249caa8bf659cc36c7937f84ece7ad4fc
+PK:  48bdcc3f1a5b8058ed9a32ef1cc48cf7a8ab76a6e4519e5a82855241ad6fff8a
+MSG: 3d263de1ab91e8dd7b317f7a27fb60a6e1838c0c793b03abbe7082b6bda0c7c46062262192c88b65c026c174584d29649710429ae44a46140b4c82c8a0b74d56a004f8e2f5c18f84f0464153772f8312633fc6ad28a7d9fb55f7d78cd6488ca58117eaf923fa28875e2b3189893185aa3ccd044d3f110e2e7cabdf6f814b9fdd6733bd5f307a87bc73b6250d5883936deb1db0e0af1be7ab329b5c6bd935bd8f8dc888f0d1c464edbc023cbc080753ee8f799f1072bad1144dfaa615a59e2aedc662e83cb1f8e52096a7ee483bf873b25a0c04c1851a0e87375063aa1a94fa835c052640366b79f735d3286197ab32ebdb5123f6b47ad3f442c44c530a68f8512759e9cf386fba07b8064bc8fe83e245495ec45f8938f8259dc8016205f78d3954442ec1b445d83d95ad1805a5e0e8b3d56b870a20da18d74f26f550a9c7534a4144dcbc1c3cdbbe470cc153905043088facf1d303559de41e96c0ab409bb36dcf38cc9038a6a4908dea82a653195c16f290a7c3ac487636cc5bcb18d15a14ac624c70b6f6462bf249e000cee924018bdf7dde39114cb4f652e122e8744da28b0589e1284d70d9f106de16d073648080e6437ff384e68177d5cb718e2ce3f17ba1e990ae3ce940660130e93750b82e2fb41aa369774568d7cf286725e3c58f63e73f8697aeecc717c5cf1af7ad74f446292c905d84e22b23d4e0d2604bff48fefc40c6204b5e34c042292e53bec9360159a5cd97b2df5786b8f5a292c0b39d14a870a4588e67bd12b2c2f7a4408462851d2aa787971d9315190f42cc588af0d2dcd91f31bb715e9250f1192814f7b8a21fef4517b0cf8bb8a1a1a5f500ee219dfb46132efe8e90bc49093a5559f9681b4fb59e5ba9ef3f05d34eed034c14d77ee95ebd76ffa5af0befcba18fdf932af4854510b75db00a7257b234887d49607dfd16180db516c7a20ccfcaeda6aedfb6a2377fbf31e67b517655db73ca29e118624d6080
+SIG: 4232d2a481084d1196db62f22dc74cf2eaf2db0df05ad7cdde67bfc29bff56cde019ac9f03d81f1827eb1e3b0abe0204ca7f77fa874ab5268354ff08bb7f4800
+
+TST: 710
+SK:  2bf74f004d7d0af73a83ea208cc206723d188f4cf607bcad4b6980268ff21fa7
+PK:  8fdcd99352438beb52f0d1742bae71844512dd0685aaf1c909e38fc4b5aab6cc
+MSG: 898e4303ea5bebd200a5f7562be5f5032640a3f5ccfa764292045a1a368d02aa591077d8f304f74dbdfc280734454ed8c2727aff392c108c526e527e672c5397b2d77c01f7741ef8dcc2510ee841b59dd10f4e1d3ac501af7cbdb85ba31129c262fde1a0c8bc83d6ff944b6bae3fa7fb62587c681d8e342965c5705fd1a6ab39e5a0770ee7798d9fb6c0018a514d53af848db6047cd02db352d5563b53662373b971935a1ac2b7b6361dac6748771813f7749316694961b940ff3805811a49fa27a9ba457ad28848c697050e0188d0773e17fb52194e190a7872a398f31c0f0ae06537a273ffb50c2c816445ab882811922c0621556c46a3a0ec40bfedb411e90b6db1ddd4bbebb57d10df566a63d726a33308514ce3b499d5e526c22b956d8b99913dcb13e437e947b666c41c54d8b3ae2356647e8017ab678386c927219ae7bddc0d821265f9dc4ff3f8ce5be60f8e9defc5ca335068ee29fe8304917b788784a2388a320192f9325d0e6cfffea21e6eaa29e7707f63a9ea4fbb2558e3d0835bab1f52361037ae59e503ee96b9d708a47a3ae4bad113e2a460a269ccf25a0003cb3e68a551864e59840914791126f954788b25b5af5aaf586ebb87fa5f377b4d7d7f84c000dd2cb440e214d38d5ecf70f20e9881828edaa1dbec37093db960686ca123f1ecba6336b37f46cf765be2814b9e6705bc9d6a49318118c7529b37c84ec88d58a8453dcb692c9a36016b948ebe6fb2c1d0adf5f198ee3097a6ff0b8eebbad8b0769330b18689516bc0fe668b0d05e3a584fcf89c49db501d61c2def7ed3722070193a5b683c5087ef274ce6a193dd4a303536c67934b4660a841ee1b446a6892b14d0b0aa3e98fdffd43c797add36583f74c94d0e2d68e2de818d9af200598f0b2beae169c8dfbc4d397e6d1ceb6daa6c9f6bbf4f8311ba26ffb194d44216c51305267074e856a1d6e922780f4798e2f220223fff1dc370c8e34514aba42df51
+SIG: 3eb5b339e191a3b6168545da5fb0ca9be209043919b9c70a07b4a7a3bf64b102f6ffd6d2b02559dc681ed3b9c82297b201dc25c4973880e155e13a29426eb40d
+
+TST: 711
+SK:  f5f7d5b73c5a65301b5b4c6710ed12c16e7903177db792ca715e23389d05d83e
+PK:  7c4762e979f0c7e207be1843e2666aca27ea89bff5b61d573c985fc7025e1e28
+MSG: 7c9318d56e63f16535436fa45afe278e74e61881bb468997d0418bc720b630dadb8128b4b65ca6e921e501813df9fe03b4ef0aae8035dd08c5f820ce5df12ee118d9c36d3b151a52c3f96ae1ca4c82fd19da669ddba94febf8eac8c42b447babc8a60b36e803624f7d2047bd8d8a153687f10dc1ca82100b7c87d32370ec8f2671ed7d067cc80587cab8db3a71ce5e406327f763ec1b3c166770a75536630c815fd8267582d1b5051f0f821c02150b2eef349b50590314aa2570793fa64a76ed2ed83d2ba1f9b9f1163154612b49a64ad8d5573c25b1cd37c41a44e3df78f1053d90b068f0d37ae00c4a32b1a3ff874c41da4a7043392f18efe5518d76e88b41ced69e6f4c014f06ebc5146e61e82fae1c49c37c394fea34199ab86c11a4467a374e40255a05d426971430d56cdba25a21ad779cc7f62d22cd87b60f0891bd856a517e14b72a9ac7672e4e8fb374a9758ab0c4e5964aae03228973f173a5d42aef9db33736c3e18d8eec204a1a17b9d04593dea4d804cbc81b9ac5458050495539999a9985487e7ca11c37582ef85c841e8f065ea98fdd6b1c60dea1ec2883521568856a6ebb2749f2072eb43448be0705ed477cf4b2004865217de5fadbe2a0f9d6b84b3fe7f7bf6c77537496246ec796b8ef2c04f68ab5b14fce0c6d287b836227d9f08fa0ee19722f6798a5d8280d107cfc1bd592d9ddc724ea86fc39dc94a394019e3a3de9e0d1c735e862de2bb9525b5fb4bd121212bfaff9ff586ac3c75c5ace746d9ca307f795ff2697f2b41a6346ed23397eb38898691e6f66841637d0ab0d968309e0194002309015416e74472fe32425d45f07c7711918b1e5790f572ce4441042d426033792297b5f81e0809bd9691f0a505e3259fc03c9ff107eb9b48795f49fb09c1bab5659d39ffecbdcc403e3803dc012438c2fb36f683015c5df0482cb7d7fc5757364a0a3c10d0e1259c01fcc4dd5494b5290a694aea3f6fae547ac576f
+SIG: 58fb392f82d5e52ff072cc77efe048f2235250c71125ee821c5f3b393bcf2fa46be4c5d8caf13cb519efe0c2fad9ee231ae9b6fd1fd509c98c69c2d36c753e0e
+
+TST: 712
+SK:  43d4be6de9cb00898e99ddcc2e1530110fa2cbc4376c485e9ca57fd65586d8a3
+PK:  3632ad389be2fab3fba0d804bf6345cd322eddd6a75d8c37fd4b5ba1c9c25e8f
+MSG: d9d55dab0fa6da76b68e841c24d971bac1f79af513d834e426a5d08114ce8b54ce8b7afe016b0fad03ee7450c6c3097173681a4b2eb9f9c179a88e7cc36813f2f5d15f7998afa9fd4e546c73bb42e7f9522be6afabca8c7b64fed0e292e4375f3e1e5fd9fcb539f4e5e543fb6a11a0df321e70084aaabb70a9950ceee3d879c386efca1e59c3cb7c45b560095e7af00ff52f8a1aaa9ccf092f0bb806d97610742ac582a3abbeddf39f49d229d32a1186d021518d74728d13d962635d63baa6743b126bf458fa2ac756fbf88096c8d3340c622390534a743f1864d54deab5e5536372ce5ac93762287414eae158a76bf81df5417cf4c047be3ac1475c517ebd3ac1d1d1bdda11b3f99c18173e030acd51d2b5cf79516509415405077511bdd9cbe17d04f47805e98d0d145e60a5d0e0f453cd9b5c1a24f12b75e8cc34d5e00691ffacbff788fea834d9d779c1e610294dce19170d28160cff909bea5a0aa749401740ea3af51e48b27c2b09f025444276c188c0671a6da94b43d1e525e6a4a8a1a73dfedf12401846ba43068a04092b12912270d2b60df6099779756b8bbb49ece82d55f0f8db1b80fb4b59bba860bd18c75d6c834d69442ae0314cf2399f5392a3c6728c63e5c516c4222aac60f916dd63d1d0517e8eb10bd0e15eb90614deb296403ad15b8c12b9e971ef2f01e59fc35d90c55a8e20e9437dd434b26d5c2c6ec2d53acec17e81e47831dc2de82183d713b59a4d1f46969ddcddaf27f44e5a311aaac39c3d5a97bc90cad712f46f85e6c8fbf5d58d8bc3ec27d310a9eaf2c369cb00649770390a3f988f362efc155f56a146a62650547e9153250701eead1bd01c89462272dfaf0a431af4bd7c3db451ada603233fdad3aa8999aa21e2d3a43b0b56fc6a9124d33598b3737f4e5cb258beda756ad2e17d0691d15d416bb7cb07ec8d8c7af5de80e5b9394e320c4c6e43efaae684ad00f6dd20a8750e959c2f04206fc023aa190c
+SIG: 86ae9325f80b9886c8381f96a18c2120e6db016a0d6ca282ed93ba9b61caec02de88efca8b8e916a4b16a58525a2f68d21e5fbe67db4c4d6209595c4abc32b09
+
+TST: 713
+SK:  7d010d760f24e5a2de34089c9fdb19c33b155b0a37ca455a5e5b1dae7a073176
+PK:  4c877b3c4971fbb551166e214d1c7624c52277903c59a562a80b91a85483fb47
+MSG: 86e2115572bf4c013e6b4b04d0b03e606ee70d929cb8ec36f4e2f355db3b5e1573d658d17bb1a310c16989a16b9558922ee493f359042103c4dc1b40dff7709901fd5830133f42c4651eca008b499ee4f84cd4ec1edaa78256edb62f24021a0076256919e4e2ce0a5a20f921c278cc299159644b5e3a3bbd089dcbbebad3766aea77e9f08ee5f7d4c19d8170bc3de1ba779a769914f965dbde2b61bad214c508186041f76c25be957656f5cfb7334eb838a3cfbc55cfbab67adf1552619941b835cd3e34103b18b49131e82096f05f570b899804bab8b6cbaddbbc02f9f3b559736d99ca7b02d3268fa273996fcf0571977d1cc3008c4ef848970ee350b158c47ec277add4742fa2bcbea9bd5549c7bca038020ece68f188c1ea3a62dd9a073d4c138ca8a9ac0408dcfd46e36bdff73988a58b9617caa08bd41bf3e812e7824f0f7e8146a444f36bf53a1cd892039ccd335f5a2e79745eac96148c2a299947f1b2e328a3789bf13c6d73506f3bdc68ea48abf002270fe4ee9ef9ed6b10c2fbb4ff1275b9d7dd35d8a52e371758574cb466c57b5abc242976befc8d98a0131b9bb846b219e4669186a83c056cd8080661de16b51ce5767b22e9a93242bf8d3205c66a673ce783d1c0d37b6300fbf0d6127940f88f1819c450dcc90543ed794f1fd44e6539febaf19a4cc98870014d7ccad74d1876a123ecd145516c743b4bba62d821ca9a7951e0dfb23f38d9e3a365fd8322f2ee4799e9ff11e1c5c30b55a355c8a5deea81a545e34705ab56d17b1fa06ed76415556702f364808246f863c319f75cdf6bd748438d1a2eaf4206c560bfafc235679ad6049c1a01526fcb9a3ce1b1d39be4df18b15fa0ea55272b17ebdedf6c30498a8a14f2042be1c2cdb09e9ef3846d6659a9f6d673df9afb7eded04b793d9731f0accc41468dc1f3236c99acadee6239c361b8bd7e2d0cfe8bb7c06687e08e76b71ad57a036179f291d096ae2fa0818ef4bf4866
+SIG: 5570613879ae22778bd54f14fb6e8c0256a71f3d79c3e5cd8e41aea8cf773e24d29f1f1b24f8c80d2949e8201465dbde8940b1fab6483b085d418e251014200c
+
+TST: 714
+SK:  aaaabb7ce4fffe4dc35747baea2bc5f050bef06ee0c1fd632a067fece1ef4fb5
+PK:  820a2442d5f45f3c791478e098fb3b068da52ec4e8dadec85065c35659f437e0
+MSG: f9d28597a3e2b64ba327ac5cd29f081e74bf461b2eb2d3cfd9d5e92158d21d1d2a47ab50981cb19fe3f8c6fe488249b1c49fb897a0fe21ab5404414fd914875c220f1cbc12f5c38cfba79f7ac303a5231a372b02fad6c8462f8cc49f0f64965b651dccef0bb9608215090849177be47b2d3072944d36e856da185c7b3a689f7edef988338e0963ed31a6b0a80d5cb0b1cccf6f394837aa6f8b2f3da5efbdf4d360d4bf4dd708ce6445587d942b79761ce951b1bb4d9050703618a6d930a80c69576fc4af306a2a56dbd884a05a1e4e9f3136cd0b55ae474bb5d3d0fbc9b0339cec344fdd085c1928101481c68794f5c890137108cea791d21f81683d3e1a9eec66ace5c014d89e69808e5fa83d3812ee680f5a9971681b8adcd4a16e9a4c165b5ef9932c5ed825237fd5037bcbefe4cb11564fa707c8a93290751414891b1edd3313c65f8b91c2e925a3c12a9d3aa45fd5a667b78393c3e39df88a8f0d1148b5311e3d87c4a92e0a3fb915bc90d5558d05b475a8834778aa943ea39b8eaa95ad1832e5916ea3102d7de0b836cde8f3759dbb3b9d56ea817b3e49c983210277c2c7c5b0db187422532fca98a28b3b659c6b815ac126fadbe2f400c73e9d2dedcbbd2d3a365ffad7e666c896e31e61b384ed3a9fcf1290538df11b9474c6281cc592c71c8808868b4292c17ece6b3edf5e3542a70b911593e93f35ecd9729bd8880a24eaf41fbc6574dfe167ec2d0e7ab3df5ec34b8b55d548ab93738a2eeaf21c884c5c8551db2edf2b049f1a2a84fa72ac8978a4c27809f209c1b2195aff504f699856cc4f22d44ebdd0fe50374468d0b1792e574b5110a1f4cd0e221e824a78ddc4845feb46d66d633d23cd23f4b6fbe4c8ce16cd1af61536da5fa67b10ac7555a68c0e0bdbf2f8d72309d995516b8118bf43835d0a01c08ffeba3ea3ed05cd2d54f0eabcda05d0037d52caed3b19374faf73999094f79055924bea9aec4470135f5e8bf183c9d1c9
+SIG: 050ae8aeceec9627b80137357a22962ac8b45048661708d394d0a51aadc381fe8535023d6e1bda0e72b349b50b26da7c3a3085e81e9dd6cf127868fc5baeab01
+
+TST: 715
+SK:  e95cc2a4d1193b7539fcbbeaaeed985b6fb902dd0efbd6387457550d0d6a2fea
+PK:  72a1ff1e9bb11c8d88968a7b169637adee438e2263f006dca4fe02fe066cbad3
+MSG: 84267439201b0591db60c0f17a9c15e45409295652d5f55b87fb351967c846a567f5cebaaed1762bff5485f04853ca9269f464094e512df1f02e13e517b1daa58d34caa2d5ff9f9e79bcafb4ce96e8a089258ad61343b446628ebc4f5b2a84d03b72ef3f738589fa13c42519a828299a3faec035037bc10b44e3bdfed9e0870717cbaf31bef8b22c4ea16e8157fcbc63eefa39ed822efd4215c247dda48786277ec030a86c0ef4851d673cfe752d0677883c2c452038970c09bd481714bc3fbecfa4ff2a3c245695d7ecc2f4dec7f5ede04ff6db43e2bb91c066b649ef73fd3be860cb83fa80b074149f431eebb917ec8478da870c11e317703859f9f2f4008a6c7c754b06e1f7d2479689da84e88922f38274985e11ce13cdbdb0f2ece68fb602ade03dd549a362491f4a203ff80744f663c523a026b431aad45c5829e029ad6256d1276fd7b7a12ddbf1727d9e233fb534457370a426e56fb39cf404a3ecbf0c4b50bb522dce981e0830fd8406e6d9725ceb1ddd3a1947937d90e04d768ae1d126e2aeac21b8c9efc54c40961b7f4e9e88025f7e0b9de901ebf0049e741b797997d8db78e9283bbb5f90f35a2c4dee273142ec258c02ad0ecc61cc5c9f12132db28af41c1fb78e524be5327b5ffc35962779fb11ff0c5d3ee0a31ff47e73b1729dfa46e8986b1b89abc88ad06abd5b6f766d23abf642257894ebdfa79e6309f1272374ee9433677ba13e451baa95330e660c8052ae872e0e32e2b2d1286d01a0ab5810424ed8b9405465bdeba03b698384676fe5ea464a03446c4f7cd7b43312ecf151360464571ad28610581fbadb945a1d68181deb403aa56eba0bb840328eee36103c7de073a6879c941c7554c6f6f2a080809eb0e5bd0e130f29a229e930db01fecac2e036bdf0e001e2a8ea3264f8649d5b60c29103f0b49c24c97facaf7e81069a2b26ab3f933f427d81272c6c8b7cd0dfb7c6bbe9c0eaab32bbda2218b9623a2119aab1f3eb
+SIG: 1b8d7cc2adf36cae1631250c82431bd88437163a6349ad96e7a864447e9fee753ac3655c9835b4d1ecbb306c638ba5402ad02ba6d225d96882889fe8d204a604
+
+TST: 716
+SK:  77ad0f942c37f0313e6b0456dabaec81b2d61f6c118ddb29eaf3ac5bf19504d4
+PK:  692d2da5a95f48611a6da89cfb3b3540f6aa0c850d6d98deea870e397fede328
+MSG: 87e6dead2c85549e3d8d2588a0a3360603a624fb65aebbc101bf7f1fec18d0b28fbd5dbaeed38752cdf6355ce8dc84e18ac1a4393d2ab888882c4ff1c9c8137f83bee36336bcbfbb72d5049e0a400874514fdc3633046e89383dded93ca31fde0d898e11e9268d3d5c240666ed5527613da79fb7e49625b44cde78b41c67902eb0216b3a7a3e560e261d71d764aacf15959c17fcd6176fb25e249ee6bb1b3bd7bd90f60b0b0ffa0315a065a24bbae8f255bf298d7e4d44f0b430c415b4fb36cfa6626a83f49a2567f6244f40e923add1d49a72f57b1530f5b379de3a91c2e9a1ac79ab37bc3b9ba73d8828136bcc87d2c01190de5457facd90f369553f7ac521c5672b0867dfa8da3b952ad95b67dab99b4820572f2d4a298e9518637779289c031b793dee859cde7b24add649fff871248a6602d2516279da6058cbb696fa8b1d89a20d2099e646443210483e5d4134e928faeb38a3b508199e0d69bb55ee34774205c0a61205b50b08febeaa401e6e3a51a2bf98efac78b7ae2b852c5395a12c40e2c7dd1b202504b5a7d2f7e4fd4f8610930d2868cba8864339e041da21c0715f41b2b23d14d0b545480bc3bd7d7215cf2f816a3332081ecaa08c0f8b99525251f57231b6750c2dbd1109ac4160486b768324b6bac87ef5a226448c431240328f42cca586be7aff3cbe7605fa341514fccfb966af3d4530e8cd9037a11ce593c2d383e1035a0c2eda098de90d50c5184a9c01b57f26b94dedd1454c340637ecccee70625754a328c65f42645b5e1a5655eef97dfb1c6308edf49fa368d17d17e06adc512b3973ea652ac40a9978e1bb1b2f86c5a9ffbf60dcc4f6bbc98a64f4de65e7ec61721edeb0e5238456f761d2d1293af0de9f793b11d8cadf01a94319a02a4273ffc4d3ffa7b34d74fd2e0b100fca58b5325f907a749193e751d6c116687aee3747b59460d4ef156e72476eae1b8455d76e71b306b98129b72fe1cb5eb405a7c2f4327f3862d4
+SIG: 696bd552dd01db80b3d67d61eeb7ecc56878404ab119442a1c7422992cfa35aea920825d2dafd892ad7eb6825ad999aee5c83b7b507906534f91ace759c5510c
+
+TST: 717
+SK:  29321469ee9f2bb165a069640332b489bf5c3fab682e93dae9d86317bf50c52c
+PK:  96f730f8ef8970268dba0f7570410b6188a1a3c86397740913d53ada262ab87e
+MSG: 9c712c83d54f2e993ca68a9632846004499c5195448ddc491c3a0d2e3a666d6b33098e4864fdf86e619d50f10b7cc6c39b3ff2801a9491f6fa97c5f1c4afa7aeff31d738f9a768a79c73b25577310fb0ad4faf8543a098f859571b6148e8b52926445757d5549fd25a26518531566379d1c274e6c6a9d64132e4ac25ac9af9381bcb885332113f43014a139a81f8d43c8a6ab54c11a5c92e06191c1e51b757ac9f11e3dc15db4486d167ff9f2d65e23e6c96223d9aff8d10d1502cf3dbce5e357e6b12dbe9b7e997c3d0a507d3bae3cfef1ffc8d056ef7dc72ddc1c81e310ad205be16e77f2738354b10b484d3076c27e6b4f166388581f350befe22fbb082b54121ee59ecc7ae5dece89882acf26cb747ffaa3e2d05a696f60fd9e829c709d8f02daf537b2369b891fe6ccbf8dfcdd7f4a364b19985be7edec67ddc1db713c0a90fafa48837772562deacc2d2a0e789e18a8b5b3bd9e083ea92fffc3183d5d414153259b33a4329cfc80824ebcbe044a7e33ab8a24fde54bd9520aea284b0c4c4fa9427d251c0ddd013ecdd8290ef5565f608508e363589e529d84ff0f26f9ecb03052d5897fabc917e56e601b64abfe5a17c3950289d0cdcaf1f6005a9f8106f43e17adcaa2d1e269166762f8054de05135d5d1393d7000a15b87bd68846a89d5bc22863325151aac843f72278ae6f4af72a4e449adb7eae6d436a1ec7e58e59b7b8bb9ef0ddaaa001826f8dcb446479deafd8b8d542041c19a05b1e0ee47b4640910c31930ca4e20b105758ec75f1950356947f6261d0037fe30773a3ece6a96c8d5433333d822c2777ef7ff8be6033345b5055d58f5eb3729af5ae8824f331ee0731c89b20ac118f550427cd958a55f6b1a2888a087bb7db55bfc73b29429b4448dbe9119c45a87339b4497a69a4cf833e8f3770cce5e01faf5e73bbaf627683c0a28c73052fbece203043389dfbfd45495e51dab86a252e5bc1b4b7fe2807e3d0e2363beab51c67fb31
+SIG: 4e1aff8463bca1b7deb1d3773df2e7a06864111b6dc42a62ae98deb2313943b3153ee46696b15c24efc2a808aaba81c78e3dfa4dfb50ca9fe84445ea68bc8e0a
+
+TST: 718
+SK:  04657750497e68152c43ce34a58d2106e64c557cd7a84ef05d9eb82e6bcb05f5
+PK:  3b3a1947b4cbf60b826d609f192dc230aa9b9baf4cd6a6092e495f1d2e47ad62
+MSG: 2948227a890f6f845b775e62c53af3805064a1576446f085d90f8b9a5ed68df1ea393ce479c4414149a9ec5a171036424dff0344b4958f6132298d0e24c926d28ad9d79f98c6e6bcf1c5767606ecd291c6ad47b4f9fb2b0201155ada627b7a1fd5b07419874083059eb52b2f6ec22818b78246228f3fe6355dfda70ebb9bbe73229378736399557ce24b30bf645a14e2256f70019b3336b203fb77c6ec94a7a2634888feead4d72c2391e99e8c8d533fd8a42b08c11f887ab2deb6ebbfe3d251de63536c36cd53422398e544cff87b07a63349fc5085dde93a1bfd7171133a2043981f607522c8133c63428d1b92626c79b7358e7021cf1f412a78afa7cb3f59ffef9279885a5bdb2466acd34cd51580830b8351ebd440a96623907ad1f4b56203f5e159a429e3546ead0c011dbed09028717e3c3dfed39197764d4d245ef228b98044718ef4d8822f21b2c5685038473bf93dc0937451eb02d31a46c8dc7e94c3e8678c83b98a43818f125b528b476aad31d1584ffd48f149e5736e58f94205d3889e567e4dd1eac2fac1f8f4dc540e5322460fb940e12e93c4c98ded1941c1904f967fb4643684c19a4d5c441d60b0e9f40855e523fe7f99107657a68076275bf84b7c69a3f2b3855bc8026ba9b00bc6fe34b99da0631700a67f52b34e1796339887a48305121d53ab4440fc4b5c9bf72394d5ed372ff18ca3f007bd02df651dc3ac438275f1a3e52422b86c4586766a21cd89f805805dbb44fd89fe24fb2c0b40d1b754c335dbaffc3b3bb8bb46c74c36374504042d86789227599862312e99ca89eb504cc3d75d19495aa86b20b2736b121bb2075c88ed4a3fbdaa6b2c3f76d1ff5525d3a2863e4d83c72bfe01e10278809474e1822de2d96283489320029611aa9dffc4829d66869e63494f9aade70b77a7b80fbc93e3de4d935913752d045e13b312c5d082f6242d4985b053b3783eb02c6614963dc0d55d4cbe887bae29cc18979e5e2ea945bcd40d89
+SIG: 7e2eae5a293f418391f6d85a7994b07c452280017ee653bf617a8d5be24cbb5d0efdfb7f7f001312260f344e6fb915ad8d7de9c0519827c05726f9ce2545dd0b
+
+TST: 719
+SK:  8bd99070c50a9fa418ef7f75c00129916a41c86070961ccb2b202be18c2d10d7
+PK:  ddd73308fce8ca6552d039428c7a1a94923320a31c0f580d3c235280f03c1830
+MSG: 485f8d680f79ee2d828be7d018a65e0b64b0f0184819863e7110eea8f299a72c4dc87f8ee8a8aeaa81af91dc71adea79fc9797421ccc646e6cd5dd48b4dec1de968693fbce0d0021a3d98d38a8bbc58195e6dfc3b5e1461b2a594103e80a29441d5aaaf889e31cc865141f0c6b2c8c81f721679ea2394ec6e4081ec203c2ea397d9484757a7a0ecd53e652db9df17bea0e32fe8b2cbce0d1d97b961ed74e8e622bcdd3558b7c48695adf18aae6110ea9a339b9da407a9edaf2ab081a681e1832cc215b1f08a67d559a4744af7cd50318c206ee91157582f82eb6c0fc29027b4461c30733b8169d1481322c4860509ba096bacb71a579246751d567540e41431e14f1b46ef16eba276104bc01650d5c4926e47c9c6040784b043cd0aa4854efe8797fd0462d4539f38035aef08b4577c1a9118d004b6d01862f5276776dfef1371864f155ac0f078389c205cf0538d85fa348244d7a422911310ff6c10132b1598bb445c7e2077b763c473d1e7a61a38b64929a648b60b2e543543739224b40fbf6d87f1079c30bc873ac38991d51b89e9d261c4bccb375355c072c1ea20e4ff91d55d9f7544e90d1c6646c59af72424d8aaa8e0aed07b3889d4e450c1209684ce138d0c9da079525f5aa02050af570e4315c2fa8b099b7765bfbb894fad359b8e24804ece052ac22a191705335e98840a624e4cbf3a1a1a327812785b2c0f5d6381457b72fdb633e81938bbb54b8c37cccb5d59c5827c7683a5247544977e984442178d0852906ca6f945c4229eb08ad27e6c275d7b4ec8dc25fb2819337e53ead6c7aa787f91a7dc6ddafd536eefcbdec2c50167be34306a82e16d5d52b3b1be008a7a611274ce2cf8d62e3b900c09943be70ccc77b070637c25061d61be910eef50df18744c33e76f6701e0a8ff6297fa67e4b4108c13756727a9d74bc9e17983eec08f866b7c7ffb37f3ccb0141a80feff6322b2ac62b84ce2797fd98d6ff269a41a0c38482db679862a38cd2
+SIG: b14a7b262012c5909e21d587fb4f29a9093c8e1c2999816a82118fefbf10e68ea898bf0da18ebfd0341ea8f82a1844c8e0dd5306e509b9d0c35b473a7d209507
+
+TST: 720
+SK:  1af4cf6d24ab3782867d96a1c275ceeb022c691a308e6245665d616bf67c2c32
+PK:  19d317ea98d35ba5fa67c12ecfb32750df275d7a45b8e211a7ac47ede7712d9f
+MSG: f445fdcfe28c17bd4427aea5676c0e1280841597e9d66de7d7a71723110939bed00f4ebaf9603d53c9cbf6271be547af29b2a045ec41288a7bb79d662dc210e215957fa84688c916543e5617f560e4d38f73baefc37e11914e47c515067851e8ed21393e13dd19ed9b73d98945fc826a258e957dc083dd8e535c30a54b4266dd71d113ce856b46282a18033627a98e6472ccb463ed3d96fa7b355d3b2c2a2b6010dd14f4ea3965dd87be1c429bdea8300b4b0b44458635b4979f5e3e8eb5c618d4e13e1d688bf88c7e4a3d938e84336d67be68df3435c5c99086321c02e13b4a12524b34e46a0b4d27f30d7ed4f5cecb36deadf09e7efcc755ca667568297914c6bc240627d9d09aacf85415412c0635623453278d9bf0e10eec65fc72affffa9392dc7881d1e5c760a40280f16b1475127b91b69ccb65dc4b35de10f94325c0cbe1c47019a2eaf2b4ba92d785229aacfad1826ebbdebefb7dad4b05f88243e15f279766e3321dd8dba650444d81fb0878767a9c63534bb4ba21285a2416cb8f856d11a96e0a8c8de1e1a75132f1564cd994995690bbed2ee154537fb6f279fb09c8dea6f6afabc62856e3d128fdfa79fc4976193bb9b336861e47b56dc2582393d2e544651ac85bc58e9e6a94dc4c39c4ef72538a14f856cd95c3e2790adee03ab2e52ca0ae471de502cb19e676af35f5f93d840fef9606cbe92d8bc25006105d92344588838842c3be505c7350e351b735e6cc6fb79275b27bd9ebd36ba4d060acee73b5a315ceffab86d06f2168a67065578196a0ed04a4dd71d6734837db083857ab1eb5e0eec4ffbac9544f4ec19bde194df84b1c848341574bf10daee85b8178196fb608123a808171d73ce4206ad65216ad1a5cbde40b19d6ae7f40df97ab8432e2c53a504ed122e25fb7a51c14354ab3928edeb39c29eb246b74a076f89d03504f401bd176b5cffee4b9db097c45764f51aa376704b5a7f210b3f1a905e25d67002f6557ebb749737cda31
+SIG: 7eb46cd0de3155b43747d732f1045d8ef74492ad827a2245bd17102828442e43a0ce7e8b268ed7fd8d3e7b28f072795da3e070f12bc4e23eaef57b853cee880a
+
+TST: 721
+SK:  2aacc8197ff8fae1c1cf3862e3c04a21782951f8e48e40b588f8bc7460c30a03
+PK:  9a1b01e2154f1c36a8e16b79ee7d2d05b8712e0d27a061a6d41d475778b0df8c
+MSG: 5d82752ce5da3180faf4787aedfb19294b4348a1d9202c85398331323e0f42b0835227e68e1156f2d4ba2fe450e6d6ef2b92d89bbbe4096e12ca8397eb2f45e676f1673aa41c959fcd30d5578853b5dbd1c0d5b3a0f0d870eca71ea13390111b258f6548b32f37a05e9744a656fd778d65721965c6d9b328600b45704770e04b099790aa7884f00d7bb7659e337210bdc23eaa71d7b016030aca6223b5569bdfc290811aac409524dccbf9babcbe4bf20946b544317ca6f2f91831c79fb273b6404eb4e61e1f7b106ebd0db9f2b1974d2f031bce25803606552c3441655efcf2c7ea52adcb30993d85f2dda79603e9415a023245a66c07a956933146f53c993c08891808b8166b30721fbd1f8a1b937d14070d786e9eb451f2ab5142f83a60f35d76ad8b81d6a57cf368fc6fcacc0c4758440d9cd595b1b0942a3655e250da983b7241546dcfbe0ae81077650295409ff9e90977fb9960cbf40a2af5177402ba2faf50db6f1a7365cf99e992429e38db43ea83fddc95a648676c0b16bc952b15de99d52f6b5233da4eae1978e8ba25e6235afbc511c76c4c874c9237922b1cef0847d07a80200cbae3c7c81fcbd0d17252ed8c61ad1954fc862e1e04444c32086fee380d1c17541322b9a60da662352e210e9ae215e353296db922339aa17d2173ec31f1c530a24b1f348a31572e1469caac808f9c76ec2731873b803ead3e54ea24bc24499b9704b3bdce81389b9d14d49527c04b3bb9e3ba6d946cea58cf786d4d28b89b41c58274035a86905ad95758c3161366ab93da81e6b4c808364e087daeea4c4c5c2aa6871937c5feaba2149f01f738f45396e66ea8063221e1c81c05255ba564ad440cb5d07cbd4bab941ea593244930bc5c289b3165d3ec8847ebc4b674c0a49f9169adef786d7767bc8f213db7d95c06e99bc11e200055b65eb79adaa01bcd2c85da43ce6370e12e349bf6d475487affdf92e20a3acded1d76f9e83e919e98def195072a50d0c571dd25
+SIG: 647cdd6c1a67290e57676a78113aaadca69ac57b997715c509895b8c5c94e82c0b6aceccf3ba8bd7cf61752b1b19d13b49f15f8bfa046eb442a55cd5bab14202
+
+TST: 722
+SK:  ff862156c7eab681c95efff8003e00a14f1f0d505d5507e6e5b39179df9b1cda
+PK:  e1b89fb31114ea46107ffd0329f1066428de54708edbecf3ed9d4708cd143fe2
+MSG: b3d1db72a6a985ecd70a2cff6c18c179e217d4f410fd3934969685901bd071bce6c2fb6763e10c6fa16e75a1176066b8ec81ae3a8039e71dc2cdc64a40fd62b7cee7be4ba0332fe45d0b60158652e33f8d3aff3cb4d6b021744d0dd178b1bf0a1cc1d3fe9321be28421eb88263a124f49792d079475a8c555ff5690873514b5d483e53217e0cbb12862b850fe390c8f83008086e649ac904b018350ab49157ee9bcae6c07a4b878b48e25e984fbb4d36b61d689b13468a28d1e387e0e88657f8c8ac9586a6e26cf94dff6f8264e3ff6258865c6dcf857b00147886e175df0432e32f04400e299f21188312b32dfc050e7b7e87eeaa0cbaac6be9937a5e0cc31113de7c8b233e1ce8e5d9c564fbe9f37bbd411df7a5e44e6c7ebb676d85894dccf4865e4dda0cadef2bbc55000b3a29f1f71ef4461ddc3b331d91566534c5d6d84c731376295320f80adc90288f9953554fcdf9213de6a905210d4c8064af91cd98325ef91898d33d70038202e32fb6709ca3d788fecbd1b841fa4e5e9062d64267c35cfd444fb69e2f6047f58b1c2af4cc7e4cac2f890888360592113e96ad3a857ed05eaaba6f9153ef89b93e00e8743733ec472d9b0eec1cd8fa52425c4a26bd7df73a2712bebe51ae3b25eb78db82149031fe7b281af6cb7714edf89de915f3470f153eed7f456243bb90342e190e647f39e046883ce28a892003315ea379429e9582a935eb78963396d136845f86c466e8faf2272f43ffefc2ada5601f8a6b2ac4cc6b92820917f2e0393c8faf982d6c5f4f230e27ce2278a7237747fa85a9c857bf1802c3eae0d235b5ad58497d66a0d3a9baebcc417f1833e9cc4460f975d72858cd118d7aafaf1c878297cacf71ac75676dc1b4fb51c1775810d03537f2d766278b9971bb97d3c49b51feb26d375e0cb9109574a816f84e76fc7ef072d5793c2f65ab2efd9052e6b8569f2805861c31a7344a3c44069a94320d274e271271eafa3bfe64de7537846a01e51fdae0
+SIG: 4b8137042d6784757d4a9c06bc7432f4809b1c6a903542736d9a57668c20845c17d468557085c57fb63213dad3be0fa36a118f7c1aeff2562ff4b8888c26900e
+
+TST: 723
+SK:  582619ab3cf5a3ae776688bf6dbacb36330a35ad7524e49ef663687764cf6ec7
+PK:  2002ea0a38a327e0384aeae468db0f6c8516a69609af9eee93e9ecb94b449c66
+MSG: ca74284f11c56e2598d78a4ecd03b40e017a558176012b26fdf695c3de98a74f8f40a47d7978edc24ee8092bfe5e61596834deed1d9d34a0f5cdaebe3421aa19e012de865b9ee1b73479b2bd1ac982f97ed9c7cd20459c60fbb11e1e2b4eac5db6844c71d72949502bba503acec905adba25f6b119eaf9639fa8abb302dff9932d850cc44c57cf90b2e58a8b5251c126a9e28f5c761b6280e2cddd79cbd68e53ff4a6226d3bd4c961b9b9e4345a2545862c7973866f0420b898e7baea90ea4ee004042ef38a1fd956a72fdf6fd43257da9fdb96680ef4fdf9e943d265cdcf2e52e3201d5408bc6ce10e5700adf12b55ba14aa829d8691c31f24fc4a51ce6faa1f3ef2ead78e5e753446ad3fa4a84c193979aebc8309bad60814f4859b931d70414764491c6c9ed8db673c543d35185cd2888aa21c1a9203427e0ac0b1fe34c0e4a4001e0956c13cb59a3baf87c2109a888a4c9e7aa481767d8020ff35dd7c5ccec7c08e971a7e218138c90546a7ddf36ad114be58557432c2ddf34ced3379f70d4407e5879f9842f381717051b1685aa7ab0ad38541ec168f51cb688f3cd1a019a336c9f4f3f82de785c074867fdc8800fc76fba04c8ad8de10d2e9b430581be44c41ecc8fc8a616314399d18c6479f57e573b22a6ee5ce2dcc08948a0de1f0dd25b65715ab18c70c762fc3d7d600cad63226038509c19ab35b5493eee73a703731ec535c90c6f06d94d3e5f7e51a09f9f8f42c501b8504686365ceee9e0fe001329f303522146717c6a1258d0f157cbea4b5a5e3d13bc907e95fd6e8a71896a02c3106bd26a510051f1b30258ab27f875673b1337ee36b71a376e0f9e7809a67c67d9acc16c251dcb8c926c8e932516d38b7233eac6159c59cad0307c590e7131b62219145aaa355bfb4acb6af0a5500006cdd8b813fe1908602e0874c9622bb37673ba1acba414231667bcc4907ac871f87e6ce3f591c19171057a9f457f5362aeda105d18fb84f7d0f0a7da7ef8da9114
+SIG: fe9701da1aa81c55bac33638f775542b804480f34b7bfc78da9916e5246a604d390bf920c872a77924246ee8d0393b202e7b25b2484f654ac367cb0925ece305
+
+TST: 724
+SK:  2bbd830ce7def3fecea1ecd6ea0ae9c9f4fa8ffc3b1f1938c505051bab40cf7a
+PK:  0fdfed8de3c1eaf891ce37e34cb4a2441cbbae0883383d70de2464850b4a642a
+MSG: 5f1edeaa3c0b2a63311d97f1c54e7e2f687170e6b46e2169cbf56c66f231bfc4a576bd2b8420bf357d3a90f8f32ea1ad9939b467254b66a1df1f5b4cbac63a5c2724260d24d8df8edb58ae247a2591e920b1a420cf8d8539ea57db0dadff1ad3e98c3172d033163cb434a766b0c118a56abdcce79c82af7bac74ed0ea024ac4ce0222d0aa914f432092b1b517804db5918a845e9cca55a87db7c2852f7dd2e48360185cc442c7930afe15dd622cc02bcd1ee778b59705f14333241588a522de24407e8e6e10d5ef3a88e3a3c4438c17f7504674fd7e418cb2f77ad0a56d2386703155e9a401c43ddb51ead5520aa7ba038e7de5331418ad552bdcd185f503a8548f55b6386e4687ca515f7c0eea570983bfb24be16f7b3003fb756e326562f2a32fe65ff844c3984c72e40dd49e4f3ae8c0f819a7939b2e736e381f5823cbc61b2ed01d9b05cf8b14648a48b0d7cbe882ac16cadd8c42aa2c70246347b4d849536a7ac22c720da3cf178725ee557a92c25b12b8b956d3bf4802e9e8a15b5ab754235cca0e5b7e55e4aece45a47e084ce1447440598ef5d4f5fdc2c98a5ad136cffbf87d3cf52f6738cca7948356092078fdf254577f55969a0c65246dac809a2fca1f60a1d929877b9a6540e88a9e6e9155938d22c687e63b387534d385e8961e5886743f95f4a7080d916624517b15336030a46714b168b83d6f9cce0606649c01f0a1d0a2a53f5e378f6aa98c384aafb3eefdb3421fa3ac98a0d3a9c029c2300ae0241067d1a4fc92e438688ea889fcb1a1a9e8634b916c60baa0c18bfcd139bfe3017bfbe16291343ce8605bb7872558c6b5fd56dfd221577edcffaa8bda34d7a11ab8cb278288e5834842676fccffaa9111bced2b3575fdd49621b76e8d129b61700eeab0314ef94d550506a4b8d1ee65508d89d0e99e9336b41d9f74aa4d722114de0f31ecf00b097f53c9aca9c7a285b58a35d70298c5c34f74b4a705308033100349f0c62f9c2ebf7dead0a77b298eb
+SIG: 13ebc979a88710e3c5f345cfbb824813b308a9d5c6dee328bfd235a97de7b326de6c738f96f69831949209996852dd9c098d5808418709f2bf510d46b7f03606
+
+TST: 725
+SK:  1a7a3c2f5481131be5f868456aa2fa90e56d52cb721c7184ebff06fed2fe685d
+PK:  7c2ad0f2a570550326fb50a850835821676de1de127f6de1670299d814f6e3ce
+MSG: c62834d9d55d1a4403e925d0a5b552da174c02f4e945dec338c1bbb2aeb4ff40020ef70ff505205cf881b629960abd62764e5a54f2b5105667b11c7d5b7a4ccc3f488bdddb958a7be9546207e6c4671897c053508e1fd83222130a7933976d2bec614ed8f9b6a6b9f4efb2a58b9d005b943e42f171b709a7313070cb2e068da39cf99922b69e285c82ad97f2d6c77922cae2b5e320e83577c0d088761ec88152c297492978a9d7a3ff67ede44c2a707cf3e2352e232f53c8782ba48928a97f8a36b20a416816e94579b9d7250a29dc8470f63a7058e2d2a99d6f0ccb530df5969505ef5c7844eb167d20f412a508fab1f8cd9c20c5eb9a417a5412b5da6a57135759fab17f6314f68df35b1772421443676f312579af6b1411535ada8f76012b69bbeb60b2897ee6607cb369cdf52f4f6ddf88cdb2630d78896f1361fea22ae634217696ff114fb42dbe4f4346f1be5b57adb384ae7e49b41f74b31b9a62bc69dca16589c634eb9d7c6c94f8ece44b60628f98e1024cf32e3e3dd6dce55a1222532f490d63e6a275281c0f3a6c101891b8d57a45de11de35ebb151c0dcd75e6c050b3cd8babae845c39f66c36c77cde05b683e4fb0103d93e7659335c87fc0e3235b2e82488cdabeb5c5c875808745eea92de86b8efcb63e16d082919aee2e92899cb0bcf1c1421577a4a0d9db09ee1f9feb92a5382103cf7c32cfe463725ae4866daafeda0534c169f8f9be404f3baae123fa768ace46178d4b9bbc5bd7aeec7903b0a5bc57538986ee09e07e32077b3b9de50dd1967a372c385ac886287c18451a64efb37d056f9f4194c08b1e3ec97022267bf0043c13d26b9ce1f53905f6e41b3d99dc81b331909b722666ef2432e6af8a453107531230ce4a1af8eed626da223da76b46507e33d7cdbde02d411040c89a11d95156ed4ac2605b826939c6cf877b4ee736c5da77cf4650a9997a3b9cf46a82ba2bc01333c04478b5c92e2498bd002f013140aedb301b95993d1d750870d988
+SIG: 976160fb5bbdabe5c8962f23babacf0b0ab41c2bb13e9c0d449067b7decc7db4e94e76a71b9c0ac4d6af387a72a8cd73e3bc63b7ed650beebf17424c490bd60d
+
+TST: 726
+SK:  191a1d90321c7f4e7494bb982909a9eb40c3341dd32ae4d96750b7d02966b40f
+PK:  9562d9e213f145c456935b7031c680669f8bbd31a4c2ed3c91c4002a5629e97b
+MSG: 85890db4e2fbce093dde5a80bf8fe09a984b83a49b7ccb5d4b06cdafddd382e4b8a8a50530e82c200612c9d7d8a089bc8aa845c3cfcc38a6195d21c2618c3dba2b570920eccfcd236f17f08d814268f882242ddf0702da8785f407aa8f86fecfa903c48da83f839777eb6b4a2bbf5df7a4da53475af1ffe44b5fe0072b8fbf3d26e6d89ea67d8ac8459492890ada657eb3dc2492b88de175b4bba1a508064d619674aaae2af09d31a5c27c8d5d5a29b03779f4286b8966ce407e6ff692fb942520a9938d69cc70acb06b014b6dfc19834206cf1ac6c448ae6f078025b55f3d827201268a92add9ad178ef76a2989fedc6e39f4ebb9f96c9b8352694fa54fa022019c0ec0012d0d769e2367803f925f175f9fb9cbec4a0c9c1e2c83ea57e6a92a17f555cab934271e72c8cc3215fcb87c20539bf14277b1bfbd6e5880ef953fc75f23c0dd4fcc1e0be340af947de02e877fd5c77dd1df7b414b5c0b40c74956a545a115b0c6993ab233b7e72c822b6b3381bb1fc10875bffe3e2ed1190fa33fc15da083794fcc2c5bf5a07909063cb289a08a2c8a33d343842c2d6a3cfa2a16ca2eafcab7ea100d1c714baabb7149f07e25dee323e780757dfa8016faa7c0626222c365f8f2f6687d1ded234f799cc50d1cd26b4cfa4045917056fc79c3b88b2b1908e372df66dac8734631648349bc37fa34b25fff3b0747b6bc16b94e3e5895e4bbd93d478a6c1f75e4fa30faa922049ed4c50f12f4b312a8974d0fed8d44255dcb2bf0febe47fb3fb8ed9903b5ba4ca18e3cc6762cfa1eaf04dfa944d496e0fe8bb7dc045451396bfaba5485d9d5f391a954c3714253ccd9b19964d4280680720783036b3abfaf2884583ea5bdbcf69d08897ab288314635abb4c2964b71ad9291feb5b61f80e9b0cc07f912a8e5598d5548defe0eea1c448573710aacddb152f93c7c6fd3f7e4ed9f7442a6b900f23c3c544ce5c9ba5f5e92aafd11c9ff5f79c08b9d045fef07970625f62e2f4334a4d664caf7
+SIG: 74cb028dc6b75b37a1daea1cf88465db83a0093fecb22d99ba855e9ab59d05cb22c87d0b09df7c116213baa8f189b2703ff953cd202eb9dea3976ee88f5fa703
+
+TST: 727
+SK:  628563aa3ee2fc611bcff78bfb2a75e9fd8780e87a939499a61beaa6a4b71913
+PK:  da20616ee4a41c2ebfdc50ab54953b6d387b06c6def75796b08809565c6cf805
+MSG: 056fb954fbe6a6014fadac1e1a9f56cc08af37348ebaf6920683384efa47626ccddfead2d5e9e8cfff45f7ac63de63f69d12848ce3c0ef1f530ade430f0afd5d8ecfd9ffd60a79746a2c5beedd3e67249982f8b6092ee2d34047af88a81feab5d52b47d5b3f76c2041725f6f813293050aaa834b01a3a58f69aa4a8ca61f5b746f600f3d452c6282ffdca4429b9338967ba3a7266690aec75ebfbf7be98d999b03eddc7292581b0d69e30a0351a151db70412b0bfd43d3baa9d456cb3e0b4fc19cb09e6cadcb6d3f3be5137cc7a8d3219ec2036ec670ed7ec523b1b1c687b5465307882fe38d7472d0ba87a471868309d2f773ff24c87d39c16b708a4ed9af43f74c8d85cfe8ab5406907e941a14970e209c29ff7ed8a2f935ae41709f270d0d08555ef7af2edfe40df399223c785a43e7f3691589e2ea4c036f11d03d7d1eea14f620035325cf2b33baf386393e8a972a7af6cd9b8543b32e2533d1fcc3177fd96d1e13bf8b68deb222f94497265d3ccb345751bd5b669078081998d608ca5fdc134839d4ed2bebb2952fea5a39c6f033c1558f698ce4946e4f6c08af874f27357f870ebeeb2199976ffaefac951f8e17fe7d0821e1b92a90aa4e9defd3fafda052a444476db1ce38a9e176e841189abd8fecde0fbc5cb55f511f5fde07ea97deb39b7aa8dc84a3946a6cf926d39b95c11af9d64d98b807f4704d0a2bda97dad9881ada1bf6636366e60a522b4821047861c7aae2146a02eef6b25d51371a0f17d24bc187dcdd05d541c2f72201427915a3928cd378689103ac50b33f87a47e8cdfa687a5f0af8a56731dabe662f4f2836de0ba8fafd86a3854bca012d7088a00b9854c2d3c708ddf58faa355a89afc2c80f3f5336da01d72a2771a055813fb35330f7d2e01b1d12daa95ed55d3bdc5df7739cbc3ca097a41b6b2bd7f0ff9dd1d8658983ba3ff7920c15f292a1ef9fcada1c607ecb45d3a73c9ffd42f3e16022fdfe12744926395f74fb3111793fa9281821a66a01d
+SIG: c9a6aaa9b4e1cce1b58445725f61f552c8fb45831f03482798f01f663e9983db1a82fd33aba3eccb96226426d50ae17cc51274ce18a38860f40b2f82361b5c03
+
+TST: 728
+SK:  9141f79ed30bf600611a13f367b40396f2ec839c5612bbf1e6e497f83954bc88
+PK:  f14eda962640becb66c4d1f1a021110251917b8b1d34828298d32145baf6e5d9
+MSG: 8fecaa7ae9a3d4a4851a66362b366e167b9f4300fdab205654751987f085de61bec9344aa86f5e5c6477514c2804ced7ac0cd0628529a3a1599236ed67bebe1f2e95aa151fe0f3b3011a1d4be9901cafab2f1891904d4bff0128c1d35ececb322b3cc01dacc5ae3dca6914a7d34da8c9657b950f89d1d6aec3299bb690111071fa87282774943d96a4ab7c3d6de7d1bf119363068cc82d45e4b76454c608bc3566b7f9b385cc7eb38ee429afc2da99669fc5c1be82161a1b0c33f7ba9ad4419d2062971901db003bfa23c44714995cb06bfa966e5023aa9346fd375ae2a1e84084314df3f08ce20800c2c2adfbb81366f6b104243d62d5041e7273433f17581bf93f4c6146fa966f638ab07ea16694a7ce305cc609a6e10623ff7f6c7916b6e4dbdebb7b52eca7f0d5187ff664d7c370ed22886aa2671329d928e0a3bea3b4711a128b9aab90266f8651d220b9cc1cbf5b1ce7265931803690d3291c01ead4dbc3329a97e85c4fe1d356608cc9e60b05bc14838a8608279a0061de28ff7b8e81f59c8a8c5523924c4c485e6ea80ac81750bb0e419efc7858cd4af50c8b8c80650facab4d8258f9cafa0310a007cccbc4185c82fd146df1d811879da3650d5716f1004b71d2c7f2bd6503c354589f8602c950a1f5139f811460752880a341116630e4ff84948e74a9eb350d64d8293002200233f209b17d78897c7ce6ce29e29f82d4ad6c61eb79f5739cb668b21a745555c96e19526845e82c6ed2b1c6bdd6364b8fc79ba9a32dbd3f8b975eb923623958ae0daa4ffa139217c00e021f937e9b791c37991a35e5231a1914c045a787432f97b8e2063db105e14da979c1c4cba785210eb02011334b230cfb6831998ccce25386f4f3ba0dce2006e9c3940b4d5a56aaccdcab02718689816360f18852fd1998a99fce9a04da3f5e23af94c6e8a5badfd39304b9e2a376a1f9bac09a85bd042476e26b58ec73f1236d41ab4b4e7a54def9d66a38f8e546de7b388e1e7d6681e5e2a096f160
+SIG: cf202d7f2f9ed117f429502b2a5aff54a7f751d2171515a4d203753446df0ebac86984c88bd42bd1fb8dcb408776722a38f32cceb25f32a25d7393f138eedf0a
+
+TST: 729
+SK:  695c960bbb0dd57ffa36151c85de735154fe5ad5f5fc77d005a0a32011deb30c
+PK:  34125e4e21f789ed0e1180c1f6369c721dcae9859b6f7b04f957e51001eede8a
+MSG: 3706696c7a906690d0d3b71e7e211c7b067168f3a8f1ed984a0a5e6078597662e4e7889d52db0f78e0d5ef0e5f7a0a0f4263b6848b0725caa4b1cea6987409511c8e5e982d3f5b82bb56a4a7947121937f8e105c5a14b53e6c37cc716b1eba922421828b046f6856c44fabf13a7516c62a5ff98568450cee78b140335047bf1ca77e1549a894feeb078045e4641832253bf695485452ec369065a60029a6c9077a379db20485ea2edb6c969547bb2653289bc6e81ffcb84bdbf773ddea4b3750e9a72395d117f644b0e22061d4f3bb7c5b612e4b70395e0779516b46659116902fd0fbcd2340eea45e9c23db2564a5e11dc79e8f4b332a443ec35aad9604fe791252088295e84f65a307312550d9ebf61f367e4a0f2b5623e53ef6bc132825fc24ebee4ebf338cbfb5df69b32d030d447c44f313ba96fe07bbfe5b0166eaecbc619bb6b2e5924010ba3ec150ff6a69fec4ded9c442f98c15e77f319b4843b3b748b5d26089a76c2b834ff93c413e04ca9550cd211ce2d6a583d782575066db6dd33e8d5e8374355d068a5eb96f8b3da8dddfb5baf5c596daaf556a8f2cb5781e5042327f92ae0621eae088b5f013592e77873a81d7e068d7b8337db9f109a835b475e5caf7cea5af3b4ad6d90baaf1c73655ec676747fcdd41775b4fbe3924c3f41d8a737528d12d6156653a22358c6821426b2c0a33e1634c62c7c8385649bc233e7daf9439f09db9bd11ea01e28b77ecbbc4590e29fdcf0fdde152f6478132fe4c3a5b45a7305af6e381cadd72496e66bbb866cea47f7e7d7e63341600af3f49ce9c9e4e37394df5df71dc10cd391fdcb8a193dc98fc19059fa3ac230ec5476bf94d85556ace6e1ba32421bf59dcbe05c5e15d34c6644e27d0a02be97fa8387ee03706f22a8f4b3b4040ad7d3f8a86971a20a09ec81b7696d834c526b8e51cb97d27643f9abf5e29ffd0333f95de15d110c2064ca49467c14ef227f4babf1a55e7b1cda0429cff256be31cf116719a81b9c5fb75fdf64e
+SIG: 4af41c554d990812686c329a875c41ee24b4a7fd7b3d4f8c8d5275f2e7cb242b258b5858a466de595ce2a2177e351c7f08c7fc4e0bf97ec5fb2dcb8252d2c90a
+
+TST: 730
+SK:  25cb17fc33d2bf8384ae4df20c1fad5c35fd765affde04b5256d4de01ca8de14
+PK:  b86ca312fe598520c64be5c72f5b23816507f69e070f828e02d2afcfe11bfa01
+MSG: 4b4a71cbf8cbaf57a77d4ea188a6f964840f0d714a5f38a095a13b4e571297a88b792417d16184427f90e043dd8a55b7f1c13e00dfa60516445cbe77068c79c8c35ebeac330c33f1121d05731a8f5132d6480073274641195a75202116fff1c318817178fdd768bbdf105fa069c7a3d143fdf5d17bfad7c0624e5292068fd7bb6d303b4a27cb20a4e61875076787d19fa6f729c94dc0ba9b8c0bfd9866da5cb2e7a2cd2edbdc95ac349e5e5c2172e5a4cf7bd90cabe2c6e2245980bd72d0f6f5479881e8c4c354f68aa72841d0c73b986ba51021203161026ee3d729ddf1a049ffe9eb25439802f03011d144e50b02bd4aca5e5506d32fcf69e32f542544798f4e87f72bdf2433b1ff3259292e1d90812cffd79f6a543270baf24a3c39dd3598e1c661612922522f387d51597692f314c4d5ac4bf1883a614636336a5544d59ff41d1e0dbcf8e6627e7c8085646322dfc20c332cbdf35370d47dcabb802e17ca84780eec661c904d5bfbc240ad6a14a7533f71a27500c61dd3e473983887a86835187abb0df08fa62cda69dce86e21fa5ae954c22eddb60ee3131504a69b50486a17767091883760638a29c38030e1e05fdb28e158633010385a620613cc10d5a5f350955f4a347c65edddb7e25159da8dcc2655928ad6f6d8c4c1abb817d7fef3bae5de0402eddee7b51521ce280a66b796140f56af9bc20e465875ce2628a8a10477ce9b2eacc7d86f88272457bfd443e712526996254380f0135227e9fc151c8695e9cc64d272b256ab95c9a9f568e93716e0e53d29882e3ce74261257a02cd497c37d764d90f7fd478a17a890a8b2ea61ab81f6869b120a2f6484a88c151953391eca445015377b3a5dffe4cfbacfb5bab2c47f654f72a9d19cbc4d29537198405e3a04b4bfe11bcdb5c1f30d9ac02f54849c57aa96f7b56636116f2bb6f2583d9af94c86aff5c137f63ce54e8f0c21b6c25c1f0472a229c90817e6162eac71ccda309a1643bd6312a5263a2efe646dffe79ebd8157a28
+SIG: 8ccb0dbcf7cc03e83e21c57474afd3ad8898097b972ede175acaae48e3ec17b2db06fc82776b0751c0f956fd7196f3d1c96321a6cf3d892415d8f8eeb4a14108
+
+TST: 731
+SK:  49e24d1699833726b18c78ea6568401a971e1ca39dd06d7563ac8b4250d4a9f5
+PK:  71cf05e90d301a6d9fad7f0b38ec8bb044fcfd97c849b04c003625de29be86bb
+MSG: 6d2605f61e1a04b6ae18c2c25ae100dd42a61e664e2db5c34d7ad1f84ac507552b741c2086c17c852babe07a91e129a506ee59edb9ce73be1b1d06d120ec36a1e94c6281054e78ceb1bdeffbcbf4f01051ed381bfc8ad1769f41e240bf6059d9704cacec666611f41e4dd438b7f50242ea86756bb1f81e5942c092129fbc6de4955d28dff35237db30e4a5036a9914c9f84dbd8ccf82ba2b1b3b5554a2b7a74cb0b2a1e1963345286e258dc8e7d56718035f95f313811cfbd852a0f8f49a29ef933e7cda7ed9c7e8b162cdba1a82262cd4df7cf8ea4b586db43dcc1e3764598e9ca46673822baa2ad87fb14b6fdb9e2032d0ca51c26c5ef3d9f79785fac2491cdbf7c399f3cd1774c1a6b1e4a67f5436d80db025f8fb6409e275bd0ed508b5e039ed2e4eec8b0f4d5be99dcafa6a1401252732a65b37c943c07ef3acbcfbb3dc06dad0a88f2f5eb551a3997ad6c6eed95edd9a0af4a288d5e43286b2ac072977c436b7c5ff7ab61c9484f257f58e010c9b6ad41581d742cd19752cde54d2b420d643654e9096a81eb9dcf804c7c2ed0e38d13a5ce39978cdd02b25350945de78feecc0c2c22ffd705c3ba8113265c7b9a7c8ddb59178bd21d7f6c31c6be2c36749ee0f9ab8bc1dcf5da5cb2d2d5962358f71f96ab3792a252a519e415351f43e7e12035b0328f28208cf4be529d299aa5c128c9d5ed575bf90c5350569eaa6f2d5521de1180309f686c97e9ad6fa1ec1dd8627ae8951581cf604b8b917c5ba434a637be1bc8b79f4acaf7795f4e51aabdb885077bc4f3c68fc3318de5823d7e0804ee995b70387950f799353682300d4e797f3cad611b4c562c8640ff2b3fe292916a970fb98c1475c1f4e27b9b33cfe0d3ad932a1ebe6a27fc3b446622954aee1683668c8bd4a3f903be5c77dfdb8e8914cedc51f65fed2d9c4d03e13a668d4c7ea5e31883e1b3db64363e2ac5cc54b54ce69c6ad52f874999b5dd2c5782f03c3d51505df536a1fe0d860d33eabed641a940089f1297dd0f57f
+SIG: a0b6a2af15b6be9e951ef3f32cbd1c6702e8e017fbd315a3f2599c3f1a11865d46e78459a0d7f7be046aae293cad09137ec847e26928106d9aa35e0982b99202
+
+TST: 732
+SK:  f8ff97032a34cf9999088058af56ff70b6acb2edf759e131faec8440fdecf6c4
+PK:  5438b4e33f1c5ea112fb1bafef4059bf095a11409b64d46bfb4d25473c1c0874
+MSG: dfb41fb9d53702cb2b9e3ffcad4ea602716f718a7ea33e21843e2a6c052c70c6c51485d72b53a5bb4e34e03e3e1d1a52518eb3e7f18f2a1e1caf78acb2116089bed4c617138e716a91431f2cf644a1210f6d1920d285994264d6466b0d8d2c62638044616f576edc7d0d93cb660131d4bb50875e153640123a96f15b75a5bcee46d5cc5eb1a431c59d2eaddfd5531502feb1551bf7791cd5989d17d10296d01ba3ae3e384c674526cab62a7c24c0ff677de71ca172621a28a85e01eefe07f6eef9c3ecfd7f9498ac42f46a43716f615318a3b28757c3a15f4f1c3822ae7a75c203a298258d753638cf425e15bbc46202b093b8e4f3e670fbb663db2b69c8fb0f625074d85a44d350e042bb1b74021d192997a2c27dd6c8634841d100a0344baed750a39ff5dcd9848dfcf09e5c8c47967b96556e2332ca17d8e42dd8f393a5445a372244600b3001b8fe86c45eafc6e738aa7e117b4a79fa2e6b00f464928d1856c83ecfe87dd34d158f5cb4e4f4d610f59717ec790bd3ff872040b67e8d3939e804e3b5db985a095621cbccd686c0934ece3e27ab2c6ce33fb52b111f48e4f274bdf320d0b02384c83c49e1a041bd2319109c85a06d8048a993357abfd811ac2f38059d077acbc36aa966c028903748625f92e8f79d51bda10f78522977f76ec4e885e49a46c68de09f3da8f86b71ae6423bd29deef1cc6a113eac115a6cde2ccd011fc1c0f0e3427f43c3e96fc4156edf62ddfb7b0836b888bab3c4345055a6c4178e9e22829fd8cfce39b0b8444eb26487cc9dc82606feaadaf4978694e6564f2729c1b13ab37c9072db4e9de940ee5f1d05884ae7fd9d9ec9cb7de56347600a88dea9208a63419fce29ee50055a374a8f22f9ae2be9805a9f47615aa59576b44042ff126a89824e36ad6bc58e06bb90fbeefbae5d6d7d62430f373b6296fbfcd4d6620168353583fbd3d5a292b9572517534e2fb0beef2fa98a464e59103e7a04287f15dad0fac54970e7715078d63ec26362f6fbabcddeaf7
+SIG: 509e9eadfe8dde7914ac20cafc0b0af22b84dd8a210a4812cd8cae39b0a272e53e02246dc8939e9226920336e140b31532d068137a34161e599a8694a95ddf01
+
+TST: 733
+SK:  2e4c39219fc92a538e48e95fbfcfef30f5a21b78940b81053bdad4602b4c9690
+PK:  f8eed892176620434c7f0ec53dcff39863109e7ca4d0b3c6c4b56410be01e537
+MSG: c87d1fba9d94a6a5408980fc8083980fd2d252fae540f6eec19ed6746c29e339a1c29f6f53bc23fd6bfa438507eff5daf903403cda707b4dc5e844805d6b1ceb4afff4b232e8e69d7d271f3c067c4854f3d94f27fe325581faca79d1f02a26290ad23af71100c12c09157647ca9da43d7690ddcd94db65e000989c878b75a0ff22d2c70962594c9b0808f27846ccac8567bce5d2e3b7602809f23b59cd718a0805d108f31a632a05b8dfa5035ab9461aeba416009d74fdf9e007202856890d2cff80fa240b978a48270fcb2f473697bcba8e730a55c28761919a23be41da27ffea09e3559caaabf9519ec08e1ffa86817aa3e8874fa816e7718c5b2f344967ba1bc2819c4f045a97b40544ea61d717083ccaf11e9ddc04a3598ef181e7bef4acef45b6551b478a0d7731c4f08ce5802f78258d419017661076d7d6d2ef39e57cf9cd9397dcc5debf64ab82b66159f578316e74cd49f5ad2c6fef83cf08683b9570a946ad4903df4e96ec008e14a501fa9386bdaf2a63993c6c9bdf231fd09ea6f96ef4d4e29a3a3327cbf74ea831054e66ca86680c6ce53b66f9465d06b3fa0798bb6905ae38455934f2fb7e0ba472328989f001308671cccb566d222c72165bb3a744fb98e2210f9620680df3e3cd14a8bd94b5745c0016dda77f059f26053b64cf4523c3d429112fb6b328398bc630a2e906b95a6c5780cfdc0641be4751bebddf7724dc9c27e78d60ed0fd736d5abd88929c1795d473abd2b0320c540475728821867a409a2ff13cc44ce35e5981e9f6b87a28d4fa8b8675e503faefca7c1d7984737871fe919ac414eea265ee31f9f78f521f3f4f8d00c3fb79171f3c6a5dbf5e1ac8bf63b4c3d8d8bc121036e9e55bb702ea6c86e925ec0b984ded2c71f3bfd4932e6c41b582fd02ca59f53ce297445785cc4cac247b0b84e7fa0bcdcf79b3e4a155f9878c1f643be9c42f7a4f27260444505c1845bd53b550a31d7953cc738861f46bdf4870f3a77ace191abd63c45adb153909fb59ab5db9b
+SIG: 394520122bb0a564648a7a8bc8dc73636c517746a3c8a05b901e7252fef0e5023d90991e311b5382d49100e52633c70fe9c26c1450e0603e6d452299af4dae07
+
+TST: 734
+SK:  f092e6be8d2d9ad069a3e2b976d244e34c15c28c48d32f5560a54185d1501502
+PK:  cfeb3e74e4b5c8356a81757b8f1be4b429fc18fcaf497cbf8d8bc0480ff978f9
+MSG: 2c255fb25d45b086c071e03e525b4d728578fbb6b0c60da941e6bf2a4898b2d5b6988c53302785ab7a3bc4bb2c205acd27d6a4cbdd1a0c0889ded784264cb7c02889c5c7113fc90bbbcd31ff001432c053f971073cf6712f667fce4698776b98cc5444c692abd1288198be5ad5674609f7e139ad1b9ccb943f8dfd9d12c54ecee278341b2ee1277991ca62cd3bfe128d1392964e9588e2f97c321704a3de106188c5eb335aa5a19acc9067b4a94129b9d1a6167c4bbfb56fb97684cbbd720c86869e0020ab0776cdc9954feba862124b073fba8de9ea9a38eacfa003ae4f1cdcbf15c32fb6b970c73115ddffcd4fa3b71846110edec257fcaed6113604f7192572577264b9905ca6aed8daec138403ca41aa954278a5720b267b90ca163a9bdf447eade8deb769a3b49237a73516977c28734555dd234ca7de4999261bc7960f536ba8a35ad3d02c75f1c2bea0a0612e7d49c40397dd6af5ff58bae6a64b6a77e981f92d159e0b2bd205ab157052f47017a3e18aec944d0465ee0017e96148a6129f74d3ccb489fea13a15a9b9aced58c6ee0e6e84e05fdadfae07b334a98fc37f7e511cd5a44e9c74e478d349e30e29aeb46a4df01e4307fe65e1394a758f6ada2fb120225ccd50a49013e6c9f175af90f3fc8c57e7a6a969a916c3f1aacc22f3e01a070cc48e6fd878e2bd073df9ee6f059b98568404fc7eae7d4bf6fa16c0c803c6be84e8b79c67affc8c88cabdeebc1134bb2386e22ba4d2e9e0f3e1ab3a0dac7c80ddeed773cda0c41dc9defa67fea37769cb4a1e1522d7e0b3d7c4638bcd983153d478be5ecf2b6ab1b40124e4222b8caa4647bd50d74d203943ab20938d5f27d908a673674046ce2ef18e858b0a01a7e7530ded0f8cc89ef09b73ca597cf73afbc9a271a4d23c92fe591883c440109c4ef416670b7f2c5905b77f65f56d09d40250356f9b1dbcaf1ee2c0b63696f84d68ddbea160085151a9526274d7b846cceb6c4348098484de3bb723ae5e85276df49f5634130ff905754f
+SIG: 63cd4c0ba3be9397cc0f3c1af348ec4b8a91e42fee675da1d05900b9a86c138f9174eb996bbdf31c4295e0c578ac0f9d537641a2afd5dff93a39c5cd9d3c480b
+
+TST: 735
+SK:  01a247943afe83f036b6b60f23d97774fd23208edc31cf3d8820e9dc63661103
+PK:  8c97a58be0e847c48a6a3987cfe250a8d7b07d97f961f6b7b79e7d8042b8bd7b
+MSG: 08d81495da77f407255cc41a818eefa727e2c47ae411f4b541f01f811d906d55fb1e3c9c484df30565364de9dcb9fea0af66112fe75fd11ae81d2641b547589f8b974a97e7976ed692aad640edd288bd863d11c4ca9836f9d7c115c3d98830d64247cb6f8fb603c6981133552a3204041961bdd83e2f9deba770c0394f9b602a453551074921a3de28321369d7f8ca640c45109e8f522c97ed9f35b9277a350e295931b42e0135e94a92fed363d6cae392f7c45199327e24b4cfa5898ab599ae7bd50bd3a00c0d007e95faf8f2ae103802ca7e53b279184d06905f5748ca8be1f72e668cb83283dd00406491f8b9b4e5a9d4a5438b2fa4371e0b05686f87575baa796e302f08ffc425662750a33a0c9cfaa4b4d7041f9264fed7be4f9fde2cac68a2158236f6ac43047e911f4c4e8bc663fdd50517dfaa8fbcd219dd7a0e9369f43d0dd25b4f0cf930f20b7b7c6db9d5be0c6e1960941a3e04d141c03e5961aa33e9024477d533c995378796bf2292ade922695b14569fc339b3d9085c63fc6e5bef4d990c80333a6b57af478f938e3ee738b1d129bd976afe686128bcac08ccbeb0349b9b537313bc7bf591c65d4a7123ad30bdbe1486b428084748b6507f6f5ef67c26ca862cf726aac140b861ae0dc74bb3c0b489789f17145e9a855a3e2b5daac418d8353733239ef69c7b565b5303eb87bd7f649abf40a2f135a29ed27e3be4c12cd6ddd2e5418a99974383663f5849bf3ce5532bf64a80aa521191d25390bc19a45eed1d3feca1d9fcc0db031bfb48e450be3d4593356d5ba0f31047b457745f21e32ebea3ca6c35f05d78d8c31640b0fecb9401165675c7f9cbb19bc4b5677c2ccedc4e7aafb84184c19199aca0db21cf5067dc3af769bcc629355ff7257a9efd71a6a92d130d35abee6e70605b5cab93c028fac3aa2344ba861ac1e8ce9a4b070c3df740d28c5ece0f1bc31c2d7d1e5ecc76104480939133a18660e4a3e4846b2517be3b8e7afafe078391d8aa8e5c30137e85d94d64a279fbee
+SIG: ed2ced1a4fddb3442a637348179a6a5beedcb44c8e988ca26f78936d2c8db5c516d54b8c4f08d91dd7042ab6ab26d87f230eb2b2156f3ce2994fce7c2b0f100e
+
+TST: 736
+SK:  91fdefcdbc990d3e8eeb60170434da10831b03081f6afd0d7e12b10011e02aef
+PK:  c58d3e20b8d47ba455b912572dc840815e3d885fa5917d1da48408b9a9564098
+MSG: 5b0c1a3a95e0ba7474766c9badfae34ab860e0a6c033a22fba721127f5bbeee8e2cbde1a1dfeb18d551c95994d21e3ebc68afae685444a3a4195bc755538903acfa6715592dde256e7a1b4c363eca71ef0f3a48ae3442d50d5661b394096b7ec27bbf52953f3040cd25b78ce475527e0cc59f1ef9ae2e0590431582b2df8141499829a2c5f7bbe3598e4c96cc01ede2f43b65605b488593709c094b5a042b28555fb5227a6d156376f3ff07bd5c8bc6804d39a3282ac5970ba08aebf7542b845f6b5c238c2ce20443f7f7755d75fe4fa16b9644ca3e21d91a9a87c686115748a16c0ae4ae4e16d1c71ae600b39cd25e5633b399fee7ff2e362bed25125c6fd5c7f5ffa2da2353fd35b784a1b1b0319774758b7390c44dcc92fca4201dfe1a37569de05f0664d08b90d6e2badc21b92f9ce872142357b9615080ab7659a246ff0852adb17dfda70cf1754157b13bc032b4c5deb8e1068b4692b93165da35efc9da86acbe6f80f01bbc26f575ec5af5b050e9828afde6c3b78e733eb5a912492f765bcad731b95e3ab8896b61758bf913b9a1568f9c5b46033cf45dcc1750da2066c608dc3d343738e848dc390cd474432e991d7aa2c5b2781421efe55e36b0b42c1f49ae277480b0fc5ff685bb5a31be3a0fa44823816077037548a5c9b0e1cc6c63504a407579a3632b3c96fcd0de5ea1e4d6e87c0caf7b6cae3120db8b1f4615ce6a75a81654f390428b64c213e727eec3ae7f9f42db906f4de1fdadd34a3da2aeb12b4d9a185f4a60cb0c26745f530b481fc976a093ce24a30916af605ee94b08785193a949d569c4b7ef59603bb624360e7b408d98ca509daf5a92a6d4015bdb6f97ad4ff0cf05c8f0cd5476a934426a059f2444446e5864f089e0f0675615910662d7c1e79a6c75fa314b7ba2c643b0d37653eefe593172d1d332c8dd64492eaf104fb1957baa52049442d10b56af8eae8ff82cd8f46a0494bec2fcb9fadf10cf71a6eecd0547dafdc7adbaa4503783f943a46b4ad0e6dd7f2cab55617
+SIG: 510112223b33a5ab1564f7537191cd292a9dbd5a323d7add0584c1b0ad00d0ac7199c3fb758e913ff3d716c2e90dd90d4e8f59951e87ef8b78214a5175c4e608
+
+TST: 737
+SK:  ef00b3c181f6327d02256751cb51c2c36c0c0a78076340548f5bc070d86d9e26
+PK:  db14cd32588fd741e8f42e5121cc811ad45063f28141e83c668f07d91228f049
+MSG: 7d6abec7a11af67324ce17b1d20bb40c668a219bc95df05e325d86f88795e264d454fc5fa7d9c8aafe77e90a6af6b57453d85b970b552a856ba659ab31bd8a660eb7d3587b453e5c5fc6b79472b26e8ff7dd6db6be3572548b0d754ed4d985b8d9965f88b952fc4fa3b761ccffc35354db0eb9c5a171718a8a5592870213827d3691bae7fd9c63f20503e04319b5e953579de47e3ef8e1628549503cb4f6871ba25db87347080e531a517a8b7221e6ad84dff83256d9ab9a433de871b9cb9c5044589e67206b317a5206aeba96c92fd6094071c644fe52658ded9220cf6abd50e2305a1c90fd66aacfb38eb05eaff6ca5f85f429cd57716eb87739a02b64cffa08c4f685b00310b5b4844920df215a9f24a17613aef85fec94f511dc8a4294eddcea11c08c0b399a23d916383e29adeb98c65d41c705a57f840520fa808d7fd25fdce159f7a084d062974b30132a571242baff4196246d6d757b312e9d608553d2dc53b623b2e95c7538fbc5deb62ba73776d85e5118fa1a302d4d076d99e100f0df119c33fc66cdfe6fd44d71997b78c8f7890c707346056220d1e9de88bc173cf0b76cb302877ec16af46e4c31639f54eedc16da9d9eb0ad95bda545dfc4a732b6da9814136ab1b9392a071b022473b3490557698b77e7447ac8590dcaf4f242ad3dfbc0df716cc0ea753626973df08d935d178e3312fbe2a7ba9c5093c53b9255eaca29b72578e3ba1bdfaf0c9ece21a5dff6ea421524f70fc1904e9a2cf7c518bfcc7e3673ee87ff27e1ca2ac32bcb4091cb34a82a71563ff6a6a15da0ebd5bd10256ce960f4eaa7fe35e128886050d049fec3a4ab16d5b0c107267eae1ab801ea5b91983839da1c488c12f864d7c3a77f2b6ae27d540109f68d78364bb627183bd503917547aaf3b3a1809da02577b3f03a9a3f5af48c8802e297c8bb63db6a86d3ea727a6d7148b3aa444b8d168f38c6c8f24088a49af33177a344adab2cf6e08e0cb0371ed52bdead132f77e7ae3ee5d8fb17afc0a0bb7311b9560b67
+SIG: 139f9cb99b995be6588cddb5051694838f9d82a60761fde304b0027ff86584bf65c73cc6d253e560f65525df04bfe146c83b42269cf3780f8bc392437894ae01
+
+TST: 738
+SK:  d071d8c5578d025949932aa6bf6a80b1cc412f106f91574ee24654b445ee9a97
+PK:  9bcbf7d2212fb62cccf8b6c76803a5ea24409da6287efbb8b1f0c7b30ebdd93e
+MSG: 3e8ee70e51e56ef57f6e66b3a884aa04a7b4d4599fb9b43996b393a868093512ea741a0c6a94f40ce49862d2fd1f7551f4647abd8075bc1b742ad40e29a60461301224fe8f7692b14772782b4e896b63fe05abd5ff5314f9ec8075f28d908ccaaace5e905ea7f57a491b99b3591eea54a6b7819167749d38a047620676a1a7af11f485a55b7c879e6850380858c8f45c0c1ccbd7406ed099d84a7471b9350c4ddb28470bf5bf327d5b3c22d899b4c660839e104a0622ae85c84aa9fc7f0a2c7ceb6e691c49c064b5313499683e8e03b2115eda7ddad55a49f9fbe62544f914511cfbec6b84dbde7e80909b45fb10502e2caaa72124fd9456a3872f9592707e9a4c5012daa972eaf65fabe553debe825701efef5c756bb465e966ab68dd52f3dd00a45cf6dc3f19b86bb0db4a86e4669885a074696a67d8ea2118c766ef625f8a98026f9f4a3c5cccf9846fdc90ed93ec7c1f3c7086954fa2f0a4ca96d40184aa57545527a1f965c11d843c90c5a5e08d7c11f2d561004e90574852eb5046aa1ea7b61009fd5dd7d6242a8df58a9e8e555c7f4cdc130d6901bfe6797fdc6c39beecfbbab6625b2e4fb9d8000276d4a94fc6fc1051fefff5adeb724b87090db0a2c697d056664d991fad80dc80fab700b1f1f2ee27734ebc26b2a641c32a0c911b270ac76b0da5c08914971c9112463a70709c0ddac7910016f913f6210086d7255cef11955710f651889c83621dd8a4fcd5366302d6c9b56eefcfac85c14a9478b6d718075428800760515cab5f3d4455e2b970df9fe4be8383d70483bbdd756071f53b2f9c275c7c8512d163518fe555837514c86776c947f29a77570287446b69be40c8d4abbd65ef2507249b5aec33acb7b8bd3f35bc859ba4e37bdb49cf913d93989c4438d2abcfa388cc89d78ac06270656492e7528f29bdfe8cbb9bfa9e73c1da013fc3ce2105657613ff62bb0c3bf4dee3b0d2659c726e7bcd9e97ecce9247d4600dfeaf60444ed862b00ba11e70ea88d4f0b6b539fc9f36bb2a1a9ed2b3
+SIG: 0c297abe0fd8ebcc6b771998755e2c6be07c812b5a80544957063170ca69432e72b60daae322958a2238cd6a462894a387eef65bf96f63f54c085687a502750e
+
+TST: 739
+SK:  e9d486c29ae811b942e10d81f0a6716317b842c2c5bfdef55cc432b7fcaeb818
+PK:  43a52d15b9f731d737b1c4dbc32227a480963091d2c6286f482ef1e8367054e5
+MSG: 14fe1ed5bbbd76cc73dc5650bda92de86326e24d2f1f6224ba8568944d6fe3442675db96f1d8498f1634ff9b6e50cba9db4eb0b0b021b2becfce4bef33c4ce0e32c8a98389eca9e059a662d6f037c54aa40c76cdeee85650f089ea56e1383ab0f5c36f6d6645ff7e87667301f944fdc2ed35b0d2c35cb2e4b45636e7498e927f5846b3e1edfbd160a4aef3320c3428496bdaaf7d3ed56ef0b7254ac597be589a70584416300c1adcfba4f22cfd4cd661e1f50f155d172fa5748d296b29cdd7eb8121483ff1d9fe953f9451c7c7a542007285ee7246bc0fdea938814029abce057a0ecb974b12d360eab6afd30797d61445ad2bac7e52bce4346315f78eb87542d59528b2f6c56d66241cb442033f643d3d2a67cb637d8da95d4fd1234b031a3e51723a1d26e6f5ca07987321ad11a90fcc1d4e2b0b896650c3a7518d565529bea806a05d447e08d2a6a3dbf1a36915b2957ca5b40e58b97ad0369735c428bd6d69bd210044b651418d98b059d90c83e46011f41c032c5655a5ef21ac2c8c2bc94be07e45426a7ae5d47b45f27cf4289ca4ddabe08a12b910207dabb34a46ab75ce69b58e7e17664bf3359a8fb68eb032c9eaa6df873829f0e0848553f732e1c3c084b32b7af75074e7bbaa4eb5d7ead7aff97580109b60f4c792f9e2a65137b0aa48175b8115d91305f4c77e2d08e7e8d7e7785c966842c2e350fed4f9e33bf6e184c550b4b06e957414edf52fa079e81973458461fbb9b7d7d34bef150357f432caac3ae9f3dc96eb5a2d123e09eda1702e1d1070177bb220c423c096ec24424385c679be02ef84d09ed102f49cad3b1fd670679a39714ff1d6e4228d8d7d0e19ed0eba132f2128d47baa569a8ecb7bd48a826282f9cfcbf60ddeceaf1d02132c8affed3a03d2340deb787cd649c51c6ecb9ff75d7a7b4ef9b15139cfea2762ab18615197a6b51f6e75dbd04573a2448094d0cdeb0fe4585883ff9b68824a04b83ec91cf84acd6a7446cb1f5ee37d5df80f17cb2bdc3f3122a8faf76ebd06cfe817
+SIG: 65191aa885ddab9f67271879952fc6affe41ca20eb3bcd86673161b03b532694d6dd88908eb1b1eec003cfcbe6146b4538e21df55969912a0d7d8818ad79590d
+
+TST: 740
+SK:  e6fa10dbb478e1e36b35dfeb0250f63c08515070ae79b22f047e271708d64f5c
+PK:  e02e1f2bd8792ef483481c6d11f7c7c9dbdeecc9859432e7f279e9d173d31164
+MSG: ad3160758d8c08a661525c95280a3718874969859f1cc918e34fec008acf23b8896e8d50c3c0512331dc89780f8b10fc349c675c4cd82a5df8586b43c864448fac00b847b9c98054ab793f63c71aa5e5248e22d069bd3f852a3b8c6e2ac8ef861d90bcd984bfca87583e59e9a7468f29b808dc2fe5302a989d6f2ecde7585cd9be4e4c761c4d4b3eeaf4699f6556ef039af2b80f9407605ac397351dd85595584495baa177b08c88d2ec1fc4e32d1c0b8d7e7ac5839dfb923f09b323e78eceb7e96c0604b01a19e49c9beaf4f25ec4a84c1a08f2380eddc3a7f012184959ccd19ecbbac65eaca155cee9ecfec11e7fee058e174fc4ed7c679f2c15631d4e1527bcdb0e3bb0815ffdffc0c856bef0dc0f5c8237f7098e26bdb69e8782d1ca5111ec3c7edb425dff8032026cba3d2e081b71310db9badad1ad02f1eccc537d874cd18c6bb01221f71ee66250d94cf8ecceaa96d3c57eea2b0a8ec72429d7606488bdf19ec3bb16e50867c7937def09fc783f20a2a5ec99253d6b240df4677dd2d5277b01c5b8e5bd6c7df0874205bc8c2fffdba1314674d31c9b2c9199228e19e0421834c1657d0698286916c7e392f0abd5545b963ac1ffa99721616c23796f85c34a5c664ae81d16b216a5b0cf5bc6b5a908297285d61644128f886f38af9edd25193d7ecc77a79994278da071f54495937feef5a51957527c3eec7cb0b4e8aa7a4e856defd57dd92334151b986aa69ca69260d1e2d7b53c05677ee0d216b28d036252dd3006debe1b6574a25e6b19dfb48fa64316af8fd68d7893b397e7db5780ab27bf8726fff605d3b46d800595b4624bee302c964326034b5234d175dfdcc2ce882e65b3d93a0438f692e9695de1f24c70a79beed25415ec5aaecf3391953b2ffd453a8f0467561a4a47ee144a43fdff83df2bea5f66a722b52abe8613f20c594af0982eb3f04505a52461dd034da86c36ca16217705c04823911d72a24769517633562886f250f2cf788b8f32864a9474f57e62e57de8fdaf959a6b72287440a8
+SIG: c03c470359127e9de3af0e0ed7d3b19faee0ec140b79c299e2cb6dac0a3e7e314141cc854b4596ce4c51c7b0dec8a5c8cf0936205361d5365f4bcc07c4287c07
+
+TST: 741
+SK:  058e3680b8fcc0aa1490089c1124677f98d74b1bfb71ee8663f025f0d946cd20
+PK:  ec72ce0e82c6a3b21243d2f00e9e883adbc5cb63b3d936efa50c07cb929148e2
+MSG: e63d14f5bea7a1abb8fee697746c2280dfd0622de7357226cc0742722a3229be126b083e868aeaf07d2fc97adc3342709674193ca281744e850ea15440050aec930e45d7a87b8ac8015c8967c20033a532d29591b135586ce0fdd2e668b5c864b3bde70c7e719ad241931251861933ffbfa96483ff82856748c56dc26e257d692e5134d82fc7191c110d9590d3fc751cd636b0c46f44f8803e59e2f93fa0cbe247a1a625b4bc2c7b1fdceb5a2b22591fa6137c5404dfec6a69639e3f632b5976ab9fe1c63aa3da9d52b044008f3ae44b7c364f085664323a88eb4583e87140f763782bff8819cf741a875d506c929d34bbd43007de4b18f687a758111128b1db86fc5ad2fb9fcad12c9dd28fee5ad10de0739f8efd9bff66f840b11b3f91c5e07c21452cab24242b6e32165cd1e69572bf216e860453dad2fd129c333758580bb7d0f19509745e851463d127a5f9be21fe549cae55d56b8bea80bfafdac10acd838ea8af31c007dc32bfd74082d9110a3e91e61e0357587e4ed32827ade9b6910a988c1d3b2dd22c0ee76ef35fe15e099404a45d4b2acab9123ecc45550a40faf8336b46c630a9080358ff8b8e58af0bccbd35010c1ecc12816655a5eceba95ad3f503a18ec5bece3a33f469dfe917e1c55ef1d81e5a75561e6bbd99c653a6d095b9f387911e40332f6216f956a35cf7d99a9fdd0c44c51e90a564f1c36bf3d40a7faf4ba28b1a120b3205fbac1a98569290be37c58bbd745ce0fb74835270aba2252adaec157dc42461221a2cff687b9e65ceb57c2d77700aea6320486c5b1bec9cc53e7ef9e48fcd1b7783acbe75a6be0267278812dbf3d2576cf7ad3911271acebe0f2c04602a080c8b96c120fd86fda282aa4e1c131fe97c907c15855f87755f511c037befad0f56b39f32a2133a22f3d5a9bec3443f29a694e97fe05e10fb8ef9991302b9e0d84d929a19eb03471f3a8613d39368e15883a7e4970b53cbaf2929d8de431b48b435d7533caa2e36ceab6cddb346e535e515c4b3db76de07d9855414
+SIG: 5734ec50a7f82e48536bdc4370cfef2e150a631dabaf89edcf0fdabe4f5839f4f5fbd8df8ec4a3acd40a8bfb963d1855ff9274dbc33165b5e6d37a239dace903
+
+TST: 742
+SK:  51ba3a4f3d85d1548c2f2494a3511f3b9515663d7e85370fb6150237e9bc980b
+PK:  7749de0210bce06d48f59b95aeb1528fd9b4e52cdde22fb8193bedd5df12817c
+MSG: d18d0cbfc16d0f9b67f2539ad6207cd9217ad5ed0333cddb1041e0ac2bdd920276629652b49cbc9802593ec364ea795abcd1582085f55bc66c48fd3eede618d6369617100eaeccc15f249d6eee5bb2c43c01b0623fe603ceeee49b40fb7c53fc68473673c09b1ac77ea9beb7e8530379a86d69ecd1ff11813fbb88f692f05ef1320742b4fe7e06d5ba71656646cd7500de19bb93d844536603f40bd4aeeaf0c4dbc0acfd202b286b64afb83d4a378dd45ee3c1df6b3ef16b8b1accbc04063250ec47b86ae5a71d1dab38b5eb80d663faa788f8b59a754c0f9c9f6d906252af46ab1fffed276d2388dbe70d96ba6747d1fed4fc0b55293d5f787bda0c0df46a73f4aa7d29e1c9cc85cd043e3dffe057462ca5fe5c6470e739276f8b534c0172e460f340487a569468aa5890cc14f20d67d79c661e87febac6275971c3730807ebf175e0de1049bee67c895e57b71ab8a2f3cf3641fd548d09414f5fc3026a0a35f6ba951673944941cb236f3d1976dc69077d951450e7660316988f6f2a6fbbff3b37ceaa02fd6f0273bd803185a109039c63f2519b983daf6554253bed5497c0b0bdaa0bd4a1fac90026ade3e40c554cff2ccb36990e71556708c5c4039256ffc7337e5fea11f5e90d3e4d93359179116a85c24136ca34835cd34012e4d7ddc7b721c246c73700e276dc2ff9f2770b43c8e80a17f01d32680bae228e6423a880c3fb996ab8d221bc6274ac5fa770d205fc878fba9bbd776a3d79ed77048950f36dc0aa3ccd28e4756a991904ae051b8a4b7de3a1f2ad0fb45a33d0c68225841f8eb65b6a16e95f893591e1aa73a64f0d2ee938ab69adcc8c59518bec501c39f139174bbb00699e1a0f0e0d889aae543a55e6ac56d5204c1ade1f27d82a6a95e14b2d6909dda7bfaa7f487fb61959014b78795cb4639f09f0d329feb35ccf52edc2db721914e423306889a483fee876360ee326335319070c564f3a8b953f52f41513a2260883c38dd978a248604a41bd4bfc9e84184dc9e84d2589f4afff8417824ce5adba
+SIG: 16fb290c913b20eb1c3d7b798249eb8459d4bee8125db2b3f1daab8af9d9a700ed798addd802dfcd297a412593cda7be9979a1f09350e86f698ac3380e341d07
+
+TST: 743
+SK:  7ddec526a4971d8912a6bd43c69f92ed86442b15f42fbabbf2d17eff98993161
+PK:  0dfeffb2762309b4734e4ce2523cf1863149f7e19a7c147ec0899e110ca9d87d
+MSG: e8774a45d4d8f86dda5c08802ba2472ef3c8d36c7f383ac04612a464382e9d6c07d8d35822c53f4388f5153614fefaf46374747b9d4fd446a864769a4cade843c1eab8574319112f0179d2ea9e3c195dc068f0697462b9e07c8794870f8fb8ffc081e4586afbcdba7a4f5925e9fd9ec942d8434733c2ddd5e29bbdfc7342b92868719b544088a48eba4c82f187ddca8f474625a71cf6b7aa5f081c74f7408f53b781636e7e9d29b07fdb6d9c35e5eb382db7a31a8ba516915df8dee9e1ad3f182843683e8d1dc5d8669dbfcf09541a43c0a04613381a5b5e4e71b23c5ad09b8eaa51cb938d0c752cc3d3a10f10b42be8ee7f6bdac8078568434946bbf56da70e7d54157a6efd4846eb155278c94c3888658a7a2f8ea3bac147aa891692ae8b23f1afe71ecfdecaa6c113b5caaaa19398c7dfe73facb4155fd6bac18d5df2129e8b2907ecee151bdd147a7c3e46ea72754de32ceb066d9db1c26e80df3631292b16174cfa6f1d9c0828b849c22d29651a73e910d9275877f464ce9326c6e4ed6b07dcb3a35363c1aa6472e02c5cd855e38aabe965ace9f3f5a4f5de03008694cb90afe416c9d48688de7f75cfe243ff7f41e059310934903db568844508262c899dfa750cd6a2829824ba027aea1b6d0177726a343add4ecdc5f7e6e909ab7de615ef2807f9e7d71ce2f78acff57eba79c3f5e07c8b661c1e3027f8176d28bfef767dd68d4e5d628fec0bfe88799341f306128734fad202aafc9f11123fb3e363d10aee0db5e27a1570dfaee47e24da473b07fee59a6c93f0981dbe325cd8cc2d2ed7dc17166b267c1b110536f2636bba34751a78f7f6298182442d83c123bbee4f50c5b0facff03e7c556ed9e64ca27c4bca5ab0de0d5f9c2cbb54cc2d9473a32df999390ac2ffeed3d4cba34973dcec3fbabafc4d54cae4e7e85d4a6e8afe45cacd71e0f2e6d04b4f9d3bcf43d3fa41e998ccbed0f150d5ca1d5272932d93eca10495c68334fa3268f31de522cb12a7449ffb5cb5e8f1462cd9b51770ccaf58b1e0d82ef929
+SIG: 9e603b015f42871b78eb27523fbb7ce962fca32ae270e8e12dcadd25aa852b891f6fef77b59a546c9a7a7cacb55e1d32adc805ae5f61a69e6764c7c08292eb03
+
+TST: 744
+SK:  0b6590dd7c2f15f94a56e240169363c26732302b9d440b532723002e155d02d9
+PK:  cd18e032577c5576f223f3e3d8a1fa8e9a870fef09e9409faf40d7143e52fc44
+MSG: 71fe0fd55d5ed1206f28ee16e419fab6fa66a251fa6b0601da261e429f55b8d5ae3f3c52a17fe1ec734b810ab63aade4447039ca0ae4687c2435f561e46c5b309717ab31e0f64076b2169211572b74e18a1f4525a64fa717a5edf149758129cb04035e7e20ba4005b74809dec644504c2454a77f99b20c5374f3cee7d8c6b68b243cafb30098dce90490fdc3b92f54948f424639e19f8f2020d15513daefadd9e9b12a84761e5ecea088ad561f06209fd4423fcd003fbcd1873ea54963a2fa07c7476b1388f9015d9eac305bea5a3de194f55a17b42d599e5ce62c8b7c19e7e7096137b9d0a65e63c1a3b84538ca65369a20e8822fff5ecb57fc09b4e6845b4f24d4886971ac1ac28c77580ea5672ad14ce4441719c214546d0736cb7ad0bd9fb5b26c6d9c536bf8c857ae42577b36341d392b43323bdae7dfaa491986872a23d827c6ef8b57e7d00feae3834c466400aad1d367823984aa02d2ef492914ae1127e7551b812559378305e4fd52d8bc7e4157ecca451f43ee9f54c82153c7dbfaf7ec35238773051b4e587db136957ec571382b90590b5d1026024580966b7252d2cd3f4f1625c485ba906bff175992188978f2d6274f3a031749ba7e702f56547edc96ec267b84892880d750d7310ebf6db241253cabe4b25a977458c6ffc9e353e62adf05e6efc0fc1ebe89f527705bcc26b701285610d98aa3bf23872b6996d3de480e8d09d783c4a08cd383c9012635aa68978b5006818bbde44f2987479bcb2b711c1beeed27cf09970a164e454f710822eef555c1c7bf9f76d5254ce220c9aaa716847a249488f9cdb44c48f452ab52c40f6d03adc8bf3f197b25e3d127830e74fd81eb14f754205b3a4844c596b6e3a9936ad6fd9e80a16320b381c3ffc7b69eab54536f55abe22c91d898408e880c6dbf0fa5648d517772caa5353b25db6050d753faf198ec1d375de0fa72180a93bab03ded7716cb87505b68ac6a35e73d0fcf34457eff82178952142c7bac9dfd872a9a82f85b24b88fa42d4be0a0ca0b2c70f4c622
+SIG: 642d81acf38cf099a833a74f2d80b85448ec2b1a5ddc64470b213d54b7be6133689a7194f5d89792e16e5df755a4fd9ef4689ea952926e0e4ecb3bd481fd9102
+
+TST: 745
+SK:  c6d9acc5175fa2b8965c158c56ba0a5a666ad2c740cd5bb679bba9b1dc509284
+PK:  f5cfca211b02fba7720347703bf1631cb308fabcdaa67429527c5b7b676dbaef
+MSG: f245100cd2d31648f5f351bda564c9db4a35820cc30ef651337c4cd888070569d117a934b9c918e5df8b3744dd6620ccbc49f6b3e5782a30339dbb9cbed05dd2b3b8c5bf1546e70af636e6615c48b2c3c2d19fe35420df5314f63c4812b58e82a2a60b1802f38e505ce748017afa977d3f9b1b6bea2192acec73bdce12d65e684da4d8b41fa9a86f11086edc2d5296f67efc53ac84070fde13693eb2318f5a8c3b117c233422adcdd352f328f0ec699a4650c93f9b4a7d795d7fc2622a03d99b64f7b3dc3194f6c3b1b69d9907ce092401073f47a28f4799d229092a1b074129954be80ca4a3e6582ee05c302cacb7431d1ca6a451aaed7278abc7f78575241c2a2eea2e84cbf9a334df402109c028e345473a13af9b008e20bc8cf0bcefbb7aa727ec856e9925b4ddd99deba8f252911a590154b579a8aaa31f07dd5025df5cd8a09f742964cc8c365d8aff4eb1d79f6e5a07dac5f4ede92b4e2e61d34cc2d4f0aaaab037ad5fdb95de6cd5984ebaf7cce7f08d0ca0dbbe483ce3cb35cd790ca0427065a34df7f4c2af86efe9b765713aff257f5c1d54709527ad18ac33abcdeedb208064ebaea4835be4942b8fc666ad1b79b6651309e5ea1da302d7fba2e99f0e6319e82b9905a1ea482ba043b6800b330dc48b3313f59bb2f9e8a7f07eb1800a702745db14c6299a982dad897954445b7d98eb5837fd70bf190c649552c8e86feb7ff5b3ed8e0a06704d4553a3c2dd74f18ea8233ae0a50d914fe08fbcd3a1435fed56a9f3a7effa140fb552ddd21dffff7fa47332ddfc1e5317f4177d5e2f11a06ec84ccfb89b654ea81bd42d7e07a387301d0f40264abbf9f9107b30ede864cc7690c06d2e247a060bb2244ad78ed5c5515a1a2a612d61e3d931e28bc939b4d3435eee4f7331b1f0f85375d82ac9a77c43740032051746dc9269458c147d188d84401954a489cb4fbf9bf84ba7d8f100903ce67831b4054d0f58cd883d542c4933103ff070cdfc9dbb0fcc31efca466e77a33f1a813da6dc0c7c31585e8f4fef1ebf42fbd1
+SIG: 4d2ce707090b0f3f41462fd75bd609a2724fadfe5ca390e313a42cab42868ed6e9a8914dc13909c0d6f61e63712957c76f3bd8b7f55349715a3a317515c07108
+
+TST: 746
+SK:  7dfae416419d7b0d4fc1f823840c3e4bd4adcd4dc2dc17b38637acedacbdbb45
+PK:  bc51d7745931317e1e346e2e7c92039181b6bf38ee2f5a44fbe2339c4f952ab9
+MSG: ec843dc4dda6e902e9be31b70f11763b757ab6ce7334dc00764b2d084e9daf2484485984ee28a2830fcb94c541cb469440036731de80ff560f530c9d9e6e1f7d9c4c5bdf50b04f5403c29f76d7e36e00bbea35db1cc60da8d776526266c3324ce7efec6450859609266856d701a47a48dee8bf37409565c7fbfa99a204e5530c971c605b44305d5c7467894114253cf43cddf18b6296dd254a4d96ac7000918186dfd4bf454ed30974c553d0ae151ad4cf540cecaaa0b5948b0985a9c7b6e7815932bac11732fc7d10267f6bf8f1e7c08d650e567b4edd15ae7958410e42f1f537fa732f727a268388321d5344c4e78bb9a74eab9d6abf968965c66693d5f112dd4c14fdfdd96005eaa6757fa2cc1013fe4327ab0999d117f3dbf325b07cd454d4b141991ef7e23db5ee24beda35884aa3704808648aa43cd6256259f7d3db5e055311f253e8b57a4cda5afe0b0adfc364e160ca37e8dec6b95aa6152e5d5da6eb91be0e44ffe8e49533267b7eb795f5f8e0b2c35b29dfbc87585f22bd5b909dfd6a5edc0e3a9d97b0c4f3adc51e969937c08fd65f537aacda8f11275af02c3354542630f3920c393f5c42b9fc633de9d94c72e3f20002349ad0418035b3f25f02ca928e5b2d40a77a1c3e56221f4b9db0c25b096d6e5d0fe758da2c69053e8d086def4edc6e3453783ffc63a4960122d923671a906008bac10561ae6219d2b51d5367bf13ccabf5931b9f186eb109bacde40e1af2b56481e0c6dc6f5c5473f8001cf371919acb40cec5b962ebba80e32d6ebac4806d04d24768c2ad2e3f92a8cbe47754f9bf615953522b263dc24937fbd932c8c459eb8b109443af6c195a59fd2721b0125628f2b8143cf3c128bcec1392efd16b734c10716d96ba7d1f413917ccafa5bf5f83f524fe8406a152115ea770e1745e82e8b51d752b8bd785df48bfc12041bf874fc73afb42ca5d69c6416479ceb4aaa0492b6ff21ee12db2213a4286fd5605c93a7bb8a3b071b0b25fb01d77abbc8771489470a107aadae9f640c24dfd5328f60f4b7d
+SIG: da34b1983e8c55e41fda8ec8abf23b367a0da606c8cdbb1e8b57e0343c0557a5f0e815e7f22f8605ae93b27d03776ac1f7de3d792ea2933ac22d2dc23b323d0c
+
+TST: 747
+SK:  709416074997b9c9af4d37a01139e8a3f9f2ce5d72a57d805e822a81186d017e
+PK:  aee110f1f4d46ea60649d786b150052e287a9da60122c47b0908fa8b2ca28a80
+MSG: eddaa369c0e31a1fcc1da46f65362442a0cc21c7dcdd5cd90e0a2ee9f25110812ba114931c868a708607ac16084d79715d13b338c05c6aef7343e7dad282f96fe28193188f0cc893c7dce805fd3a7cd268b72894160b5245fed9fa9943b7c80adb3c2d1a353d8f12df25a31dde7fa385bbec351da66f153032e17756273f8d54e9a3b9ea25ae67d1e9c18cc68be601e3d68282818ce0e7cf88a4d1336453021732f08d9e76cd23637929b0911d5f8614f4842e670c142860afc265c50172b13bfd35ad8fc54b28657da32bac153ba9affc897afb3c721f48caa46240585710b0f2d24d5ff4965d1d10f1a07b06abea6a08e1d6f1500da12c434a6d778c941067108000475ce831bcfe2d0afe40b7419d07059bc0cd8dce4be9587ff29ad8bf0b268ae23ce0da5bb5bf74ff0b2b31b82112a9fd5abd9bfd0a90e6f4723548c6bb2f99dc061ba32eba2d53e6bc79bf441b23fb7460de04e8e8efbcd4d4cc7355de9e3b0861a681b983839d4488e551751f23e9a6e2e4d443273b9e0fe64d8acd1c748b5559438223dd21b5183189e0f3c0e8ed414c0356bab77a654de1a5771462ef14344970a491511a722914f4a89f4f1a827e18cd84479cc92592eadf8de2df824b976dcbd284a3ba64bcdb0df15e8f41c0b2471586b26a06353d905028235c1c6e5c4587222725af083e11e79c943aa444d4aa41218d3e974336e372813e99e2b0c5f0ae810ffed9a7a3d6cb74c5473d990a5911329b8e82ec6bf2bd4321bb487370f8739e7a2a4a53430833d45b9fe3deb93f79fc6a51d563695ecdb97858d213da584434b7c71546aae8d967e1c6d0082b10d4a72de1742e53c4b2f92eb8b5c8c35ab6535ea8100b37924a0a91d2a728d0f5642437aa66c82ab74b5d0745ec08f7705cb81fa079d89ecdc9aa1f8d7d82dc7746d34615343a6925dc318f352a2b45012438424f9098fddf6e61fd1f8fb49da40b3eece89a1af1996de70cd1696cbfd9e301ea5f4437c71ac2a032254c140a90e85fb8ffc4667fa139c1ee9bbf12eed906a967bc0921
+SIG: 8e4b41f097d83614184ba7f52ba2fd9f0565f8a63721ef55f93162826b9f0ac070c0e2864b5ffd8eccc18efad18b2ce84be57c0b4a41c52e20ef37722377c60f
+
+TST: 748
+SK:  3dcb7ae7d9f0f141f1d9f07883635b913ed29fb61d0f741c9afd05a27b045b06
+PK:  ae62b7ee1b8db5764dafddd9724acc106d6c0a4d1e85d8906f7584b558f577df
+MSG: 38116a572669070dd5863218c91a77a4ab47553688488c792838509e9aba25067adb7ea4249848009d914ae987a6032348c1c0681cf977a9552dd6bbf4e6ff32acc9fa61cbee25a39307650f8ba6a7ce421ef2f71bccc0958138f9324c86bf2e528fa3e4d1b19f9f2ca5268409b8cc19c62dd979b89697e457ed2d98bd2096f62d3d9e247388795927803e79ab71d4f72f568e945a8a162159d9b84836e4585644d4979f614aada73ad413a83391e9cf880c42ac2a98343b6a82cd2b61581456f6de5ceb24fe46b7625d52ab2c2c324ac74703d15e15f1aeff8055d2f739f7363e16ec1d78be2c6299436c8c8d336bd29271a897a6ec932ed08725be21b28f9aa14eaf4f71853154db14587c930ab3eb0227ad7ffb45b3baa6a999499cc8a6e45b1ab4d0b339782bcd9cfbcf88cf7eae891cc841e9c88a1f6a691f3948a6bc85ba7f4611642e84223c3b178946ddbeddcfcdef4ae4c4e1a814b9b1f02b1eaa824db93f44b27d14206b340465a1cefcf535c63e55c4287224262733d98aaaa154f3ad42cd8546a461ce0d46d886d3461a2150cb45dbe56473ff63d3dc7a2b957b823969f19b5968e8b424c879741926d82c6386753b0fa1f080284e5578942363aadeb21f8e1e8909fa6c380764149bc915b228604efc56d92e4beb720edc74c4d78f925d6cfdf7ba2f14b5623775810d2d07bd388c573e36523f215738e69114dcf8d80f170bfa676e31fb626a7d449ed96647363475970c8c47809709bcb5e7200f2a227c7c8e7b000f30c0bde61d67bd6895361629a36c8fdd5a56b81efbacf15c1b3530a08cded5b1fd457fbd2f03042f56f1b37ed15cdb912fa0298c276725087ee27d3cf2550fe6e8a0330af417f4f5baf03627ed67c5f8323363abac5a1fe34823180e3e0e2080f75bfd91c207cf6baa9a229cf443dd442c5902e0673f3252b8526346585872f6cd366025a56992b70ede39bc8d322f9c22a1dc599e9f0d524cb6d2ea5ae2878ef6bed4b702807f1e1e73ebf290eb6c0eeb85c13716f626aa90d364b4904837ce05
+SIG: 09a1e6fedf971b3edbfaefbeb89aa539ca0b02b37e7ac4ea8920d6d4348ee0cf9a2d5e96fce517c665e7c38368baf24979249a95b70ea7436c00785f16a3ae09
+
+TST: 749
+SK:  297311ddeffec9d2be68ef7b2a20fe2d277e1d8e51648b03572ada27ec1f9f43
+PK:  6a6c28e761640c4008333aae5a3366302e2f4677a953ba482ab6fb4a1d70b447
+MSG: 2652acfc3bdf09a599ec6786bbd94fe577cf578e0263cc68d9f57a6c83458f80acd8a75ef03040a635672b968ff2afdb288d28b9996f6415b2f3175e9ea37aeb05df81812e38a4c976eb92856cedb91a269a46fca5df9bd730fd84452b4bd93577c61f42c14113979882a86a9fe632e4756afd89816fc4670a310503fdaad2db764c3721213c3e60f29c2668d4de8f42b087f25cd56c69a4e48f134f5598cf145be638a5c2318863329061729aac91da6a191fd774880cf9cb555eec15b0044f10e5433fb46a9b8892da8f6d24f142588b70ff0b49200c506b88bed449ad10d3f92c2baeda6bbf58676c5bbc67d31f64fb12e8d5e78876d5c849fc314b2cf8010c510204c8633d0cc31856ec6a114ea8a89c48927b07a31ab842c9b8352d9367345141a99b40049d5c48e7d27cab427adefd1f0fc1136b353cb01c3def91fffee8ad91e88f4bb7d2615c0dcc95344cd01950938ecb14b8446b56a06bf2f2f65fb8735e8a7bc96bb46ce9cac71a88eb8fda5e69d69eb29aa42a016b8583893e9d7277cb1359c5687eedcd599d8a46e6c14963637db04a929f4bc79304ac2dae733b3a839eb74fbe3de5042fd655eaecb15f39b2fe16dad8a6ff8dbc054fed51282a856e9da6316fac6db5d56f77f18da8412eb377e5b1b8f4cb1354ecfe8fe8fd54e62d767a80de04cb7620229a8831dbc9ecd4578ffa2ff06b5445e440d69aabc94c47bd17f22b69f52eeae5cfcd01a5cafe0580072ae9166b95743d68c3564c5a7e46f24bc48a898a1ab2ebe63f36851d2aacfa0c4f32d993771d314e725a43d9805d1371cf723ef161d42e63ffca688d7f0e21ef5b3f9a561a6210702b85fbd1f8ca75389cc7a22739bae4ded93757f1520dc38844a1a88be8e09645059148807b933770878cb8a9ad9211317131e69324532fd0279b83185b628fc2f9e21500384693fa29f26bd1b9c301601367665f05f372dab4e3107726cd3f639ca62bf63a75f77eaa75f7136157ada2374e65fb4fd349b45e25441fd21b13e6911366b97cfb4d6ad522b850adf40c
+SIG: 4bf0b92c6ee4eace5e8eb10370ff9d9c68a5749d59899d04327aaa38f8f825e032e59742b37de23107a3ecdd3f7a0d08122614b78fdd37293c8d05e28f5f7108
+
+TST: 750
+SK:  4db2b58144a8d2d0ec03bb9bc29b4ca893854c80b64afa4af7a9c936935ecb04
+PK:  fc5cd750e174ed718bd938fa8ed99a1b9d556ba7670f2a77daf1c720113732a5
+MSG: c8d1dbc936911e122cee18f92b16a39a2eef0823b227f898cdf5842b93d59fc002edb5498a20872e19554ef73999eb3a7b3e2fdd9070e1efa9228e9e93b29a868ae3799e4e572324836b1ad5aa812bf00f845bc217ebbc3fabdc4e1b6e51ef9efac2770aa0a4a11ee52ab956ac6448aa2629cb61dbb1f1edb3bde99b4876da392a6e0b9a0c31849a5890aea9522f56d015a1935015b91bf4c6a0011d2377d671c3d0d753c27f8c76e405d0230f1f4b9b88fcebba1eaf13777235e55324b7d3f81e686109d91ce689530b90d2c5c71dd18772b385d62ccbfd2e089a1b670983f60c21c4455cb9d1a0dcaa74c874e35211f8227ff7c234dff85ec0b07e368cfa50a343578395a14c68f1f89bd4ecbc172ef805e5831ec89475fcc8d685ca9255a77e3ba3c147508ec92d7bcce879af0abdd2416b67b5f50507337914f390bbe0b450b6a2f1159372c4bccea382ce3d6d9fb2515ecf7930059a0552b75f978862bf97e8325af24d1b8ce9512bfc7cef884232042341d82f9b5dad2e502ac6ac795f99dac7fc60e3b8639d0e1500dead4e78aca109957d577a13c1925d7403c1acf989a9de6711e23c67bf8722f551b774cada931b5fd973434e3b7172819883e70c52785e3b49d323d05636641158640dcf6a4c200eb2c13b1beeb2dc360352470d15386e59e6fa60367e5e7f172b21159d5ee7cab0d7f5868239858e2a93550480fe8fb4dcaf4f224c4b2ad5448791632df30e8e5fb998b35ea9aec8c934a4403aef82187ca1abf82a344d00ffb993d9ff3461d6fecdaf5d3b481e0d31153dbf6aed288c8add064e8331550141bd5f7a7e047b8607d846a6bfb72d683446a445114606250d8d2d3a8b9508bb07d4623cdf1788b5499e9cb9a1379849bfa19c9a9f4cd3d9253adffda25f47c811be833b02f3327ebba83730195d614bae6fe4e7a3830815d2af400d20a9417a095e7e8eea1044917cbe512c4018d656e2db67bb989c00e1e507623e8278d729925b84fb5c186a7bac189e6d6ab14fd7b62fdc632bebb5f77cb5cc2f707df4053099
+SIG: 424517aadd853ce3985759a327e7760d9156d3b27345383f0e4ad6661ee4a3724d18d820f6c557f82797beb62d2f085433744f89a2d85293796481862ef8a40f
+
+TST: 751
+SK:  c820413c2456747104662ef4dff3ac233ac4b91a76d3c4ea754490bc9b1e291f
+PK:  8993cea2f7f2806c77b3981b54bfa9bf1762151b418e5e725371ca2c04d223ee
+MSG: d2992f83924a594887e6ef13f2ae808fc8639c7b2c994faf0f795e36016dab7700a0ee530170f0b9fe98ab7588ce03bc50c2bae65e052647e756735b35d0b59c964e917d8c83e2f9fecc4cb05564287f0e34c9494005e25b1a8b1b942b54d89035f1b1c3c945fcc84e4a39efa2ca50959b459af74d21b6242e2f56518f70e8679257c089d26c3bb792687c923355b2c18ee2136d40cba45acb64240d9667f39dba3639b6516d4c4947573ef4ced876b5b2ea3489eaea539f557f58da204691a76e29c94b8b0538232c5f7d0bb0fdd016910431354b3e1e7ce62ad436917cd5c315a5be9b971c80f97bc9d5c156ffd64fd4e31da56083e02a0c8fce554db68674cb62700ba951752b829b03c542327412eec9ccc6a50adf47bbee15446682da2fea42048936d763060cd8f539652616dfa808d623ff777b4113652e789ec025b85e04efe8ad4c960b190bf4a5a6324d6f57c1ad22018c83cd7e7e097fc67b80269c13b4dd9701ca98f9876958ba7689c6f6f10a732a64bef22e8b98bd304d5dbf4fb1f9e4ca539a5c4aa619c44d6f58f824b2dbae77b7e83b56db5e5aa7b0ae9ce1cd10a69f04a80f1379eb0c474e4782df0e3ba6a148226bd1a662d95ee2d67c5207333cb1d54176d9e506459479029f31dcace269938f6bc562787841dcfe101f4db60bd66016e1eebb6bfbd9cd83042dd1379a464f405aaae3c11807848cc4f95c3cc6fa92ab4ea5305834eb86b873fa30ed1f7f470bf663f1a70cf9e60ab680cd1dbbd03ac0433b3d4bb482f8b344d46b3aa934b8633f57090bea5fccca6488799835f133f8bcf6e887ca59d19076d6ca19d4e28349051e016b03e9a920f4120fb523d1371d0e38467319543f127ed914b43ad062226a536582db728ccd76e983f11766a8863c2f424f65508dcb26fe0c5a800c35093960a121976e3051e2ef1a2a99c12fb7bd8bc037a439686806eb72017a071a91b3e39c90e86bc335f9bb543b127c9886738cb53806b9cb3c2594c7effc2a5920aa834be65c49f47964e89eec74728de771f3d675de9d1e
+SIG: 7ef70e4a14954d509f117f4bd01b220bcc192d3b5fdfc3482fbbc3b69dc068a7c4761d1bebc2317d6db74f906a155642b0a3c6592bdc72e64eac6f203fb74e02
+
+TST: 752
+SK:  6769cc8e125617c22ce57237a4fca1507f941234661df74328d04ab62ef86c47
+PK:  05112ca60baff79b4916c1bee2b9390c047af08c35ebb3c381b9748d1dd4c4fd
+MSG: 685489739b98564749587ff1ac96ba682da30b40a4de24f54ec8b083dda45333162167cb3f97b2c7314ce7a3f3f3d319ccc35bb6a9f0077d563161e281469cf08968d9dcf7ae5fff830a5db00bc38010e6662d494f3c8647c4f70ce2d29a9da84610a080b5759a3b582052dfde66e4a7fa5fb27f065073fe723d83701d5bac06ca43b46d1e58097670c194a13af8b573a3791a9661557cbc042757ab8add0ef7cf4f35435a4212353fcb3c203c73dbc9d26852d0e91732e3621ce828929cdca4d9192048751922ed225eab2900cff971a2a2d342463648bbb1944319a8ef6d43db62480fbf1d7257d22694539793f25c927917caab25c1193a2d2b23bb5cb8569aefff4f0ca423d19bbd46fc5ef7524ff8cb706ffc47076509c05a8158af77f98df6a9b5cb3244aba4b5c5f9ce597e7d29ba07013dcac1911b6de7113c736a4005c459992979019a45b2dd802a07660909eb4ce205408170d82545dacba8686dbde927dbc9c7d962058e9a95ea66b8dfd3ea435357a93c73948cd355f6ac6552323f17c2a678662bc0e9726ad5a5251dd27647404cbfe61ceaafdcfc08a475ffd87cb7f597e56ac1670409dd9408ae4770420c6e5e6dd8e748fe03a72dc12803d02771d92f47e6e717ccc144fc037275b6f745dd30da1a45d29db6d9073eee5009cfd5462733414a495f349db0b6dbf2cea9ccd57238ed5ee91ad8bc86179ad5695a85a50484e617751de5ef7a7d8a8db950a98a6b7f7dee9d42a5df692fccf555c940dc39cf2eac48cb9d15cda14dd2a7ecc0b76ebec68ad4177d1117e07766c48590d43ca7662868eb9790ac29f4f2392b9a93f89759e7ba546b925bd86f807d8d16c7e637dcc666e90590bf430d986a67f1b0c7c2c94930845869ed8d8adde18fc1887456881b4b26b53dcba7a526f0eca14e8bb689d66f0aa1b253c3dcfcf59540d5d2f5ad617f52c30938a5a92ea385077d75aa4ac07afc2b35fb8c1d5e78eb295fc20fe37c41ac06959d3a1797843ad7056c1b412dd0b480aa3b39bcc20587d9a0fef92c6c950ebc5bb8e142
+SIG: d39d853d2c2c5d21b5871ea5a75c041048d93a47dc599a5fddc0856285ce636fcdfd8564083d06ff284a524bc633cfdfc3b037163d674cb9bb5ba3bc25bed00e
+
+TST: 753
+SK:  1df7acfb963304e51ec471caf181102556783cb7d91ead30bdc2534d078a1488
+PK:  05a31ffc70e4e3569fc2be110c643ad5f087913c7aa476dcd8d6e4bc7ec22d24
+MSG: b0c3eeb57f14606ab7abeab2ee0573843ca22e6db2fdf2c9064cea5198dc5830eb158da8e2daa88857af8b8eefccf0c26c3ec0f330e92cff06bc05a29bfc99f940b61f3cfb2964b337097a6550a3e9a328c85be6f160d2c0a57ff6f1b3c5ffcca89089425ab6be0172e175baf40cf12b24a815f70f29a3a4cd0a6a132f120097752f4bc743ede08f5f21d42f282f7671f7783e27b2a8e2c14692f1e0e5de82855dabf98a1a63976006ffbfe5f5a579b460e26d06bd542842a5f9261bbf260451d2321c508932013cc6e904f79b5e4686d033e12c7bbd7eb1c92379c5ec341bf6457a3f17264a7c278b27501ecaedc361eba844442342b4b10fa94d265865116acf43fcbec965d2ab4bbbe614c4f90ab6b3e0d5383fa04988bfbb260307dde22d84098b6331d155141a927bb78d664b341d2f2a93e291cf79baaecd2612f6b104f3fc81373a7c6a045b5924bf950cd542f7b7accef3aa7d725de053055d951bd768111392596638ae097170f4492ba50a468f8e347763db612d3c7de7e56459b26ee029c630827a353aee73de68d6d72b27afd75d22164527945c7226844fab15b8dcc914349e3141c61316adc894dedcdc843984d9c7feae39db332dc393e9e8961bbde071c3d2858b3cb5f33b164a15616c6fe1bbc24a35f21336d261c5d8cf759e27e22c9101c4aebde3e126cf646ca7b2e03128095c5976bf3f6e491af0f0b640c7310966ac59c59fbc5bfe0548f88ee61ad9ec40c1c06dd29d794c44a3ea22c3d4762622ec1e8b333e45074db93741fda193c911f6db5879e55ee36ef602614ae64a5cde9d8306d22fbc4ae9c881a594bde6796125fcb628b9f3b6fb3ffd511b353f146a27272afd3e5d28b77f58a67f1fd27285c25ecc1ccf64e38d21f3b9ff22e00ee900629ef1a63e713f258883dd911f30c0d398b74bd797149be5e2696722da09d52d4ebf3c673929d298aac34ce05bea08ea9a424e93459c2eb8fc2222c31cc13d803b90a8a70bcd0a30c209211dc2ccc85b0bcd4582c695f58d80bf6ec471a2505f68847a75f6e911fd87
+SIG: b181938de10142f32407b4e786cddde932eb11dbc0bf0e5ac509fae7a5bcc32961fe3448f912c8500fc6db4e1d3262a83c9dbe769bb8c3a761000fe36c0d7104
+
+TST: 754
+SK:  7ed87c36dfdbae60c940a3b325c19fded814d76a544820a32f286a5c0ad71d72
+PK:  3c4ac510b36222c252a2dc1afcb40fb0eb85bca90391196a5883aa2cc912b2df
+MSG: 62d313912abbb006b7774a6737714a349970ce0421112f400463d3db0e2f7f128d7b96939f43c1e7107b5118a77c119683d866b7e3d72ac21f6b4272b4be9289b6556fe31b6051a0b42ed5ea0cf347696d30fb8bff6b8b572719de19a231cc85459a990c37801f0837186cefbb5521569666967cd4243d7307f1b0b24c8e2b9b692317304fbe3dd0a263650191b35216f52916573af90524f91db1a92471d758c92dc6d14d1a4b26f41b40403ca87dcfabdca47b9fc2533578f161f3b0199b5c698e080704b21c9e615269fcd0d40439ed8bc3bdfbc9afb44c11fa89275f0eaaa5d08fa959d6378d0db89910d48f2d86a1ebfc5cbf10eb2d5aadf51bbd8344ff8bbb5b8afe05a45011b5e4b72eb864ad263e8a03a6c7f98aeeb354f730a318aa30fb56d33d80748c98ebec15878ccf3ce822f69d3456843c400dc56b481a95e688b8a4735bf3843f5833dda0efe09e7175b567c661387afd2ebc079a48e34967ec97b927dfa581888f231a98a7ed33103bfa8e8f9ba6513527900b39b86231da7911a2fc935888a75f1129584afff2025249c4188f09052f85687706d05e299144d40de8898b7c8b2dfef0c3708573d8b0563a6bd0a504c0b6745702b1b57121c6f040aff27198948ba69c21253a28d39eba726219beda1f8209fb83e9adb07ad409fbd6d25565889ab45123f9d945ecd7d9ca7028ece092e35fbb7cb3f328126efddac5d859f2b2c6eb090133690e20c17deaf3882685f07e9ed2653b803b9b383b70748a1fa92c86f86d6c47ea87b10b12e363ba508060f47ce2a2f3b6a3eefcd4dacfc71c41f436fe0c2bc34d4baad49574e7443c126a589f6ef7bca44954f0bb28ec7151b0511c23c6bc42d5e85983ec16bb5f50a382d688150a49609cbde5698e86dcbf0212c2292299dc4dcf87429f6cd2eec80948ce867e25c94584cdc64b099029eb854edc26ea21421eff48cf4e41f49e2d89478def06c42bea220a133e50f5c74464c7e73fb1c1a77c507cf6cda85be402b7e6d6d21e810d6d0b5972b9fe77e54e74aee1f3bbfd6e7de6b5c0
+SIG: 579b38124bd0591a597cc9a389127ceaf55156077363edb811d0b65552acfcc677b272942199ca25ab790de6e084603ad1052ec210cf6fcb1417289067ce3c08
+
+TST: 755
+SK:  6a29f81b8d9aa48a1b23364eac8f6a4bdd607a84cfe8e88d90175d80643a58a8
+PK:  4c3be3a2a8425ff31c3a0db4a52a0cb1416ceb48cc3e4c28a4f2284ab3460715
+MSG: 7876a3f4eb69bb7e54e9ff954ebd3b10b93a4c1afeae92fa03c103cb6313a201c5b33a9a7223755cb510e25ec582b54e81b84956f6c53f1f08a63bf0c4a261af450e523fe8f61ddb3c0eeab8751072688801b2a473b71a2e38708da68c2f37925cb05a20c4283b3af97b6f0ba65a5403554375e215d9e3aa1b0f9fdb0f849923edbdaa0ab481c545a5df8f51d1f68b223507ea0eccfaebb5fccf5e3dfa65a44eea504568a88180a060bb06c51557b81e667b4b04e3210fa4c379876c49f3e56bf2be1cf519a7418393d240dc8a224c6c38ac2ab9d8fadfc5362030c7930c3ce7795b147c26c8a28c653429d90a173a86a8b18a009e62aef6eca95d39bdbe45647778a2532a415ae19bad231129127842fe1d0f11fab4a1cf0b17e498cd5952c939e090090287b144895dff00cec8d6aedaf62481a41783e021082ce352063e62811fd99990104d8a46cdcaee2bab458e5247fb023e923330a428c7bcfd20b08f520e8946dd658347352ae0c4be73c3d5eccd11149f3ab7b8052cfd95c35d4164546f5d8f377517a7f432c0d5563a7bcc7bd119d3421dfebaae844599b29b383bb8d5dbf140d9bd47a078b7ae7c6aa87b1e29236c9fcfd654b7f809794cccb261588e18dec6c4046a934067d0dfa03791d03d83b718ac4d24dce785a3028de0c9592dba7c5c5845184afc9c0dfcf94095860f0eb802ebea20178e78b5642e5dd61c33b39769052d9d854dce902f476e21f96c650b463b7bc3d0ff2996b65c57831f8b7c0fb915f4dd7226ac955cbc7dfb03f9b758dd3e0dfce2e0e580c91a30c783ff567b17f12dfd5d3137646e20011cdcaae11102dc716886cbf123c09488b173636abd54e962caeec97d5eb940682e703b730f61562cd14b9e6561b5e93f60cd0e1e86d1a1b4719c5b508242bd6b2d9a548f59bbb875075969ef2032f3196b8aeccc45a44d9dbdaf878ed16f1d855e8918ed65a45ee5c7fa32a1ec6932a159cfb50ffc87be06dfcf7228ae8870ccd357fc656e33fa4b6b8b7d1a7215553cabacc70a39c980b971e51a17ed6318b43b29bb
+SIG: df09cb9b878d3dc9e542dbac28943e28e41dcecb92cb7ea44009885e46499743330561ba1d36aedd467675fdca2baaa4701b6fad979fd839c470d13c82daa905
+
+TST: 756
+SK:  ef12df479d983ad96e8ba65330b36d49aadb983164e1c0b452b560ded1d08d60
+PK:  f761cf2826927a7cda8cb04faa2c59f8425a8f7d398f76e867021c951f073809
+MSG: e58f34daea755ac4e41333d6f0ed0135f7dbce50309bb1956bc71acb12c77067a647ffd86aa5870c0c0007e8f995a22b88c467de225444544201c557495e253e3319cc5ca376d3e7cc1eb467346e52ad956a6fa733720b17117b5b7585e4d559409aaefa95580f91e502015f497c5cdcb7d4d561f544efa35c1e2a53b72bddeceec2d1050f177d480f687405664dfddec06eee4bd147a912fdbf74f2a95d1fd1e11268694ce4d4ec4fffd6ddb3254d360f236fab4d1a17f8d0d1a511f944692f239639ae03d64facec6538427ab71f7127f4a276f9bc45bba611dfcce6446cc13968976c8bb6d6fe2106d705922dcac956966a76d48f2aff4b86514e39a67e1643fcc321858024e693189833c8ad59b4b625298ebafe64626b480f326f1340723cb3d383f4fccbfc237a3f4c4f7ecf0ba436b32c2fe35179da93111b48cc9ea24202bdc1b2fb60a4319dfd9864470f73f54137206e0bf007f5ae88a88747008a60f4789ad167724f179c02b63aed002573d28a6bcf88e07ce8daea5d5f1acf487b4c5c16c2bfe11231ea5ea763e8f332cc73da1b2f8c198ea8173fd33d4b2ae69e5d4d1aadddf2fd821b85be45151962d1f99df81308618852ad7cf41d72da08a1b39df7d8b994b4ddff37f9dfe8f38ce30e91061d95d58f7ae826b02385272ec09f01a7b3e4b391d09bced665dad69505b419da8481bc3792bf8b8e7ad64b63f245666c8c32fd5c1b1b48c9951e1c21a1eb5f507cff137cfb862c2cc98766e878c930a083828c9d8db18bf16716685f39d6572a8ca8b2a514f77003d4e75bc154aebf14103778f365b1c3f03541ddbd07d6e23e56762d971eb02983e93c4e01ba4b8a2178928c4337d302f31c9ccb75b249a82dc96821e95a03ab6b770df2c3dfdbf1fe9773f8bc1bc5b3afa0440b102578f3d213c8d019cff124f75ce4accc8c667feb27c751a6120074813104e0cd070c9f5e451dccff4c80d71107c975abfac07d4d270c727d8a2fec349b533968e271892d2b62c125fb7974603c305ea3bfa30fb610fc5a23eb68a8406444391a521337
+SIG: 4c8010866d9115f05293b934cac68104cc2c3437568cb9d5c570b1a8bee706603075537033bd708a9c9f3d1e2519a915b1c4ae4ccddfcf0ed0c049d342a02e02
+
+TST: 757
+SK:  f731317cf5affe58704c4d9497ae860bbf739d0fd96b7c02efb6777b3c858a19
+PK:  d7d638aecce1461e314255aa29d9a6b488aea1396e9682695a470eff23f3ed84
+MSG: 16f51c59e9aefc26b0da5e0085eb2e2f1f856def9725769e3af12f860905ae133f65074da76dbf25c67f6257d2dc66c05f9b31ae177b69929fc183b588c519bca14796a0896d2905fd942d7ab4a3fd9541a5529f729c5851419b5fbef7b134d6762eb97e8a951a8ff52aa0d7e67444d06b07aa55e4eb9ab892f47bfd111df5b62f6f3fd1a5ed84125feebb77da637c05d5265ced113dfe8782dbd1cecd2c6c032b8fa8855b3ae78de74faa5aa20a761463c2a30be66bd38cdec75f8957cb94c113a45d546daf475d89aa1482f8d2803a23c939202015a08e94b132728fbe8f6019d7168a08a5930170e5639d110e4739db85e61e64495944b5423a74ad5a8a0a510612ece655ce18864051525b908e0b19290abe8b1182c48c700d350515fd349956e8087327f30b6fc3f131c2144abb3f0e9ca331172b35064a82811a68e2cf36b43e3ad2e8dfa5b1cef50e2a60293fc5f635c9a9998d8c1ad296e7c78fc0582022d63067186b65e764828cc0f5f7632d5eef863e6c6d90e38ccc87d7b747fac8491d632cf7f54b9a9eed16eebec01b6cc33d2463f7f950d828b55ee3f77cbe974f48948eb757aed4e0dbb00ad95ee01323486eba3c8da886ed7f57bb400d63a1b2ebeaa2e70adf0379e3393001ba626c0dd54b7f0c9a25aae6c9875d4e7622f3ed428fb3124b29c5db9a7ef16ebddd6805f095f5e769823c43f262868ff43e3e0525746d9497af124a01dff61ec718af3b5bb746fcc08aebd16684d456ae7932ff5ed7d6b0f1b25c7adeef598b5d58877590ac1dc05975156796998774081e5b66822a94a6a802c3a2cd9f489e1628aaf4652be1184b0fc7c5ee7f97ce08b9233b4b83d9367be5f4aae9782593a35265154dea4c375c16f0caf6dc4594d2bdbfc3375bb2a0432c482f13941ce2aaab4d83e74d116f5de4ab28f8dc3d1cd19d271e56e10398bd1df5c870fcbf93a7d1df3939547c107bfd90643f6f5001ae7e06397ae1a271bb82a1f38e097bec667466b80ee3e50dd4fc9d5d54f18faf7a5b55a8834594ef0cb7e508bbd28f71fd34235bbfd3
+SIG: 2a4fea98f9240171a1823f2f69352062672e6c6e6652d388a87714d647995df75b6e1ed1746af2adf4e806135d60754e60fea032128e35abc1f1615181125f0b
+
+TST: 758
+SK:  498e5a21a9b0c347ba83a47ac10069457f5783c2e1e6e4640045e594b1c69332
+PK:  fb3948c81199569105cc1b7d9ceb3b41a343bb00575538592e0984f4f4710abe
+MSG: e4fbea864aa51190826645d2f772cb0f9eddd3034473fa3177c7af9a5d41e1a73ad5784c7096559fcddb7b7c85891cf24e82c588d74774ffcac0c6b4eebc2f3fa43e9d45f259d67564030cfeeab9236c665b650af0c92c875189f5f9383504b15360a0b9a5a00da31f635b96f6c73ef47b6b06f02811d1d19c2e8e53550ce22e42ec50a1eb2ea2f4cd03c442d4aa436894238ceb1835fe99b240358aa0562c249698a3f123c2c17e591010bd6fdfcbd7dbe70b04520502ece37a9a1dfa1ae3370417b004217a5b8fe9903c9a3b9f4b6d5c46c0ed0c538cec22f2dfcb2a280a42adc489cf2e062912be9928f0c060891e432091177526f1b3a968069d4a57ade828559810ae0360681ff99329fa0f59e7e59cdf87f9f33c40e97031b9f81d48fc12286efbb3d4e5a62ef57bc0d52d533b99c5106aa79cfe1793a908518596c383483ec49ff98ec557bfff7490a46daf6714f2c2c32f57932ca0d730f03f381d69decdbd9a7a6d4afc62406543c8ebe90ac76e6afabdb82492a206a369e04286d313e11107d8cd9b4bf68f815dba4e990b049d79216d3653138342cd118b130f66b006f3d89ac3cf89837048b0f8a62d94051d2eab891ac5f47888879d88e546676d1daeeb4d175d3f04a9d74ffcdd47746016f84ad0d112afb59ad12187e94f22535d77e9e0516fa42185c197ba774b393227f741fe68273f423fb0e0e0474bfdaf2da78aeb1cd5b98c1dc0832124742a4754125fc78b19c559a5b3f7711e068c440cc0469a1cfa5c1864be18735aa8bcd406c4371eb857754d908bf379b91fcb24e34396bf87c19a04a83d59dae71f3f3839829d06221301ef595696e719d56b79520a0e509929833b1d804a6a0ea40400bb45028ce5d36933883e17406e27a8109057b1a1a5e5da210a6921994f467ab41aa8f0d88775a8a8ebb4ec77d7c80e45a7bb422a4c00c90583911465e6b5f0fdcdeab72871ca542e1d1a2ca94df4ed2eabf90ded0045290324a9fffb30145470209f3826580989349199dc5ab8d4a25df7a0529cf91471e30842abfacd44ab781dfc1395
+SIG: 2860830ccd1d41d95076816a398424f7b739c49fdacf5654529da85fe3565584f6aac2614c63f774b61db9081f1410fba8e50ab3b4c39dc06314243f3f0d8e0f
+
+TST: 759
+SK:  c24cbf401ad03bd88dcc7b519ecf624db2223e990289309e1e9f1f8f6127c6c9
+PK:  a74666f357209f7189903788f107563e50c051c3d40c3f3dad10d3c3cff1e678
+MSG: e7fa359e6a09b2c54aabed3bbabfb72853a805aabcf4d18ddad39f03f34601e55b6ce263c9a3ca6a3e5f1425c821928c61e7f750919bd3af32bcb7b94d459a7a9a35f61c941792e2cc2e4327beb344a841a07f32068af102b3de61eab64ef6d5e69062e393ab5edf6ac9ef7b38d49a01bef0003f421174c8885975c01832899c3135e7a86e5b55d9b1328bb4289b5c40200f49e5523b3c461dc7175e1465022297c3d380f2b1fef39cb82c00fd160f447eb51263fa25b4df0fca41ec0ca2ece7472201af86c3038c49df099a9aefa1f88d0edfd17c0b3c86046629c09454054aa0fb2c6949dd9c130185dfa5d903891e08742cd0429403f57f4052158b2f401da4756854e4aaf024221e37513cf677ee6a0b159f501d377ea32eb71e778004f27203cd6d553fda5d65e1879477046f3ea3d1d75c9d0d30311456709cc7f6ab68c7b0d52be40f04cf655655323285318329e84c6a5b07e0ceed5f78f7f1fa6229bef878793c584728abf4510b7f27794b5942916254c589a09c8e911f0b954211a63699a752147f2a4e1a18956644bea2ca2692ba182280e04a72dd89b0d1268500938f347bf43f2a242ee9b9a6baac9b350d656fb19ec834abe3164440f2d2071fe5e32c8e4cf905539b839ceeca2620fcb2a087f780e6c7f5e05c506888250ea7c856fb30983200aa8f78fc1771054ada0f3fac38ae2f33dc4a4f851b76ed740c0962a76a4de44080dc620a44ad8f23d3462b792ab3afb19cb8a9f4d9e59ad765a771899da8cbec89e5077e85c0c93126376c941bef1f8bb992d3a35f270725846fb252f8b5fbb7567e406a1b53b619769e632b2b4087cd4c276e5d58ff2b56e89edec48ce53a52e329ca1559538f10902c01a85fbb3cd72e6b8291e5fe639bee9d47d34c249a7a07d7a1427a01f63d60984c450bef819b19f65e2614fd9c2fae7b9231a0bca414ed94a5ee7e66327d2a99c84878b7bee087e891f253fa1fece313648c06c45db2d9f3bc8599937b752d38ce5063d0ed9a43ec9d4015893d43bf5b2d1c60478510468968b796f0153789595441722a
+SIG: 581e6c85aec623b62b3d4c9bc9c77759d5492722e252d44c1f8ada9da2ecc67c17083273aa091bbac046ae63c78893152e14d926c41ae35f0e6e3959496b1306
+
+TST: 760
+SK:  8b3dcde4abbf4e6211c4a51c4b026800a8a2a061cb38a2ecc7c9cf113f9270bf
+PK:  514535580f0de359bb0d41f2efddaa04c2ec950119f31634b2c1a32f195f6968
+MSG: 481425027da672b6f26c91b80e55582caef47bb15a2de8fca852221785180b20a7fd6d4907b5881cc1d6e39ab9612cc74d6977e9141f7087bb27ab3084a26285586f8411db1f503adf52dcb25ab8fffd2ec1504c1777b9d6dd4a29e2019e5cbae1b7eb26f95bbe07d90c2f6fb0884a59a8d58dde5116edc3bc349d37c160b27befbe5a5c181ce7256392354d221b58c47eb0bb10929e7421795f4b7a7c275edd08c088568772e993218dd6f3c2cb4ac657a0a3f91f3126b991adf6cbe7d1b19b8cd83be3602ed18f039633fbd2387bda69e2cf0387d8644d97b303fb00639aeee7ae463f6fe1a2c4b89aeba3e9094c11fc29114b20283f287c6dd28cb098dae8dabc48e85bb59c0dc6e78c956605cb7cf06942353e7a22e96f80a37a66f718d9e4db8c52452aa0a35772e81ba2b303205b412dd2bfc15ce9b436f99fbb32126b63ce9cb43199f157d81751a7c4937d13af4c582952b5d606b555b046bf1de06cf39b63a80287371803609a387ee80f3a5d88b9d6219650ed17d3cc183b2c70d5eb94e3bc52aea7aa7f53be0e20b8972f143d8e20162e803edb4aa83d5553fdd553398b0fa176b959cba140d6e980c9251b0fa0b65e908417f82f451ff9f2de6b9ca5e3b5f41ba40d05a54f3dab4886aacca05c9c2798139a4cb33e96a91494749910a17ce8b392fc0fc7762974d79d33db924bfef8655a723776ff87f950fdc568b1e526534541f572723b840663c19188c424f7c489235a424b09fe25c30727ea1cb04953d706d68bfe12100ef6f64c35c6b8de67edf0e3ad014a400e821ea34024321999867b43c82c450184b78f7425cebd7319dc6f65d360665dfbe7c36674dac3a54e96da910c02d3640780b22d512ca0e3ca3587b94ea9fcd7a31b4af69fd6207c68fed25f89921c1cdcdefd1c090204492bff9bbb52e08885829d012bc2dfb4fe8c35e59cd13bcb8ead34193c40b03ee4d825ee1322ff4ef071279574cbaee7c07f14be606b9cd0e261111ef20d9681d76cf78c89a8c397d6b8dc778f4984166ad5df3a81aaf2e6de09f700195ae2c1d4609647
+SIG: 4f3d4d228503017e74a6bb58aafae35c3f37bdee4ff6be2e6240b5082feddb222735e12f31e056fa685447e5384803007ea7910e605c1b78118cd5acc587a606
+
+TST: 761
+SK:  d4a7a9524d30a6337c0a0be95ca90591de9888038e3e59e1b25a4181ef946629
+PK:  9fc3ebd139cc5b7c0e05af47bff6619b812815bb01ceec392a3ff0aec3811d2c
+MSG: 171980c03fdf7a727bd5bab3ba0945e6ad5faf0a7f506a56d1d0edd9a306b3158d843266d3091fc1e42281df97559a2201f5bdddfe683d0e1028d1d95b2f313b484c392ffdb1cdf88508afde3d6fd2a12888bacedeb79ff3db40c9ac0ec3fb901b228698adf8d845ff4fce10de55d42436dce930973a34be05d1401f334d4ce8e3a793799eafdb94d0f2ab0950b079e6653eeb499fc7447ccbeeed8dbd5456808cd7a38f9a15a2a9c738d61334cab8ceebbbf4a4814d94c61859178784604e0c2154597e72cf587cd1f5dafe5922051890e76d616d8cd5b05d6478d0626ea83ce808c46143e6fb06b4182d228da8f6d4139eca5b8f3b1b98af68c59b4b5a53c136ee90432aca2bb915529d26367949826233b43e55804b55fc9f215eb0b0b79291465bb34edaeadffabfe6cf41bc07b5dd4d0142f0361f058ee1b3b9fcc196eb9b35b134be3d1d232004489e8f6993f625a63015bcd3f1e87588324858ccfb770dddd894bf297bd763ef5828e21f5c89aa98cfbc1c082dd7fbaa4307bda40b4a758ca8f39f4e4aaed309041268dbcf0af32de0d7fa90a523963b780b6a932cf89499025f0e0d0474c74348947510e6c5ec7c9e05066eeb4a73520c3d927c39ac26ad7596325b2cc47c5e82a775455b7af03120b1cfbfd6ec3fc0c3be6078b00cfdf8342ae8bf147159f50e9d564e2f68306dae3caedd1019f323c478a1e1f67598dd834bd1d1a8733fd7fdd8a876526c531518936edb72d01656b344c7d65ac1cee37ce5997ba48d3f4d064d88057efe9a482d9e00ab5caeb5aca2d660e337bd15487365697956a5e47b02abdc30d8e353fed4e1ac41d2bc2120021143635935c620186a522bde54be0446fbd2dc88b56304b3a64227d0acd5f85a6b6787a3adcf2d7cfc86c634b4d7ab4315b97de9e666cff3ff1b88f3295e7bab9e9fd46fafddb4f5fac51cc0170129c651b4ef4d3950d6942ff020d1668a528bde1da936c0ec1ae09e84f8205861fff491502a872c8154a96e7ea25eda955a7fd2e4b4c7a8d273f60bc74fab7b4968ca6f75daea5040f839fd56c2a980
+SIG: d15788bcd88d1d81b9e61d4fe26ea49e66819a59d2ae4832321b814d5062fadb87807db6852e1d8295e31a291b1e785d01d834895f88f400df8832c1607b5b0c
+
+TST: 762
+SK:  d08f4babba3b5365faf738795c9da45db1862cb28b93eb6635d1320da0f4d937
+PK:  ef31b454f734e52b3438ee2f1cbc35631b1969de54ac98fe4633f2f500ac8712
+MSG: a394d8854ceb5c43afee1a48926bbd6685aa8aecfdcf854133333974d624bf2f1f9c30f005bbf34cee3afe2b290600eeae6f1dd12a0c346fbb2ab9c916c5d5d80dcd87887875a0ac847678039fdcd3a9793541f5d675143a6abadc3b18f0fef5108c19c2dbfb59710eef9866a4f3f297a09ee48c6803007dd6ba8fd4be841cfb10ff0514c30fc4dd49a3cd43bbd16e460443a11afe649e901d63d89af598aa686b2f607ec11f35e17a798a4213b75a38788da4f27cf2b02caddfe61c3729a87ec6e6b098f68e7aed28a800c484dfa0130401208f986d792f54635add2848e151262a365eb21e2727191e1f700f3bf5c73b0fb4c546d0048a155c18717920fc0425c8c8fa8f167c43a277bb366e0ad702c89bc5aa06fd470943be05cb9e3259787229714c30a4e87b00a633aaf7be6b5875010d12e107c9a5261ca562d67025bea0fe223463edb92ea01cca92c44ff24da9d8a80a6421f3d4135d647d1bb0fd988c46c8a170ceb4f33fff9c0ffb6abad1092c84dfad8290898b249516a292e8da96fd51a81005eecfdebb05933099277d073a480c3f9eb8aa11968c4d8dc0787a9aec3e0527b7fe4c0635411335a1811689e88f6d5ced0d40d6b48b7f2d992952934894153076a8d37372fa00d9cefc5cf8c26adb5acf325a01cd005ab8d474a52d67114078c6516aef804bba19b887a28ed5e46ee9995e5ad3a82fb9cd93283433680921114b4d9af8fcb6b2b535839c36de8df12b17ea6ddcfcb3334ff40e6cf04ccd5ca6403ba0b62b4cb71bbde91d8babda69152c9c93ae769b5529c8d52fd9a6909a15e1a0601a714649c96ec996c1706d1021b97487980d7b2c2a39bbb0e470d8e46ac4aa609a0922c9bdc01612eadeaccd5fa523b2a8d0e62ffe56281647d61fffbbc840535745d144259cc81300fe99dfbffea6b0b9bcd28473982d32e93ed46634a9987906d6f48939d8dfbfb37d33b888db608cb2ffe39a8cf67b72644611c7d32a4a8df612468cd5e5d75fbba79e638aa1daa28c4e0eeb9a637ff8a08b65f7a7612414df76bc7b0b56b5537d666facfddaf65af1
+SIG: acebe4c86fa9fe2c1a5c576ac0501e8ab0f640fa40380536fcf95059d53d4a3555d220ac363587175e4bde163c0d00650a12963d46766c99bb62bf7573e2870c
+
+TST: 763
+SK:  8f474f88cf863c485456a5a2155281ff27b28459f63bc4f1db00e0031064f649
+PK:  43144a329d751d04e07169b779ee920dd029cb445bf376ba3a668572182344a3
+MSG: 840891d948ec19c8c7f7c9d3c4775362a544a0ec97457ab5d14e125dc54b59c8dc9a635e7badb6be73c3a58dc0e9929f2b420d8356d617c3d41bfe69b4e158d4bf08fb17e688d3cf3c948b69b35f0b6db66272a8eb2bd410d6509f6c828b6a20d6586eaf857601ed9d6054799c25320eba8077fe1ae22671b33a1588ff2b235d3c71a27ce5c6c66e18889198d116933676bc4fb0710db7ff1ac2f20ce369bef56b43cd1d406cefdacf00f1f348b8ca7aa614db11a3a640fdb59389d1a6a394755c133f1b019c8308ca5a951e73b810a180f6ff25b29dbbccef4c13a97503393907a2dba096a8ce5c86c0ee6f97c1441b8d6331cba53b19606b421af52f65f9c663e63d3982718f948c6bae961b8e4bf8cd9e31cd09928e4e80616597ccfadcb8a614154933bc37589c85c776e34e5a90660f59a65b5e93ad438842f982d02b041e6dbddf171099f8db70995731a0db8c4625c9bca710805961fb176dae819768fcad7ff9bfce36403ca7f783e7613726d7dc59f24e247cf15068ff3b19c725fad65ea8e8a7f722d528c95fcef1c0cc79d18ef07cee8b011eeabd9921634d76a61a8a3c8931b827e8189881f81f7a175f21fb0378b8188e58bdb2017bef390f1800d9d74f263a81df8e67522d092e775d01e004e7f8d8281ae2c2fdf8c3a445f9eff7fdf13f261a773ddf2dd9cc6ba5585d990c995e6eb89dffd9ff0a9dbb76ce5e10dd0272d5001497881366f5d636a9cceaa283228d3ac614db217ab891d6689dbeb950e1200c3de53bc5da07f1d363dae9be6ec36eda6e687d26290f7abca268a7fa03d9318864eda9a11e3b26140605920ac13adec1b5548c9a7a3215a5876b7e941afa1cb5d7f7f0c11630cd429f3b2b37dc76c6cbea4f3b726aa8a5f8b9f705b05d7e9451956f8af13ce0a85955c7135d64ade5496ea542e70f8da5b573aaf137085dc96c6927099695672668b3c7c6f93c977a4e8e9e770295f20d52dff187f8dbb25ee7e774024eb9be08121ed74b6d5462f4bb7dc2003874caa31bb7595cd93a99ebe1eff928bb5fcb9e9c89dd31d487fc0e20bbe150
+SIG: f61f7807c33e196d0fe182efa4d4516a9815ddd449538bbaa6b86b6901a05f5ddda0601ec90f39f1554779db7a09a60572effd4d128d0d3c2dd4e883574bc60b
+
+TST: 764
+SK:  e42b30d49c43c4fad83dd51fdc2a4ac5901327add800b66972c8c70bde180adc
+PK:  f734aafaa4dbaf315c258cca8bbc1d4f34e83601109874222aa05589f3a6635f
+MSG: 0d497051861e22d8a9c60e5f7de6c895cba335b2e82e602118ad8342b4d4edaa80f95efbb59cfda1fcc0291725700e8a81bb12a0b8623b1fe2891b8d98f7a84c59fd92f8a7adfc065042f7f4fd7e1a79f55a1d4d5e54e04e672f1c9e4c4cd8d0003f3cd54b76e2163dd737acb2de5c263ac102a48f696b60caf9be39c665cce1e0f3d498553f579061889a5ec5603e4d141cfdede8e7317572cfe76a0f48e4ae06062c9157b5eaac3468938192db4b16105c7364a94432b215a71797fee14c3c9ce2f746ed790302fc41dc492d37d9ef024ab51da3bdaf0f81d9a930aa0e025c04fd71026b6afeb7ed01a91a1efd6c39f5e447c66dd38a7656c613d02126f3585dfaa02df930253f83bd42196463ebc50f8cfc949ed350392e61ceec1309da15a432f80dfe948e261ce6d8421c5459cd21f3ffa2edb500982b2abfa52e82437ca230f609116320d9893eb82a14df72b7736667516fc012b28a03c9dd88ea4308d8ceea44cc604454cdfa2c797615bc0a6b3e0089af0a81be54d1b110a13ab911b452c342800cee2ad239a2b188a7fa875e941daaebcfc88b70ae4b1c575cdb6e6d89448136f60ee81c703c47822d2c0e50c7f1e8b7fc7ebd80789fcd7e06c7e50b5fc8b776e8b9a4cd5905a29069bc3a558d7cabce2af4f310767d5b117e3076b3a0d527175543b2ccea28d5f716fac32efed3d2e0276be44a8956fc8240f2db3397614f2f2da02166694ec6a7feec6ece39d72b64bbc6b476a4f84f8d879380a38488e4d6e58cac0390ae25a5fcb73d47414b4c26bbb9b4cc66e42594bd56d841a360923491d117be2c6eb2320f3c6175e44e27b6653c5dac6fae73600b67960dca50aa855a89e0ff511ea04f143e89f1da028476be4bf6d94c80ff726339e8bcfb7dd9f8cf202259c0acb6276c281e3847c2cc8d2fba84438d2d3c6031f2a7b95c1d8f9f3cc86a5eff65cc011de95ad896858e1f7f6d6b94bf49dfff5de2d7fd71ef108134285f61ae475483442dc90bf013faedf3771c47c5b96dc3cf8e48510060ad8d45fd5461622780d869d4617b57fe3cb5cc0203153aae
+SIG: ff8e076e343c8b73aa453bfee9b2bab6d5c2f74c35e1bad1e52ae777d69f79764083f994368a1ac851a641cd247008a34f3b608962f4dd5109ac71cce978ec02
+
+TST: 765
+SK:  5cb514217482bf42f611fcec36a5286807c2bdbb56967691353f54310e1ad553
+PK:  280699003d5d3e1c05ad10fb10959bbc595cfe213069965cd8cf39dd426a0568
+MSG: 2f57258cca7932e58bed546cb0041115bbad23d18346ef7ab5e3110082b3a9712f6cbe1270e6dc0cea3364a06a5f2f283ec39b63058d34d59979072fcbbd7a5d0f442bbdf082d5bfe2998aeb51bd26127803e5c796c38843200ae2f6e605af312f54fdff17ed1dfaa89d28fa67dce462de4fe25268212b282e222a443e2f31e269054171aa73c719a896cdb7a539dfd1d42991978197d7c4f2d30a641be34bf1380a4f4dc6d9b101636636a496beb357e347c1666516df8eb560a0e0d1e1529ce36a60e00ed278da3802be192342989bb611b4e3cbd9c37e8cce07efc12d29befd7e2f3adb13d28f708d97b63e107482c862956d7ce8dfc2af5cac8d51659267b0bbeddd5efa414ddeabd17b23ca6e843ff49effc82a5d07e36a83b67c2ad7e48eb9990b421c5558009bd6934e86d54a8a6ac4078796e305c7cc810d3f66ea6b9504fe0ae6757c504c5552530a6f8bbb52409be079d8e4a28a6fd7dc8935f8eb9498adc0f23d0807ec86295f4898f5d05e150bdc43aa8b7bdc893a0a684c3063898b6c95e7d56a4c102690438e9df99758a90f47c608dacc4ca240266faba35fa1eb2eaabe288d2c2ad50b6cbf107c002575e91ff472a4417940667be8180173854c93df84464bcd312b7a7ae4dc2b9059fbe6f83f53806425bdff031c6aed6efafd9de8dcd0dfabea8e6fa681e99193fb3c647e442112c9a23f596e65411d8d6bfc3923004ece91ea6deb881111b1dc29943f578981ee8c3bce8525f78565f34b85ff20015feae846f95b18700bc5cdf14b2db6cac69814d63d74bf20329303e5ca9f04731f6881cec6d3abf87f5eac08734faa34cff4d3cd9a4a11d7b12f73253b4dd0a43178f0d3c19c0c40d9ed918dd17646f616af79fdf6194262f0fa4f71b3187dedca48d9cbcc19931a1519677456256ed38354567c3a67571cdf82170a2c85bd2c5e68e05a0f3b93903f191b894f84946f89000568054c1cea9fd0b8bb55019506c54341c24931984548ba458a4d813089896e86a2dc33d94604003f354a7cc941c754aaea24253cbe4cf2147ffec5e7b950cbf28e284481
+SIG: d53ee2e0f0fd657b2052478fd15df1d38fe0e93a5483eb4a6e7de93d02a4cd544d8fdddcea822b71576ed02853d9a6b14e1a548aefe90d92f883792b7f1d8609
+
+TST: 766
+SK:  87d3ba95c40df80069b1797ddf68e866e66d46c51fde60e768a9dbc5c92f57a9
+PK:  2b812b2c9b60ff31975c429a86736dcc17a58d3dc1daa34623a4bbcbe2cc0581
+MSG: e11256f82ad76f3f4a49d7bad3ced8718d36d2f2bb3d31bb61edd1ecbcee6621fd2eeed3e3deb597b149ff71b851f61c8c6819e131f9a2af7673c3f20702acfdc8b8f9064b415c9a3e35568e371d740a38127c1f27b391b45d07045aeaf00a54e5b7fa548afb5f96feb5f5b44f60cd1707e8fa9567f7806e15f6a01aa02077733fe738b08f21efbcf98c19d5b970e6163e5fe8f4800ef9ed22a0f9b5126ff1eb1c7d65019c8b440391927029b813dab7c7e863d48229f8df85394345fcc88a300f60a8d516d877a5a3a7e3c49a9eb06cd9f2665ce2a89022962b1d49592b09c7543da835ce63bc9abb822145762b71cbe150292ce5c8704e5ad34fb4592f972044e43e69f0e1672d6c83cf25aac68efe3d27af2ad34274b9d2b77742d9c6dfbd57f92ff64d3e4c67c541d8502a7d031895af85319a4eae2d254335835eff11e7a3671a6a0d21b72ce1fc2acba1a920183834bc0a4b73f639ffcb0f6b81cd920f2e9420d612166d5682a06060ea0b6fa695fecc7704bbe4b052aa3ec8f720f7d4f32e8aff86b80b8c1cc12764a04874037c3103e9dfecb8f7abcb0e073b23e67ca0a9b1fc72993abf31dbc24a8fee095b3251c22626af5dd1b6d34be5ea06a02ae176c7b8cb9d063501be6f612082889fdbdcbfadc33a0d311b080b8d64e49f16b16dd8edd3b2ed1193a74e5be507609b042727ccf08afb05cc6c50524ef0e2664621dc8b05b15ffa81ab6f7e3c8a5bb3eab1f68e3656c119d969e4144cf3285af23c04dbecc038aefd9183c4e72447b2aaa8315f4696ce6d1ef429ba0e5c3d5ffa7f050be39c7f612f4e10f8ef070df72f8addbeaf3339c1ad8b5fc39a2ecf29a87f82e29a0117baac6625ad5c80cfe759fa1dbcfaa12b374477d80bfcf06796c30f2c39cf0303d00dc56a32d1d039592ddb06c22aa068841c0b46fd48df8fbb7492ccbc590c563c8fecce4263c8c7539218bb97b35711537e988195dbf5bcd5ccaf06faf508470977a5358e6f02608349fbb99a23fbe36b8c97155adc246ad7d93a8c203f75446c83c4342c35ba104ecc67e669db4a95466ee68f458a
+SIG: fa0d12cd53236c41086bea8c0cc60b7764a3ed72bdeb9d1ae5eeacb48811fe529762a2c6f2bb06d9b318218d968f644435497a1bd0d0d8c1612ab8996d98d707
+
+TST: 767
+SK:  7c27ae47072b0c9b9c2c351f1327899895efa536c9c067d0e0ce8e82e6292793
+PK:  f9febd121e17db7229b56709021849c35d69fa08b50620e667f842ec7ac782dc
+MSG: 1547876a988d1be714a42fb91cb03763f1913a892ecbd4de2ccf8344d20758b7b6d00259101fe97225b297f87bfe222004325db7f632ceaffbd134c96cbd57e985bec8434f81a4ee6af85c3fade50e4c4ef20cb0393545e4d4a86e1fa39aaf333fe4ded054bfc050a8983a03dd1ecf2b5e9517baf9e1152129a8a75935711edb20af5c8cf9c694a33cee451cd950b2fff08e3158c5cfb7b15cb3e90d46f494b6a108d8888d5ec29a33c066023b497709b2d9401feaf2e74ff26c16d36c39e6517ff954bd98bce7700671988f66e85107644ba2ea007a13018c1c144e3c5bb80db9511fcca4101bf49f8c80ff3ca7d298257cbfea629f83d5e06639d31f639db4b8726cbe224d758829bab10905171c9c0ec370d58031efe4cc5ae72a495acff6cb2ed9eec658ba117088dd3c6ed1df8f9cb10bd4fe0e5e8ad9f5034e34652d98668db15c8533393a6e9ec0870c35666ce54efe2bcb45c34a7230e6a700676349c7b3abf31de7b7b0521f89b30ac4034c2a4ba8218eefdf8d2a5c1f8ed9b701579e47af8a529a95a1ff64d8fdb885c36839b4c5f6d72a99257e8678dccf312754b9d4619beeceb825526de622bd9676fd5f357693abab078b9e03ae21e87ca161e778af77096eaac2d2d32bfec8ec94af7965f61d68ef66a4523c1cc70c9519b0750b3c9eed5aeba9f0a9b7ef52cd4a2de29b395b705fa53f028fa766159f20e75f4d384ec4fd66df06e744c99ac88cb849c285757cc557e2eedd86959da2c1b81f5b2715a6519848901ae4f89d0913c8de57c53dadf2e5e1aa2a9c5f464fc7610e8ef5f5cdd8203a67a93c33a06dab358dc5ae23edfee6334262f47b19b113d6cafedac1b43902539d74fba29aaa7bce68884b72616a0542c9fc69547cd19ae1df01723abdda65e9bfac5da0d04240c6a2175c0062e4e1ed8a5b397afcd4de38e86209272c7a424b5ae8d5a40b484ce1b4704af2831609ad0f36e90e07b2afed01dc05574ad3971723c5b5c1ddd4fc8bd263bcdf568af75e73d8abd1008c9ec712f80ffc65ac34e2a79304eade1d2a1dffec0e4c98c3582468f320bf8f66
+SIG: 327196ddd43bb602d04d1964ccc059ed627cef0a88d8ad91be4931f17c250d5529f552794a3e269d17a63bd32933eb5e519c1d506574770ae4a72964e06f7d00
+
+TST: 768
+SK:  08eddcb5625ae19ffe7b49a7dc829c893c7538b0885e18f98db78c8beb569c26
+PK:  83478b1c58576a0d1834b28d46fb80516d6fb6f9f591694b44352eecd1e7e89a
+MSG: 015b1d3eeb00929ea80bd8687d18286f0adfe645ccf25a22b5061921e2a030fc76d033fb53d0937c69b31c5be49913ca1f2c3dca121b2b87c59b3c84c7ae52af19c6b9fa1bd675fb6dd8b329d5668786dc7883e2d2e8586ff4128b90dee84be0ab54d6813f7a8c6134757173981775de84c4dd39e336f8a4ef8dcadec943e90d421b229c11785fcd3fe963037458e76c820b3bc2c9476001262b261d28b65b489d76b4be2365e4a80fa871b0a53b6a5fb243688235acc5f4774db15d47b42dd6c8d9e12dcb0b5d980dab0f3ad8a496f76e5006c2ca82675ff194caf8070d04bd384f97e583e73cbc4f7f257310a61b1c8062322dce8115f6dd93eee8a93ffa5cab6634116e1ab705fa86c4a8eaa556c6c89dbcad010436bffe451822491f1ea86c20207e4d12dfa362616c589f97107ea5d8bd8a7215c600ffc70b80e2abb15acbe4becca20d72155abc3dbe8e37cfd73f7420f21c9bcd0c3273513b5049670874d5519b3bc1db523c1d7e90c165967c4cb2845a2e8b47b5889254f58a9bbb826f94521cdbd0416f5f18ff78a3fd0d7ab897906264483cde642d8e703fd82e5ae70a9f978f64ee80520554850528581ca9a0b38c196fd166dae5879b3f72f59cde91cca2c8bfaa478b98d624cd34724402de578e5754825ce227d2871b45a5117149515bff81a923246f3b72d07bd458125c70a14d87c3fd13392a3bda6553016e8b2d07bde903cf687b445cfd6f761492eba46522ada84a9615d8da3498b258067269b788e559b659d4b48a87d880d6378be6a88746f35b322b047845aadc523beaff3070f721c3c071eaa319b7a47c1b20d300dc0321909b669e57d39a1ce2fdbeaafac21350ec2d6e6d5b880186c028a861474d5076a4adc5032fec9140787c36806ef79c72e3a19d8c8b70bdaf207295542d96825a5de7dfe108ef574599b8f184c63a5a131db19b3be53f699c10fc4ca7c63f3500211b356a0ac664ddfc1a9252590026395b479be9a5e4758423560b65bbce5bbade493b13d00cf8c1d3b7e9221367e8f0eadab6e6d1b5fffde7b2d741fc2c830224fff7ff14ae5c07
+SIG: ece75322995154b292437e47d38a6a70af37e2020716fde46bfd393b3d369bddb53253b556621cfb34c8a90254e132fd28ecd098433413a21bd3a9798ca1f309
+
+TST: 769
+SK:  2273942db3e5d3221e80d994fd5e1163af55f5455a8e52be852dd3adf762b440
+PK:  bc58674e996b6f3e3220b3e94f0067bb0e9b0d97d9e1059cf13997a193ac032a
+MSG: 8aa0509e4b914186ffff07aeb97a04b546272da2f9ea7bfa659a24cb50966c23eb6542e4f22debe33b65769245c4d1b5dcf3e699c70c5c2baad9734e9d1efe5448ab71c8946aecce5268d26f19cf605eb3bf38b0b3322694ac0dcb76b0f946842f6c5c68d763fce74701bd6b78e71c8c3142add4ed46e0969bb9555be03602d562e4c89f3a919940e883a96940542f2779fbf9ec0a285d9d8a72360146e3ffbdb78d210316038d95d6ab757165aa943c033eebb321c05a399569bcf66b4ddb0b2e0e33c4793d817ccff57f99b3189c60d5d7b9419d1ebc943a79d4d8c394566180594f559a80529cc1ba28877af8f5c0503e943cd3aad99811645272dafb49b9b3e6107eb5e5186e1608757126053debcec75dd9565ceea06a1391a8226d1f4593792240ccd97c67a6c2b1344c22c91f42033adef52861f32a4e0712a917879a0b0518b5424bcdc054b44e972ed24d01689f4f27f5f176f0a578ab2d3c0878272e8c08c21582118654124dca39585337c13c1865814caf0996cadfa65be580dee322ebccda704b2280582604067dc3c6b1f7d8a26978a65cffd1ed3196a2b065fb3caa79e6b5b66c13d7bd7d0ec14a3a4d58413f212f471ecaad3a84af35e598a89fb3447d3324f020fbf1b73e2a986e0da16c0183bf92a398c419a0f9f30537bea0df8df2dc53c154e8ea160689e7bb4d729dd8ab90031427aa3945863a85e89652b9353805166f7c0a18c939954b2787c37094f92512722e52b0c976b9e42af4039d2c0578ff14fae1d8c2d1396beb2d6aa6ebd55474a9349867a03f3a99d78780634ab4b35cfe1b87a9133252a698bc407d63842870e22ccf3933620ac0423c3d1f681dd73c01d06c3b941506c98eed9b7868e017b7f99716b0b77f11321e5ab23dbfcfca9350845ee180444c50ff0a9c965fcbf777708e4f34ccc637c6a08d854384f8d3e2516956c151d031bb1cbe712a5ef9ee16619228bd296f2afe582d9953d590d18bb205f70f844c16c0a2d8318037d43dd80f65c6a753f2a8e27c89c83e7ed70c52f7062dfbb1f544aa236b5c704e7b39ce0a55fd46528083ca61
+SIG: 874ddece08f30b30f0d4c8b3ed7c615149b8aa740daa347b55958f1e2119044f695a21069690506448d8e7352b9046511d7f39a5415bb9c57050fc17055c3808
+
+TST: 770
+SK:  dbfa45abaa55415238b1287634d5eec402dadf622e270c04a8914ced270a72be
+PK:  c0fe323581ea296750797eb5508ca19a583b537fa7df4529f0804a33c1a4bef4
+MSG: e26e8dcb44e641fc20080e95474bd39d716c5afe5a1ffb056d1eaab0c49f8570717db6437a03228a9ad9f4bb0b343b95e16023c0807eb2a15106a6eb12dc76683e69dda3363148c5d7dd9713af6f87a09410ea8f76b6b78a114429bc85f784812fca31acb0309552cc188c6e9697093cf404c6f0f4abe8a1608673fdfa5eb78f65fc1d49cdec4094b1bd234a46e0ec62a4b6d31b829611540127876bff4c173de058cf61004b014a7bdf793dfd6b63c507d2b23e0f56bc2fe6baf637cee40d18992295d848ef498f8a161bd87e60c91f97a91e9ef3f6d97f2b2d2104ba6fddd6c680706273dae87e6eec1af2a45984985069e809e8de32c12889299a32d40f38774599ac3324b7cb0a4ea632c5f910ad87f5adbfa5c3bb20498279fd53c1c267fe0a84773085da266b253cd853df7e963558cb06880780973423c564cd0bcd6b93334c195953d7cd899f8a547d1a1a0a8deff1381b4321574728cf71b96ff209e899daa8f13f41b230e17bffdfdd2a8943aa5d21e5f36e1da07edd6cee92dc48b5b2a7580146a9baf713950ce676255a89e34f8787547d62868db14ba46594da310d7e2d9e7c7dbe17dbd71eb47c56c5721dc96d696470573794809411cdfa276b059d0007c25d74b2a67d38246de11ef46dfe2670926fe4b63656231bc7268bba23f378e84a428c3cbf45cc539678fd467cd33dd0757cfa024e54da1ff54ce820229b778b184be1fa2e8468cc19955940735eaaa884022f6418b0b1f26bccf169f1bcac7d82a35ab6ef847e1dba537dcaff57250a8d1c71facb134cd06b01c45319132745dc488888a1d7761b8486a37e6988a1120bcc1682dbfc89143fc35b46935d8acf6ef3c42f0f4bf679dfd6ff44b6ada26b01a9f89f374c7d2ee48dfe1a410e897cdfd97f626d2668502814400793b3b07c8720bbddc59cb0f9de964ae075b4af3dd4baf6d0e4f94f294e8109d6577c4f8a9c7a5f7d694bf88f1a5ea7eba0a66da6c770c08b3abffc534df219dc3e3323b022e96cc86002b189181a1d2b527d27950b7f425a47da4013778bd00b71105922204921e9dc692c233f7baa04
+SIG: a462a9baa56dc0f7a71bf87b95f48d642022d9d1733ee3683777a3782228ac85fcd83026be4ca97a345b084f50874e9124e16ba17dead4ad85c0e56f16ef1804
+
+TST: 771
+SK:  ef64e17a53f7fbcafe3ea4687684a0dadb18d03735a40a53b3edb04907ee6162
+PK:  9186e6bc142961c4d3eb369e9e11578292de5b6af534d423ff240fa26e21a781
+MSG: 6882456cc3d1ad0daa9b88eff0969f15e97b48d051967e1390847225f26ac25559f0246bf7d683fa28ecedad21491d77bd2696fa835d0fd119884fece9d803691b2fd3de17ee087c74007a7de9bc6534bbfe95fd32e97c375f4cb65731aa1e8346bea21be9f2c3dc874af0431906ccbc2c600127f4d3b069eb091d165ec453e672e93cae8b72f03371d8b8a8244ec4ec2e09f31df40206a2b1c84caa1b993cc675fde1c79bd4a7d15974fa29ce2e892c2899cf482c3d9663f6d2a79784f41c1f5866d37c8546f357d564d3c4218dfa6d20b6c282b400fedde52439d472212c5767a35da5201032da8730968b0720e8a604de6c1baa3f4e896ac2614fb1ab6e3f6cf387a8eb2ff8a92147ab349238432e509d829cb75b2c1765c51221848e25afff5f16e4dd0cd5c9f713c4aaab2ce836f8494506b5309dc2b0ae745bb9c4798098fb8641d520a08b02f75ad80dbc2ce29e890b4d72a3ffb2a1cbd538e1229f579c29ae66bca85e0fa08c8647a1abcfe8a49f5e508d4d2495556623d926ce49efa4350aaaab5cec2cd885be1d63475e3bab7c7cdc8d656173b8d45602f4b3d281241d17190327b24c3836b19311a193af86a6768f04852ab06e67c8ead591cdcbf3789c613209cfe03f58c0305f63203b487f7c5fc098877ec98a689c9d35af81e84078d66fe9e4eccbb1cc6c71991c03017bb811f41f07de68fad194146061324f3d0ef217a54cf38f7a625a38869f67d0b7431df937cde349c175ce8b26ac88d39a43e279b018764efa4dd627cbf591f6209c4a5bb19ebfa7c7135592d02e501cae5e6b31c90e72faab47f7dced2c48adf88443b3ede60cefb0d6379d6922ec437f086bad6217d4d4ffef18e22523664bf4e9ca1e65a28c2a7a60c5f6bc906b737c29935f9097463048575befd1a2549dc474b13e68aeecf166043e075aac515540f831b43066cef932e63dcd5b37b61578c35b09e45cc2a8def57103edfc5f649831a8961fe4a4b3721f1d6df4ea9f033881b474300e0f12cb9cd3babdcffbb918dd9bb0e2f5b21033e43023a0d2e66da3ab0f07ee988b16889ca5d51abdc05fde
+SIG: f58f396ba27e067a5fe003e385582ae3490e05957715d704da0da63a6419d2e4f6dc66b7e88e428a6f21b9ea202299a3c36b242b0ea06476ff12d0b6580c0403
+
+TST: 772
+SK:  3347dc47bb3d2e5d0286ac06a54fd921c9e96b6899862a54e5cc8115d3d0ba99
+PK:  d00b645d86dbb7e524757ec778c62b7e60d0b6576883338c9b67c2c7e4509268
+MSG: e2f48edf9d643320ab991c8ff9f6aa75fe066e7d88ff1e472a5ac9c518de1fb62983b1007f6422809117bdbe8a0e5787f66bb057d27f129a200b40576e1719cf9e98fcb72af94bb82ee70f3719a2e2cd9b64777cea5e446459874b74bfbf56b2d2526400592a9b45a5cb798092b60a81b71d82f0685fae7f810b52d226adac7ad8a9183f09febee9d25046c0fe306681ace2bff91b3482b0bc30b2021c4341645d675134fe3081c51e5c59e40b375a1434f63b426e30530da9353bb2a9423220434ae59d7b6fdc143f4982eb8cfa7751b75bf3e9c913c73b760b07d395310c59f3b77ebf12ed2d7b03590d3317af17df421e78b0849fd56d945c5696a040fcaa78a93ecc16d5ac3445063611f3013e9a3ae2e1c270dd01a8ffe3e6126bc1e4c95f6547a8651f26b6404e39ee4ce7618918f3f937a52573ec277b771e91ad096fa15c7a340a809b470318a4636423eb4888a12160c4663fce2996d638896c839b2c7ad4b3a9b2e6cb71e912fe39b843c6e0832eca22de938b50ae863e48582c10851232f75e5225b8896b5a470f818b6fa39eb7bb590357678612d25fe1a40ea1b9d71d880909c1bd4ad176cc0ceffdcee7099e7882a7c907e4bec79830c6771acb89944bd54a5165b31870916921b198acd4432e7eed8ce1deb345b107eda760266fcbda3ba5229400a30360a4645ca8db38c3d5f4a8def157bbdbbf2c1fa1dc6b0514a4f5a0364f928381b40f95579a26467f2282a8a255758402ac9ca80e89b9cc6860a34bb3f90c3237657c2129ea48c852b92569e81106bce461e2024454821a917592d1991b5b69f27bbe019977528a2fc01192c56b4aea873cf8c58dfd7cb4b0e917e87a8704c992820f98d77404d3f1d2050c6743f6e93cdb51a61aa6f45b351b26461d1329f3151272ac396234d0d67c178acf91fc510d86429c69a87fdf101155da8d94de6722238a6fb17016862b11d502c667ee9ca0aabe1c20b97789f1867add78b8b87e9ab51934c0b4a16c2cbc4d2efedb79c05b23e0cf789201ac75fe076d315fcbac20ba0d31e4dc616927d6eab1b1c87a1c9c778e4bd285295874
+SIG: 9ab4299b17729344750b69dc6037368c98f47be627fbd9adfd8db39f9964ddb7bc92d674c7be740756396baaeeacbf74947b6191c6ed1f5d32a63df36d542601
+
+TST: 773
+SK:  ff15d6e74e28e41d05a8663a702f038d5b8578c4275e772b73ba440bc5f55a06
+PK:  4747e2e9b82637b3844b85f75b59f7136b7fdb1a62e7b70d6aac17b3c5752f2f
+MSG: ce7bf972844f5184ae8eac87b12be9202c7239961dc23cd41ff55b9bfaac0cc06f3f1decfa9571095c8e82b4eb6f8a1c52c8d3deaa61a9aa94e2ecd9ab5b8063f2da6d8015df0a5144fa3a48e305ad9f41eaa11c4d74854374ecbf382e3002579a9a249efa1e1ca04d338447d7f2206703e6cabf5bbd332b42573bcbd3b6f71b7c3bf73d4c774aa01e866841432829d07f96e1f61a20216d968c90e3ed11f663f7d6271622fefcf3ab68f344328515d5cce2ce85e8bf3d1d09043692e1fb8bbddc07a4ab0a3eef8ca6a420e74bff8d3d715596aa821682954fe89629ae27c1bb03b6aa09f36a39a3e37ba98132f4e23888f9f335e7beaa2cb2727acc3d2777309b85295232e54da88ebb6f1053d6de79ac6609852eb93a0a35bc1a7bdc22d628bc86124d696c3f9828b6f8b9aade1a65216177486c252a4b42d90a4e0fea2093489e244d808ef7021a97d5608c0ae1d663c775e8bb9e9a7315f1feb6d129b5a541ea5929a2c633b6d8c3c45441717946cf873e9b4c512180135d54f053abe44c6df39b7b062ef7240162cbd0b851afe5f91536a9499418e8bff4996473d805ebc1ae48da2d0b129e8e8252f1d53c328f32db252de3befbe5f31280121143a8004a4cae631c827409e520e394cd0f8950cd4c3cf3f3dbd4952a4dfe69875f565389061ad0a0cee6b6aff09ceca26d990e896a2aba9f3b26015b63423768684c03ed0de6cee7ac5bbdf9f485c2275cd12aefa8f907b851a02d51c34f121b77f3a56a9ebd1d65ffe89bee381ff2a7480e8968cff25ac8d04e149a9d5027d14b88f8ae2604d2ac22ac67d13e90ada620c2046d28299384d0959fb76e22588796ce427aaeaf4e2a8aaec3e87f84ccd082524c96d766eec66f0bec3e799558145f09d330134f1c63f37053cd4bdc1c37fde97291857551f50ac8e15f06ac1c73daa1e8c5bc9277e3d69cb44a3237ec57dbbccfdf6685ada20b74a1bc6b74ab05690eaf9bd0c4be17042f5cd320cdd613dc08d29af346aa4191ce0b4f85bb2ad7f3bac738a9377ec6b84062cc70fca9ecfbe1f57fe5b2ce7a4f739c81cabcde046451dd61ce1dbc
+SIG: 42c1295fafe26de3ea34926bf1ef80bcafe47b21b90eaed19635ed7538d767cbf3a1e5dedaab82adf75120373e923202f7fda0826784292eba8b238b6cb88304
+
+TST: 774
+SK:  1ed37b610b8b35417d04e59aaadac688ff81f1e507c89b4f400160941908cb8c
+PK:  48e8cbeb1240bdebf0a2d92953aa89b282c49aab2c38ae69044c51515c3300d5
+MSG: 1e6767df97db1cfb4088da7b200d9f59ec8dd4533b83be309f37650031065727cd5202cef48426a5f3a11d50b381f8bc22ff101827359f2d0a610a4f755464a0c891cbd98d2dcb41d9779d288fcf1fea62e52163ae67e90428b86398efa218f1b982081fc513305fd3e8ece7f9acb0e10e001d2ed299a48a80870b3d5d8ab9006309b31591caf0583380073a2db61f45254ab965b5e4672c4bfaa86e336c49278552729fb2da76ffe502ec61e1696c7fc9ef19f7cc2a2775b29700cb384294063a17fed4fc635bc13282a90dad0c00aadbcd569f156a854f8ba9e7d607d20f2e9e5337981161d804644668d064fa63dceb9f5801353d0ab9f41d1d8bdc76c13ab2f023ea01adbc4c8168d939e98f64fd8919384abe76709263c0cd7c3efadc2801cc4abd80a09bb3ed6bb78cd620969cd35c6a3a5d01485ead4c45ebb6ac6a83212a7c76675427b21da8a7a5047b30a6100cda02476c186e6ce40d2768a942c9f87305e9d363b524c0094a9e2e29f585894c0adbfcd60690fc7fb0a9c717cf43b484fd45151b1304169c26921db2276ec05ad22ad166854fd2f94085778c470dc452e5cfa4aee04facb770526e1f248d3d15c27280fdfa1fd2c1044bcbc881c3d99815c97fbea46110be02dab774f3a610e5802abf36a49875c682638e0ae4cc8277c5e9aa7307445e6bbcbe549eec2a45b1597f7447107b62e2cee0a5fc51beae3e1fe9befb1885d9b30f9b4f1f56206dee0d67779c57f484c8c3c899a515a9d1c10f6059840c1c73d3f05bcb88590c52f7da391838dc2e73228f0981c289a4c27f0c757faf7b3b89146e33dafa490d9e0f9275b0cfa6a7710a73831459595bf732112b62fc864ca4c829784a3f16eec4e18f936918a7b9891669e933223f745fda562bc0a4e61e3d14ea45dfc327e2fc0cdfe6f2f97546c90fce82f522291480111a1e6b9388272c0be28d20ed84bb84d49bc199cd599948b8f2039d07827a3f4075d3a67ee572a01379a36213fe116e768b4114e8a4b3134c3818960772d727b0ca6f7c997ca99843b7eb02ffc013971cbe0e6e60d49773f1e8c0b30606131cb10c3e04
+SIG: 8608815e10590d5504874d8999fd6f09626f950be20c912c27c9de6e79b0faf777a533bd5bb667ab513a49458ecd6787a09ec0df6c9c9d6333c5e3ae61ea370a
+
+TST: 775
+SK:  84364478ec94bd25c4bdb82d296229e6dace2b1359d6d21be2b3afcd7bda19c7
+PK:  a1814f8ce0fc3b236093a50f468c1316211fe6c52e2345d9f0766b3688a03cad
+MSG: 7bb7293de55f058fb2ec22b687260543dcaa90f140b9f45eddd4bc22e40977e00ed33cd1ef1bba13c1d0990859005569a80767e4864a2cd288c81393e04ad971782e2bc493108cbe80dacf0b7b9cd534988407a4f9327ec8e9c4043284ef6ee5a26a5b417765d3eabb48a007e7c7f32987d70a139ac41678cdf7a55cb80cf9db5eaa45f3de0fbfbadffc40996370e48b1ff5edd97940e750792164836a4a5ac2e3ff53e48a1e556db9ad0c5c0b944f4aee519a2b0a88bb1c1fc7454524cd57aa5350986243d34fc58e24e819ec0b8545d8dfcf6b20311441d3a35d3e71b3e3ecd7884dda8433a405e3d9969000c820a89b95d197841d98ae734a2e81daf6a7dcf56cb2fc26f2165a5f42b86c7e9e5b11161700a1ab9831f3fae58e14208be1bf33b58ecce81b0c6b7e02f88adf9ab030263e2cc9b6e33ebca3f495492e32bfe372537de6c6b87644828f74942a02b007f14c3fc5dbde76333d36d07631b7a9924f717550040697923fa7b9546bfb0217024ea3f252b515b5d64a62c48e027cef6750beda49a02447039b250a0bda07dc062491a662e26874c8d00f80e6cfc8b30f2c3bf7720b57f2615fc478fefaa6d31705b43c5a54f758666b302a8d34953131941b7957730476794d0bd9d2dfa72fd203f22df5ec6bbaace8b9394bebdaeaa561461011b4fca6185c9a38283f5403fdac326d1f734c6a5ded6724d9f384aebd6cabfcbec12abab9820d080732515e0500cf5d3e2f9ef80a4d7646a7da9eff410f507c69873b32d540ec32b283ef3179a4c632b366576dff058faf8c8c70bc69be808982ec1497ae8911b00165a66695f4d3b987e7390b5cf878e35e676541285e4e13dfaeb2f368cb511b778b106a428778a1b8f2a7d2e093519bc9b5188e38c6793e96bd0d30e2a3db9ee1468c3dc87cc365c810f9dbdf01a4b51421f6fc8dfda3a16e2da7ca7159b686a5e167338937882ff715d3e750d958fc9e4b1f0553129299aa8430183e506cd7f2b279076e0e1cca9749cf123ce507fe07ddbbc4dcca6cdb9ef1b833f61d4bff00bec012158f432ceb75b4f2edb1bb84e5ebb9259e09f9625ce3
+SIG: b4c2321ade3c19ed4ed4c639d5a4d6f2be8e2fb13bb7bd625ad6dc87e2c20f93ad6be7b7e42711a878db9d76054bfd7bc25e3774a93da1543c9b4f6633b0be09
+
+TST: 776
+SK:  00db37ad2a195f08a08440d059259e539feb40b474928255e7c94ebc3b05038c
+PK:  04f88bf639e0f71a57d0d0afff5fe97dde3809ff28ec68eb6fc423f4faff4390
+MSG: 5a94f729d30dd8aae2a5c8c28547bf4506295dc61bfead9727746082d43b0f8114c8c18c5edaf2fec7cae819356338f0bf115a17b038acfd7c96ba6262cabd5710fc0efb43d13df4065becbf1b9e279c03ec9bbfed54d9a13fe06a55a3bd05c807858b41e18dbde13b0907d4034132262d9c2f4d2d376e1609ad280de20ba709844dbd12950257f1b07ef8cc3337c01a702693fb4d92d047e698c3a6dd46c4a92a10d4c780e52e5025e09d56535d7eeb9fe7f033e6e9260a68f9d54b6f37cc069656e3bcee06922b349681a8e7751cdecbe1ecb663fbc6f7c861f853dc310f33defa98ee343a68632ec22cafecb7f3212f81e70b71843b9fe8c86a68b5c86f0322d348a76da7f1ba0ca3cd7b6fd15ff89292b3f636cd08cf625c74d5102cabb571a3dba86a1c92f41c7203b44942f5a24625ac37d77e49a57f118238699d807c250d5bf46f7a3cec5779a6e5ae1a6ca160cff37fb3b78388fe9c030c40e7154601081a517fc0aa1802cd3b845b946efe94aa8b9e03f68a80ded0dfbfad4daee40fa838c133841ae8a3ce0d79fa8a2b9434bac5e1da6e0c7193e8dea435a03a85f76184f7ebe2aa749be9413104a178689ba6d27e94fccf61eb3aba0e6a5a63af0ca8f05a35cb63705194e44d9293de3929b0d92be6f8e627c350a83fc9000aa95b93820be9795c80b5662cd7b34822328061356dc580578d1a35b10140dcd248e4853104d2c5b2c13ff683dd5c30794be4a76858af1c0d9af347ce1dcd972ee49aac12bbcd899c9329871d3e7a0683d175779afe35f26a2d248fd780ea851dc4ba6d21f8a171aa6cb8697d9d112161540307cd54f931775d70b33d3b6de1091fc1750531c08fa70f7be38aa110d6746bb565db7b470f900850fbbf1c662fd613e4f3a5689549e3107e9b0f17def7a5bd7fd7596c4d04c7f48c779fc35e09335e1df784084e55d8551d1ff49de5b311cd350f347a0bd2863a2a30e6ea183ad2e3eedebc18dd28c6a596e693dc3389f7d90b713e3a85a62516305a70667fc1fb3cb10e8a955750273943c568e10769cef78199df4450dbc490fef1b304b052221b2db9c44fe00345
+SIG: f4d1c80f5e7b91c5c7a82a682d49ba6fb19d400a299748a0c969bb99816998be634e84da78581b06e3470efec39804fed93d29739f0439a8095ac40d9d385e04
+
+TST: 777
+SK:  6ca1a1482a07f2a6c57f041197b34a5119e68903cf6dfb51711d9550973163c0
+PK:  8034a55e3b6ed799f49e2e703a81f4ac02573c445d765e3069be42f09cbd18ad
+MSG: 08fd8487503c3f3296b6f1b64d6e85906fd5986cf9c5d9fa8a59d92f44e6470af34bcdef336ffdc86456ec7a7b5761f1adea027326630e68abc6b8cd5ddf40b641a259ad024321bf3ef98e7632797149c492d53594752c550dfbc4fa6bf47176f423a2705693947aa90d68ddc8efb6cb9dbecafd2830d04fd93b1e9e7c12b93e0d0f3e2634900f25860ddadbaece1780ff2d3f3d9fb838fd0d5d66f8afb305ff1a1aedca2b974b63e43f5b3cc9dfed1bcf11999176ed9585ac829bc6794ef3acd872e8d2e92608b320f894996a562e1eb177e21be57c22c41ec259a3dff9c7c9491db838d76cf9b0383111598e357f44babebf121bdb24ee9d557b7d5af491a0a0365c90361fe4f7e3d13a17da3a39fd43f690dfb0b2d860cab419f775ab7152cdc8f2afdc50e8d5da5da01706eea2a2ffad4babee8b03da336a4d843d9d7e0a93f36a92e6610a368b63133f05a3fdc55e3e1a440b0f87a53364c1d37242c57a109e6df69345b01c21c1089e790a66f4f3380d3b76ffb420dfe1e6200eace579265a427fbd355514ef953e1a6e968e37021b3c6a290dcd0293da6768dad7c66311633051c0accb0b9165464dfddfded23bd13ef908744f9c2111dc153142d2f10534d893fe0b545fec53fdb3b35b518398b02ab21791fa977e30cf4b404e7a299d3787108b836aa0d59c114f1f36719a7acf85ac994d9cb72306f258f78ac0a3b6c05343e0b7a9aa726e52267edf97f4972f7664f43720ad33ce6e615440e36537cbc569bd6ff94ffdaea51e06029dae78c5b915c537caea6f1504147979b8aaae0bcd9618437ebed0b55efaec320e84c75959a37a260a02d4ef1bb62641520f1a03ddea8c4c1de8d7fac58da408b0ab4757a135f1d075c9f7c99fb99db9427ce9b0d626cb1ac189ad8663d7a714fb5cd1585c3bf99a0aa46d763978d0b12d65c438bbb73feaa51ba26a459e7bea25439466c08613e42540c8c6d54367f221fcce0c5eb6af2faa181ea21521809be75649cf8dee7671db7f948f346cbd0302bf9a06eabc72e2e512b3df885f6daa398f93e36dae2d6a04478121f97787d4cedff6db09aaf10f27b1
+SIG: dd9bdbadd9fdc81ce230288c4a068df07e18b4c7cc51c0ca4811dfbd04765c56bc883240e46e3a42c01d8d2424fbc332b7c5a17bceb1f6e8dad0bfe562cad302
+
+TST: 778
+SK:  2784df91fea1b2d21d713de2edc6652451a0c15954b8656062ea1dedc2445b2a
+PK:  9556db5370f8fb3c7478de03d23df1cda96f2740118efdd3d1a9fa4c3bfe8849
+MSG: 2e3bc54df416741dbe7916ad25f04e48d5a9d77a623e57f9cd61ecb44f09f76833eb2a3e9ab7aa89ff5d2d560c07177d854d7c49cbef492b7f4f7e567de1275124e16ca4a7980162fa0fd162a8e5fd6f35617007034bceec57c8faf7664f4b3baffdea8d8fc2ba22d585e9e2d739f5ffc99b4e0dbe9c3686547ea04815a59c4a25b5f2390668e418ba0fcbdf4c4a51f33905c74fbb830a19f9bc8636dbaaff209995447996d2e5b1c377b4cb87a4e1efe12de34d33599ff397b74017d711edd3e772155be5a4406e74cbe2931ef51359afd51b5b1a7b3ea22ee8eda81476bcc17ea7680f6f3104703b9f2a35cf2627eb741d1a30aa4beef6579ec7d0b07a4ef32abcb4d756970f70a3678e17e6e5731890aebc8c92b956d4b3b5fe2adfd79b211a1883dfc8c9a4b1b9c8c1bb265e1f3dd392445ea59b590a019551f8121849f435b3ac1b29902fc8392554056b93903d5f263b3d540843d6afa75a2ad8304b7690de99a734c3d130b69547b18b09e98cbf252730e4aedb6dc4b58b2243fe55e80939d37b0a59d72226d8a2cc5153095e15994ad62195aa310f2a6426676b661e47b9fcfffa04d6dc625f29f44c7cf620b378a65d238344b380448cd119cc7f373f62cdfad64149906353f3a54107c5dba65e3cc494b0531f4d64749363f230738b2cfeed983520227dd5bc43be59b3268e283216f6e9c75e0c1c71272e54fdb29c7858d287d1efa1917be37c8eeab5e44c3ad7b36e8ac9f66991eb82a5148e5972034ad01c62615a45154579fa50869e7be9876b5656eaad2e43025a62dd134b612d8f4d5ebcf8056e198b713438e8e0e347cafbfcb89e394aa330d4c788d49c658fcfc80b3e0078f0e8e19aa9b8fe8eb0bab93de785d043e0f475aeb60d62e38fb1f8384a00b7a902daee13d2136269e50801b80a65b2f913cfe3ffb365d9aa2fd19372a0b0225695444e4bc54871d108e09c7e1c2b42dcbbacce24ea5bd5bf1fcf4ac697a3fe09a54677b7a8dc8d5eecb86cc792ee9b6fea2de16a473269fdc65dbb73c258c821440407c642f7d3d3f5c708d55332da8343106c19b230a51427f3b771916ae3688b
+SIG: 17d171d946de3516158407e132cc1acecaefd6d092112be653999523e20bd495f7b7f600e8d5a671330d32693d6019c08d2d003b176e6319c35394200e027d0e
+
+TST: 779
+SK:  4bb79236fada3144b68296499ba44ae534074ca94d4b581e5edcfffe13b3ad19
+PK:  0a8399f1e5a423dcf7b25b2fb0ac9e1e9548148bea84d021e0428760e05d58bf
+MSG: ad81abf6937a7acd7f1837f04d3f10e708c61a5fbedeee4db76e1598570384e6efece97c925d2e5c3488cab10b5b52b8a5486e99d8ffe86c1981a1f1d532dcd4d489e5546d86653298e7a5f96e8144552dda8a18e75b5f7355b13541621106e497e51a56d8659d198fe10037e22128afc2714a2cb5a12cc5db0968a343ef918e8769dd6a3e5b9e32aab66cb0239ebe4c17f18218e252eba6162e977049ebac0b38048b3aafb7d4d72263e9212899a3bfe0a69c99e22ac61c5e9612456303d92458b5c502916c34a8ee5cd9a582a52576b6dc9d7d4c642f212998bf3358d4a8c2ea67686e55d489f6a76e6b070e6e995a745326c9aa63630a0033ad30721aa65fac604a6e58c750721a56ca6760c94134d611fab4d354e4f66a29677b1a666601e9da79f213f582037433c07f94d5f0de6aa9faa0b32f7b023fb9fc135a26f97052ac80b39b306aed13926c285419a29b20e2370d8a095b32258fa9893489ee21089c752ec062e120359e2f3515128254c8098cca65a91a022dd057a2c2a1b6b85d137c3c967dcb70aa17a2ff4b37678b382902f0f931ee743fc398ac1b8c10469867308479e40d7f2f04a4b04c4489158488ddb7bec5a47f20ff356d99a1b3e9d0b7fe9b0ad949f298960efa4d9728f8101cf53da3bffdd9524bf440a58b32738d0b6293e853f466ffd42c5607ac9e353ba03efb578cc9963d8aaa9d2e266d1d2ae9296f30c9ef44ec691030d596a401b6cee72a540ef3c42ec0174266ba5401f354adc8e25404437e888b08286939bede308acd30327ebff06270097cc294f0a0f39f9aa3c66585ca47e60c4b8ea36089eb8a9088bb18b0343135bb6a456d2f6a3bf390723e78b42c037c2de2e1432caad3a594021294d43f5b15a2e819dc748e451de40068c8f032f13b4711377012edcd4f11dec1111b12eb6e1b00633818706d7132d991ce20df3b921db2185ee25bb6f5827576ec01ad890f79793baa358c2bbfb6faad11d8cb0d0d2d2b2981fbf4e372349fc6a01c36077b59325f702b380059a65cf2f5ea98d6bdc8152053b85b28c81e413c4cac7e226c13db3267d21830f0e5431102917005
+SIG: 698fab68510db8121a465db77e4f8b586aee895816e63bbf0beb242db4e84c157f4be201ae6564517a870d17f60c858370c01cca17189cb4189e814391d1500d
+
+TST: 780
+SK:  afd765e6aac0146d4811ef9597bc3f44763f03378b7be033d6e64ca29decaef9
+PK:  6bb76123d9258922686c53fb6917b9a459cabd30be8c43970d80f5350c2d98ef
+MSG: 183b1092c7904e47a1420317a25d0f59110aa84d6b3419ad456865c43b29e9d1dacf755d9e5cf94c5591d5d912d05ca9a52d015d6e8f5dc94efdce0d7cf5651203b11e5427a9f679429e00414a48eab13fd8e58b87eba39d1025d6a18b2cdcbe147436dbf38a1ce86413ae318765e1bb1df7e2b3be97e90408b11717cf459bcd0f3cac58b4a0d35bffb533e20df37451c11401ce1dab02055c7e08c5ec46390cd617a6b5f22f651830a1112a06ede4c40ab7957851d6c66f171cd16241590900b852a3d019957be1b7bb7acb8923f2a357c3264456cfca9b429d71fecb7edae39b252b4eb610e8c718835699754b8d4124b492488ede62610cce44b59218663b6c9646a14a8417eddbb6f4fbe5a4bbbb482b37a445e3c16b65a141cd3e12a5b2c0481d614d6d208479b9b209b828854dae0ea1eded506555fe18e1854005cf001a8077083498d27fadf118286b53b8974d69fa2825be8ca3d6036a92ca52f91dde6d5b1ffe2888f4d60779fad1fb41d8c0714049af681b755f2d4204eecd09e077210a48a195e72c80e127c3d4875095c6570a1f78095907528cf7746f31d97111c6f4cb25b3741299a7574822d46b6e79ed23c2fe057b3ac7290b460b166ee90a45562effedcc6ba8f4795f7395818db56b6edd59ca2cc4aea1841fd9565becd6c08104cdee26ba9de200773d091bc77a57c547f1a6ba0a2cd717ab32561d7422ea7235adb0cb36bf5cbdf88fcae06630a15647d9a357b4e0e502d273f3796a51e0bc3fedbf7a1e64aad722aac5fd022fa79d60fc707325f127eb1f03868795ccdc0b4cb26f2023d152153a97a260bff11745d2e2cc0bf860d4a6e358a6d8176d2ac178a9ae1a2dc75e8b490408ff7cdf991329f33cb0c05e1e356925087e0b8d96a52351d1d17768eb134cdb21a1546aaedcc687dfa1b22e92fb5241a83677a153445b77d5e703508e2abc588a9f42e5bc710673e4dd8ad703fab2d7db1eb84226c89d8762a709e3e9138a1fa790f2929bff61bc1ea6e8aa1ad0e3887d70a56d4e6547fc606a50d3be3bd6db03663e00ca9e4f24fe8cbfd7d8c9738d6367554b7b601f74190b5970a398
+SIG: 3dc9194d50811419049eaa07b655b7d4064bcb0e7fb5f9e5326b5fc856fc0ab8705973ae1001df55373977dde2d9b81079551414adc71cc852d499b0cf824f07
+
+TST: 781
+SK:  eb347145f339edd802785b6fbecd5cb80889ac7ce4ebad2f67076765db939bca
+PK:  994a456eada03020921c3d109c135eb961fcd4a0a400bafd32ca061bbc862543
+MSG: 5b8b31baf88483f095b5d02e17d8b7b46cf46460e64c6b02c56d8dafe34823706cb5c15f338ad9b56586a949711aa7312cc93450d2fb9af4613fc30793a631a55c14e53c0cb15f06116399398c8dd61876c62915f9f9e4cdf8f7d89ade129e6dde7d63671a1863f5da8f42ea64c079ecb9a2c1b1dd9adae60e96b9cbbc7624532aa17975eba17a7af02bfb219aac02b3d4306cd38933a85060cd62ab513a3965b09150a488c92bf7cab0482eee56463f0139009b9fbb3ff4ecae211f428b5bfb8876f004983b90c447846ca4b74566e979bc30c95e99faab69a3ebbfe4da6034c82d63e9c5ccaf8486af3b5e0d381422938b0c22f516955bdc36943173f5832708a33cf52d8875d97fde585b4917e4adecdd1e79856762033af22f254b50ce9d0c700e77a731554fa0113a0c666683f3fdb19e3a426302230b63e33a785ef24a9289455b3b8fc618fffef49c2c6e48fd4bb422f504149de2b4c0355c363408e66da81cbb581552a411e364fe3e4ca96d7072ab072e7568c13d35e41c7825a13a5c68fb9fb5988bbbfb9a0b51165764660cdfa2411f3d42165da187c58edef0105a6db177420543e958d5d5e8a371f7987051c4e1786d018eb3d732c210a861acaf671be95bb63fbc88bf8be7be5390939cd9fb2acf3981dda61b787a7bbd78468e1d32ca46af8fb32a18463c180f524be1da910da5508d42a0051741227c9b62de6d19b33c0bd48067b035859ad9bdc2ddd97befca31e65a886cfc753afc4ff2a7212a89d37c046cdf3999c051ff1396bd99cb54945639eb6462db9ece84077b0b3d6b3df3952dd36756c6dab2abc25a51bf32c1e9cdd0a728a7985f7b7e0d9c1a6f66ce1216373d252daf5958f2e8973fd268fad0efe251ce76fe47bd0a4d0c4f1017949d4c2b16717218e149154ed6fbe56f86d82e19ef0a91631912f2a8f3debb00766b6177802f4b2e79f6e7bfa9c62cfa2f75cdb60492630a85c9b43177d2dd9ba8d0548abe24923ae8443eeadcd0f58a7b82dff50d884003889cb560f7ac53e710a75575362464b1aa43d2a9b22f2bd2162d302faa7452344ce7ade9983687b6c68eca47dddb289b15
+SIG: fdbd15e1e6469df720d9552cb5dd177bcbd292fcda83cd93c88d0114912dc8703109bac0d459ace9957df2293ac16d40d514893556853299b97b4fd4137a3d00
+
+TST: 782
+SK:  3208837d1554b6511adda09cbae565da78439a472a5d1b107ce0a9b1d7757db7
+PK:  9b525e35368a921e3a2e9a35a4de9ea4c436caba27123e5c369e2a6cf5c90ab6
+MSG: 436a3c31763f93d4d546c6d1ecfb7ae45916af754f839dcfe96d6b69c61214d016fc842f56462a3f07f661b2e2505acfaf482a0b0f4f5501eec4b2d2d7d444544de000b990f4363d3f983f5d4e09309752ff579c7320c915951cc3a1e3238c1ba7a19130eabf6a37f5f0bc56e25242f752061f3c63acad992a7501e967deb925b30ed105431e582102fa4f308c2f0683612b56686d52daed6943a7219f3beea2e0a29242e86d5562ffab83b56b263326664e029e961e7017d8e89f5e3e1d10f5932854550ce6e5cd76971fd235cf9c0027d0cfed3315c2cbf18508624d8acf047f9b968f907d9e6f4cfa5e45c80a272c2dbb62c5d4194580dfabedd82cb4d76492344be96ccf5daaf61e6b2b55efdb3f65210a3d6e1f369887ca0ea0d58c3d146ae3cf9b000076884115fa51b5fd66bec0ccbf0d2920196a7d7a38445fbed22dfc7564dc56f60d6e29e592485374c6bd1e5b15931b69ca6ee6b3aa2525c23585f0929f31cbd11fb1a5330216b90ae5a656df7a074cec64e598184f503fb23cc05e65da9ae7e8441f40e2dc26b8b56d2cb523a7c635dc0847d1cd498abf756f5a13ea14f8fab2c410b1a470f49aa8dca4ac0256b11800de0dd0ec42b142c561128d357e783b12f61c668f5e6e06b7b48b7b2254de5bdc1804b723d5fd6a0f4bc7c59e7c5054182613bbd2fa92b4c1da16bc8c97e16bcb0dbf8c92b74899b37f318757140b6c4fd535e2e1e0570a50818cf78fb988e1f4ce40e76e8fe3d697d7a45850f293ce170fd8ab07cf1534ea5ffad34f6fcfa42d0d21a91dfbfe0597c73fd9b9767614ebdfd02c3ac0c49ad10c94be5969ee0808c0a30b2a1eaa90ea43b8575c3056f423cd4b6f34ae51c2223765a9ea21f64573c1a13961321246e3b5349ee048fb62d5fb61b1714391182562b91598360e5f9bf4ac80db246432afb3a43d349650de03d343c2e97a8eefd1bf30c10c25867f53266bd1f0dc14ae1a6be9efdecff67e7d292c6cdfc90d80b886668f04c2a0f5ad7fa17c178b6e9b45a11f4ddfe2d66960a3f75135ad5ed154e513e1a5d138e7371e84d7c92453e6c62dc59b8e1fa93d773a2540d91c257c
+SIG: 709d1ca9ca2f742ab9dd0b049335f544cffb2f1a3693d5f53f8ba083b9b0d86e5208fa8e1e8156c9cc2242775abb7e15af3085868ef457634e9926c404ecf30f
+
+TST: 783
+SK:  4ec6829b43997056d99685389bd53c528de7e5ff2715d65c956619826e3fb5b5
+PK:  7d922d57fdb12792879aec4e8c651463ece064492c721753d22e115509fed706
+MSG: ed26b4130d4ebf3f3861491aa3dd96a4eb69752173fa6c84ca65dfc991c7fe44e02bd61650252a1d23786682ec38c1fee82cc350db7c3c3949a1c935ffebd7baa24f35a393fbd27e7c34c2f9ffda60a18df66c3e465d90ed48fbbad3fa7947dee7e659a3eeadb887f0963f6bdd76c36c11ae46d088ee50bca8187a0a8832db7984b7e27cbe6abf12d2c94f337ec78cb38b26241bd1a3d2f5fa4407fdd80227d2b170144b415978e37201d0fcf43174b9d7b2115d5eb8bcec276a775aea93f2340d4425d34d2047494d917e0dbe37857e6c99859b71c914aad5e54f7b2b033e594e272cc5cfe919f888e55cb6157affcf357246d00b532cc471b92eae0ef7f1e915944c65279315729853da572c809aa09d40365f90875a50d31ca3900da77047c957c8f8bf20ec86bd56f9a954d9988e206b444ca5a4434521bfc9c5f3a8a06147eb07d11dfe1171ec31ff55771588b333eee6215d216c47a8566fbb2b18974646ac5a92c699d77584c0defefd2dfa58fca27199e41ec58a246320b35faab75b97951924226da4ab28f01b47078e712e4fd9f77b251c9667858c28e32ef1cd01fcbe435c542dbad0a84a13cdbb5775e62d811dc690d9555c37f15f91767a561357df106eefe056e7360670650fb818fc6adc59973e9ad5cdcd809807ab56397f3c13948732d98d676f4a4470a95d8b518237e226f0cc5f4765164a5c3ef050714be02a126be8f66546481581b9e94a26aad24c693b7fdbc18acd3ed7cfc47d8ab26745d78e701d0cf05dd844b5b345a29dab684cbc5092ba022e3c582dfc044c3100ad02756697a849822915a16e2a2b810e6815f54421d2f3a6fff588c0d9013c76f33e09beaeef60d8774230e8ce7131289aef2a40686c819fb2040b06124d3d9aa419d56788f17fa7ed9b9b57ceaad1337a0101bea0440cff745ddd9722055d1f9bcfb009ce2c2f41a9e7e86806b872cdc2059bc8ec68f5ee56c4bacf4bbd30ea4c7155864d600c0e2eee73b319bda4372e9c603c772c25890c7610489989475d37a77a4574a2ba55bfd9c9cfd146fb97e6165dcc19559f4f85dfca2f97f3702ed8fa6b3c2a9741974aa07ab6
+SIG: 159ca404f7f74117c5163cf404110949eb57ae2d7662b1ff4178cc6756e90adaeab71b064ce1dff457b2dba7e2dc13c217bcae8a61fcf8ce1487a649c257ff07
+
+TST: 784
+SK:  b150a78929ed1eb93269213e1ebc22e2e40a601bdb005499b7beb058917c5340
+PK:  28866b6d1c393cb08e464cf5571440a649e50642380ddf4ffb7ad150485c108e
+MSG: 1bf55d27f9dde6c4f1c0ddd360a25d9493c0ffdca74a7ed5e5a514e95515cda4aad8f45cd6ed7901f8f224a63b38121cbeac2f56dae210dd053750cb207514a8891e245a5d07e7de78a2e3814463f148d2acb7dc71f995c9299ad0d6266cfefc94269657fd47cf5312b92af2750651c479636c9d36aef08f7d1195e7fa1ba3abb5dcb90136b0fb9a37668b87a2db88d1e2b6440d3e6e601e6d4bc10cf1cbdf1d6169c0dc2c4aecdeb6cdd4567d4250b2afa715b166c9467f907d3fa5a6daf200b309c109376830499caf3149001cf3339448ca3d765225d6b3c1cd267cba936e7aa4832539466fd20cbb38323cbb2228a271f2d282561c73ed79a1ad04698e27efe393235f3456c295407da0960f0034d8deefd1c185736fd3eaf1f9a1e32f09174c1fe12720b7c96febdb33e01b1b6a1c637150194be4ffab159e45b24585576846bb64274eca7b39a3ed9357de7b084213024a9e8589263600a2867c2a7cf8b99076a12a07bd7df8d5277bb04ad72e639b77eaca1ec58ef9637e9a2376ba878a457235a06f78fdf0e0d925cb2fd2a38c77188f60372ef6009792424399c9b67928da2e3ba91cbde407e7e876ba98139ed22ca3b983bede0000528796448e4a1055acb2deaa56bc308254c5bd498c275ecedc1357efe1fda01d34d916dd4d8647e5771995a653e0f8a5284cc7bf73157b3349d59e6f920cad6cdd1719f038025c4300e0210ce249faf3c82de1fd1cdabe61c14ecb1df00c5c466aa6a012a9c10dcfe59b7e9d3b155dab6c7b7c1608c1edd51dbdadf6ba5876b5e60fdf7f19e6ef712cd1a7dd3a062a6574a7436b319efb944e4223f542b2502c1ba976be91e05b0f85a09fd793beca883375fb67cd133f5284d89984ff3cafa7e11a9d85e7893232a524ec54b20f975d3c0a1143a0ef41176b7051ea91d40c5f44fd9e100558bf1212a7b891e68b55ca61f4be945266d9a1007a14aaeb68c48e257f0f46310ad16481467ec1773535d5fc084915f5d004ba0dc7591d2123c62207909d84f2b382f5ef12759a95cd3f5189806e273960aee162c00f73e7fa59363957654bb1916b5709bb0a9d040514ae5284951e6b
+SIG: 276dd0962e6ee64f0592441a8af0e5ef8f93bf0baeba20504b9db4f95a00b939ea38def1c797862898cabe9dc4644f0e677e87c0a33b87b6a4d22a807d0e1e02
+
+TST: 785
+SK:  9fc7c49cb8c4f0972d6ed970ae2c6ac337e675425cc8dce730fc41444302935d
+PK:  4782520b06f93344aa766780e54401363dfd7d967cc3bf06488af90920a30f85
+MSG: 82bc2c700db222a4ac914aa2be8fa28e422067f94f3344f5362bebaabed7612b0e464a73a6c456903564b15393485140dd0f3aff90aa6e1661ddf682850d0490afc3d735dea05ba47c85d97e833533514c198b4cf6e66d360ee5bf00e14a3aab1ad0e7b8ab2aacc964d42830c78453df1955bbed1cd68ada3db0ecdb601ad7667d5c5e2fd49e36f7328eaa337dbd6ff70e7898a3f98c159d045a2427ade5333c88fc4afd3819dc82f4daa3c523cb57e35a2a5a725d63d402baef51e51f1ef4f8f9a595c9379c9aba873fb4e765a931da09148aba6ec5b44859b0e81ff9fc229598ac9fbdb0bdbddb5692a52222df52ea387bbbf36ad64d1946bd282e323ff4822ad9da897ff73f01b390cfe2e64de492d55de77f5d7d0060a6872a0183ccba610f53274ccb29ce6dce6a036c5317a1ed2a7c1068c1b246fc1d5881d00de06eb401cff95e6b69148699db13e94bb5b280212dff54c70e56de235a5f1400b5bea56772d060170f1d0657321561e4b49107eb96d9b3bc5adf451c2a524eba4db003b77b632a5d89827a6224cc798e096ba27fb33bf61e3b8eaf18d001ae8eb52f85c90d9e12544803e67ff02047e0d23c22e7f8b980c01c3d4824b2a9a14a2e8f672a7b0ce03bdbb3bd56d754a0964db01ca899d488001508657b7b022ccf042c38fc1949d0e00af4d301d4f00c3dea20e308a0f9dcacb43222b3824144af77be18a504aa8d268b8a5600725e7cc5f3a2e6256a8074d1aebca123ea53a0767a92e1783a4983c5ef3d7dd7f02aa9d1f4f9aac6ce254593f08792014fb867eaf879b88a4efb18e89ba11006ad09d85431cc26575b538d8e7890646c5988647cc105d582907ae625e09cd089f47249e81814da14044c7014e80e7a8e619c7b735f701616b6a3c6f492cdc6ed463e71a3d22291482d90a1de6f097c4ae254876184c562b16575b9d0d19313ed98864f49fe2e1d074a21211b2b2a6d27ddb28611520d5f7123058fd007bb01001def07b792bb05bb741c129c6a36376c3853b8bb4f66b5760c8eb4ecc7306ba3a90c70da47c965f6dccbdb61a7fda18ee967cf8c5f050311092d0fdeeaedd1265defdd660abe70
+SIG: 5c783a860aa668184dd22c4f9a546b5ec96ebad2e4af00f968c688671354e0cc9b572c73bc6f19937a05f1baf3434763965c96e103407f0eb642c5644154290b
+
+TST: 786
+SK:  08bf059b4da9aa7ffc702f5b2304c4f96ca49b7dabb6afb41dc91c0f00c65b78
+PK:  a6289ba28e80e8d1a319223e4165dc0bce7352aaf242f70cc968d21d77752832
+MSG: bd4fb28a1dd08b07ba66e17f0c4f21853fefef1c9d20ba7977f154641ea1a18becf6bbb80388886294e0756a3c508ffdfe90b51e1356d112d8cde5ee2cc6332e61d169ccc8cc934994f1bb560fa4660c0b0fd4e8149a225ed4883e68fbb69da7af8a524b17141ccb76b50cd8e1b67d3ce037ded7dfa59bc7c2674226ec7e07b78ea3f782fda3e5f1e9caeab608ca387c304654f801d00e10a7c29f4b0da3e5f89513a98037719a1aef4c2506c177af5451a00757a59f16229c4f4414df51580d48210dabc9377370b6068a88e81d3ad1bed4985155c3600ff48768b903022fe02ae480f2e6329f0bcc91d75f5c6a09fdf77bde90499f3ca395cb20062a0984ad6a0141fd01c2d54dfbb1ee584610640773439a1658d2c9f862f183bfefb033a3be271812f13c78704657e7fb4f850175fcd63d3e4405d192242c21f27c51477f3211a9ce248e892b42fb6d85820f41b897836f20f85a1311534b5c404f8b7a4a0319bc6cecaa57fe4d4f20607c99c2df22fa0676f99d1bd87886c928c4988c6e78c57d758330e6922cbe03c10340253d0dd483792ce75e6cd09d12fbbb041f0205e65ad25ce7c1b24e77ee8d6f915e3bc3e10d09fbd387a84bdaabfd1cedb52c0b1733b5f47088c0d35e0ef458c85414c2b04c2d29f63f77586131ee65530f209b518a0f257a0746bbd5fe0a2e0c388a6c480e1b60714fee1c5941bb4e13f707eac487a9666a723b5793134a268b77597786c3a3193b46d355dd0895fc6216c536a542ffd7d7b08010c86f547a5daa38335a8bfa2655d5f71b4d8807f50c8545c583dd0b690022ee65873aea3e8f1a565f3b0e4e0295fb0d321f5c0b397f2fd0528f86a0d1b707f737b175c69e9e7ae3c84d4b2cf3a38a631aa8032b3e65bb4528f66d0bfd34473ed0101d2a61255b215bc1cbab9a26d2b969324b77c8a5464e5b23df6c5112f9d17c587d95559de212ad241d8b126050e5fddfcc839a7e5aa2fda1ca20c0910d863418f195b38adfcc36e92f2396ac3144b537b30fbe4dde614902f89978b7fb42cd99f13d99c45c734fb82c3259f90b88fd52bdcb88f7eeecdde4c243d880bac7614e15cf8db5993ffa
+SIG: e24765860137689aad50ebeefc8d6db8e936a4cba62ce87a7f580209384a9d7eec9070905f60ad63a7befd7c70f0ae7c8109169aee4e518fcebfaca723c5b207
+
+TST: 787
+SK:  dbbd0f7ecb6482cb01c4dbdc3893c0db81e831353a5b01cc75d3b11f2ff3c59c
+PK:  2d4e588d31a384b17858c0d784f6712bafd0b41204cf8f0d57973e59c770d3da
+MSG: e0fff35975eba78da2b0ffcc5c1b663600888e8255cd208f6dce7e88953b7142937389a337ae82f4cfe32fcb34f552a48fa8899e1a659e3ed3d3d290efc9a0f7dedf33e21d048d8d910757037b76e8a7ee9e4eca30f529ddc02ceffc26d64fda7303cc0d8940e9ef59dc983c12ccd1d2717e64d3006af82ab15bb878bb89d1758be44310420638b96a0b5e1e65009d69395d027a5da4a85e901be9aa2c0b3acc508ee18574c1b2fa9bd5d7ae7c7d830712da5cbf26be09a3128470a12a14909a80a266659befda548fd2b22f24c5fdc206ed3a4e75f5320682ed0e4ce817d63d5c7f1ee2b440643355be6542f59dc6c45ab15772f2219a812ef7527642015bc75fe45ba969e8100c268e24ceef9205a83a3f7b5ae800ad06e095b9b139219489793a7bce84ebeb654ab6669e2855ccbeb694dd48651505b959d32a77020b869533e3256d40685a6120bab794485b32e1169256fb188fe76e04e9efa6d10d286ae86d6f1c87e8fc73ad9b59fe0c27ee92a46415b39d786d66325d7fa6fda712f199da554fc1c89944a4e84c196e979a807553718cb81c076e511e609d5cac23d8f45b38b94bcfcf158d0d61602238d52e3ae84c815322f534f254e63389ae155dee2fa93396f0ea499d5d08c2475908c648bddcee591e1337e9421dc5a257ce89ccce4ceea809d7e87134e039db1be598196d3089fdcfa8978e02c1555832da0a72b08ad07cdd072627409c873937b0e835715baaf2608b2395327467cf69a1cdcce6372418383e7b89c8df4d531f585149509ead1e41b6627fea81c7958cb49d2d3c3e2fc691e0b8cf72679c08b8904654531bc4368fb617ac7557d9db8d329d77e48d8fb4de73abe7cb9388274af585f875c0dab793e4353518bb24695342af0f5df5be4e9c7ad215be90e25540da3489717dd3d29254585a45c13e6dcc7e9c8a3a79ff755cbe465b25e23a1da608e1084fec83bff80cfb7442b1460187307acd75e3f2d12843a77094acc32888fbe5f1fc24c615d19a065391d4176474644246b5343da77626a2d483fe204f839328775b71a4cb567273e169640af93dde3eca9116f400e23a7ad3d8fc3a28e565f125d6
+SIG: 96c00361fb71c52305e1ab7707e0465203eb13df3e0655f095fb331942a40b15584143b370a7dd5761fb03c075d04a8348661ccea9ada53365b500087d57ec0c
+
+TST: 788
+SK:  748bb3cd477137bc880ea7c61df25c1dac6ebec9e6c3193d81ffa6f7a81ec667
+PK:  106f28cfedf096454226b3b01fc24ab1c9bbd7f2b0973e56fe2f4c56a0b1475b
+MSG: 00de6d990c84338a398fda5f4a2cca733c56b2a2ea396c2fe667c268e38145878539bd41bc140a2cdfe7e18360411048cca60f35ce510991df261cbf669039d9d25687a07fc0476a41f50eccf38153ee6ae9ffd392b2bec0cc67101ec3696d7a2ec8cbd447b6a6ea063d33ec128ae8b57577dee17b97162563f15e42b55ca4bedbdfb631a9f6262f94ae35bb35f795c35a01dedb4645a73cfa6ed9ee521e4631fb17bbc06ee57316be527427c8aa55c631187462d4b2c8822ca4e18b7a5d4c114c11dc22069bc832656d5f4d39548718c51f5e4fc828f60e37f01307505265acb22d5e8d767b9aa7b866a157c643873e09084a1a404a7bb58ccc4b5a390fd30601c896935e3556f60d2dc6bdffe47da0a687c8ece1241ff6c07d776111ca6598fca968cb6afa0a14a34ab8f54b95d3d8473a174bc725523f8674dfb2b10f874207fee1b08b42da1f58655305a359757aa0251f14138eedbc280cbd385bf4bbf5530114cc43b0474779e204962f8560d4aa423e17e6aecace66c813784f6c898b5b9cb746a9e01fbc6bb5c660f3e138574f59b9745445486c422bc06a10cc8cc9bc56458ef85e0e8a027cb0617d0337ddda50220b22c5c398f5ce05ec32f09b090f7cf6c60f818c6b4c6830983e91c6eadf1eae4d54bde754f75d450ae73129f6c4ff5c4c606f7cadbf4f78a18db2961cc8c8ddab0578cfedfcf95ef0888afd385537d1d0a07648a5ce2522d0633507d77593e1a0366d1ece843de69867d7ac442ba7dad2a90b59d8984e4a946bbe5f172da427638b2b61209041fff50e60ec02ec2c0b1dc4be2edd13e87b64d1d1663114573cf58a17739f463a1c3d6b2123390183b505c8eeffb20539bdfeeb40776d20c459bac4569968fcafe44ea4cd624a84bfccd7876dd7bf55f83ac7040e30f326dce325588e1ba5bc0790265dfdba09839eef571641e8a1234b6cfc3a36a866bd6b92cd71ec74e0d4deb9e74d158201aa502f07c8ba348ac26aaf9b3d070c9a40b52a44e932552b67a2df05a7f0f03c617b48dc2782366a231e0c4e3938a4274b36aa9450ff936be132dcb692838d654c94542c6e047a7f78ba711919f908a15b30b9
+SIG: e13ca8e5ce7c268090908d61cf2f0a3e4572412bf5adfc5addfe88556f148b5fcbe3e1bc65ff16117d35c9d5dc3b117198f884925b4035b2c0de6c402ed47a01
+
+TST: 789
+SK:  393d44dd0ded71fc08477bd25ed0e6629fa7f88f082ebcef091898e5c9e3d5b8
+PK:  c52a993b802d84540d275479a1af5e287d19ea13b380fa3068d2f2c68eb97a09
+MSG: 142b6e82501362d55a04b89d541a796863d7783840d34cbdfc516a3c84772f92446f5f0df4c45c6e0dc8ec1e9bb0ff7ec1696a09cd7ae34c10f8e61a9acabd4303f0a9247237621c490e8d9d0fe44482c560d051b82b074ac3d8e49bb2ac715ac4cde3d4709d0ea3afc51bfdef4b656771fbd55f89da9fa6dcaa62cbae561208d98cfa24cb81252b895f6a4a92c8e407af6c1f1ef49d8dde154fbcb1ca457a204b5ea5432e4d71fb7eb24d43f6fe25e7b4c659b0eebc4cbcc8b3cfde07c8f07b18a51570e7163e33b317b61360f9ce08d95de2c3156af1ccc9b55bcf81eabf3c40434046bbe82e02992a2ac8b3b425680a23d934726cb1b7bf26ceb52a39022c00acf425257167b821185f68e3ed17903d8d22275498c39a9e8df884ec00558dcfa43b8a119c2e853b9a0318bbea087f9cec17ca49b70817b8d7c170a8906f3ee9e8f8cb27a1d0f575abfa627e88f08ca4b93c3297c4f317072f421c5e602e2f831dfb82551bdce8d71216f05cf9a2773b90fc93b9d855a91e35ade332a5061fdb82b309bab4f56e2d586a84c67481d1902c261b3f97dc30b184619df9fdfc7a329d061a41df332202133d8eaeeddb4cfcee53536e07aad11553dcf5ed1e949d45355f9ef42c7832b0de7c2f1526fbef86b63649b6b85ae5ca86f0cea6df9c126c1d79489cc3bfc6e8bf0346eb30d01643c010150c5c8d0eb5010a46112215137991085e57493b22e83526b7b172c6c7341c40321e9ceb7c82bfbaa48f3bd8f51372d96d47444ff0d8bb2e5fd26514eb639105e33895fdc41f6df1fbfdcb08466ec2d217fc99fb012fe6540c0c5a5966ed3e66fab1202ab9daffe8e27e8f7462828d662659ea3b2c608cf68e30dbac62ffd8229f4a53f59ae16833b81a159161f19369f60f51c43a217efc5efd6ab7a91fe249c7b8a0c14e9faea533de133849a92447676f6cc18bef4fec7f37319759ce80ea3eac18fa2d9fa02309e1ce93ac6cf4cd2cb2c95f1e2aff7b2a8856405a7b8ebabeb4906d9b9734da9fb5e5d3f322bb5b559fa61ec8f515db9065ab4b91a7a31d5c625061c2fd2bcfe17f94bbde4776302b8aef3d5b52db3bc73ae4a30cc4417acb
+SIG: 84c716e60de67b020cc1a6a24e6549fe56c6d941a8edeae407626666c31cb60dee6be5a71ebd76baf71b75114bccfd37d163a968bbeec1f76972151296c47e07
+
+TST: 790
+SK:  71193640a0a2b22fb22d00a80b33a5514f3d1000034fccd885d8ea8638f0b0f8
+PK:  b1d36f723b7086d923119f46759b39fa1e4038c6418c379ba98b5840c7ea5068
+MSG: e0287948bb85a398e6affa2d25fcff8bdb9326f5d14fdeb60549f5fbf0c1816f11cbdd4e90fea039dca60faad1696003f91515c9b272882c95c9a4ab6e2777bd927e7d8442aea6cea619c9b15255fed612b5cc3158fc705bb7a506f4afecf4e34ed517b2c12b8362610e5ea270485cccb3c9aa97ecd6cb19630900f07d94cb293cb6e089a9a77c0194073a7f7177b0230d25763a2ef98d47704cb2c3af4c3c1b495631b4a5b21b2e56bff2ede03ea4fe7cf82917347e3a9d4dbeef37d1cf17615adaa0fd17057969917d478d03ccd8f8b88e5e5acae6732a8161dfb5f7d02123c8d5a565cf4dd98dfc9aaf5a335058a941ca43073f2659615a72fe78c101c41aed07f3bcf980b0a5b3fbafdbbea92fd889cfd53d403278bc15a59aa140c2d773b8889b963dcea365362e426ef4609845c9bce9f8aeb591d1a469b072b41209f5a8b6dc2395ad9060eb2e370978ae3311d1cf0a8f205142d436bab6b95943a97c23e61bd14b2d95672cb9325e9ab1fc9eeeaaccd58b9f4ac1550bdec8449b036039496c5f07a5ed64d5d85171690144db5c81c81cbc4c16718d52c4dfd1958ca5c9c8ba582cd9d706f27a74744c3a05bf1ccd51f1092010d36f1578b578ae0e9ffa47079055ef94fabc9ff72f738bef68461eb3404ccee953f5ee864c974ce70e9037e3388fbaf2889e1366caa0f651e21b339e3d56b9d95ac30b3592a948912c90bf54473cebc467b09a3943dcac4868acb5b35ea691eff4d8cc1cda0c6c0a9c169a4ee10041f35f433fb53d26067b291056b1da69ff46fbea1ca7213659a990d5d5df1406b093da2a33c8df95ab3ce811afb9c98c5bfd7c4e981b3ea94eefd2e2fe95707d89f307fa76828b5c6774950aee80626714256e197dc7da972158c768bbee7fbd169ec15b4bb7be72976dbed3e512766ef22ef3b812bcac4aa3115afe83d31284af8eacea4ee49afd42d9c44fff2d861c08629b55dae00ff674fb028e738b05dcb38aeaa6963cc3faafc7b69245a2a122a96dd2f03a824d72b0fe0dd798df5c4bb75a87324e764a50a5ff52547ada8f8f88e6f38aee49d58ddb012648854cd59d0ec97bc3d58d0ad4491f08590767ceb1
+SIG: a9702a3395acd20d754373095dc61445584d8e571080e179adcba3106bb06a7ce4d460f1261aef8643ab1634f47c9414a32e183a327691e65843dd6c05507207
+
+TST: 791
+SK:  bfc9626c91f348fdaf469def2302e9e38f9051e7349e48f850cf352a8331a28b
+PK:  4e8193061c9d65a82bcb25da089b4a80ba41b3dd2f8ed1dc81e1cfd03c849115
+MSG: 2f11f40b2a19f640c0044c7b139680c3c3b69f00ff9f6a4186fd7ded569c1d8c5720f19dd35c7816d08a94c08204e47643e264d425e21cefb83129c909a3d78caf72c46bf1a729765ef4b8ca803fdaf8052ffc6cc4a6b579a160b703b15355c6fcd3b9a2ecbc267e60dd59f6a2b19420e55727a80b0bb64167c83ba0c805deed491d93e723f3b43263d17420b85be86c165c552779db960e0aa9eb4d9f3a164a5a21fab3f509a8f0199a6943c4b223cf9daca7e110e056a81d9ce0e0c02ac265eeac05ecd84448468a4d122b87a3e04c2837e43d212704fd41e7f3d198a2e76beca0e7029c432a0654ecd44f984c5df06741964d8372c86e162a8c5418849b41e571feb83eb42fbbcddb8a082143909eaa5012b979931dc7e3cccb44c791e04b8065ee63f0561da1bbf37bf6503477879cfbaf6d9d7d9a7475553f53535f847a76dc3b2b7a3d1d470bbe17124a88e03fe994ba10c24221e39e3d0ff53c79e2faafa19012d5ef192bc6d5260b66f997b644cf48d99f3899d7c485e684aa1e6e30855cf75c2d80c7a3ee4354fe13c676091c8667373d30e60ff8e09fedef175a1a87395fefa0722bf6c01c6555cff068892afe9486cb1fcc5fb6641e82d87079ba5d7a9c139355d6c14c507dbd594724b55351100965be9e5dbfa7708878c4b29f4d54c217746e326ab2a54f99b881d7da5b11edb08a6d79d885691b1f7085517310b309cf9b1b714aabc5c17a509b140b89b3f9dcee50cab441bf5ad3bbc29990f627406170a7a10f2d47dfc9256154f962308e769a2ab1b2a00e27e327f0d1fa164d1e38ead5ceaae238ba526f54b81b45dea6c8974186b1b6725fa4c83e62f3e254f729871bda4dc444bce78f0903fa318eaac822a95532ab019e9cfc5619e2c2067f258f4375d2e0222ea5bf96a253a2a3fa9eea02c3eeccb028c76bc60d38298b95b9afe66031b1a2a26152fdaa7ef4f837abb51185df8b2ef85ad2c9be6dfba75e37dc7d12e1787fc55f866fd066f12291dff1976afc10da913101e70495d8783348d611b011ec671c0da737bf962cdcc9e4a800b513935a56d084ea64a7d4e8e99ee9440a736132e42c909503c2224a141b25ce
+SIG: 660242c1dcf3291369c65c9d7f89872eab482200e344b296e336a0a2e631fa796024b6e1119c27d52264a49815dd781927a7df467e88b801e684fc602296250e
+
+TST: 792
+SK:  393b769482375b821427a66d16e4f55185b7a3b7338f1a06f67cdfa7e35c541c
+PK:  84afd70678ffa85a9f6574cbcfe3b15d04a9fd15016ff8550a987c4b951c7122
+MSG: 8ae8053e03bebeae544043b8414b385364add1673737cf8ab20193d4aabc8a78e1d69b9c7e52729e69307806e927ce3807b07c68c833c4fcf16db15e7dce604d1798915fd4211689b4864642502d38e91b1997b71823318b69abe5bed6f5e3015bfb22df30db371f2260c5c22eba60df39b3edd3c4d7a1e111cd9b8aa46f67bd0cf3a717af06ec0ce567028e06e4797934ad69b1f5be440ff37a8a034b1533fa946424ac595400ad27d3be76dc89ba9d6c49939a09f2e401c8f20f7f7b4b9e63b9d55201534ab4cc7be885f0432a2c6673d2e765194dffd9b6096dd2b2843918750959a8dde4a3ab407eb2f7e1a49c2597e30805f8480dd0cc8272a320c00aa2b210f576e42577d3aa419703697ca406d43a1a4f99b0733664f6d6b2403cba1bdcc51f541cf24236070570540755c7a8631fcc2f18938fa11bc291155b39d7a762a1ff4dca97b448f70e2d3de447cb08f918ea20cb433fa115e30880c96c8cf5f0ebbcf482309db6dc1fb64e17c04d7cdf7a90f4014d15ae7696b44423b0ba084eed4d3fb28c1efb39828aca2f40ca6df342c20e95f8006b2767a83f50c31fcc1581a09753e78291f0d9931d992ad3604473ceb885ecbe7857cc52ad5585334d1485d022e106b71c29bdfcf23ee8a475df2c090532356a6ffc02232317988a2cbcfbc2a36b4b483cb44510e85599b612596b626572b0996d8a61c0ee3efff1f7c71c05fb5a8d8c5d09d924ebaac8800451c9db2456710a279dfe2d22f6aea9de31801dc742534362b0e810e99e841dbb7f0cf9af1aef542a52c776cc51f287368fbe6ad651fad5787ef77c73535f3dfb3618cc8f0dbb549ddca9b9bf91135a3456001a46215ade388e7ceb9fcdfd0d2d0a0356afbe2cec1c2e78b4d998d4554f4621f1151dd3ffd3ba4c0bc852f311758c5dca425d18ba15a8d67ca401d0e6cf280cb88384a2dad49fae39ba2a77b467b3238aa28cfd137e5c5c0ff9000f8b06a2192e162920692265db24ab6aede535e31c2093be57ebf8805df1788914f3a884f884179015808db4d3020f3e78bc34285d233762e899ebff28428215e244404de291728fbf4124ce5b2435260a8e341180075a5651e6
+SIG: 31f98c0a08fda8e735b57366aa1b83b93dae63b5810c821d99cb39df521feac07f3c410b27ba3307757d6049f22454fb6de9e2c3c2438d68319097d112cfdb07
+
+TST: 793
+SK:  26cbc2510ee6ea390a2cb948a015d131abf4c0954915620b7816aecf4e11da6d
+PK:  145e8dd22b4400289dafb626d95a94c2f3b69c65197717cbdcd85098c5492107
+MSG: 9cebe24b4f8ade86430e279a3c433e4ae17e008852a24f08690cbc3d75e3b7f200da897c25f7483b37637d4bc11008d9224cd581fbc038adada02d271ed2a5d285d843a0f8b79e37945dc35bc264becd804307e1d44218a643e4b59a9311de985d24b4c26fb14603be5dba1839ee0c8d2ede6cb50af67c804519037b1b1663318cfc6e75d0f051dbb5d3eaf3aad1f78ef0cff48d5c55b2fd25db1539d0f02dae9f25148a8d338b97879bbd39df961aa2c396315a2a86cc783581e67ea844acfe8645428a27b8d32ea3064e3bf62dcf58010ec4348862fac25e3d9fcd4e5d65be59905d816dfb964992ba7aceef8c2075a312e5ffc4f9530ea20f77f93e81cf8a019dc3945634364babf79772045a0dbaa77c47a22b77223b704debd2d003f6a5c7bf6b19cd2c49b614fd4d47fd251fe622cb981785c146bdb7c1d2ea02b116923bf98a1afbb7858adf2df938a790ec1f9074adb8d1afb5633fa961a84764010d3bded1c033d25abdb4b00fb05ed7640fae61879df88f0b09e3abd057b9a52108a9bc985fb73a5f29d84d1ca6921b62f1b703c7eeb4815d9dd6d066738db118baf61b0422f388f1bfc9e3a9bed83a1a727dcc266a9988364846807f4d5518bc2edd0ecb3413c26fd0c79b75d8cb5bcd85c06fccea4d03fb8988dff3ed0cc9dbae78d6ae8d5fc4024617a23f52bd615385d4eee08f9134eb3b250c8f822b47d91e8c4d4c29298016e6fc81f1f1099253d7945e0798955da0dde14ebb934ecfaeeabae87883e1cc398067400fe462a2c4e9f232db5cdd61eba949188cf01b238be7ada938f002dc3ae31fdfd425c8d46ea032323aaf20dd3de2507d36bb45fbb91c40969a9e5da20f7f936b0f4b137b62fe2ba3a667bc0362d93fc50d3f2295e167fcbab0fb3a39b7cb024b578f9490f734b28c9ccf7192f183947d5a513efa4916e4d82b2ab4ba7ec2ffba213ce82ad6ed3b10e48553e733c940aa9b9ce71337c6c2805dfb8dd6618b6d4090a3d6cc963ecea26d1cdc2bf5ac999c11276168a931d816469d79083c24081a50dcbd222752385267ce1bfc1db76b1554ad57e34752b7f8983147c116d4a3fae6f6d57e654fedd7378d2b4989ea
+SIG: 6710d0dd00545b444cf714b79144fe79f38cb1c0f5b74248d4f01fe360117a26ffed4a3bf21323b28a393ae9dee07d69e583e316c6a573d37c644a8d62c40506
+
+TST: 794
+SK:  b1f59e3c2380d7aa414d0bf90893a38dddfc293859303d16f00d9eae6cb3450e
+PK:  84e3f5f72f19095b0f533848a5a91d0f0743b8e3a3e2f52fcbd7ebe7c5b5a998
+MSG: c6174c9ad3685dd648636017837b8d992200319e9a5a0d26d94d2da75e2c3aff46f42d7b3aba472b7f860b0fe1f695529731fdc8cf0da705d1d09acad04f010837ecef419d57e9ea6cacf168c5215696f471f3caa897607c629d443de099d31753c24677d8d75f4bf17246818b58adc0424b762a191ef39a7076a5ad12614cf54c47eb0908bb866518c5fac1ca2d2e5b657520a2b3695c6fb360f16f4ab357998e4c0e97231d6f89c968dc29ecc1aa91fa0d7543b5d2247b0d85e48743ab7cc815cfdaa82bf68ca6d3e2250bfda27024d61b474c6b8154ac8d1b5a36209782515c1646680d37069b8b4412f951b025a4d543625dd02290bf03c6734613f99b7a4c3af5c5f9e9ac3474465e648423018d40a6adbe88a3301d3d259b04ee44cc0562ee0ded4f5e26ad977ab5631f85768dbce53f616c029a8b8f933e2a9264b1c81f517e9ff58ab9f45a23eeed4204358f8fff0c8f975ef1dfa5776a5f7793bae2f281d7b0cbef240b3fc6be058821ea2b800fffe55a7de0afc93ede9c60c8de005abb9a2c88f4e61e8deb3170f1078a36e2d8f2a58239bdee496e90d137d2110f0ad857a88b3527664f781939e0b2f76634ff9f6c57e1c43f58243171cd862ef4284576172af1f6c3bd37d5d74b28a7a98698bd74e57bbc142e67f703f9d62cde761a02268fecb343fc01418836414f1222ca24bcdd69d005901da2a0f94465e4d4ba68898816bf7e3e4bb79c8ca5997fba9a8df84faa2d24b044c4ea61029a46cba703421e361dfa52caaff3bbaab7fd753f2856d7c083aeb9768da11d821e2d309f7a735c399692dac2f262846b891bf6461af23c8c7ce1d4d9032c3c140f739e5584c36f05eaf4349ff4545f283a4e0fea49430a1b180d0871e3742b88ccb591124fc427ed673b5f27b0b0a6f54af22ba4a6d1c6c1db2a1fcaa6d8a0308b77ef2d0c61bbf51b95f1e8b6abc5041d97b6b6f1b569b3f63cec05cb567aaea106727096ee8a9ea87b8804901f7e88a7409c66f152de9dbfcbe31952e6fd83b2877a775fae425b3851e0eff8792ffb3848f84a65cc317253b272475e717e49e9c6ff6b7859d11bba7c4428c82d1789e0dca5bcadca2fdb259e98
+SIG: 60afc1e991fdd27cc472b9acc9d405b4d2b913089290b311c4fa891ae2eea05671fde7a0ef86557bd867d1c0b747caf35229d6ef528fe3e0d0bcf630380ea90e
+
+TST: 795
+SK:  db461b9f707eb2cd7748c44c99562f1302397489353df5f303797fe0d0b58de1
+PK:  635116da8ba5a36a377728e28618e75c5592aecc18e34011c4c42591970b7366
+MSG: 1a2ac8c1b9ea099b831a6812d2b4261309058ea5883d70b1c607b9cd3fdfdb86e79902b0fe89e80ea7c478207674b2d803b0b9ca147ffe62e594f506c796d68997ce482b51a46e49b4a5d858cdeae2c6ec9b694198e6822f0e33ed57bedb0335c7890a72a7ee3c23823be79b7f9471e033c79aeed52e5760fb0ccbb9d38fded8b47383c19103ce44705834c59ddd86f7033948612d6662f516ce4e399ff20363cc7281a69b2d5c307b10b704150184ece32f390d772ccfa78483bb77a9fba84425366984171cc2bb60b0ec6c628d4e9030746dac1cabca60f05683813346a1a5bc14727549795c1c926869e1aa25093d591b43e086e43a04d170d942c4165e1c5ce76c3e64973d9136f9325bee821682f1043e951b02767f3fb458d02449add3e8a66e516fdb1ed580e056e0f78ee33fd9ee3280912fae07fe1ea02527cd001d6f6f2f89ee649f517414d56f57359a846891f0222c321d7e70817995a8cd8e94760b6e74832bab68d55bc4641884221fd29f122d87a9a868b6a6060c87b2382cf7bbdda4cd6aaa1bbc8e6d634ab580c865f5add6a1d54e61a607dc2c37b08a8cba6e610c12cfebef9c989eef3b782acbd1bcec5f04e835ca101298b5e9bdd8813a71b0d469fcf12727d3de1c3f97ddbc6ab2658440dd6421019bc68f356d6f25536865851d92d90fe9969c3b7c35a2e88ce153476ec3973af9359f1677a4caf1cc481c71bd90228ff5fc6dd83b8a699ffe514929f5c95cb4f04b00dd18a2872c41868d3beb76498ddc9234b63f599d7071801db2c2878f7bef4ffddd813226f06db84eb30217a7183082e3c1242bb6d01cd3a6ce27bff16bfbfdd75b7e5104312c49c43aadfcd5b4edba0ff50d2890ca3cd9cca33e4fc694c057c47ebe1c20a4ad115f985dc7442c6f6da7be530b6902289cab9ca139c6b24cb80ffdd782324e602c45910db63d8b5c44ca29d27f56dbf00186ba583c34e16031df357546b3ab9a3dd65e91d7128c939195e646a0f0b89bf5df04ba233d6a12a271f7e04aa45cda99b4a55a21cbbb738515e32c56aac2496232b1008a6761c8045a1fe0f9a3644047b5966a58a600466c1b1d11ddad5aa573c43ebda887e16a05
+SIG: dd049ca79beb9eac325acf44672ff578a968502fe1bcf5ea19d52c0f6778c7f1c7bbf742747907786e608123911a920778d2f9596fe29be7cc28fd009d7c440e
+
+TST: 796
+SK:  f5c0a7f8f6584c5d2f2e1d0810e8e86103e4e2d45cf9a721d8c47f67493396a4
+PK:  3c6d6cce49633141078696131a8d84ed823f30664b289af9dd30c6407f6f0313
+MSG: d68abc609a7a0ce256699eb17043defe1eb822c9708f65718a06581fab2110ec2db09213bb9e0f3612ce4a3f8fdbe757a9f0eb2c3eba438a9088b18f6c5caabbe5c82f7a9ab2fecf0f5859d175e139263033742458f82a6f38756cd5bcdf9e0736db2cab20a0cd3f0f1cdbea8556d84909358dd8f69f0dacd49abf8ac1bfe75940d6939e6a55385b5ace7ce1fde120679ab6ea7a89d14268d29ffb46df105bf3909242c6605f3e3e2ab7448937d6db2ba054c7b14f432db41dc18a5b957336b7f52d978ec03e7d5764e9bd2f4b68958d937bf29823b27efb31e25b43925c4dacbe6718a60fea3b3270e7b76b0de0e70f7fa3c12c215ef72b95dc1b5276238179dfc52fc48859649fa582d05a60df68599a1ceea64f6412d3f8498ae2cedb124245883a240bc0851f0e324965be120486e1ea89a0182dfa8eabd3b8fa66a99c51491389f3c83a3cdb4267f3e4dbc98f0c44856b044dc88d90eeee8415bf73de171afe84be9035e0dc4c80cf0422469fe0c9bd1c6aa654a59b5e34eed351cda2871269ac478e8d382e740e9ac7ab4ddc4c0def0aeab797b6f1a427b8e4a8497a0b9797dadcd35c414fd55b783130f6cded38a44c1a89288307eb8425484137a8aedb030d54b616a82e3c5acffb08d6cc1a61745c29afc68a0c1838b139159c5fa6674d66b9e338115aad4b1b4710aa5d9517bcf7e1cb12d4e6a51c11789fdcae9d9bbe78f69a33e52df1833c876b02687a404facad32841cb2d52554e7b8e2209e3f88fd948c1ecf83957c96f43b034beda6c476096bcb09301ad61f8367cc43e156131862b42ece285bec2dcc2d02d094d042a16072eb22ab9888013be82371569400ec1f8ec7e79108c41b853365268fa4cfbc62c4ac12cc98d2ec38a87d6085859567c0f27d6d431a046e88a9815558660705fd05eb06c6c05e5b7d62347ceee27dffed7141540d608cb975075a9644acc6328439f9fa682b226b186154549011c3b0f0ff4f74caa71c1944e4cb836ce851d9b5d9e727c553e3c723cf98c273e5675cab899bb66f4633a76dea357341f983c53d9158ad319ada75408b41c06f26b7435b80dc3bc0aaf22a833ddedcd6785c87d196b0af2c9a43d1
+SIG: d4c30a48c4523b1f84b14b657af8f859755bba6359988b675c6d85ddf35462820da476d84f6c402e65b020d9e8a2c285c16708ae58d1f8dbc65782a898a66508
+
+TST: 797
+SK:  1ab946c0c1aebf9ca37c2f4e2a4b337d5b1ebccd24734c9cb2a1608c881e5757
+PK:  9afc63dfce0d489b40907aeed6dffe4cd8ef5a6ffa22989556445cbf9b3519c2
+MSG: 9bb071b62c04064b0c96e243dd198c39717b25c99448c2c002b84a99204c5a6e23b4b912028675bfdc4df93c5b2fb80881a23e0d44ba18bde99121eee86adc6f842819d6ebc7a288992da3285805a8b8b6fbcd2267b686b3e1bf7960b45f244f852e82492944e3d618bcc4514c17f722ba49aca7f2f3bb4e91f940e9cef015650c3e40b0c855a17c42f11e3a34acc85287dbe0f9093c00373d50c0b3064a5a5f2b1e89206517528295fd871703a8e762b5e76fb9b7473d2149b85b9461f5587ed7e7fc8b50aa09876deeb6e237078502142cec6bddc70140fe1d1f1658d5d3e910fd7036a2f924b499db1756f7c8ce0d5f0d045b39bc81c5c2f1a761f52ff393e0649b8db0bd8854bd026be2c7c3cd63526ba5a80d48335f033832d63376071b6308f05960cb3fc9fac932edd8376dae51f2c661f75b7c6f4ac856753aca62062877609fc4a0ff60670282c05e882d1a035bf9890cab296ac7a8df244c56f490250f020054b8af51be4fc318beba506232bf45e17f5c740cf09d37515a8bc894bc955c8a460877c7854f8be363b21933e16287ae0cb70f222d4e36b8b424975559bb4bfc8dd1d51b3c0faf4a53e302196f9fedb53287d09315dfffa2bc4b3acff137f9a76d6856217f79cbb25433fc97899fd6540f18088e84417e4833e4a91aaba4658ae9ad7f760dd9c5b7191a0d3c05541b83c025a7992138e6d1080da14c2c887c6d670aab374d436c272f9e96f85a9c423379c0d47c46df6de334ea2057158d33231e1426a66d3c70827aad5511b846e03b94923d5f94baf1f8cf11a861373a5b80ad5e317ec2a529e94e636cdc3aa29e5dac205a0c13f68fb198cf9456e6390aead4d9782a1038f6478d339a81bae7af2a04151c2f22e8d39fe071e1a52168d57c84c36293413f8e6ff6934f05e7efad6fa120c8c1c38ad1886a3d00bfc306459203c02cdf4f06652bc8fa0e8b9cc779d43fbb789e7dad5dc99f41d4cc588c1b65426a4e77389edd04977578f8f316bcdd9461d666472cdd276aa569721c65232256ba1cf0e7f5ea55321729bb0e0386a77b865532024696eddef485b7d7b28c1573b9347e414d4261995482e3b312de1331f84e7548607a84
+SIG: bfabdea41810a53f8e527acd66ec106ce2ae1a67ff6a9b522e0f08fbbf1252682cb3a1dcc875601944cb88000f72e13907007903a77cd0db0316d419ac38c204
+
+TST: 798
+SK:  04bb887a8a3184ffc7ea09c9bc7c1f7c3411556a7c7c398cb8b2d98ffd9ee866
+PK:  6ab1e4ae4aa0d38989aeefa805b578806e2e971ac7ac05409958bfe60071f4a7
+MSG: b7ab0c8163f478c6cabf2bbd7ca37cb02456d76e527eea1b0d26db242e37877632985a3e3ca41b52e21d79017bff81ee551ad72af277b410e42af822c608cd69d00bf440b75b787a8c915d70b6c6376c3f67fa64d612a1b449a7e2134d9c23230157d576e06a66a8422a611e2a0f097286c199ea2a162861864bd035076ab20bbae2b4408a2c6433cb23433a889fe6598f47be53bbd2c80f07a8fccb8aae511161e609da4d180acea544811e9449c5dc2250e3e5a0cd41da33a2da632e6038bd86f16d5b7c1be49fc6db499076ca91f7aa028fe38529700b21d072d2b75dcc8b43781d4bc4d3bb584d9da01c3ecc85b1e93fce045dadceea5106468bdfe5f70d66a4fad60e4fb864ec15ea50f6cb797223c8c756f7a1931a39464ebbb9679f6b01687c174eaa32b968b9cface8c167120aa7bd0242f003a0c377702551b30da2488eb2944052934aef4bfe115f0ab7405a3d5fa9bd796b371742bc114a9bf28c5bd25626295ce261a6a83ef60b77d2d32dd7105fc83664aa89765b3f8191eeeed878f2ebff2fb97663a61877c093933bbd0731e63757571b0e37cac99ed01fd214cbd4feb977e856e0a1a7ef0c408c20e0ddaf1fd8f028cfa08c850fa7090dca8cdde0cb6903da18c6290c66a1c0ae0a084bf250c51a9d035e5b16ec616636afb9b5bce36a775fe2175bcc2ee07220834eeb31caee50e9f8063fb1fc8468ae25e3966789a6d8dffe08a6f7a1e6726f93ae7482de0262bb1f8de0c95a99ecb95684d44b3f1a332a18d2cd3dcf253c33d735522f796b651c9a633a8ebe95d02bc0465825ee541a7d927bb5b90a6db5499f8d993ab404b1650b75e792a7c834eb41f0470138b0f578a04c9ba5ad950ac7c9b5d328f3408b645ad9c6bf196dd961445596bc78f284b8914b2a8cf9b7bd3a716d8f144bb6b15d831023713b5e41fda9b587ff9d6cc43c08d35a707f495283e1ace960487e7f02b7543b68a731a29bf3be14b6e9c37174a9f46f561199dbd27b46bfe62243e0c11c0edf13b64f411c8e8eced35d8428f79f10eacffb7234e546413d1eb0fad88c0e938593b43b5ee0e4285d4dddf5295dbf1a3ddbe9f4134dd76d3de70462c2f04fe0aebdf59a
+SIG: cd84f55e5ef4531924c5a2181ec87a64541388c1059406bc07d53157a168e203cc8aa0f0069d53ff58a95b8a8caafdad26363c7d0f8045c4359e97b43602c606
+
+TST: 799
+SK:  9776a467fa1400735412a79b495f9fca078ce1d87a8530d85c26055d3a394488
+PK:  c7dbe0e41c0a31c0942793ffd142d8b95cc82e5caa92a379ba23f644edf224da
+MSG: d78553a1b7055b58b213101b1c84c53e164e39c6e9d36db43f30e19e2a125a9a67709eafef964fa5bab7261ddb3a8a0188457dfbf5159c40e51da8208483245781d7131e23a8bee5e506331816b9deeefe6e556e3f0c95c668d1bedb7da635065458ad20467012f59f171352068020ce3c75878693f6437bc4a09f13b9b0f0cddaf1691b872f82008093ebfbe233d0313e72c8632d7d1793f0b81c7688f54470330f04e64860e6446bfc6d96c87569bf182f0f4385af485d4299cac04e06ba473465566c477f07b9db277ab4a9de2fb2ded0a5011cd06d675c0800b34f55bcf3ec72d21ca150c8bf2361287be81efabb96d8688a1dee3f430f06f637dfd06f151464a05c95f5fe76af2e06d0123f6948a26b3be835045aa268cc1be976697107770208a7568f025c2d53c719e524cc369d9b4a337d8fd1ef345b9bca57fbd7b65a6b997cad3fce4cf06f2ca43ebe2986d09682d47c922b2cb7569d98de97a6164f5470eec71ceda520ccec7732bd01689ef81656e9f6d0c58a895558aee863f5469e7ab97915bfe0b80a064c659b183031f7f1a86fb11a9d528c2815dcaa2f0dec3d21a882e106e20493ee0acb7708eaa2912574ae97bb288b41fc0925053a29b0bfbc0ebae8d63cc0b46e3738046c5a202530bcb15b187a72854aa2d8a7a76c89a89a5db46032074e1bd7de77ef2065a08f389d783cf759ebd5a63a44d919f948f560c3e94c4239e274e051a20485a430cbd529f313d9f7ed679a34187b24f8413087a9021e4731730f5f461fc5aad6654dfa1c0504d26124707e63ee57f931b2785908f86b104b3ecb96000251d06ce1fa45e4cd6df91ac15bbf7ca3c3eb8ee0827612a29ecb7a36d5470c40505182fa9ac913570d0c1050d9a43455cb7bdc17d169805f018956f854f8919bbfb719e1867b36a64aabcdb807f48dccc0672f67887450b3f3e958d78499e0d1ab368aa49442e5e8a332bffd44c169ea67629c85724db6f1586b6c6b5be4864dfd53da7c0f7b8bb3573116be5077d332bd12a6300f3a68a89866b479ec2baa277f9f56f6e1d49d741eb322035ff8cb1de85c8dc87ac8e6e4c5d20bfb6d317ab125930c42609be3ae82242a9ef0568858d8
+SIG: e1317ba2a123ae3b29e7b60e8e93beedd7a08451a013695b6dcf358e4034026dc74037afbdd217ff4b148b029138f4bcc8f9836abbae7e6276e9e769dbd8f007
+
+TST: 800
+SK:  09d8122697126dfc7e11685a04123fdfb47ccddb4499d8a3aef418cb65aed7a7
+PK:  f8ddb1c00f6e0f4beaa6fc38e5d0a5775ee28c80dbde3f0c7930a33aad7150f3
+MSG: a0d8d8798eba22f56760c30643e9fc6795547ea5f2f2bbd11c0392b2ebf711aca22f0824199fc3188a45bdffde70ece9ab15a5ea89622a5871e0ef7685d10f1274cc195b4fda81f879d1e9bf42f873b20a859c233f9e49adbf057731e11335e9b6d8ed0e069e134ec461ca8890d7b0473c405e8a9d95d15711b12476103762c626d9f2aa5dd519bd825b60b3234ebf651e0d1933371c52bfd8ce33fc36bba328f7f3f2ccc01000a89904af37e4e1e9e15fffab5c2b0c47f37cdcb068db33ac36a5f0d6de1203fbf8949324bd3efda0f9889db00da2317b49fd186999df7fcdc3cb4e1d18faa254561c251178b8d33fdc9dccd8d2d721b93a536ccd3c0e9c856337f195eee7da9a7f6b0a42b7c541c6a68c595bf34704d9fe3a56d2ec8481d577c96ecc08b8e40acdbf050e20c683f39c414e8cbfcf4a0152314c05987a83bde3025b735cca3023abc5feb7e00d0236b4f24b15e679db052c8d2fddb3bef8663a6df819a9815527a1a2f60a0fa4e5078ddc6d435fe89287b30ffdeb5d9ae05d1a8690fbc7590aad57d43d22c12ace2c8196888e354e9f782f5dbb44149e83fb8bbc9da6d89ce206c1e2b6b2b28f933f3e5ff1175a31a8ff5d31e65c8b00c5ba462224a1e09d4f09cb40fc87c36e7d285c774a96976203651828e783628847ac512e5d1c35b35b030171f92396f5ffaff585cead04b6ae210d80707cc6832d98a20d3a947648da2604937fefd25a9fe0fc5cac083ddd7d2075307f4f382664f687dce8c655ded9c12d48ff7601df2a48d37fe214970844c075f2eab002059fc2271e617c9657a01bec1dd38f6c28ba8a617bd30851e3f9dbac904418df1d0215ad45dfc9f02b5c5e9f9bbc6de8b07af0bd1f7fa8922544f12d2a3e1aadff7e9c6b93320c3a61ef33da07eb87b1617f9e77d7702e558bc7d8122e0dfe2ae83e836c5b1a62aa585c0dffe716f7463c0b33da5b1eda556a1ef1e45042c79bdd3ec3cb8863a7bc1b0f7e1c05bd9920f05b4eda86517705ed07f6dca7bb00ae0456e6787d9fae8ede4ecd0bc572eb5cc6d19e891f1bcb229e9409e06574c7df058173cb58c3fdf20f3ff17c3705af62d9b7225c5743f600607f77cbe7d6e7618abc79
+SIG: 18cfaf6dc8e4e8582bcefe0cdc6fcefe6a4a87ea629585f37d2fba446b3aebd452426382da0d491c39cb7d54d273005dc132121568d2ab674520adda7523840d
+
+TST: 801
+SK:  10201bf0084367590de674cc0ed2648ec25d3ba8db40d00ede153398508bc126
+PK:  badbd05e5f79e31169f740ba46a58910a1b77705af45717b2af80856457c58c9
+MSG: 7bb1470617d11e45eb602a829ad773ee2bb7e6b88da4c04a7216a450f84993a498cbd3b9254028f2f99fc21a23288bdc1e151a72a9130c3dedda1bbbccd4e6c0f48ae9f35318cbefc959f405045e6e0b5fb2e738f2b765be11b1b6a0f1e8319549d95fa8d1df8167cd4a7717ae1636a9df54d96eaf2d63236900fd11338252a5008d5d480e2b1e9861d1f70688c47eae4689da01a47da3dfb6d2bab3cdf505ee5d801a152c267093d17e9bf7137a6ee7b834d0085500e401c17f3286c1575d1c0100fa9807630c4a990654c1e71a8b715627bb13d442c84a449844c404b872bfbac718a48d0ea0945c77166a53139b0ff0098134764f9ecdb88eabe07ccb2cced4955e08249b2f5770ad41fccd7b5bb372e6c33767e07f5be7d10712de81841b134e193df0776a0fc156ff5d0e96f40a704753e1145e9fa083c4ddeef4416234f6e1a2382c8e5b3ad405458e89d2f493a4d7c29a23de2107485b7f56350124e7e0d695c522b6de7a9247a2924ce6f2863236c10cc21264ad54590d314763ea1a19afacd90eba955870407e8c6365a143a5c1b9a8be5e4a4dcadb72e0d47649bd53abd46b5c6960eae2cab773753cc0e04e99414bc2cb30f48bb54139d066e43e2f0e1a4ae963858bef967df8c84140d2d09202b406d5d85cb7a96cc57f233eb2187ffd02f94e92297b5e69d969d3a5936efe4929144f258bfb39dd0ce26359c4549fc218a0aa54f31bd551b8781acbbf61cb3f732cdaf622c6a69188cf557a3a92ed153e69125a4090ac451536a0e9a63a41782910ffccb4e850021123ffd1f3bf39c73460a65ccfe4dba9bdefb5d5f4da6c469aa1322fa27043238363ee72918688d7ca1c4c2952e430d563256bb86d350a35ee82e01504747f31d02e03aedda546d0f1b2f451b870821602d00e819036ade5a7c7fcd21a6de6af35b1f9632a70af65df6445f6fadfbc0f416755c8246640e56b856b66ddd92a60c03538221dc8fb142ce2dbacdb7425f33cb85d850cc02c315cfc111f6f651dde1bdb67fb208e1f6bde784ddcf7bd18c8051a2e0bbf1018b8f39536c589de65eadc6cf379b77cad13f9089cb323fb2e943d06cdd10705c121134c6548dc53415f8c370ec690
+SIG: f1d996588b298f271e970cebd2a1b339979cd29dddee3645d07fab8ab465dde3e98667ec01ad7f1c0a6592e0697e665c72fd3814dbe189ed5f4e76c794e53809
+
+TST: 802
+SK:  c4aa425246b5173f5ef898152eca3d092bb4c2dd02853fcfc7178399f4e2f758
+PK:  29b77a3075f419243c0c1bc39659d73117ac00e55e8de38fe9829a879cc5b8a0
+MSG: 7df978a1f4976838ffed7449a4dc138b604f4b2a4ae689ce75018ebccdab2eaa0b60768f7208257f2b28e7aa09bf6c05888da46fd396d1c803011750e30eb484870c8806977696f12ebb9feeb4caf92a02dbaa22bbff63f842c3ba147bca7c00314278acd0db173569f4e36527958ef6f1002bd3cd01f407a86531edcbd9f31b3a4ab880a4f5b52b42d0d4a1ba66a2098651ae3e6c9151f40273285f7f6a4e81606bf980f689504b42080fdb97c72846fba9047c7e660ba5c6bf126a9a599e2571fa13505af7581bfebc16513f5c94dc71937e6e61b3ea10939b02ea10859f32d7912b9e3806abef6185fcffa68821478005cbfc1d637dd020425620a318074898bdc30931c59ac0c66c4d1238b097cd5b170f084435d4bae48a03d92fd48fc2caa4ffc505f1bca516fbd6e4f888cced982ae0ddb88fc28aa697b7071d015b0acb2809b01d1d9c7e7b53eee6824cc37cce5b6993d88d83eafc2e928a6f147db6eb80b1a69f01605b046bd2fd1d92c5459d6d3398a9caa299ddd0c3ba2e08941307b120cc13992f7003aced14a4a4d923bbb12fc393ffcf920b9f6d4775e94d4a512267fd26a6997c6062b4c9900f9862b9ea0c8d7df19f05c2b604af5b9864fb2754a8073bbbfb18233e6e150f72a525e3a5760fcda7d32a60034f956e3cbd3436c200830b3e7a14571220bcb627d5a4be72c20b23351b2d920602a51c3eb32c1237039dfbff43c987fd8563777f0e5a39f8146c164bdffce44f3b13ee74d64bfdcf9803f03dd0172ac4fa4bf6c7839cb11f3d34baef0e32b54942fc4fa38f473e2966f4911c0e80d76937b25b7632275ba88309635a60df135489208d3e734b672eda7d2ba21579aba8d8860ea764fd67eaf9c38ea7637d1bad57b2f3d782b91e1d5d92ac300bdba7ab9113ce913d0c793c12a9a726e3fcab05cb479977871640630d459e69e81ca5cf56ddb2a0611d61d481c1b8cef3804bd4e5754a61eb49b17ef2b03c83057b5d20d882058c00f54b6cca86be95350dd7bcb25e4c1c4658f45229c8bb9f5cdfcc44795c978e3388d325760106e52be9834bd81ffc5c62486b6f33c27459df178eb946e7a82db9ce0d295b925bb6126dd55c31f49a68dcefc7
+SIG: 5d8545a4be3fd6da2578c2eccb648d83fcfe587133fa7ae4a1cfca9ae6daa49259c952044a85a20b6f5324f827dba2d1a8388c40a928b950913c634fb3092707
+
+TST: 803
+SK:  f13cafde6f39b963dca96626862f4fbc5c2e00ddf08beceac7a6e2fca9e1ccf7
+PK:  c1b01a91e8ee0b9f19a72e5e7e0aefcfdc44a157474e99feebd0ff552d73b2ac
+MSG: 2bee73b74f1b7622eb096a28d83a819bcec22d9999a32062103d604ae6d78edf8f893895d2220ab75690410c58aab590a98ddff23a94d2350f889e53464200a527d54d62571107b27e574f542ebac249b8e2e3ce08d1bd27bd8d29f2e61243deef0e6938e52ee2992ff2187d7a7f5282edd98fc4985b619acb80aa9d03d6cb84b821106f40d6e5f4c387ab0af6f206615d0a175f7e60ee2755aea34675fdd823eb24109a9bd818ea2d9d9bd199cf8dfe79624b0372ae85e98c60200234bd413f4a62ce68a47b6c9b12857c0d399a448e5a5280e9f22f9b12ea2cd3c68713e77d0a11f3628d8ec5e060639031d3b640021c9c38809dc5f42d2e1c2e2346c86e24eedc5984a115a42de8de7e35c9917539e89885ca916e072afd5d46846b2a935961c2fe28e9eb3c8f896b86fc120cbd3af2aa139c499d29cfc3699db79c14484e9ec257a5f64344b7ad1e3dfb34eee7654c6bf12fd38fbba80fe1762aab57112b3a94e2bee79041d1e88440f85fb72dde68d49e84bced998a2f6335446e4a835e70c5f827fb3ad7823d5fbe3be5f6ec7e434ee524ccd9ff5b7e72a32d091a7e17c8b1ae41a1af31793cce91d84c3622678969c8f517dc26e3cd61d2446912283f9353bb5ad03c111c6233de314c61b831cbf38b04fe58cf44f1d2d0b45f25a6b4e0256859cd5d830fac5ec3c8d76398559e9b26010f5e1da5f25d2200935453ffac5aea51f7e81e72ec8e5f04d2f885c7b45c63f64456cfe231b8cb24aa1620a902639ca78dd391aa4a3d03e11975c8907f964fd55df9bbb140e38d6db93256b4b39c2b7bcbe35b11826bbf8c08f1dcb48edc4bfb70462a35ea8cd8cba79fab8b4c44e73be7ecfa112166f6dcab70d8bb55d8b8428c2da71aaca2fc3d90f3cc5ed01551358d60789b9d571efe10892027fa37404aaf59ec1c2d7111ecc3592467ed1d9b8aba8e229e32d2a00c19db7187fbcb122061961c1fdaca307e9c9c9de972ad51402fa67dc1c2a403b3c5e8b1e246862d6ad6a498db6d761fb566f6065942b60ad4b4309d182bc5154cfc36863185a87e23abaa1d541ab763a4a1066c0a7a8c3d821ae32fd31c8892401046d0a20e91a64779f4bda81120af3fb3486d3fc0a7
+SIG: 6ca9f80a62501faf319fb84af471f676ae3fff85565c97981f1457cbb8c49f97b266316a992db0d42bc502f095a5f2d9a4e1cfac0cc935d3882c8a3a0ea6e10e
+
+TST: 804
+SK:  c846344261a34865393834bfaa3a15a3f53ac9e13833b0b287122781b79de392
+PK:  ebade0226195ae254b6115e21696a9c65a19d5e040443131c22b89f02f69ab78
+MSG: 5abd13e95b6ee1d5514768282200a14f7d1a571f3468e22efec993463066a37aec8373e5fb499564191f3294a9b30afb5f1a34d4d88abc3e9bc303c1aba05bd8faca90ee35d97ac3dd9106f6fa3ca81a3810eccefa6a209ea3f3fc3049dcb1b003c728f7f6374ca98c582de6db1af760f0a02133ca4a010324304d26a0e50af0d13c134da34a03a41e83ec8f10ea5b859bec1f51b01cabb2d16c1fc52b058f8e5defaede128171c2e026902316f871b35e3292656f0e5b39bbbc81d0c0830e6ac01fac9b4539f47f9acfbd58b7ab9f5a125600f251a271d7bf167f2954ca8e1e0c96e16b06e8307df88bb8e9d57d5ba044f27f3eaff81d9f150554aa7122fd10d11f35d2be2b1624e3e1a1d77fea4c5c7f8b983e945ba8c08dc1545b3e6b2973ad041c44d0617eccc871a3821a9ffea9db7c2b0d055da55de0b35063e4225aee6b225ab2a7906a8ee329d1b3972e0d1f70817c50ccfe9403d12ad62c94923b9aa2d7f85a8dda47be4dcec0dc2b0b58f7ac190ae0579b9b13bbb8b16a31b0ab4d6f2791253ab4751b536b88d3b4937cc3a110aa82a6ffed6853524b66b3effcd2f63c6f9645cea13aa23cd1c99d9ffda4cd3a9c5df45ec74726c3471128b7089fbd82694d2d3f08dc9306c0fc9ce7c801138eb1ecb756e571e9059b75ed03f92a31502fbeb5fec51de9359010c4397d28b65e356e38001d0d51ac9600728c78b5766e0f217938b410e785b4c01e86a3452bcb3884aca47540859cc49b000f0b61fdbe72752574b27a22d4c40413a43b310924b1bb140fc9fdaae266d65930e3f234fe841d82b26176ff86c5d2bd8d965c52d728064ebdf68dc8e4834941801cca0b2f256d4f6c3dd19d35d5362bbf9b8a3a1c863e092689dd2852add488bf42685b11e1e1ad5745d075628d731f91cfd749159e2e1c837f4ef83d80ea1dd9bded5f88018ce1d4b3371f954353f3d894370062c0965d67986dbc481715f42dd2c91607ab8b5f0d89f66e68d73d50d640524d72e69134b887298e5cd8c4b905ba5efa0e9d685214b842f50a2a3983a1af585af2ca43dbcf02c40897ae2e1ab51dbce570345e8e135fb7b4eb0a1d6a0bb5a8a1807e425b2d628360768058e61ad1cfaa2099
+SIG: d5e41b47ad0f3400709770ed43919bafdf24381b661544e51d8b5cee9e97b3676a4c0ffaebb2cbd2db798532b65cf654a5b6c166ef886cb0fbbf4a4f844c440b
+
+TST: 805
+SK:  faaf55d3c29714b65c2281e2c22d6134971a2e74008fb94089a773eeeb4483a6
+PK:  39862eac6dd52e381bb34dc196ba8a374dcb7df6cb140fd0cfa6cfa39b8c753f
+MSG: 94e661c25240a89e823d7f5dc0e692eddd1370c35ac44d5a8c8798d0c9aafdf0bbfb549260568dba1c69086bee636be8edccd3cbb27016244d54d7ed2feb7fa64614d45449d7e058e71b306c22e6911c2ac74207bae5a84d0fc247be49d356e5d4353ba5586b6e4b2b97ce9e2377b6eed92c849e676944ae90dc4208e300e19cc91dc26bbdd5a30cfa9281a15efd873066f85af3a26f310623e009804853cc6855903ea64a909897e315e73d312948980ef6289db21a5ebbec8c8efe20d1d53dfaad6d9f4296532e887c37350105a633abc773188751b28c3a08f1b5ee0472de4627e6b61b68278dd51ced6a61ecf38886e45339dc6c60c31e850ef8296ae80f9d31701776eb9af21693f4c52ec062625738d4e3afbf71d1c81fc4846360363ea541a976623a5e4e6b6a67237e9237173f1a1d543302858885714c2a591d0a786282a0285a3711f7bc2b63ca7987e9ae7d02035555cf3b6ad6f71ca98aa928883bf81dd6f86493eaab5637b4dd569d1ee8de6a44bcedb62b9706b1db89e3f05df16310017d89ef3e4bc099b721a5c8d38043d6e4a22cf04009c0fcee6be69937829954941b8b4a1ebf4daea0d774d0782be176c8e591907756c2cf75dea6f7877dd6875b8fe1012f3050cfb1289cf088667e1522eeedc927ac86bfe2c407432b4a813a6a7a5504e999206db1827e25fafd70ced36db3b281b6f7b14ed5baa0572315a939c5bf4abb133d2e7b16d52de20817af055df5f141207734610a0c6eebedafffd9cc9f069b67f9a1c0454be41d54c138be542e5e38cfe2f293f7d2d3df66977acb366a42c19b3185acfa1b363c6131a4a8111c3b1f4fd7ac406d0e69103ba15b8c4bf29bc2ed9c45cfd1d279d8d931444b2b1849252b8a70eed80fd260edf5a3c01b9690160d2311851d21c9302d985986eaeeb3ae2c07c7c7672094f91db0bd50be377e4d1eb07ee76af49dc136a145a11b172f0811fe73d6259be370c4dfcab6f19e4a64b151d0a6db8050c3de2cc325f5c5f6594cf6248eb081209539e08ca3422984e7bf803de3a419b14423f1e5a54224042ce4f05488a6044f4042bd649b1a08ce10c2006ea76efab4641fef2897efd724e6054a3bd1a69e39a4a5e2d502
+SIG: 5b0083f7a82061c65cf6c75640c81c28e8d6d2e87f6d5795c9aa3bb3e390e91990e82db6f07e614f507a560abaa1eca656c678ddcae8198251e6af0b76b88d0d
+
+TST: 806
+SK:  6d7855e30f7a13e237b067144346434bb4b05178c7d88d492e79027c4b0f3cdd
+PK:  7273293828efa349822392dbbab07879577e1a77a6fd6afe33753a9eec88c4af
+MSG: f8b936e793b017580cc0e9cbda2acb6474507f4bca3afc8783ec46eeb82ccd4dd2525676aa6ab5c0dcf7d75f7e0311e6fe6bf27263f8578feb55c5612d1f28e888b76656c41ccd8a70b9bc604b42724fa2bc411d44c31ab68ce84f8393399e34d5408579c2ba2921f2f8d11487aa7e52557feed96757199d3aae6377770154b17f3577c7ac3d8c76cf7461b5e8d42a7185078ed4f862fc57502f615075307b6e103c77c1f6c8bda7aa17e435e21b949af44dff5aa30a62da712fa9966a612ffca14871fd6f860b4a9614012c5369910e0ffd6f0fbd889a9c257c32bdcf90bb80627cb272ecd4599897555955e1fe08cd7ebb21c071be0f48989696cb39aa82ad11baa5d4ac613abf1b6db8a20e686836222833f8b6dd2f0006227be48e8580dcc8de620dacb2f65a693675d6cb45ba5dd1aa70db76bc641d4fb567ecbc7111442e294158be575c71ddc26e94f41266a2fd3a0d435781fc094648fadf5f17cd41ab895821894ec0806b262c393534fe66f21e3783c14a96c88f2e0653fe32e75dce8a463bb97eed6c16f3f3228169abb5b4bf9ea3278c1ff0f86eae71389b6433acd097eefa9e6e05f4955cd517830b8d9870ccb5227415e50f23f6473217a745096470dca93d2b34673c5d6a57ed02c8e0cae119b3f329d8ab6498494c2921bb6f496dd08381e7d39f2db5763b14a2821befcca0a9fd312545de68abf206d12d8e02e73bc7e3cb796e7ee26cc63d741efafc5345f8132951bcfbfddf631fb7cb43ef35b9453c9390eb23b1f9d8b1c72debd24f09a01a9dc60ee6815306188357781af6e1820aa35e4ec121b7ca34d7de7611b246a3e703ed48c7eb03a6fe8f852ee7d32545c9d852d64d5d75930e5f1ebe21a307efa7622edaced6d879026f0f85a9112012803705582269d39f143234df8909ab3d948e76d3daaa24226d9ac601eef277fd2cfc4a19aedf4387a21617b03ec3d3845a38554f5e97036e56ec1ce660df9c062c2c993b77c5ba6a6d05231dae3764183c3e96aa539cfb3415fb163c645b2303b2d6d4bda8ca6c72bc03d5305f9b118e925e27d29ab7dcb196470e6339631b2380744c04d1da348fc0fe274277f82f95bdfb0b64b4cf3b51e571c0ddb3b53ca6
+SIG: 0fe28eadd9e5dd574b3faaea810d44522c8b1bfbb3e3d57ed889faedec91d0e14a86b914c4c766f1bf9b8f18b0db890db6c1b125d57804333619b1e0720a3300
+
+TST: 807
+SK:  7ee4e7e98c6a40f0e74413f24039bd220df1f8c7f015528dbf5284ab9f7c82e2
+PK:  4d5a800f9b22070e016ee23af8a310902b369d589a847f345c2ea2968d6d0924
+MSG: 8fb01373c42e69614aea99af49323785f33861b94e90f565389ebf70e219f5dec732e0010b58f7290530df222ac9c73e1c2e92a5e6061de5590caf9c0d5021d729eaa11541fa1d082160beaf611e7cfdc0ebb315d388e538b4b5028f9b30d3d973347ffd44263eef083b81b21b82eca5756a494b1d81c07de849506d3e3b668797a5c544254d4ebe5cf8171b39f8724cbc4189291b3c53c21ece49a1d739563c65b49025935647a7303ae0ef7f6d24554645a428dbbb42449f5399e36dc787b7d6958a02eebbb836e5e53e26e487239de94d1d250e7943ac0e22d92750a0cf3473be1a6225cbe79545048269f6237ec9f9ec307e8a34b7bb34cd4906e43162a3708f329c5b989d7a7fcde1099a542546fe9c33182ba51b843e96d11c79e91ad21f7170e257fdc2818e12f9168a974c968a4d273fa3ffa9f35ff905980eaad3721cae802bee36210b40b99319bb669982e943b270a4c4d0a92ecb5bba2dd8b40ac3d2f0325c469d5e9d483f5241974010c5c0da335f16e962196c2ef14eb24aafbb311bfd5fa8dc8d2d61e6878ad2cce0dc9939e44522723d427ef32fb43b967f5e44fc665792796f8cf934f01c325d63d583dc3ca9d4fcc757d9178580daef53aa3ab21d2ce435955d1c6d47638c5edb62ff5561693d1cbd10ec9e399a71bf9db1c9969fd59e4eeb31aa59bf39e9f184178def7246ed4b8f4be5badaa5db4af867f4f2ec39a13704202c8784fa168ce96f9cfac71017236275fd857cc3c51a9c7ac256215e14b843f7214dc9f824b91d1a5170d0ef1d37696f93ee966a2b7dece22b4f3afd39c16d601e5ff8408d45c1a6ce71f060976c5be4c042b1b738df9580ba5ae77880a70c0b94f0e1c9f9aa34c090d612d57a9b931f50a125fa35ce40a2cb7faad530f80908c73cb78258afd2631390041d92617e9bf64ce96e8e4ac7f3126d8af8a04c75ffd438769de06f74c2fc20cc8192da353e79061283bba08a8d24e6e4e2e83ba5b08e4275226062148d8a02afad65b6f627cfbd29b71ca18aee5b1f97169bf0228b376f4106b50fd91a38a66211d69ebb4a7af0e1c2217f1ba014d1e0cd17508d58155d163dd9de2fe1c64c7f88d5b553e9ba1e1f25430d7e125b07a8c2ed
+SIG: ac3bfe3adf941c934d3349c492de70d5166be389f955be87c2883f41f2da146c910651a3b452c2d739dc9b531c5745565e69d98359f1d7d93ebd36d70abbf00d
+
+TST: 808
+SK:  1f28d9091d196cba3d4552e5a337a4d8af3f295e629e4ba6fe99703120ae41e0
+PK:  814d34bf28ee6d90f039599041db810f7c9daa918e03e96197414bc9aa31ecdc
+MSG: a69468bc33ebfef0615c643c49dac6e04fdb6cfb8ec45857bbb7a27e528fd631fc3411baee65cc1f94fcc94aed4a4332fa6861e065e06163541709d79728e01be2b140a022c83e7b23b9ed2ad2832169dfc95690913cf3720130657080c9d5a7827e5660757452c5fc3dcd80cc6be098c629226d5466e02b97126be74a1452ee16815095deb42bf06566715028c11825820a8a23c60da2b68dd9a55dad2a29a4964443817c07d776b244b15186819a3bbed414abf4579a3ece3a3dc7b105d0a9dba37b9eaa78be8e46e1698b59b0940b01f38b283c33a9a4b1d4f8144b16eeb5fc0a7af0d081696645a1eab3a787cbcf88fad93dd6cd46d295a879a1775033a98563822ef1f6b69a581e49736c8d701b4453969340521e4ad4bf94b911b0e2d86f34eece4a6385ff1fe63220cd3cc592f36d6c491fa18f7c1404360d2a7753fe073e09a2fc42a4bbea55bc96d7f05c98aed2cc4a9fae8fd4a0197ff01fa7f0046e3c3eb59aaabca313a4ddaa5d20d27c2c5f1ac6d87fd3cb4bd35a1ec75d104f7c367331a3e295e53c4e80bae14b9792d0d526f740d4ff036faf5487967ffabe8e883d3fb0d16faadb28e1285ded41570c0b07c2559b531e0f9254ef88e5b10f64f4839a9a0b6c3c7f1b7850f4ad9bf0999a7f2ae7c45a658ea53036fc70199842b8e49e60f967de1ff3abfff6cd735b7cd8b8f9e248f156f6c6543869eb99823daea88debaf79f01e6521ec63fe72724ee3c822b88b3968b24852091583c49ab3c15fa1f79b18d98f04d9b6841c9a7ca0de2fcc02f95dd649492e8b56a31ec1e244337af6aaaede8bf99fc814ef57c0d5e08c3c7ecc1897980aa169a9926d20698df6930e2110cb460f49390100741095f8ed00412ae696d98efefd290da5f7d0b728d20a1ebfa6bd7d270f281a98c7b1e408435125aa483c6b7d633ff7588a941658f6129544d62945b9b8af71a8c62c0a50076cb8541ba7e4bde4ede441722c6eb9df8cfd0656339e86d226abaea05ea047f6b8307701f6c9a44cc9cb837b8eb62445925e8a8881d2538fcb2b249e4ee8b686ecfb49c4df86401d249aac35841e914004f9455d3fde375d20a01fba27b197a698d384c76505106801627e8336bd2d76d761a8
+SIG: 5be552fa731e836793f6dda895dc9b1e2ccd669de1c843e00ea6fa3c5ebf97a34b26f1f3ac7ff2225ee4a7e430072c13da4066dcdcc05ba2b5f61a6e8d210709
+
+TST: 809
+SK:  c64dd20d42627526198a22647690c895b5b45b698f57a69dfbe48dbd426aa470
+PK:  2e01d40416f78acddb34b8445ea4fd0ab3fa9e6643044752213f07c7f0ff43a0
+MSG: 821b9f7c16104b533bd127184fd72ade092b13bbd9aceed29b8d10f16688922d165f8931d53df590fb713b674d805ce0c9d6ce6c43ba6968191d12bfa08a8ce22e8f336b2b491af25d1b1606f930caebe522392a87d42ce7bc167aa7b610597220af31a665353071e8d9e5f42078b9c388bf040258e21f9c3ab38c0427618b2c28d3430df27921bfc58487b3461978bfa8bf586cfe8358e092f8f47466e762451d50164a0d74360f66b4cd3a3575da01da23752430c035da859f577de22290aab4ed7f34d267406ab547eb445cc64df53019427f4eb72bca55397153d01ccf7ec97d7a967d9aff46231d2e2027b38f3b41bd2cb1b798a4ae88abf4896216d315bd5383024259e59742802a911badcf8473db91af319733320cb9521ef9ce437267b6ea17bcafe5d0903b123a35c988f49834f61dd552640a3276da26af17ec21a20296586dd6f4b36c7a4f0b899d70b42af89e29370132edfb72d6834194a1609360b1f1feab89b96b8e8f0f68987c57cce0bab768113718fb1709de2df32177d44085da5efd9da70e1a858c92f245acfee64b71f3eb16e04fc13989e69337999701dd73abc266c9fd4cff91a0fd04fbd8b13b12e6f450385715848e007fa0d463119fd7de6325b640042b654212e0db8da1adebd2a7589f77ee4f752d282ca1119c431b17ad0a021ef2bf95e5ac4704e62d7039d0e651e456d60e63bade401cca77c9a89163174d5022d745abdc76b9ffe2544155235e3063e6e4aeec44ed5d8ab408d966fec12016c130730bbc558732065da800a70cbfb0fccca45d0028cbfd9632ddb2f0ed12edae7b930b106c9d1285a4b870de7507999c74793dd497408719c898abe49f7f33a33e69b50fa5af9480068566d1fddf4482d79704ad8ef11b88b42cc69fce8a557b5ba510e708b9375123038568270de407232e95621e2d04570bec2c41eccfd855b21f0c9bbaa23b5c5815fc888f7fbed482c320ffa1e063e87b55bc8f7eeea374063a9be65f7ed9225bf6ca34cfa311b79f3a258c252e6345ed6ac84748f46807a55d4ba41266169cd262d4f72279ef0caa77ff44933532bd1374756c23ec85f55efe9fc2331f26f881629f80c2692f7f53e4bc6f22efb45457a223f0d1c4
+SIG: deacc8c23218727676d540a23bdad7810211e6d57ad294c37d4b1c9af6b337a53f7880d2bafa73b30508c008426bf8d7c965a1f4a422a1bc7d6ad6226fd19706
+
+TST: 810
+SK:  0f8e9f3526b4faea9276f22a1779e6f82709808f6d0c612adfe32a6e8a061005
+PK:  d48c3f0fdef382d1d80313e846fca95e418176bb5dfa9d398c1d2124776f690a
+MSG: 0ccd37c4cfd8e70ca3bb3946d09d70d0f6a4b81d6dfb079d7873748071589880927382f7436a6ef8f51c255473dd01feb52c8edbe4d3255713e68d640f3dcf158f2bfb9fbecf71f0719dfe8ce6b601281ba6c20a56b4f8e7caa4aa9f868fbfc5e4321c22d65f0382c4896bf9bebe3546949e8185a4d817e45b5d1293953821bdd98ec259f64a3de53865b149ea01c8f683ecda61da5dc10e7ebdddfe7484f5eb1031b7916587caa399a06b6fea4c5e6e0be650fbdf06c1036df2cc35f62ea0ea713f52809d77f47c2e55c92392481680b6332056226913b0ce88a6c55a26bdb5b8bab3cf4695a8c522302c4eba37d31ff77e58301bccfc7c7be8580c6342687995f44acd190965ae0d7bf0669592b6ad88743ebb360c73e0484a23d2f9e99e9eb038dcbd87ca9b1a498f1b2d35fedd7f8e1f7fd8ca526486911e076aeab4877bbacf378a2855f9c5ac039130dc690e177d67b244cc8ad032379ef71fe05e9c8613d8f5d6ea3d4e3e47222029cc004253be47f87fb5e3314c4898134b87acf10b2538bad897bdc5012d8f9762c871b653d400fee0ceed5ef6bdd16faf3f0abdbd72cd0a12940546f0995ff14b0f1bd54856ff74c36eb4f22d7287aefdc609998c1f41bcc3bb3a5fa49234f4fa8e929cd0f554b315395dae873c61ca70e0410c2fd5a115d2a6ff1f1c94b27ba450b8194b21f095c61a5f215e3c84f5d43f0e736286d33b8c47814db979f9dc00919846bee685337d99555a24472e6b00b3f4a14311a6c7c904ba5889da6c1ddcc1117580f5fbc41f2b8a4268cf0e9fa5bf412534c9e4052aacb504cb86e2147ab8023d58800b763f9abf9d0440788a51dfe5cbd44230ba5228f1f5960ea3a4e4044d36daf811cbdbec5d696463d8e941f27217563bb44a2118a4f5acd6e794de17e028cbdeefdef2cbf03dd32e7899e65a1cf839f5d90e1f8c364b577fe3105353f66768dbf7af0c521aa8a49f7a22082d88f901498c90b9d7777ed2f9f0e8a552d8a1fa5e9632ed853258c9c215b6dbb4111dcfca554bfbc9bba22f88bc55552c6d862556d741dad59f215e37288346ca7d7fd8c65a380d720caff9efa149f3fda232daa5b12ef11c0af0862bd0229e075a3c6b60ef0bbb3dad7f2908
+SIG: 2f59a2936073913834eb15a0e0bcb9aa804089468f24dd1b2d37a1934ae9ba1020ff64b72eec03268d0a7c012c4e796300f6df7adda01c8bc5e9015ccdee1a00
+
+TST: 811
+SK:  fe7cdc7966d0ffb9c76f4a18e7f0bf90690eb76dc3d3d50884648e2e3937d020
+PK:  a12ee9812d6af6aa4879fa72bc0a69804ea1a85f9bc4a26a5ba7cfbb914d0dd9
+MSG: dcb91cf155461a60df07eec29d98616ed1728b34efa9e1f7445a9158a8f88d7faaae0e24725aeff263c3f74f0c684f1858f05b6995d2846b6a832f67085a4276d8661aebd3bfcc73181f1f510293b6de5e4bb23ff2dca1df608cb14ae522ac4b51e1f9b973ab8bafcd534e71c57181b11896ee1061fb369ca4d2939d1e57060d9f4db0a5c0b07d52687f157817e63e2fe7ebcc3e7c95efe05b859910c95eede86d14399e616248a28c24c414dbb693af9be435a3a9cdc33e0e2a586918d91b8a85cedd1612d7c1a21792bdd43a915b157e04bb3a44ecbe23fa49cc55daabbeaa155a737f765b8ddb0f3b15d4ecf2cef7054ca73ec87d91752c2e99195cdb1958844f144edab82a97549fc9cec08e8711cff863b63fc231a77f762e5cd9da9d59409252e99ab04c42bc57097e464e3c6a48d80241e6325e3e4094989b34c0e8b32b1a7829d54df32a050ee87d8f7c4fe3e4f4f7049d1feecdbea67108350db4e8edbe3c3ff8ab2a25d147b1c1c5821b0f8c21042d655db831691f59983f27d2ed1d4906c544e24e79be68653c9b229a7fb61ef545bab16e9881cb4d9265e293590a0bc2dc86bad23007ff40c95861923b498241c10d26bf4848f62ba7383f649dc38af1840d0de928a9bfee5e11b51434163a7ab1ed537415f1e93285e3699205720158f9557d8641ed2bf485b8212c8f82668bac3c228e6924c17d0d98f2e6d9234371c4425eb758689fdb0dc1cea1394a2862e87bb38e624c34799168613278225fb5e19c9247ada35554f2c4addbb61d5a502a708127d6efbca8f735090bdfdd88db29fbd14b69ab1262f0c3e26d263a59c5ae4639065383d5250b54cf592bb7adfeaae0d2fe816b6381e86ea2d1c71813cbc3d8fe2d31de7b30fb6ec2294fe4536a36c6a1835a7162ab4bf89d19466119657b0e4645aef503505b4d55df977bd2c90c64406f4970d5cff245b835322a6fbe234e5efbb5ea45e8f0d3973be4aaa2aadaab077d6c9b25bd4494409e93479d2d1507f66bc8bef82999a13c7943b472b9e61ec29debefbf2241423e0faa42c1a338a7a6131ded935ba03a28662e68593368dde54b462f2a5fb746185ff5503e69ba36bf16f71458cdd057e5c17267f67498d652860b465e
+SIG: b52d03fdebcd429737ef70920687211fbb4c04f81e355cec7072c5054175d2ed77f38f466f001422da8fcdf067db1451007cab607f049c2e2607b57d44713c04
+
+TST: 812
+SK:  f6c9ab5ea75f294e8e0c07c4c09ed8eea3113bdfc2ef759e20a264571604108d
+PK:  b12ff55bd3ec42610eacea28b313a16e19c9e8b47c2b15170991be088d65cf63
+MSG: 71623b39743e39c7e08638806d468a1a8a6f35c2ae388eefc27374bb52538814c4b36c9b8e389ad83183de02a1bbd0325734e4618754092337d3e7dc1256928e3528870ca7f00613a25b71bb15d1d9eaaff9f2269b71c19769e003ce845614b2ec95ed28ca855b5221d4cb80a6ca9466aa33e2510ddff7dce186159da70fc8b1fbac12a26e1fc0942276892ad6e9b003f56959bd313af289e7a0532a664b76b96b919854e0650cb8c52ec4c5fb5053af2f0cf8c0f22a523f9e2c6419df8d0b714ee3776800ebfa70776084667d6dcf541f14cf166262e0f64c4276ae28885e6cfd097b70c0d6186ea5dbd033323c987613da08645de07208bae12a178d8f7f650a25afbd701c85a1ba639ef9f121c40c5c129a4737343386a48183ff3c591389d89ecda526cffb2674f17bb1c23090554b1340849796a6d444460bb419427e93e6585b0f4f065ad87ee6edf54be6188a1dd5ace1364defa561f74e26769c9b291ee7555276501c6a49080da0924f3792c2a728a52007b1c07c95578fedaf403996239e9c55a9a44c3dfcc37cdf03fb485db5a08dff15a7a4f7b7f154742e8431564dc17dbd432e10337c2276fcfd9d70f7c3d570393a0c19f64051c73a870e205584106531d1fd2a1dd1c9d0fce14ffaaa077bb7e260251eed6c62bc6edc2422519440c2244eba384046b0eddaa6cf2c1c7eeebfcd78fcae18b82290552b59c0463dc450618ba67c770dec0e229b8460936ca819562bcb36969c8ff70bf113c11671e00b941355bf01ad54b05cfe2a048b38728cbdd1b49809e1f207aca3098d9942eec47d6c9d413b37c914fedd38acd5ffe496cac757c2ef8b77bd8403d14b1fc98a903fe2b979468233a7f2aed6f8d509d874e1dce05149af9df3fe4595c71e8bc463dee9384d5e0505d2a6b0a2b8a1ed6216aaae9dcc7602487a4c0851fdf09629c1e99118809a9544a6577af9f915d1e65d816220c48c8490fa9b70da422ad6800223d6d8c340f9eab2cc7e149362124a300b40cbb8c0a65da301dbba931ba564f35973ca8bf2d1edb56c194661955b3b68381fa15d4b8dc6ada1a5cebda3a4ccc55123e0057f4f821041937dd549209c82e116570bc908a28e3299a9441443498f74b3cc88e1a62d
+SIG: a7f9d08ba14183ef247f2c25fecc2b83eda6de58022e466ce78fcf50f71ce26162446562eea45d63a21c3b22561fd4680058acb825407a15408f271361a1460f
+
+TST: 813
+SK:  43103df01a48a03c57f32f52d70c6849ee44580b2ab4ee72d548d848134f7ceb
+PK:  a3cbe0d64b0560bcb5ae009001e314d9ec907901dd74a804a0059022ed9c6d04
+MSG: 738cbf06d00d4dcd5e5f243a1c18dd5ec20278884695a1cf3bea67bb5b05dd7e60a2a24fd325be6bf46b462873ec907f9de88dc2c762620b7e0ef72765d4bda662454993c828a1746e9ed8d19dff43c4c48527ac845f2186a4ad7c1d992a16245cd573073e0940dceed368110bb5fd0a4c8834ce88a77125b9147393c8b58cb16e5ebdc18244ebfa48baba46973fdcd485b1b2e5f3b0e70992cf1999580638d87f1f5b27c4d7f91decf37de2e734e3195535c631082b3ebaa8ce30a9c2c2db016d7d3547e621618850e22040038d0fe0faea2f9bf510b682c4fd14750e89b4c199ef0c990500543eeeab5f0b507a313199c2a2a0262d6d814cbc0933c592e256c3e29d524b066ea5a4543361a10450e0aa675c61408f307f26ee58969d63278f135b7dcb666b93f2cacfd83873471e974a286b09023f5015fa1aaf18bfbfa5f74385d0df6b9add516ffc0c3113e37e097838646ac93054ff4d9602066744ba3396953fd78168130170bb275c152bdd366f73065c0a7ad7ad00758cb99a7ac1b7809d26dfaac758468201eeb60dea368c33f257afe2f1b4c02e37bafe40f5d7fd40c87d1c56a0cb28e9d28369a3924bcef8b6d999dcf4294dd8c4143d75c6c25b5a4544488dde725248c78d93c15b815b01cbd0f31d1b00ac04837ef85b4003fc96d4457ac5a023623e67b66da4700a0859f83fdccd3c7aae09de09a057e00db44a2a6aacaa21746a49b8224689a5cc1854ba3dc4aa2aa34524e7a5a89d11eea356aaea5ef5fbf542c99f544db940f5086838ee2ab218b8d3f2e107d0b29d4b04830eed79c0768e02c2844b3cba326895f4ab38a3994b83ab30600ff511ccb595992f8cc0d2954807972da365b06fbdab539b2e03598b34e53cfcf93990b97aac1d329783366d451f972b8d8a00b6b8ecdb37279644cec1447c0998ee4f7090f34c9cc8530590cae765360aadb0ab3135004941c92302cbb2b350a14e8f30af5325c2b438005e3a9d4585e63265c327ba725754b33256917fb965ae9f02ed2126b481473dc0e931c2522bf00fe6a2ec95c792247b1e03396112f783070e2fe6c2cb982250d13f2d5460c744fde45323e631cccb540cd725f2c55a7058f230e82b79f366afcbb025b492554395
+SIG: 195447beb1de4a7e36ea89a6ce3c99bcc89411df5e0b15f7ba0b1d110c456abc6b3f5f1da6106ed887864ba56aab466a8a63b335cfcf4c64d65c0e6fb480b401
+
+TST: 814
+SK:  f9139e579fa96ebd6287db3babcda60f92e73153566f924cb5de04de4493481e
+PK:  c06ce335533af8d8f337f2b38e0aafa2ce9b27223cd9ddc5ef32027f04889b7f
+MSG: b330764ddc628e4ad67aa4982ae86d4581071c193ec3c58f813d7921b84d2a54562bd87417ae1de590a1a48c4ec7d556ad931d65c0543fdf0607c749859ee12f9952020c195cf8746095e1087cc6c3c8ef9d24052560ce813d6139b7a75c8f4b8ea30a9c4ab888d0a6341c99abd35e0903bfe56c93152340c41276d7f24e0912b12a4db3d7ee4484dfa53afc0b1aea1409d1e0328aa1c8604127ca2eb1a5e81bf31f8c7a51c6052c534efe6b3d0ee74ff5a9b11c6157e36477efa9382f5751be8c8c6454c446d6f8dc7e929525cc3de78cb1ba4aba9bd4be152610437582c965eea48cbd4caa6f308f85f4f8d006a042f619200762e1bb9ba422e65475b33a9494298cfbb75a152b36d2a05501807705b952765350cd14141d35d4986692d6c3bcfc6d61df0052a620aab8cc13205e754c16f93eca7920bbea5157ef112f0b64c1054f90a5ddc175a89e29242f57646e74cc885e81a1cc144c3d782d1152a9e4cfe76cb3ffabe7dbe603fb3869eca8699698709cc87fc961c1e299cfca22e3242eae788cff11bfca61026745f4976225b26ee200c4f1910c4b83df5ce46ef487d748d9c4c502141b7874caf41e5a297b248c2bac6990a15b07b4cf810e59287442d9a3696c02e8d7324d3cf730dda540536beb13cfdeae6180dd7484832dfa94e94aa6cba117aae17270f48f93b2f98ae9581718163f4463546c0ae0f279c36b92bee66f1ca2d6a4f726d2dfee0bc11c1d8a1fa62c3cc8aba266b98759286c1068483b2376b403c887fbb657dc0f255dea90dbd23308f7e0e842b498a8dfc7c9cd5aef0e87d56be40d50fc1dd4c0aa7dee55aebe4d6b6a52053962b87b0f2ee09a90816155333d5c57a14724e001bc3ded17843b76e2c47a176339c8defc54b55b2358ae7d01b0f6e08f31216ae90340694168a5a79ee883ea7858007d17c37359c99d6597efe460c1a2f7738ac32c5eb5e39e500c49c0dff9c4659e8c50cc5ca79d8ba4e5972d67225468fba64167a6b2c6f368935c7a049d35d355c7672520d3c9e4e43c671c3cb8dee259047495de0f56dd7191d5bd4bbd29517e364792ff89d33799b6e781c20193f5a316fb40de74fee2acc25e47f512214de3b1e9b382a86929c1573d3724c25017c0e5
+SIG: 051d8d7f0b68d2eec72c81adfcfb31ae8558f60ab63c9f5652a8df638f666f1ebc0c6e0b411953bcda6b5151b2b93a39e3c5330a8573e168792272abd36c810a
+
+TST: 815
+SK:  c8ee954db5a11b292ed97764fae6b283051db57dcdc0aa0df5393bb60c112ed3
+PK:  5c2f81824e9975dd7ea353bc66807dedc7610349794e2fc08e5a31e002e3fe07
+MSG: 7ba3fb568315aa81e21f197780edc2c6ea26d8d06a4378912fca2301cf1eab3d803c8469deddf376703ddb7ce06a77dab20e02344fadcc50022ab3c713cd03c1daa93f1c7ea572629f610b5e3c51411bb8c19694bbce903cac4705f9b5dd0f47bc5d0aa3253f908870299027ffbd3449eebad45332b5d0c4f533dbed18a99a2498b9164e245fb65c0afa0b053703a0cf95940ac7a0195d4f7046609cf04371338706b9b1986c0f118175d2cdfce74a6f88659825854e94ece58f5157636d6235b76d32745a2a81a9671a8f86027ba9e01763888fc171cef7c451c36072bc7499839d431cf18cd7c6c9fba3aa712a054328ccd62be4820abd5e782162764611d4539ba2cebdc209b3f4e4b69c3d64073e920d215214fb0fda44185aada5c36127a15ba15ca28a3ad086e9d03366869c60c3fbcebd869d2e40643e833f894803f980a2da7ea4e59ce4d7c06fd2aff087ee7bcfddaa3b32817ce63a63587dbafef380013a6f1ee3734b94ca3df9644dd0434302ecb324afe35f465c9c1c931b27294fc6ee0272de2242ae90d7f2e067027ef8642e8f171ed880ffabce8a20a1b3e339ad4e3f1a9001f20f90026188fde34b217a6e26aaff18422b7f843d0fdda321c319c778f23137f20ccc1bda1890e5bc916a5456d068d37b5acc6347720c56a5a491bc348d6c848a9c8fecfe58c92b1f302fe14919718cd5e78b7fd601d09dc01e6904861e8d68b3c57535b6136676cbc6e839af0dd739db89a7abd913fdf6b00e9ca02602de6ca0afd0913d992fbaa8ff822b9d9b09dda7a29be91910d8fa3caa2a5e518346c167c9f51941cf7353f3f34c1dab33485d0a8c19daf951fd3ef20d0b119d8038df90c114a25a5b93ae40ec44b9a5d2bc1c6517c682500d4cdc197142bec3af8232c071428dc54c0d30454272e7336b0b5888a6e8fecde859e2accb7fb094acc54ffa481f7623d944691f04fb3613a9954980f17e2ad2173d68cf0ec1b67d8a91d6ec82946bcf05cb90681a71627b590238334e3d5ab9da6a089bd72624df9074cdd2309e04dfcae032812fe84f9db882cdeaae69ee5daa5a66ff427fc452edd0769b6aabcc139d0f70af8b97430e644f58a41287a93f631deda82ca0716d79754c5c503e52a665da
+SIG: f3077a75101e121e5c3e77d8ed97b578d239bd421803d3455b5654405a4c586a6092e13a8529bace468a305784b373e433fee4a3df8956befa012fd8a8eed10c
+
+TST: 816
+SK:  6dbc559e4ab193eebf70c5c32d797be00b7311e8e6691da9afcc187291f2501c
+PK:  38a7034476fb9382f1417768c42162951a2636902c3898c029be278ab4c31f31
+MSG: 88ee2365f7cf9de33acd53564968b2dc7f7370b7e7033f4c663a88c25f60f7f711d61908ebf1f5bb72835553c8aa8c8e4fcdecd37978238289bf6ca84876d228217a28d81b0b457c922e91ecba8d3e1d2e6659c2b0aea051b9c2e09c7dfeb51d30ede767570341ffac1ecf0de20c82d1e9ed0775deac72da7c2dec234865dec83f6715e1c3c59de2033cc24d86bc2d31aa16649686ede0dbbd8964c3a64a3dca5588d7248b1f24df8d75f09aac62c07828ca431a3a2d77a60cc93cfa3495cabeb1904ed5b563984e8c20777bac8774108a64eda58fb320244a3add3e3e7a76cd137cfa4a09b6e6e93011ea0ae65171af130711766cd25b3c74ec54c0bdfa02b3120ac29087ebac9837fca65ba971bc4281dd557c500e225ea66c3c3fd52206c19a9f9395463169f8c7a846bd9f834d7f337d0b61fb30bce294f478ae1f1d977e454e433ee8729fb065cce03fb2e435dcbcbfba01537e7a6762e55e7ed22528303704beb5ae381f2e181056f25133273cf17ddf2b06e2d9477f2c09755fc8d9c73cb33100468c64131c686cac79fd384501e50f8b0bee28ba39583f42e4fd3799e24f60da5fd3c779aabf699ffd2321ed045a85bc6424f60fdcc49c1cb31f249a4236c09491768181b921f58602fd415c1edeb26f39324addff14771324737c6720cc92391b949dcb4212bd6931d4de51401e7f953b7b036b223f0af7a8e408b04ea635a23fa0709ba042a5d992954c09d8581dcccf52568ad27a1cc71d18aa2740f621212e7f4c5e5e5e5e4532d9a67ec2773ac21c8a4b002d6524f6182dd371735d2c2abe6c95c281c6fb1e976bc17e383fd52aeaaa9fbd4abb82a2cc65395f8c2cc7d8182a0d250c685cfcba93a951ee7c503c6e3eec236ce33e086c610728737c1c3b3a24252da7f21672d928ebda993a94c458ab990f5d19d80023c36aa16eafcab143f352e97d6409f3249941119bfd9f5f9084724d9ebad383b10f34d33ac830cce9e5cb8aecee6f40301cbbe309fd061534a7d0c3edaaea02a171d8b2349dbeec628520ac334a5bfe28a9d5f4c0d740f7c72d4d72d89a97326a03002d1ef38522bcd37b42847a314bd843ec88d1f2f9d39f57f2f1a13d0140a8847450448c880b3ae76531e95c4392973250
+SIG: 31f16a7caf2b74f65e057c9333a1a2633dac7346338f798510730eb8d5d325fc1080dd5aad5fce0534e9543f3c93586804464af5886e8644129c77ebaa485f01
+
+TST: 817
+SK:  c9d416830ae2028f2175d22b614c79198c670cfaa0e7a36150ef0fee21a95ce6
+PK:  6e3eb4d01873072df946f1792f7106330895e7a76dd9ae27f8a988039490fd4b
+MSG: ff9ad4837cd0bb77d6210fdddc755e6c0f1a73c2bcd03f7a5869e7342cfd73cf7086f865561560277bf6c3421a912d67658b1fa97057c496f4be8edcbe18b5ecd08a1e7db25223abda208fa531f4b280aa03b04b60603411d374ba7cbb020bb9a8ce4c0e45a7e132144843c31f8b45c58eb3ea853c2ceb61376e9df81d9778e721adac77b50354937f34372fccd575e88d9d058e43df942f2c43b523c8098e6dd9e6bd21d5a649b472d41e345fcd5efddd49eab30270cd8788404f28516e09d3acc40048b39d3246f757e482e1459c626b799e04d06727137371e120afb9fec39a25f4e6764bf9792fe492ee0f210b57db9ebb9e8ef41b02c7fee9edd4b6174c570de020a391287133fe8ccb41a83f91bd22382b21e1d7ebc2c7e5018ef5142d82637d02620fbc0569cc09c44e911112bbae99064d68d1c69e77c9930b0de030c8c1d748c414059d5e299b7edc08940651894b303a2b32dd2c365a067c9723585594644d3ee8de1a51faea0e650f2124885a94cb99eb903b7d4579bde591497d953930d363dddbdac627b97a91f49682df8e7250a7073d383a7a22cf113f2858ce6b632a2892c4e88aa9a0d289eb57629b008d3b1b6081e6fe5d3c0a6c802189b5f108e766319e15b33eaa5b8ced4027eaec83b4ac68b14b8298bc51cd8eb3809b7a2d684fe32bbd9fab5c918eeb17cc444d73f730d4c8cc057bd3a2f1f0aebb61632934e61702168829cd7e91de81509629d01a8cdefe0d1ac49e21f0c5fbe1b2244827268a0a27357e158bd76884a21e7f1fac1b6272166d5a9f64f9b672989a8762f512bf1df4b2ab699765f2cd8396f476e7f59995dee7d890207eff0fd27263ec232e37cfedfe7c440555d4ca74e52da246c4b83757beafd2ab2a51efe160bb02b98c26d6b2c3f0c1aacb2f3c34a5b2a3b66fee175b787548073d8b5777c6be880bdc196b3374a2154f94d9360f7755ac6815a28af296271e22a8f23543c74955a609125b02a569218011420295ccf0d7356999a5b895cc88483fadf7970cec6c64240f7079fdb15ffc5c4227e53926d278ba0fed3c3993bc86822823dd581a32ab2e3a07f79430224b274eadd845598a7d1d89676aaf23677774b7b0583bcc83599d155d14b09adcf49ed505e8
+SIG: 47faad4e655293eda156b2a1fabbfb7e009fc290aafedbd5652114a47853bc77a8233a2b179f605477d787878cbb15ea6124df8dc57b2ce7be7d18b7162fb50d
+
+TST: 818
+SK:  2d277dd55f57195ec072b47cb1448cb582c835739e6c98ba71ab128f70ce6b79
+PK:  dfa92593ef0f0d974a1137830ad13848afef3b810c2a21bf779178ce4b3ab974
+MSG: 14549eddd5f2b7905dda19d74ab207aac6fb3e3df3295d845231ef3aea6e1f04ee033c9038dcb4bd3d5e452c54834d0ff2b7de3f322e5626949cd61d6e890138ff0ea8ad846e8fe887aee15fc48bbe4fba42455f5c17457ae789b405af859611fe1f8746185a65aef2134ea4d8f398d48df7c1bba4304408ae7efb35292409d508dd55ce21de8c28160dc9e877700c763d06b01b8542052d7ddb633554e3584279c796937023c8eac37277be2b8204ff3e0e1031190a01014cf5f5b4d7ad996727f97531e0355b87c9e611525aad079958e9afe2ab10e4a3e7a1b6ba0aff815da2cd81ea9eb9f536986633f316dd06c2503c6b198dc59304807b98b42935f51f637ddb59e233fed566439c1fe96cdaafa49f4412d0c1e654d8c69042470b3a59acb6bf67e40b38a77067d5997b8d35ed61d6eb3cc78b8bdcb9574b1ced9f6f339e9e38f94146ef63f049e6b802bfed2a51ab42e7d489f316ff4d1cd898bcf8505651687440749c0fb7a57dbeff72e64689faa41c07b4ade59933d2fac6d573deb739549eb75f1e6f7385d8c6142894973ed685eb8ed080c2a49f3ac6571161af96635ad057df1486d396773ac8983210978986e1bf21a20806d667a48a555a963221d50614a8976b2eec97512db11a358194492ab5455801baa14a511b26eb0c68289d790523712f2ff8709892695c4db9ad310df8c6ee7bd83c871f05aec33b7ad326f446692a42f7222376246d536a326c4d73eb572feada11b8ac7114f6cb444ca278fcf07b970d2ad465372a687d36b7daac478748ec6a932da20843948efa393097814272e5ca1c73e711973a52683f98c01e55241c154d28e38d3edfade2303a4e7c45c2a7a1c996ee1137af864a98b69809fc9214eea8cf3afe842fee3eb9a9322c3b82fddb05d4d1a2de09c1ce72734453a8dd3a8920d0d0ac96ef778b9e02c6a3f12872e17d3a81ba75fd233baadbe216ea0a58e9dda00840870208ae413540030b3c05e5d0b832df87c8ee7f153487aa11bad9f139c7dd4bcf418f4bcb95bee857d0e96084472387cb39127a947134501963a7071bdb34de6961be2b6b06e403e75918e6f69d08021cf2a8acb80a0111f4d50610c152d39c6621c0578ac689959b1ce6f376f43d18af062e4a
+SIG: 73c1060649a7c014ed01945851b53e285324e60d061c831dda41f033b5658306a1f112327afe93caa921020730aae0069c9a2b45eef55cbb4a5a9cd46cda8008
+
+TST: 819
+SK:  428066c52445726d0ea2007e504637274d84ee232325b505f2c516357f807583
+PK:  dd40fe8f67c665613b3c459f6ace8dc28d34e0e77e2f6aa060592819be6a9d68
+MSG: e2796c50d93df812bca41bf2a1e1dd737d8cf6f6b4f76242e39178186758cbae0884e60c6b4aaaddaec9a899a912e5c5b9804d7b0497bab4458c585d4f259222498ce9e80eb6a7979bbed6d52cc38072f745cb2c63e663bc3b9d6caf012a607f6d3b706e1557578717ecbb971aeb7c48e1df95711c550e006993bffba911cb64ad52d517ed18be82369e815819d3175947d4a35b2cc7b9dc6c10051326b3f1dc1edb1b68ba015ff7ca1dc361d8967abcffd3c31f7d6b0cb1396ae541f29759c4130be52ecc11d99261c365bf7cdec781494c5fa0526db4dbbe660a432be56043c66ea07c25627a5f72b78123dcf986ff71ed1affd1659b1393d9621f711dfa63eada383430797058f1566a00052d67ba53c1237b5691de3b039fd4476f1151e5ed5f5a98672fa33a1d854fa01566b33231d46acd7f34b8034479981853764dab87f49844cb62c63d536faca920447d8cd1e8113edbc83e4a6b7815e180cd78b933d9687fd5be99d0518a44662989bc64011124f187d43979994a95e0c903a006c1c0bef1c0f3df1eb700f980c28c3c1e997d0c56d113dae196882b05018fcab314d8117fafbabe7700b932d47c57362b2035eddce2d2ef33641ea90c3ea3fec6ea5b87e161014c4f8214fd03cebf94abe122537a98703239df5821c5ab633f98365cc636e3f1d2f74e0ff8f1fee06a3f73907ee504b310fd5224ad4d05cd23c356df8b34647298c49828725ba5fd60611e829b6337bcc9dcf8e8971cab3ee9c26337d38dfdfa036bf6096b635ac1bd5525ecd377a15272a8ac9bbef133107a42258d8b19ec69dc4261be5300a2d2d5ca99f31efdf259f9d079869a34413779f3028824d747686c460ffc496f2010f403e903e27a87dd075ae0a7f1689416d31bcc15f490caf975c40e715d549903e8bc0f7d9141e020f410f3ca2b2c0797ca0dc8d7392bff243528c7f3be138997185a4b36f45376d9fd70ba20989d2d1a911d4b98d160d2b8de592de2f4c04f35860df320c548440d5e3a346a14d3a63fe485c2889126b7f41d55a6eb23d5620babf8564aa79d156e983f36d9ed498da9ca888d946b53cc4768a5892d52d541526960282524ba6194da65941d1ea30f806bb6d97c7488b93fd0a770a9b15efcd12c5c4694
+SIG: c938829f598b1ff1b8183360d223f43c594730606876a99a3f31b2065d04e6f075d1396b3c8cffb0e1e2eaabda7da5e789ccd1c020835fe3a71dcdb6af03960c
+
+TST: 820
+SK:  3145bc68d82979408e4657b775f150c6d28a324d746ea6de90fd72b17a257982
+PK:  c776186ce47f30ad08fa1d2c616a3644665ba54ff730fc2f4db1dba38ddeedca
+MSG: 2ea8dce1487f45d6ff8eb83c54fb7edd76ad6e608bb8daf1a1823da4f4e4e9863173897c197ac65804823bca95091f59e86d63c18dbcdb85743f8893ee694d815601f8f22f4d7df087f0114bb26c3795e1fe4b7f4a8fa31fd9f4ff10fe5dd452c54c5578c752f888213076be467ba30d2e2fbbee877c4be9b6ec4f04021c006f9266311943cab7cea99a2acebb69eec3e618c131f97430075f7975e39f26d5315178b69a1ddf731761051b93fb8df7e0e8b41e82e7f4f75e91d6c890b14ca533e094eb8ea4486d387185966c98295d3f58b17eef6cc3b4d07e93a3d9f4772ee52f18a5bb30aa3972850e658170bddb676f33266c9fd10f5990bad891f0ceb782736b40f01bd86509b06304a96d93da233dbed18afa1818aaf57af9bdbc867b397ff235a83e857224b15065225eec039dd4e2d69a04ee10bea0695041eda59b058ec05f49048ee324d16c4d6107b6ecd04875eb744e9365471b4c5fe6611b261893f9d2b128e135f92e474156b271b3c82e9a7663dad4953d30e10eda0862607dec3372b39970f2a84b12f60e6dae7f31799086d38a7e34948419c1b07f44c2159c86b8c0cfe8747fc2bad5bf475356cfe69de2dc6ad5a519fd65c12564701c05f7c277ecafcf4c87b148df1f9879a9ae443c55aea52138c6fa01ef0c3abb5f2df90a57ab6624178c737b54915b7aa29ea78e8e49ef5a816d8a92c2f81b8a19632779c892d66f753d518c41cccc9e593e50742625bcafa468805c37a21f8e29a6960ddf5c5e5ca14a7b052a7b6015697a0210ed6f0143e6b484c3f5b3b4726c607d07bfb3d54a09c98043f21dcc5cc20bb4754e2e5a73b2f806c2204b72f36ab9e96a62c6277c0ad66be7abffc163b4e8fafceff5e202e5943f4f0e6b92b4ddb953cbb791f83166036938e6c44ad91a596a5573440fb30741e660b6cd5f86ffa746e6e972b805c10b7b7b9a63c0551db8eb4f8400cde2868c0d0d4eb4cf117f8ec4ab9744fc5879dea7f0ef16c291d55c17f08b731b7c65d0c441b63bc8ff5e94904c026a1361dacc80a93a9b9fba3b403617aeb94a568541848011954234aead700f034c47c7def877905255f18bdb9a257ce5bdcf0e17670cdaaf13b1c7e09d58f92a9663af239e22078e180a23ccb6f64d64
+SIG: 24a433337683bc71a6ca3bccd8cc2400c24464fa67714b46515f2a1432712705d570614db6d26bbbd3f0267c1427ca1c2f40dc9a6f1fb0f0fc714a02e24b4708
+
+TST: 821
+SK:  5a25ea5e182d9bf8e930a20b6cf55e24e83862789b3839b1ce9a71e938c42d37
+PK:  c981fc36f1a6d5f7d451cd5ef39cd3ab02087fcc6af27dd78ea827497e779e21
+MSG: 214dd1927f2cacd9888714249b85434602ac78453b4af5386eee39295d3d5a2267806eb0cff2c132d364c2420d04e3f6cc0a967bf05a10ffcf1217bbf315e75b98060fd458d67ebaad9380f4adc4dbdf74cbf1c6479202bdd7fed3a946697dc38444d88bfe51d41d7a9b38da60b850c56b48ba984f6a1889514955c0dadb69a8c736cc76cdc49f13f85a8bfb7928ff0a0c0c03f17c74b5e1062d7553fbeb9dd3d5081de1dfd8a6a9976697c6a259bcf7d4bef1c21e0aaf3298b0421b919fddfc1dcb3ec683d86ff3d423d71c8f2d723a42ff68d82e9f391749b82998dcfa112160f52a413a23d95fc42c3bd22384bad77754a710d8b9f84ae0a802fc46509e7f2b07079012b43bfeeab719bde56f00e59b8edf1c472883b1985b2fa699a1ae90cf45d7ac580ceb5f2797def5b8bf4f2b9b3519a727b9f2cd1256a2f076ed2296495b5c2df7887ff89e88e236a14cde6324f43d68d90172b0b88bd28803e999dbedcc501db654544e171ec1f9f32d4d3321d589392e03ca659f96752e1f08a55db553d866985541f5bef84ce2ee323e17d1f7dc164b50515a287d5305fc28c5983b9e5398b2407ae47296fe4a481d22ffb4b865a66b97a6c27935dd8eb86994b79d368363713f101dc37f429eee0fee2441c2dc17bf43924f0c044f143290eaf3f9ee4d946dbe45831a0d83c076e751c14f3b1a7267f5446c188698d2b46d87e6f3b20bb3fdafe24cc096bc312d8678b38a80c3f052a0c96d5ad87a5dd8c133cc9a15be33574cd94308c24dec1a9bdf189ba687199f72ef6709878e10f87bd8a03dc84c8fa96420285898ca3211d8b0ccef64011ec24f38e574da34dab9d2f002105227890f92488c621e5713e47dbcb1a82a6da60d8b2201eb29d494493360ed5a3f4b5225eae7707ee0b4c0407305c16754c7f630fc85c13e4917047bcff3b2a293fe955506c7264ea65bf3a9b25acf343600d8fa0c7c1a290d0271101b7f40b96e7fdaf29def9d9327a5ae05446cb5a6d322453a8b098bcf3aee1f704e14d00be342b8934d19e529218872ea3a2fb2124b52667c01fca5841c66e1e64a1e680e09ba186e04d105186cf6eb728b9d502a66b829fbc992a3881004ecdc80adfd044eda880f8af72a14fb550d7cc74194a945207d
+SIG: a4f35b49d7e198e5d326e353fbb01fa13b6ae260d1e48e30c1b967737a5e79936c97ca2ba799ca34e5e788cea5ac8ed10d5cd15dae53e42432321cc26dc99809
+
+TST: 822
+SK:  42335c30b3f6b359cef5aab6a3ce2858a151b7a4fd78d2fd3ee36fc29d249404
+PK:  301c515a02a4c66bc6401080c6ca7923b7831e3c9a72b55b14027eb2e7b3b152
+MSG: 6da2251e6f559536b09bfafb8160a2e8102d31f8b59324083e5227b20c3e5c3a06e2396768dca3ec76dc7fc0eb3d145e62ed07fc1a8b1b2e347013a0527274d0b234fe725026a9d128f8df20dbfa3b6503818edebd7f24934080945a7e1ea02273fe48b6ed1e83fd168d7973fbb7941b4037d3cda555e0e89c2b943fb1e20765ac7d4fa3777f35a0a8bc118f599c847be3fdb2d8e201ae12a30bdefb034ff24e3e2e701a0d1733734078bd1f9a69bbc667e461211f2c769d29db7c4d62d6b1b92b56f5f18a931a926064b78da146e18b48139b9b39862aec37bcce12cb789429e68ea38112d0b5cce30bd2d26c5f7fd415daf7ca317b3368b7617d4525e5bc97d9461d5d64f6b5d318d0bc3b76f25b0605426909f2aa0cd667a4f0e075b9a9fb2e9a6c82704d8a9f1666844edc32f63a3d4e0fd9fdba30b51b3336b96e9eae392a342de49e9b5fa0f9b90171bde09cf1e946499140008159eb1865563c28394b03a8d7a552271b2876687566b80fd3be2b66332fcad196cab8527c56e21536a141652cdc7fa745b26a331d787b93e5e816d8d851a58f6ac07a5827fcdf472e8685433a40cac0c49aa569319a2e57b41c9998165e69723ba77e5c0423c4b4ca07187bb7442e7d31caacb27700c71ae48cd055ed2fe4da363f44821124cca1bf2e63d9b8abd2fa41b1422f52d558bc5f110c863cc600864984ed259b73cddd5796b32979eddf76a07bc59b7368c48e129ecc0d4535dccee2c3b8e56de50e6f5cc6ea515cd6a0ebdf1ca79aa2794821ad2e109edda450c9fc3c84d8c96bc38d4b437a738f818b4ddcb684383c09b11b36052e9d2f76a61eb4d62049ced5f61662c4b9ecd24a67f4519d46528c5b2eb21005f49c73a3370c68e37ac2b18d481fa10f96714fe05c168df11cda54f14f4937e9fce1f516c0371b36a2c0a050bac7fa5122a6e35ec9c40436585f316e6c911bdfd7db4b80b4306479b82a2b243a52b2d2b62742ed11282790cf6fdc7c9c824364cf25636a855150bddbdf7e640f9f952a947ec7974925e8245068b292101b1f4b2018e85d078c2feef4492349729ad4acb38f1c7c0270b61d3dfd7636c6cbf181e4c8a0e64fa06132553c2b9db7019e3b3c485d8d5b7dfd5f515e4d71ede535ae7f2aaedc23
+SIG: 67b0f17449039e8c797bf913aae6e4f0bb99c74d6d10c973b990ffe03e7ee4ab5b35806db15a98c0846a827e7bcd539cd3bc09dd118ab3e52663a357b1299107
+
+TST: 823
+SK:  be6b2babddd2dca1b0e10d12d20a9ce29c6785dac1d60f2edfa94ac2784ba766
+PK:  398f22f0efbf8c38355e4791bf670898951fbbd5518f0e2a605d460023f613f0
+MSG: 5c9295881b7a670669b04cbe0dabd89693b77f7cce0d4a33f52e02eb26959e713d9aef5f95442bdf91728383325202aaccc037477e3666facaf24eac9534879aa3efe18ffc1a5c54e39c7687d0937b2471bab389b646cbe6b3e5d5961ea63bd452b4743344ce4c793374523795c781ee84d511e2941119bad1f4a746ed9dba89c8d0751a6402718635f6e31d9e18681c6956c5373251d35f53baa1987cd448c9031a07f32c8029119de3a91631dede1d933e0fa32629afe1b42eb591c22f87331e93cc083c23f64a6e5e586ff31cc04e423c56ae3f6a73946c48de4d85ab0017ba24456d69b59dca6d403b64b07c40d3b90e1223215e3f7e876c6701111e37e517770887310ca856f009a0d60654835d94e6587a439da5db0a0c37d7c9d37ca1d703e1b3227631adacaa79421a1c439d60349ae57741b7a8ad09ec293123030bf6bac0689e531ca7e72718223f9ea43becb0ee9d9c1ab845ed1cae443e3c5d4a9b1ede6db3417c3ace281143f42d85f599b3b9d3d05fa0ed07c1ec35ffab0305168b4e56e58afa0617f9a86b1b5b201dccb072b4cef0bb7b95c52daeef9d9e7424a5c0f148f9ffe60a5b23e0ff82c730992ac9c17f97f065cf0ad5377eaccb31d8bb923bd260ea119e6fa9bd6983482d70d9219102402dc6a3499193d0c1cd3ed2a66921a98df69b791413f4970bbce04f639af909c64f4560db0af6003dc46219e8ad2b372f8b5f81cfaa041ab71a348c931e8dfdbc409c22d7ee6e07626e104ec6cc7c6a4116177f93af16f124f196dab619b6f698c2d191858e960c2e947b51f3ac4838759c21fef7ebae35da24f55ebda9b9879aea17a6d8d927de487b175fd7faa21438a20923ddbbca72e6726934bd6c21e8118019f65b3810a07fa27b1cba64d0f39f0bfd49dcfafdefe379bdea82f31a9c39f7e81d294337d10f1e9d8b50eba458ce7b753d36968538513eddb0e84534411c4af3f0214610ee3901a0ebf316173ccaf15cd7ee496dbfc2465eb834df62029d621fe911824d7987df2d46346b4dce1ece7d19d55118c037c9955111d07f1fc362c739f1ea5b275c71c0aebf59655e2def16e123b3eb2526c3ca5e83cb24d5b68d7ac40a67593384c563afe0b552adaf60805035be97b80676adeb1576520833
+SIG: 702ab9acbfa75ea2adbe4be2b6847625aeb409eef9596fabe39d2c533a03431e5e579552e8a64fc4fb7d926aa8fffe0640698464c4454ce35fe83ff263051a01
+
+TST: 824
+SK:  b1e47ca31c64b68aafafb443512e66787c6592f334aa78fa219a3d93c33a4ab3
+PK:  58119b38e6a148a936bc5f92f4f29b982ff2cca64a5affa14ca1b6a62fe328c4
+MSG: 767ec1b3daf204387f3fd3b20010781afb1f38f614474213287fff11307f5ff5ae7ec945a2b9b4870049d4532f8f61c1a7b5f211fca2e67c374d96219d8ea9de73f0e38704fc94c0e9e72f2e15daba3f88f749b1ed702660db1a352a2667d4dfd4e00a18efa4c6609ee9c9a88adacbbb985d3de8ddd17d4e4eb7cf74a1da91edb390852ea4cb9a424f7fa2229e083033a34059117e5efa7b6613d75e58b702c6cee5d004e8599b97503a5f10c4c4e5b9577371d3d05b2dfbf7cbefe6d092d65cbd405138d9b04c5186235983fab6d4ce85b636276206d74a2ee7db6164dac47cce78f50db99af6ac6e7064c13aab793be87e66289c94a09fb0a31d97971edd74ea9c0ce874d2b7d6c4abaeff07f870225151946a5c476f6b978996b87d8c984606c791287da6bad0aa44b0130be88671a556e2de35c4cb038ee781273530ace0a104c27809aee033c8bf9029d90fe7ba06aaa94e16a52c643dfd92a7624fbbee77a7158b2cc151bd3f61a1a76f32b28489307acf0dd8c26cc4adbbb8de430db4e4f58308b6ab90456111deac2978172fe1fc0ce498088add4c31c21f24279025feb48cbb7a920cff2d28710587af52c844db8a7aeb7df10d43411a3c8eeebb406d6efcb19248887d450b573d90305e1f23753e890511dcc77c740e316ad7f52d4902073db3998e4e4acc4e01885bd1188ecd6165aeded1e778702b6a6a79a94999102df72018f792f8f162007e812aef8f956e123282bbdbd0c35612c2d3473f944c6d76be9e86fffa46ccb1ae13505a4a81f31b8426b8b60de8e8a7c16d1e1665b271434665c442a9c6a977ce986f6993b7439af03b402eeafff1456d151526d9c58f515fd2485e0cbb324a503a8d491344cdb2aff4c41aa8e2ed66e58083bf0d2fbf4877c85a4bcd6b9cbb821242c94147e5fd8b7dd792ad0a28d49d41100b431bb4d8c7833d8505dd9e2649f9ca7051be68712ef3637102036b002649473ce259677d82c6062895e161928b752f13c91a45955e80f007de690edf8a0e5eee4422e162b9d2b4a921d3a64845793aa2229e9c239e57a6b1a90a5254c3512f99345315ac7d3457f9154296c66822abe184d64e572b9c38492958e21b0292675410e7348b2b718a0b7592caee94581a948d2f41fa03c61e
+SIG: dfac86df586ec34c7cfea5d5a6cd1140e50b6bf050f8e41a190ebfd3b1432b95a57d5652dbae8f53e037ae326e7f18cfef7c779f40346f7c0d8644610593f209
+
+TST: 825
+SK:  fbd55fa743c3a5910b3857dd0b6aa584f3b238de056b76ab7617aeb52638fef6
+PK:  a7a163c4183bd84b756df3c8afdfb9cd5b242352d9499ebdab90785c3bd6db2d
+MSG: bf5252b2aeca1163771f766278768066f21971357ea7996158a8d6e908dd59b59971349fa17882cb9224b972d0ffabe85510dcf25a9f9f9bdefad2f4cadfbbdacc1fca9d948cb5412f474cad23b5b9199bf3c7370641339b750e1f78c2adb460aa5b21b1fa8f97714abb4ed5e9cb51d6de55816618abd3fd2b286bc11c67ba01129373d435b3e7e391ba372614da8322875e46a675b645156024cad2dd13f9a081616bf131a24358894e0efa1d56648ffb42efb54031da7f37d197615155aedb69c4e709c8bbbe7fbfcb598347ac5d0c638407847b281cf116433097f5662158719fcdd37beb489268ce71de7d70ed925f743fc63a715f7eee7549fdb909cc454c988b30ae4d77d62f65a07e2c8f9362385d028a603108c945872f5e1a97419878ed49542e288ef07b5c90f5c4159e162303d080f6ac2b058ddcac60746f9e1c9ec1df8eda42d62738586d3fdd65df55f4374f3294e0868d41ef0bb1fd55e0cbf195bbfcfcde5bdb41fad9a0477e4c90ca27fa8cf503362a33fdeca5a4f0ffea26e8d7e134fad3b1ec3d056055bba5e65d81153ee831873b938df7d2c83c2a52b3c221827f961bd008362232d882a0412a047afdfb8597c865a2aa2c2cf5189934a83ee6b752a626941edce0c20b6f7a69f1cf12f9a331cdfa9eda24c8defa769ccce2ef746c307d8bb04891fcefd49af3e6f96991a7a20f27b6c0af1218be31791d1d0293e081b90af3b92ecb175ec8c789f7a8642e041ec3a61aaefef62a807d1a5054adf8323bed942241623732a2051dc01f9a20a29aa48b3fdf265d0ba6c138fb5793e2875002e7de3f5c3ff7e83ad27d111c848b7e6e2e5ad5f28eb7c363f95f960cbc421336ce985f946b0515b1bdd3a832c3fe903f7b44e20c92ea80826fbf97e2a4fcaf2db1a08698dd62edd0a84589d7462c447b4a896fe00860042496bd51b1925cb79cc3b829016a4c7e62790f8058c546f2145aaaef4d4b1e273ff61300f8008e946b622f60e505f5f6290d51eb997d20fc3fbb3e99edd68ff5cce9e8c283881c364ff215cb50045e60f4a7ee45b6c9d86447f38141d342dbc5308f8c66efc47f7c45f6d25e6564309a862db90f4df331787ecdd89d3aaa46053e29f102624ddfe80e8a3f99287cec19fa83e44d557c0441
+SIG: effb29da6985971c202e2450301d49711bed25fad85f6199d1eb1e71914d964cbe18e34cc3e32872cdec026bd119a41c1c07ca41e82acba62fb0a7c82aed800c
+
+TST: 826
+SK:  5d66ceb7c6e58cac91e288279170e818e787180c6b42dfa168787dd07f809fa4
+PK:  efc9b35db81f346198a7acc69f65fdfbf4c22e68dd7612e3b8ec68d378553b8d
+MSG: 94d72f6dec4f7c9206b41510ce71a02955604f3c5de8e447d5871865a75898a4d207a26cf33d10caf05a0b6ed0d389fee9ed49275098a88e1c0d8304e81b4074214c7a5ce157eb2617ef04e1324ba942129faf32c31cb4aae4a5916c750808726856f7180e5797ede44362d747d70cec159d3b6acec63a514c7ef31b2ecd16db7fe68ea9c5ead9d870921800348f695412f3093e61985a31eadb79b59d91dd9a37f8d4ef7a5ddf223d4b24774c2e44e3f271ffb8500d595381b3df2e8e6b79ee65535a519a43eaa5e52b256c2643305e3170cbe57606a0545f8586565cfb75bf5e9564c62af05f15ee6e62afeef8c2c7a9dae235c9edd1d7c25cf49adc033ee7b583f518bc168ea48836b50ffedd2032b3f630cc56daadd513ebda864823610fc67a72b9a7d8117105c1c71d85a96b1d27a441fa1e7c6cf80233a49fe0e76a40278d06e34347d87be77b98ded5e2a3ea1afb13bee1e6cd6ca63be54fcf88a20ccb7a9fc324bf6143201b44483bcc964033dab71cf8f2a591fc050d5724e95aa50d32896eec0f3b34311d2a9934e9f852977e253f15304cae2416c2c4fcd8f1fecc3f1f64bb79759929abb0e8e8f5f7293d691af22abd3b2a6770b0cf144608f2d62cc7e52bfe333b2ed2de39b99afd37e3acf07eda37ddf0df029bff2ec22544b60bd7db238df1975ffa0075a82abd8d6b05b267180b870e21abf36981ae7768de53993b304f1c5453872fdfa8edad45f8001aa0e7342b3b58ec0f389dcbc271fb0f9000628757abba58c057e1a0899f6faf15f3740f3143f5c0b7a9159680de8c557266441b3b01caac12ec278f5a1025df53edb6134c96663a9666ae3baa90fc835111ef051bd912f67967449113b6a85f71df8c6037724eb8fc7d8319bc0385be9b0e99e95f9aedcae8d45a514476f05bcd7235c013ebc3aea9123c67aa6f3b79c85ea5db159eefadfb75a50ac6b95b496b5572581a76112ff6db263fc14c5818aad5bca3b2cb3ac8116d429482781e06f61e7563e6505e51c8ff998bf84aedb5202e2f9ff4c2689820296cc69603091b8b818fbeb2af5f4c57060d98c1a904843a70bf975b3c3ca6031a4cad5b4bbfba7e9b47491ab740d9ebe41d768810cb8cc51a937f7e3b22e3cf07ceae0ce20831495afcdd8c1a98
+SIG: 6ef264abf8b0e5c2d793b2c75279614a39c775eb2bcc0891067abc61f6d644a69ff8f814a30522cca90536f012c6283a76c32b89eee1bd9a4336f4fddac8dc0b
+
+TST: 827
+SK:  62ed8682bd3ab3966eba3bffb775a318a03d99931979e99feb2ddbd69455a0ef
+PK:  d32ada178b3ec7700c47dd6d365322033fe431c302b46f8d58798ed83371566b
+MSG: 9eb13bc7facf51a180541ec1dc5f5acb148c8d5eadcd2c4ef068bcdd11b34925eabfafabfe82a284bcbaee1381152af8e5e09f037cf1bb6484ac18e37359bfaa4c87aa07d3d14ed089b053910d1fa473f7bce143e2a59c4daf99b6c6e4e9291d97c864712af3eaba53ce2517a4f75cd7ecf278f34e22b7dffd088fa5ecadc0dd22135e42a536c684f2195d315f6924571e463f5cfc11b9f9d05a7ea11b98a169a1e39360973c50ad45c7491b57138ec050f43cbd5d17eb3fe0013e3d28d526054e07633152246f16554f3054749eea687b9c371b409cd3ecefb111a1d600407344e6d6ec38c60f6e545a92382e46c4d113125dbe5b9826e127f10181a35acfff28ab3764ca7f238ff479fdbc45b7a2ad0ff538c8acd0018d4470febcc6a307651cb5832f326b19241be9867e4eca6ae36f0e2d83fd77b97202b364716e36d1895a36853e7e76e88f62dbbf7726c2180569c66673837ad72ff936cf0e2fdb9ec6afcc79f8829e157f952288f4e00d0410a72253bf605eddceb01440dee5dd32b5a803439f038c06af1c90b27b5fe9843c27ae76609cbf832835c0e3c4bb59976ccede448786d91e438e0775c06a92d0f0b8dc0ef68260f7dd9e6871c4d0c0c09463852615218516f4a6debfdb46273b283382cd9ca744abf9fd439194b8cf1bdbb3175ca9c57a1c373c41fce92bd5fc012b19a0698aef37baf806ae09add8cb972a9ef9a7a5a9b1fd9a41d854c30cca1396140e20c2b98654fe6e511b626a43915b22fb2dad747ba7fe7460d8cebb2006fea19b3284b09c06a6f52f179a32beb56357b929a659f0fe6a26b697033def58ba603f430f74aa35070981db74ccf19190a1fb05144ec0a09a51e54765069730b09a7a2331ffb3de2a7e02c5e184da4013dfe937c371117524f7b210ba60e2692dcdcef36ab227b4c4f02a9f488972b847f0d6b59d02ee54fede8821db6cf731cc8ac895350ac5cd4d6baa3ad036f06f20d10a140c4ad3d10ca985532e3160462773385a2eb5e464d528e1e59c29f66b3de59e9ea28af3f97bfc5589035752a5a5523decd2dff01fc00ff31b30152ff5dafa331c6ab15873af41aa960aace7d2cb4f95c23df44b9e6c6e2f86788a872fd3a5cbe4acc95810daa09dcc1df933465ef040c53d9d959f9dad
+SIG: 3da8d14dc4e71fe6c32ede463788e41b826b4e2160ba10c95f1c8a2749aad8f12e98ae2468303baf6908bdb35ef38a5ecd77741e72ee3a427fd904dae66fcf03
+
+TST: 828
+SK:  4e57f0311fff0e5d538849b1216f695b1a5277941708204db2f0c15b3c73c82a
+PK:  e3371fe236ad2f6f42f9e1fa4e1eda2c3e29c36c8ad2218a3c037982f0b579ec
+MSG: 052a1f41ebfd4bf65efb0ec8e74dd7b3065e9c482c49b99262e6dfa8407d9e31ed34d229ba41fc49a94a1309f990a99cb9902fb84f4ede91bb64714564a913d574d4a3c286f0a192a78ce2d55aae5c9fb057ff36120018b2a8b54d98085537ea64aea999d5321c7880b36ab43018ea2c92a5e68350d3de8526e2c8bc9141f4349a18a34f21de0abbf2930987567f0aaf8eb19145580d71306ce8a69e79f8eea26cfa0b8beb49cc5aa2bc77b797d4f8d50326ffb937399e94fdec85e192f1272a80e9a0ebbaf5d01f1b97060802bd4af34c0f7d7e98543f9d66d60e0e6bc0bf9c990be31eea1978ffd16733a8abe49558b3add0dce6defd64dc043f1519b1e9be66e06e41ecab168c8339a85e0b913818644ea7c5334468fd7196a01e1d4ce8dd1e7ee313dd5350b8dce4f5d7a6ac09857c4d3d0f10a3d9062609754592ad1077b2e2096fc9e5b1978c98b5660ddf51b46ede9f9dcd41b2ef44e79f6daff7d3626870e2243cafb2f4367939109ed9c01484b79eaa30a1891ea18f984e161dcdd1bda37134bf6735d2b2149b4898dacbfda61e6002d72a6fc5d21f1098213231132d56df68d6a9bfdf4eddc0524db8fd8f248852049a6825a5edd2360c009af24f0a94c5079ddf6fe796945ff984aac36411ce80d987c6ed67b6b0ddb6d417f6e809991e729d147dd0d21a093241363cf4ef3b8e3ba02d486633b6b217f5493e2e432b8c2e27d00c5b56c9b65f9aed49ce93d77e7d0bf5f92f92f5bb4b595d66f887a4880133f970463ab8b7f3d8c794c0406e88e3eab9ae65f1a185d6e39e2dd6abb8a93d2ac4b9208398dab89dbc07a41a50264026412da022b58f489d4dba31fb882fecb1ff8ca1820dda1865af1551e46cd618b44c4e6eb3037a9333fdccef4b895189e4390e93145d264ca5f45202a3eb2853593feed6c66dbb288ff3a3c0fa832b2aa7e529b5568897b3149402a907e741e1011ce0731c915f91446aa0d5caf0595f1816434fa4576db3bc31e10cc2af33f613f03ca7b9491a0a340525271ab537f62a11a84da01c7f5581ad5738c372b5335bab9b2b9dc2fe91e933304d9401ba8e1ce8dc55c4fb466b3a8ed7f53a122b8381d8f29047d7264d06fb51ec3e70071f2736a4e7e1537a52fa256a04ee86fad27ad2d28a9b3629
+SIG: 4fdc7b6e2827f64ba3c033c7fb6d1b35dd680f532999a0d77aeb276c31bd9e39c670978be47243c113223a57aa10233150678b40db78591c04d08df57a70a209
+
+TST: 829
+SK:  39f0556b1c5dcab387104181bb304de0cf815920b972e871d5f0fb416d8e616a
+PK:  d85fb76e78c3d5bb7ca6b05b310191821a4a7d2d9bdf02292cc7aea5642e4819
+MSG: a8d034e170fc22b57a44aa6269ed1f01cba801f398df1adfe7df044d5fa468bbfa8af4749ab50d24d62e313ac0e73a64b4282b74626af2b4a4b54c274e5a6bc280b6dc25dcfe07814c9c816d2f9e36c05b9bfedff7c6b03cddebd4735e0993d3c3fdc6540443c6005e900b4035e1408a85016aa1b89202990e5d84ed9981c29b77206d7c113052a2029812c6ea13aae8be0aca7a3306bf617242298e68becd0d5d16c8887fd1950b7785a46bb022b39f7607cd8913718b3017fc3f86d6933f75eec5191ad1f1989a8d261786f56be4a988370db82961a9fcc953542e51c2e086db0e02b4fc346694abd9059d5b11722647669e7f17b745a60b02f7339fcc99bc35d59fd0b98b60c314abd4bf8aa4b7eae09dd0097acb9189f02cf85a251ac92aaf691b15cd4a33b58d7663abd0b0444333044af5ce20fd71cbaffc0d29835819f49293fc26e7f9787fc368c4d35cae92747f21ca1f3efd87a0d8104199416482d07bfec1281c66f565285bf672d5e7486400660c017555e9fa2bf6a4e7027f0e7e5f443ed658b75b590612abde0d80d1a26cb8bde76b996eff6a74e3dafc59eb1b584f4597a239cd839fa1f1b7bda1a24d150c4e24b91cec01ee53a3ac852a912de195a3c29dd7079aa7e88aa81e9d31b8fccd435eda113c3f82458b7f7933572b776753c92240cc036158a4ba0e56efed53ecb53fc093fead14343485ae5d9105bb163f262514e48be74159c9fabcb71d1a4280d9ed70d7e42b75f7fdadd02d69198f5f465bf604cb4254417bac3714b3a99e6f1acec9e3b3d097f972fbc36f2eda3926d56112d4e9097d89bdc35937b9a3158e7cdd5da401e180d3ede6b1ff02864192eb729781534f4964ddf2af11800d8b5b6d01b209aa3369366c19a28c79a87d2174ec22fb1489a6755c348a996d0aa56e0f60d58e26befa23a86bef4e3529512e30a9d1c5e4885018cb97aeb7c93c5c41caa34236575c226f3b235eddba364e285b6e352707bbb3b339bbf2a63a9cb9bd333a77e79bd58a48e14ce5886ed0cd07c2d165a81b5e6a31a8ae7806bcf2e0c4ec29a967725e577f1741ee68f345f5f7ab0fad31c8b4b18b431c4977d5c584004b45f7cd1961affe8738e24c382610efe998353d7ebaf919b279bbb691c3052b8b2c5f09808ef3a6
+SIG: 0166afed5a8f7c3f7ad6f3fdd2938eff00898eab815c5455ac90fb51f6e1854f0c0753194b7629594cc1271b003431221c574b0c0d19082feeda51b084ae5e03
+
+TST: 830
+SK:  bab3ff7a4448d8a03d8acfdb913f77fe77804395c3e54ec235117927e32b50d5
+PK:  54975e35e5b1d0323f2d6fb5c6158bf6654b084f76bbdcfd72349229e8e4a6e8
+MSG: b647b67cf01c2cacc39de5969e199be6d9320167a4cebbf1625950b1e6b7adf5ca24d1349568865fbbfd90f513f05f79f70a63a23873dc7a195d4b285a08f30ee061d0b8e6b4d6bf9b2ecf2c69f3d5a07a6730537cca4a4e4c7ee684702bff883fab8bcaf89311c5498bccb5a0f7c8d49b54f482fffbca6e7da262452ba59a57a6879d81b73cd7adf72a3be28a373cd63310408461c21b907f63e086b292ff02833e8a2f46adbd671d02b03a69aca2e11d287c522a954520442ecefaa905dbfcc8254c58c3954a89bf56cbe01ad5631971eb39eb432a854e691929df7e48b900ca6e740accf578b31795b49a6ca774bd8b993106a9c4948c18714948315990a5f191692420f289328ab713ec19b7ea894d16e6476100871cf3168e4f935b5505d1ed5b0aa29be36fa3a346ac3e76f143c46ca69123b79c36399a0d2ed302772494adf442bbafbc4d01532692c7859df04d2ca78ba55d77fdf3e5ad993786a24cff2199bb49387873cc414b4cf1137abb7e94ae3ddbf97f534a18fc5ae58523a3cc52283dc7b016f31cd6557981c5076c774f303a47c427870e207ed8bd66640ff092db503fa124bfdcf020051dadd106dd245840b31910b8a9060d5986f02b60aa5e33b4d7550912cdc5776c772aac93ae19c73b7ecfca389e627681a8781eb47d84e93460ba891d3ff6eadf8f2a903c383474beaa42b90e032236dcd898d02a40efb44e47ead52b75b09c7da1cd6a2dfd4d1c0452de69f6acac1a68dd78daf972ae260821e2ec522fb5749bebe0adb452bfa4faa1e97911c1299f16568d68eef405f4b1cdacabed59f7b0fbceab719a34b299f58a4ae8154f98f4d9f4f140b1f085006946725e7c29bb0bc6ccf2534497c61d4c1612624a61d70d26c3efb7d7c351848657f7f8eebf8b990747740e6f910c97cef150375765c8c0b3b449c0d09d66f008e67cfa76ea2b6808b6fe632eafe0587f37e36be98dcb17a3f4a15b65a9f6fcf9642b52522077b1fb4cc3c08df4b467ca716db16b737f782cdf387170a5f1f6a7ae0ab3f5b7c585e3b0655a6456a503595ce8eaea2537855e7f0d5061bc29b4e67daa82463c190e9fddd52f8322ddb4e0f26b68778228eb57e1a185b7025da14987d44baa767b22ee7f4c84591032e88ec12eb8c5a4b9e157ec
+SIG: d6b4135fc7acb3d7cdf987896d91b8a90db584d8933a6f3029e3261ec1c390cbacfaafeff443b6da4fdb1d84c64a54560feffa2f1c7a91bde9730222923b6703
+
+TST: 831
+SK:  486c7b436c1d43d6b703512283c166dc863e5a33802f4ea65fc738778902d014
+PK:  b5dc947d64337cae82122bd68cc80840596de3be56cbd0c833af3faa3adc3776
+MSG: af036053672dcf3aa26e28ec6aa642ce284b896c69887dfdcf0824515eb0848d9d970ca272df77a86b3ff6ddaf3cbadd3ab6283bc37cdf7a5607d5dfc7cf96329299cc53edbbe657fdfa2ca24467050a0aeb8cffd7d33d543ec2c191cc0bce89ac37d33293b1888ccb76c28adc671a4935a846d907e4add0110febbee5aec80f9d2ff74e2af4fdbebbcf49105a6469d7380006b2ca44364814454e445e36dc0012f339c96854f836442a05a50bec907327f74ba9f6fd790ff0ad3783d297bdcca76460783703eb5f2b1f51b0a740ce7a8f00a387e3636270a971fa8f15b4496730d88add807a7f7e987cd41595a2e7435df5195576a35f5e91b2fcfac94ed5d77663783b61e6671d34838b6b5644fbc1c539fe159b7792db967e8352618ddaca0cde73437b59e7801b49eb4609b10577ca2692dd6f9d5e9d4b5e5e62c5913e7b87e6b347be6153b17199c916a13f8a885b378ef09e13cae4d8b079d7d5cb9094199b0f20533c90083bc3acb2667697eed22e3670abb4a553e995c9dd9594e592391a0004b6556544f35612c4971359577c476382ca53b3f262a5e33ed26eec809f4fdba4898a113675cb6af717db62579f3980b21463be029cb4160fe5d257c46cd6664f9861ac50fe05c144057dce2f8df1532aa7af589f41270601cef06bbe4f35c31c782bb3cfff7d5ab64a14ec417361f1d32cbd38b6bd0e02505d1416302b8505ae2a96e8d5339c346c2b0662d350259c50c5e48795914e6f88e97c811c393bdf9aec7ef82047ca28ee971c175c27e36e109727960ddf1a1b976ab44f4851607bd966808ac46d54003128297f5f4487108d6a02e7a16413d2b75ecb42fddfb669c801d23de50a6f7bf658f753c6b2b3b47c0640105d0a801b32a1943cdc15c886555eb75bb7927b93c35c5be1f98b196caac2dad991b1044ea863944d54d883abc3c6de66ed868ee84bcf9c34ccdb80fcd9cc0402747732cd630bbfa3bbe8b038dc1dbdaf436d9ac00c02d528ece2e791ee312a868feb2f587ca44db5731384fa1831142061b2ead2b80c66bd2fa5dccabe6a25f2a493feaacd231d2f409646b942a578545ea4feea9a73473f79dcf13e0c9f1b49fd8912ec487328045bd0fa228922ee6e973e61f6e93365296578dcc21c361479ee2d24879f2e9b
+SIG: 31f95cbb7463b87528654227bb1397bf1065b4f576808078207dfaf06d124b41f4c318f4a9315a66085b9e568a71e414ed9414517310c699946db0c976285207
+
+TST: 832
+SK:  a6e6ad2c379c6fccadb4a49b232a9142618ea30103c33c226ff628bcfd81f426
+PK:  f7c4323f5c419d9b3f34a8eb42ae7f1faa2333079030c5d64f9ffb1e9b16002d
+MSG: 2e857676a5bb1c6e9e94507f83c60a67f547c5de9e94566b197a6af6cf4752e93dbdef6b9f66d1febd957e42a7f5ad64ef1dbcc4fe69ae9525d1a4de67054c88f29c0647bacf8b82f321ff99fe9eedc992ed34c1177fc5421227ccac10feb9ced4082f5658da63714723979737e7dcbfe2e8b5d50f91dfca83e7f95f35d1ad8dd51144502f3df672432611f0e766a90dcc2a5739c805d95fe5b041de9d7fb47b4404afc803a3bd4804c7817ebc5bdfef8add9e250b50966ca8939b22b3c6ff936eaa659a240c0c848b810acecf6181e0e4db8e4cf8fcce7de559cbe8afa9db8499570911a3887e850e509cdb70debc3477d12175014f79f81ba113d0b7b335118f85cf59996f806758eb903cc450f52fee102efc01441e9ae5fae74c231dfd85eb6bad17d6b70e938584facb2172cb03bd5ea07b7f0d371ffa351c0ee4efe9ba4a3fd543874655e7d39c53ae86329802e5c385e9283a2973cab8cf7ac7ff0f91d1d48b58abfdad658d812f07881676bd226bfe957d7df30c4130a448354a6b94405a411650a9c8fc851155ec5a8a3e3b67ae0c4b5cb89bb73fc82974be62da73f0e23092937d405ba4af6cab9465ea43a6253f4457082a06ac12b75e88ec684487f9076373fab8892859d8e8ba431423aa805a220cbfda431b32b1e03121f7fd4de18591f2505cc0f5b2b1a7605fbcc63757b07e299fef5a2b7365230c2e92a25962c2e8012ad3fa9ee94882709625ba68c7b213664ae2532b609d7c9aa0e83d493dbce7632f35580e06d3111ced320dd0190441f62d9e35f50de59c272fb00f568a00b0746c33a9bd2490c074b91cddc487ef2e45a0f030e08fdc1817bca8a9ce29d29279e755debc28dfadc3c4d1b458486e3c8d0c4318e7e6f9eb5a3653b3f7c49507077cd5eb81f10b88107cc0f9316932abe9b64e8886d06856a85be63b0c2b475c0afcb0694426860fb24b5c17ab6ab7733d5e641be74fd5f6a1ff18d2f9a42770fb30750f56f4854e38d58aef18a2a61cbfb49ee576ed97737bc28df3268a334175513d97af009cbbcfdfad5039d69bb46f708867d9b3ce0bf2f569e3cfbcf6136f8870d25208b21a3edcb73393dfcd4172c1402c41f36e3f82a4ea6dcd891686ba66e14320aa0e22ba0c1ef033d662cdb860cdfa3a40f6cc532a08
+SIG: 07d9fc244fdab00159ebecc5a00883453f08310171769d297001e877010e3eced9fb60ec91cb4d88e7ba40c530b1f9237978ccd96d5cba9e4fa27e2a0ad9d60c
+
+TST: 833
+SK:  9b6d7e28eb051597324dceb7a18941246725e88d53ab2c34771105330cf1f4ae
+PK:  8872a50b5fe362f8ead1d40e2045f0d40b2e7b50b59d8090bc47ad68ebee09ed
+MSG: d1e1987bff65f62ad67624c6657924f5d673b7824ebe404026c0562ded3143440be637f98c9e01a6afdfa9a47dd49c7cba6e3fd23e4552f7632b14380b27cd3e9606cce350f152ab126bead0a5d3bce4d42092d934c8ca337e987e11d86cfbfbd2acc3223bd16744a927728f485372175cc694df30a73f9d33765ff014ef008d5863210338cc3482cc27ea317eec921b0c568c38ab27c4a564e802b1b94668c651e20a0b55f3a79d215fc3a0d04904010932c4cc68c2a9e7d00e5d38d82df55206bab95cf697bebc7206eedef6fd18d9a20c2cbb285b00efa769a08dab2b3abadf00d198b4f192dd44bcb91431823ae6fdf98458eca39cd29263f0999303e70dc694fe01c53a11c1d1c34c1ee5068a201dbe7e1008d764358968b402aa398549507f7bd1850800e411b1c4e28ddc04a859e179be8ad7e6670e509db027ad7e517e4425954f5a807414a6da267a764e712a998465064982d851a265ea3c4dfb74f992a7cccd9a82687fa61c322c4f589e86b8825213bfa951dae6af354ace18f073995adc95839dac0165511d61753791a53e48e3a8273d44823d2596f2a2db2e5f1ae597221ba7f3ebaf4a7b2888395002bdaff51fa54bfb979de1031404ca7789fe095d4d17f07a35556b10fe8e1417c8a6a631c2ed36cb7a0e6181776289c344814d42131a73b12faa35d77814c681a601374ba71cb9ad5315fad42d3acfc7c1d628810256daf7d8c3c9a2e5bdcfb770082fa638168958523a1c3b035dbc6d5adf26df89a7ccabed3e7dd377c16da841f13c6894d43cebb4e39022f1ccec2274445c78b3adc7bbf70d890b80236cc4468f9569c59a7e33b570e670380d244e4e310e11c392f1e334054b92c8386c161ce04109b037bd628d919dcb62da1435bf94e88b0a8846d486d16778f7a3b880e660f441fdf86e56b8aa0661f55aaece27f9ddaa0e2a22c215b040539726b9853915a1592dffeae32d7b5b67eb6205bb0bd7279f788d5f833c4066780ca0a42d3e4e1aa22bd06bb5eed89b9413771ecab644ca72d1291d00f740901a7311dc036715d23ebd9a59891628f0d87ed489502f06d75bbd11cd1602a35ee7e13335d6a144b08830e669c02e652f3f100d393ef9b4ac05321439bce6ce36ffc5abca890b8796ccb5e16303559c5d9117f0f31d
+SIG: c6dc5ca1e8560015b493afe2666ccf6fefa803d8526c837fe7f123c7991427ab030d7c770e45f6de8481523b94ece97f3f161cf5b8c7aea39f5ad826bf8d0a02
+
+TST: 834
+SK:  7009edd0795096edc4fed55a17ccf484131e608c6d5d6696bf3376e26924959b
+PK:  77574bf069527145e72d3e85ce7d4fcd671a33e0a71e6bf0da7ea471dd6e86a4
+MSG: b12c12470539547c2de6bc4eeac7b63e508ed710f35637d9fdd2dcca322a7a5071dab2b2845e30792806035c9fcdafe2783e3b677d6be5aac70b33910a2b95e8b5d59bda615935a417b7ae19a7853774e89a12aa547b4192979a01ef6ef32a40de79d680057a83a074617ca6501f59e73564927c38b58c19585a2c03659c026e4de3806d6c1ca8958dee47bcb889e76d2c3a9ab5b8b6afb2e842298056567bf9b58957415483336233ef4920fa57f496e1f0348cca20366496fab3a75bf4214ece47a45feaa1392db3f254d96a7f37402c9811140d7358b4ef8f20a298eeef904e37d68f378d33cb96d00c03109fc83fd06a876c92482f61ab7914eb7c2e5e84066e0e91e21e42e9be23df12b5c747973cb86442c32291d3d1ae719b36a62faf3abaa2053a313f625d85c51a5198571915ef8a2b199ba37d25884575ba1b72844cab4328b57fab1ec974ee8ea1df7ca9c78a4d3a03bcb0ab4169bf06a3a438d9566c6c501d8d9ccccb1ac26b4da4ae1a9d8e8b9df662821ad975c9b015fe26f6898d22ab912f0e405a5b27cfd39d657dcd92cdebe6791902713484406dddce71188731e44319381af27daf76792273b8c35251d11b836afe8b3ce9b40273f6915ebe6bc95a75bb941a429209867fba8764bf6c40db6eecb4f21747837cf6ae7fbfe36d5023df7fce2c0c3c57af2898885313c5c4bda35c7da6cb29932fb1991f62bbb080b32e2050619311ae69abb3022d913fa9eabd5d5cb4dc54d75dca638cda9af331c0cf4d2007b6ca39f655a61c01039f12a4b9782bc39aec4d22ef0093388dd7d5b56dfb8a7f9d8669004e2878dd8a6d76857c0845245068fee1c5319631e78d3785165c70afd65299301378551ebf613584c6a7620a0e3b6779f38c0940062497008eb233870868c21cccac239501b63b749a85602c28a095cafc749b0511a6c878edb3b780ea174d07b121e315a826dda6ec8dc54363e2cd2e6305a194825c0ea90efd7a9fd89cd97b99c4300bd3bf9353d82fbcceea71b4ee3f1aae9539b4cce90ca477597c174ef20f4b9f4e62d09a570d3135aabee9551fa60983958c0b7b8c3744553ee14e7f3cd103a19251c99bf6384abb60a76afc6658b80dfc5110adc4c732fe0ee32933fb284828e008887aef80f6f813340446c0217c12ee
+SIG: b701b8f9a434e06d719ad25dcc54060c7986647f44f3884bcb6e5ee1d7a446cc265cec029b537da7f2523326558ac9ba34f4cc2a97cca3452e70562e7a8f5504
+
+TST: 835
+SK:  12fe8e5ce20cafaa3279da7b34aa87752ead679f156128aaefb4afa5db4f2a6f
+PK:  e77f44206bb0c4c59a2870cfc2ecac63362deecbe8115de5cb1afc2d9a3d47f1
+MSG: 6b80cc6fbbd332f8c6197cdf2e6dc19a2130faa2ec938ef558b884ba4fa5e113e5b3e4b1aaf51b695f13effe13f77d39cab3c07d04d66d430d9974b1da3d39df1278c00d6bcbfd4bae75b8c076404dbbb83448fb493df67000f97d247e8f23dc081fce992b65a21b35d7bd7fa7dccc54a560afd14b1ec436c10946f6aa59eae1be3ecf311def51e46b6b4d1d080d1784b2334b80cfba72cd931f55ecd298b05dc836ab12d0ad8b5d6e9b1e3cea3d843368eef19f5c14c6bbad9414cc7a4db6a726e4fcaed44440a019fe12a60573403c0e662dc902d1c873ff30c931ba7e43a3b3bf71d5b094ea504971647ca94356f0a53e444b4c008ee5977204221b400deec37fc273452545f8f218be988725bc38c85df212ea73dc0bc7cbbac907982fefad680fbd975c2093a7fe8e6b37c1cced87f81daa57291a5a18476d11a18ec4b5cbce5d55ac9b624b048430f254f671078506e6989df7c09256525039085ab7c130c240004abbb3af6b481cc1a0617e57e388ee4b1f052f34a003fe6bb202cb87d2741bd8e3454ca73d2f612011ecc74d88343510a63c9313ddc36c25d3fb03e188f560bd029c801585ce552988dc55b7d8522a3396c01d5e715ae26c622c64fed5b98e9c559e4aa78d1ed3b7b890d477ec8c50a0ff107a3f83b07bd35e9ce9a08bcfc0f168eec7aa311f71c66a71ceb9d5a2199a14be36865ca8d07e186b1392b9290c578004d584f191c82a53d850890bcc0d12dff840e043dddc2e670c836020924f58c044b218763ca61982bc332d247b2a008ab570b6565a06892a26cfb0853d79da28ef8b910a9329544b792ae4456ba7765066b9d1b4a300210448660ae48b504441017cddd1f6f00938b1072c8ab824adfe8ae34923c82eec754bee1a6550ab1d3da086e3aebbf21169c44469e03bbae0d72ce863457784cfe1dfc276f1afad9ee53ebab5a3c6572eb1cae099a4a5fe19319290e6a1b8b0e7541ed735b3f21b1e2c7509f87fd1fed00007479b3c1bb78432466302d246d8d031996307260a0c41a0e3ecd1e7fd834dac11a13eb036b39c369966fdef394c183e54e7b0cb3d0ceb198bd0e66c00d38db703aace30cbbdab369dfd1d9e514d0968f100c9f07c315089adb3ad02e59c04b9be46e99fbf5a62c6bbecdff5b381e55127824ddb18
+SIG: 04eaf900966e0992d36e3c220a4bd4d82bcc6eb998ed051dbcb9160bcd357409736bcff7e6630e96f5538aeca6ab8b0d0bd82c0cd7c4549917febb9cbada080c
+
+TST: 836
+SK:  ee9b6c2e0c9b01472ce32d54d1762ab0303317d76d3aa78f5e08a9024ca1e083
+PK:  016df0f717bcb7adf626958d83bf8aa325c70518c68bc7efd84253b75db08788
+MSG: 772cc25c3b69bb3ff5655664efa478ac414adfaea70ac4a2a887ed3968c54d34dbf1be32cc9a9b5420a4ad3c9a877bc8ccec94ad473aa7a3c7de08a0fdb5ed1e89872be78170be221d279776bbc6ed9c5a67168980d5eaf895e1340f5dfaa3df622d6544b399d74945fd13bb1173621e0561514640137aa7bc9cb7debeff2c626977d447263b7e57d43d69efb230cd25865e4d924828f5e36f964e403e3493f30d6dfea6ca3b781075b5e3b25c05ac50e555f15ba12b0e059bff996484129db6eafd88993d6f0b7ecd15dce2fc99f8b8e43516352ddb461a04b9ff3486452e6aa6a54b2d1062a7714250cd2a88ff6c4c17b6cc6652d8c5ac27d4443aebf3d5fbaaee4521ec76f0413db64421ec8d6949626725fe56160ab307c0e73906c45155efabb47222021f220d32bd3db0712abde2599ea4ff799717811dcdf8182df6716d2a038aee15d778da55ac20f01f25309cead5b5b7b22322e1828ea7c91ae666f2dcd684073148e31bb2247d5f93506ea8085227adc9ae1982e950f006a9da158b9cecff8929761c84f9d976fdcd317ffed36cbf6acda3e50c9b73bd2c8085409d119b64ced7349a2674262a832becb03c2edccac0ec54124e82f810181792da49ea10bd941f9895a06959fde0d3b0ae84c39df05390ab33c36c79ca22e6594d7fc6e3f86922d78eb7f5c25495d822a3b41051b24e57a76fcfc165cde6d096cc7b7e9d055fe864d52942d629a8ac261be1dcd3a21f895f49b67ee47eab7cf1644d571d5ff38c179f5c6a54a3612fb34753412a1b95bf62ff3179804ffbb99051f2b080563a4ae0f27cf996ea8be3bae0a4339dccdff6b6671559266eaff4eff682b8dee89c9d2d45acdbec4aa6cecdbdb1d284609e65efb77bb8f1a51fc4d4568a705fb9c97b2303c1467dff8c8c5ee27559b93ad1c5b9c5c6c7c529fa8c55c75ebb59b2a818aa9bda1e9e79bc66029772f8aea11badd3226565d54fd01bda8cb270e70dc9339b46900b5818e932075be6c28e73a191d02cbdc7454be12387b0d47a1ab14232d2342a6f1518ea97098b815a1ca3f9c70b25722b1bcd7dacda635622fc8e72959f57f767ea563da4c158eef7200109f61416c2e70439923062437b1d082a8c7f4394713c1b7ba0587b841c114475ee3ff059df8cfa12a321d901cb47f5
+SIG: 4b001d9642835d72138d680198e6af70b5de7af015131ea726f4e51b5e8b6d48c2a6ca8e8709cc8222a5047c09a66e518ac5e8b6e53548948261f0701f687308
+
+TST: 837
+SK:  a3d23505d07c5f937f13639dbd818e85145234ee7017ecee8636c7ba76ebef5b
+PK:  fd7fdb3d022ba36eadfed0daaae5bff04505403f171473e4d361ee8d150a0eb4
+MSG: bc298ed69892904028725e21b114462d89d8c006dc884b178756838af4954ff0f1b79517307a258a0e7681e879ac47d7920230b0cc1d66171eb214d77cd97f617c405e6c2172fc589f1625cc5e1b593110531f6eb53f1e6f486d1964612447750a041fe51b332eb3fbc711616ce35f040442b43163b80b751e21ec1245f12e4883c79d3b413282c69bfc6a465d1e7896bab038dc89b4cfc032fccdfc87b07f06110e1f506acca8157a322543bf1ed8906727f28d0d689bcd7dd3df85935204a904ab3f7a0d99c16e5a542cc2bcdebf5b502dbabe33b972480e02e71a438a1980a8766f108bd8ad51104223994d9bfb3c3a4b7a59238ce2ef7d7288383ffbf291e1602b384af60700d7daf0e8fe60f8caede43db06b3f4c8cfff749aeafa46fc61c49b2d5a41204cf86f049254d809e9498aa9d4cfdb94acb2babfcf786ddfb03691516b3838b0d4f201cb2591edbb0b0f674e1e2820316b72e81b48cc5a6b29338bc36681f8f7dca43ee6c0bd2e402afbf967797516453bc01be86bf42299d1b736a0d97bbc922f5a78af2df42e6f8c28e953f2ceadaffc5e93064041e425ad6975f88c7aadf81c368691a581e885f2a6ba72ed68b8fefbcd6ce368626d44892a20270b5f709c2e34b8335d42eebd67a24df73f45455c41944187b6692f054b2fc9591373f19fc71aa7fa27df6006a1d549bbfae7d3c3eb36e5ab2aaa10aa5538da7ef36c8ff354b6058134004d660a4036321caad00a30b1c498ba3d808c4405ef79618fc2212a7b83396a3d7cedceb863c66374dc469ae183c7ed74b3e70d6374a062de0379b21cf25d3c4c5762115cdfe755545e89ad4052bb0279d938e90de3abf504410caad72b7c29f53d01d9dd7f2ec5e459a04592bdd66416613e6edd004569e0e6c98827b8c1d7002a6d1bf303e18259501dd89f6ee94766d18af810463eb13b2efddf1723af735a88716e1fcb4b7b43cb97e1cc903b2408ef453ada4164786f00845fbfa1ffca5cc3e1c4bd9940e7d99aef919166d058b51453c9c14fb9f3251ec5fe4f153c70a4492dc3496296186f23ad47ebad13c66e68727ce50ba9487f1801890b693efebfc37bb5d95f8af548ec8d6498289e55f9883fc5be84c256d2bc5484938c709820d9b6b8059c0aa4267dde69078e487c8865c0b130a0ca8ca
+SIG: 67a667ee0d6254ca0a8f212582c0cb8b6ed97cc967db021296ad6aa99f0ad3a944978cfdaff13fe5f8c6e88cbd831a5473d0742e3734b3e2df00ff3240a5de02
+
+TST: 838
+SK:  6e265105ee7171d1bd793effd87d1e2c79450d5e188b57be3aa162e2a52528ad
+PK:  1f403c7a755031c13ca63af57635dc6e2c4f23bd6b1d67ca65da68b09943c554
+MSG: f8b9d4b027ebb10ee511819e6e56fb1ba9584018418d82885a38a449086007b8785b5105caf782bf9b36da039cc60e227c7e1614f29b640b1e9b22747eea7a6725614e89e0783ebebbb7ee557ef36b2b46cf6461e5be2ad1d7a7c2711a475ca4fbc33092ba425667e34d090060518f2fec636b049123876ab21c8bd9c50dccb984ca011a02eea020564fa821fc362bfe392aab50c273fc7b5a042188e331621b9d2f743e5c8cf3ab1faffafe2a0004c8ef7cdf5e6dbb5eb544e4289f71a6fd15c638ce29d28efb9c039e477429a3497a83827e76ce77a49816d90b41a8e152f37a09e6340dfe069a4ac6f27dd2eac747fd21e3152088c1b1ecd32ac679927490750488c291785147b63b0b8ff11d189b9049b8a396b6932f85bd6a15eff9f0ce1808411af0f9c8e6e97b814f110bd4df1386a9797dc511f0aab6ab65071d9ea836532cec51b92ca7fbdb8de1c8436658de2eb65edd86044f6c1aba3178647ad678612ee74f046ca3c7fe2f39c09dd2e07df2b4227085fe936e794d22fd5f40a25f08771580ac801d9889f5a76aeae1f0cc4a9e1edbdda3750c74c850524b32f44933fd883b5372bfb7e761e069fe7c1c0e7fbd4a7f58467ea6883f9d5b7f66d386b0499bb6fb5ead89c9a1fd2cceb973e2879b5d03eaa452e16022d59617daa0486f4d4c117807fda8499dfb7a286fd2f71a8eb5fe64065c41e4e1e2362ab4e477969e3a408a247e3a56fc86f2b01ef8d3cdda87258234bc7f25b66907f364b37b6245296c4fdf499f20237f4864852fc5d8cd5d05418be8b13859ee9a43e17e1f57a4c35ea282ed68ebcda6828174245a49c6cb6590eb1f2dcfb007bfa1c32077956da9acbe3ef0723799fdb869d8de30706a9c026814d16a01e033c91b59070dfe445c5b848a516612e5131fe8486921e36b8e7ef157a88822886c681b5da71fea94d957dafec26f4147a3b2ac383a5f47c8585eb17a8ac65790641b4218d755f8bea4d97ae2a45bdcdc23236294d852c95d08406d2e9bd30c326452538c1f5e5004d4a1a82720da32e59dc3ab18ea08a058f791d24418556086c1e4edce8982aa23b118fb266e60b542780a6933add913265512c07b114978d44af73b2030ec47b06fd09dda8c4f1d4e313775468c451f9ee611e9cd4c0845c2501948a7b14ef1d4b5cf
+SIG: b5a83a117a60345a67e4a665f37de722a6ec03913829389959f376ee626477e654ac8d720fc727d4bb8fe1544f5d0b0b850514290b24273c4cd4b73aca4a5300
+
+TST: 839
+SK:  c4370d2aaf35acd158fc0d1622a399c99f41b9da4e970b354e5ba05cbe844ca8
+PK:  3545d7d4c95c3db6a54530537afafa4d86ddecf9cc7e66c319ba9f7dd7d07ee7
+MSG: 619f57de2b1dbaee209a825d8ca97f84ee49eb12a0b13dcdd2b3a4ee45e0176d474cf09460c831a8ae1d3f39beebd08808b3ed1761213ba953421860cc07e2db312e680df03e60a6870264abca8fd51301e1c1562023d802ccd5c7d196db39fbb8304b0e59e333164192ecc333387eef69c7a78a5d11258862d6c281b19c0bd336cd3edb2f9faad4021ac2f205c16814b38548433ff9eddfd61133779769dc69afac658afc1d1b416d390ad5b45a1ad5cc4b00b4b278fbe4b59d52e61a6a5fd00241c6cbc382d2d621a3ded002019b330560e361faab28f41d1af9c9c0020f2baf99e8d8ee58e3122202147c0adc57d670c5b380af594cc7ed57b87ec6674ab63f3a9849753b9462aab5de88c948a8b109af4d4954927aac58bee953be0d8d7d71aa11d11f1a87b1477b9170bd735cfc2449f051b82bc59b0bee76a172e8d32670f51ddddb804ad110a565e384cdb76fad04cff67893091e41e69cfdf70ea926c26369a5b6193b19ab0a62558da55ffafeb8789757710644aa19f474be4ada9dc1849b07d5e17b85f921e1016a54aa6095777253a73426fc7864b9955f04907023db207f85dd21a65106cf0d622385870c34c2da9a11e4726395121e4a6761fb522229d9e5cc9dab35aeb87d0d79693c006fde1cfaf116208bba962059cfc0d2d6370aac7748362ee6a0a3ca7bf133ebcfa20f1c4ed8307f800cca7e6c4beaa3fb2ab086125364285c44ed1a737a67cbf3b763c9f8b1427e89dfa96d290e9d4842fe6316afef834cd8cd1fdc1f124ca3fe26266da62e275c0bf7fcc8e5f9bba6c0d38e23fafab1e049481794c14f4a8c53be1c96f769c9b13eaca39a0e49366d2c9ffe8f206360a9d503dec598621112e3776713e7fc0649433e257e503a546059a989da89157d76476005fd90e4b07aaf0db0bc0bc0b67db8dcbadff39374e1afae551634e0e32831ad0e5fa7d5216fa7c644f73e1e8e07238394a416c169aa9d5303f469a5d4074308721ffddeff6559e5adf0c2773b3f5264e7aaa8c2db888e28e815c71069c3b4ce6c29034c0ab3b5c19a80a9d8c2e874813531c422752ad62b3c5a1a3d6c5a5db587270693aa75d5f172eeddf4eb839bd793affb1c796a1df0e442ddf99b780aa41eea0fe6f865bb539ca53aa45db9a856cb75d0151d35edea80f2946d
+SIG: 9febab5ae161d692a6a394500a2890d21c7f0ee26f4640aaba4fe66b90b89edcb80ea4cdcabb4d2c3a5c4154e8ff20d0e237fefd00c7ba9782e1748f6488ac01
+
+TST: 840
+SK:  bd3de1a1d164bd6e9be0a6d107f703a6dd914c8667cd341d139f19578d933b16
+PK:  9b024964bdfa852eb2d4144f35b7cdc26781143c2bd7f660233f8b8aa36071ee
+MSG: 1769fcdbf51247ed4c83a00bbbf02f4428da6fceddd0161a02fccd1500970665e1c7630ad22e3d9749c792e71a260cfff6053256e02f5b47bba14b761ae53ca7219ed2801d2d788e26419f36c81ef92c2303683735c8a1756adab6a487923153e435603c96b239553edfdeb093298f7ae7dc90f16a7e5664b9e4c02ba731a23cf2234e250ac9742633a932a948bb83dc3d794d059fedf4ec8618c7433c5d8fe5e62cf07b5768c4d9b261c71536804fe2e7ca7098876521d57677361424e47f1b959237f90710421f5bc4f109f7d489c755e94eefdfb3c85b90ec013181a23bb9535feea4941d0a06a540bd6b588e55b7f35757149ca3e640965e1a0ff7f3c8259259957ff5dab9fb8732eae719b624a4492878179b5a83abe51caf02083d737ceb4fcf042f2e60ba0297ac72b87fe3e14ba5fbc54b48091073896823bfa289ce8e16873b48812c32bfea5ff6bb221d1ea5463d325bbe311e7fd1e783de650b7952eae461d63bc7470522af5b7789f8fc2eb192d2cf776c5c24b44e29cdb0cccb1d90361438e4950ff34dbcb3cb0e81cc45f8d0ff570949f78084e1060ff5594ad516f50f1cb0a765e1c0e038d5943b936e4a8b493354e79abc917bb9271266eeba77a93a657f9ad87b291ac7ea386f5d4fcbc582e72d5c23d92ba944b0064c20e3e2dcf504bcc7c6966c63f2080843600ba313ec27cba95e7ef318168c9067dce86c1ef0d5d9eb7a6158489df32ed58b6931030818f00705a0dc55d3dbf8006a8546641b1865d919bc242202cb3ae300bf8653e3b37894c3dc0e477b9d7c41baf8d3887c2eb59b1e4d50bbb6f1792a1c9367c65cdb450c2dfa2145e611a97ad81cff1fd83c6cf7230947eaff4c21dc1bafb71ec41e5bc72b3745ec3e38bf5930c126d060f0c50a895f009aa18e87f2174f58ab5379a721fd83aad5517fd99dff146edeea61521235e2f1a16ee58303e091be8d579094c1d8a20bc74a550d77c00d087571517a63cd4126933a4f09a070bf8ea4ffb846a9780e9734043bac4c0ff47b1afccf5293ac14bc73ebf67129657e4b8a8b33ddac7b0f4d719d2dc65df6ea0a3f24cf44c8338ed601a3939ca358fc4be13e8ede027539712ca23e3ffba706e8fdd62a074ee0ad7420f78060cc96fb2abf30e9eaa241c0f87ebbe3ec73517596f7c3c5a80c
+SIG: 13cc158fd061792fced156879598251dd01d575b400fe3e39a700863aae8db1f9197fa501c0cf993e44d6ac55180b869838e8ae24b214fa35e244b7a6cff6d0d
+
+TST: 841
+SK:  f6ae516a51296fc523cea5f008cfbd09e73f78b6fdd3b69426128041a5604cf9
+PK:  376c82ba7b87aa77418727db33d326ae758bf7a135c10460cd8bf8feb83c2b10
+MSG: 8342f25ac4b17ebad6f79b9a033175c7f28af09e658e8cb98c294f15c3c8342629cb2a3247dfc875b82f5b380c5d11426a2eeb62450bd885650107c68362a3b72ce823f2d15942b7dda301d2fb638f302aa9570b47911dadd3bddbfed554c1c80bd718078b8bd2c9c314a5166f265e8266ee2db357561a5585c414a7840bfae609d7cddde1fade85560f23d638ef3d52e51f5cf313a072c5ea0f817f7281e2cba5c5c8d26c928592b81f0ff8cd18db5a2c41d880d74473863c7bbd0056fa4d4afabd17a3b89d97d3fe5dc06b0f612a1d66423923ba8dfbb8ec8246624d83784eba4f5736ba385e442296c8cb0f1b68e03342b2c6c103346f6dd740e26c3d13caef801d1b2621d89f069391a078d43ae6ff12eeca66bc32637b45f0ac627c2d7bbf8a49d9468175e26885e02821d3a3baa2c3e3a6bb96b57526e224cf3d859f669573cbd5c87393746156f3d1c7a80308dc1f2405bf0d40be1ca73b767dedf4031337c081bfa3ae6e54f6023f42f0cbd87762db55913c707206034010df2aa8753d030f03c267e71a9dd2c6c19de3e1851abfacbbd5dd5bf896fab8e415317b49f1e4096e3da99a5b5d0a3c42daf9de94847c1e53c8818a5b843323f501e3a7fa68df89a5f41f2c62c38d17f250b02a67fae47daf063f558942377ef8a89052f1a215d768f7913a7ec14e98b81e4b2ccf26bacad6f39664afc0e91a3cad691db2bf56a7ab6677b49596db887c97def43508a7a2ec2ab755ec368e2e53d1e16b60fff09c3b52263f0f7c1ea9cc35373197e95c11e6d22fa9d8299c423736f5814f1e798d227518600df6a790358deae38d5639e1983fe018436ea58ba8467548c929efbb16dfea4102253a350fb84d9831c4c2cbcb76e18d7f3e953641ada41421393091e63dfe66de24c99232c7d6a2837a48983cf5b16331ce00050d1c713958ffce5f2e9348c52f53120579a7c9a16008d134838e596129c702fcd21148bdf9174d48e2da0a8a66359edee01c5009ef6742fec41c1acecd03efe1ccc9b130d6e5ac92576a85ccb7cfc7d0e4233106172931a08699790bc41acfbb731adbb26d56b39aaa5b333bc1a10e2c7064ca86119d8c717148f92441af24cd2aa8f57c86ba38a59a100b9276df3827ec7fb4d3faf58be31c6ecafd69cf1c6410a49cd7081ff6e9fc397c2d20
+SIG: 0fe4dd7e1f608ee82b7fe863d1b03a81843ce20c762cd8bb24efd46ba025fff3331d875752ca7220c53dd3c71f2bc1e2c64a2f9c58865a2a244809f4134e5307
+
+TST: 842
+SK:  83f789900f040dc62f4d18784cb64b63c88e8d18001696bbeb4707c469d11a5b
+PK:  edfc2bab7e79f40037fe4d9041de48da9aee8f978098d7b0ae17929025e4273d
+MSG: 6c112a20d30657ab5f8c5c04478d6c42d1c6bdef38cd4fe006ac2a57e290ff29287896eea8c30a0139c18fc8c97564563e86c8d34056a6719bfe479d9e87e81b19452331bfa154806882e5039a20c9e954b1fc7c015dcf5815bd7cf7b6357df9280b9bd43f89ffc91945323b5acb2ae00254d4162868d1c83ec6e0fcbe7a8ab9254192149c6bc9e5fe350694165d6638331eb24e3b1390c698c4838378c01b2c61a3ebe2c060b98ba6ee02b519b4eac1e0bcc09b2324ccf5b1a7fe8fd0b1545a9427832abb25744eeb36326be64efed3a7b07d630a21c3081b55261c353287c66c57663a99db466a5dee22746b81c750ef85be51143e221ecdf114fef1b3082ff54fd044bc884bfb3cc5c5335997009867ce9491a80fe696825f99426defab6a49badcde403f58e8317966210747b567754de53076b3ecbf65346cb83905832e16d01b50b93d37eb9bfe20172a31630d25f3217d87d93465fd8ac554cbbb39d982ead7219391234c889f0b92a2e0413d866cac087d628ce31c61c6323ecb8e689555af10de2b656e6aea2cde932e241f6d1f8a9e3316cf13f135acef83a0c0cf22f95ca818e61f92768774c630e0925be99dbd32b499c0fe7d84a42e393287f6f5ce3d0b271f170045a6d48eab316fe17b1858b1ffeee90888f3a37a2480dfd04a4a8629f868b5c0a80ee1f03719f3a47d4095bef10e0234fc300e2af482285d78937968319da94beb6c40e078577c024f3a5cda0084e2f855a9396aaa9ee9bfaf2cc771fe68c40b629e8dcf115ef03e757a2ac9eef073f1bdf9c5a4410031558a6d382b5f16024b151b1c01ee7817413a3c4de9dd6478785b81101df5522430058780207e790f612d78e5705ceed46b0ec075e7c1dc073b17b2b43d72535927bfd271e92e3c93638e40a9601dc2c1ab76d91a4103df657d911c829ee8a5f747f7642f5a915a5f40f630b43039c7d4bd2ad2b32129d94e5b2f03ad4a3d45577eb81f369c9e3e2a4f6a8e41acf8283be58425ea993b8e98eea6330556648618dad98fa255620d836d3c7f29b907895849286167c7181e2caf55c2c184a9a911f8e41cb042e2cd48b0544ea79fe2ef381ebc5b15e39a9b5c6d998faeaaa7773cfec084c0bfaed1bcab963a4ef3d94dbb3dfe724c040ce4d1e2ee7fc2da4b25127ce3a5df693fcf5a6ed1
+SIG: ea6582cc23e0460917f782d964e3bb6dcde0aeeac42cc14919d36ce78aa0afd98072f54c795fbfd7a41d99d70606c28a5dcf19be38a0ce2d09bb8f844c31bf00
+
+TST: 843
+SK:  43bff3cdd5307ed7d25cf96fdbba64ab1811c8bb934e2187ea7ffc018d85e0f2
+PK:  00f1b5d3cac6e56ca5f894d4cdbf9bebd968d24d5effa5058b0e20bb0898f6f1
+MSG: 646f8b34182d5e602b51ca7329347c0e198cb747e4da0a6b80f3f6f9f336f6708d85cb429ab2d6bed35d5013129cd100142cddcee8635179021b3e24922b81aef13c1370286939d63d6b6a4195eda1d812ca518204768f87348c6889552c63d1372cde6a5e9daa7f8445ec8d6130a3f5aef0edeace010b6c7f0b9d24162a8d04454b81d48ea9097bd8df093459719ccb54aa10f51c246aa99c580beaf9c9c5bc60faf0ae5cec7f5137f6c5c144df45d12ee995adccf25a9db81b8558bdfb65830186e7b9d4eed9f6b4d732b1b5822d03eb017c0724f48f87baaae1045d6fdb125c9134064faf18dbed58d8fbaceacd4f097df9b342e5c4a5bc85b29597d4b640f1551c5b624ab21b48e94a9030049be1f05aa851d0827eaf8700dfe147fdcdeedbc98c4f15774f0120fb5970a2f8b21794340b628379a802b9f7c068b0df63193e510fc7b2af97ee38de47929785535528d350d88620610cfdb55d249e38fb73c8287113919ce33267d7db924e4919a44e6e29a90dbe3b7b0d3921163feb5ac105624ed852bece3538e99193300c893345699350a8f99e8c6a41095fc9fc08da07f75711f7df034406de14edd8e22a633a86e4a5a5c975ac5d34891cccfc8543771ffa080e0b45d65ab830a361ac4c426294d3685ea8c26039c71c90fc3fb512be9fc94807d76dbdaf8ffaa4fbf9849d68e8a57d30c4a0b9735c23f08ef2e284458467e15d665362cb646fde6937ecba53091264638357a722425bc62d1e30ec5f0dd8fea26b2ea4a8490035de43f274846fb0cf0209ec7437f3c3d0a560373d034e5fd79e25b6424d9b2c1761632b35a12132521827345c55e4e7142dd6fe94d620fe515c153e8395b5d130c744139b6a92efd37f22ba13fe4c095373550e2e4fcba0325b3ea3b9fe25cc7dd92cbf42e15f4554b77ac27a4a346382ff6100451508d602cf643f60b6ca4286356f21a3110d4e2c8a8962a780fcff439b3aa80499df270fc3e6cad8893348872f0f702f9390000c7f6e0627d2bbb7b7cef5c4da25dadfea8032e5023297a70a658e9ae73bddc3b227a1c11741133f012f0f48fe26446fa67e64720fc8dc97f30d0dd026f6dc2164ead857824a0a7aeb20f115d50d1b65dd5d82e09abe834e8ca88957e39984824955a1a13e3b94a00157186dcdc289e34b678c91cb2a1a
+SIG: a6b56b7686df1dc5f4ed544a4d97e67036195a32b22ecd5d31ea1730e6ed8f810d258b44c08ea45f032b937441b72cd0dc37556fd7874e9fe64f15765c521003
+
+TST: 844
+SK:  063b9025e321e972d653a062be34f99365affdcc98ec9ff43ef422be0f804460
+PK:  10d01a63012ac09956ba9ed61df35bb7afe3658bb3004852e47174bd07dd4de7
+MSG: a7eed29652844ee0049bafb2cf63402971020d7e65c10b91ac5726eea86f40dbc53c3f0abedebaf6cc449b4fea48c015fe4d907b3e5505cff50a121819a2e4a8a296d5751015bbcd7ef6fb7c2727bb000be1342a7d14bca97904edfe8b18ddb63933418327a5af817e95bad74eb790203615d082e71493ead47ccc0901a2ca9f50133c44ef8508d51fb73c616f0147532245822dd102b337a1b2aae2efc72dca7a9419d598a6475233dc1a4ee0ec6d05da12a2b287cb77ffafdde2d0acc28199933e6621eec16ab4245170cf02da80d4922631a23272915165ad88722750035d2a0977bc791d14fb3d8cb02bc77f7c71be5242629a4c9a588dfdde9578494d8baa4e68f5194b8002c8e378a0e833b7c1a96981c4fb05e457ff48260b72493cbcb82ae11673d14cee85288f6370bd4bca9251a7e214c3eb79e7bb6fcebb16c9e056f29b6272743efa6fe8bfd25597ce86898ab3059eb0231c73b5305903fd1319bdf49e599d8bbcd74a8b9767308b61563ccbacd38fc50c83ab44ca759dc9b65b2a4b547c5097f220c1c88b2b0a48f65f91fe78b1501278e1e304de58b4c82a5c399981098a1784eb9042501859f2a93f317e41772fd52f972e51b07ed94d314e1d1af4ed82909a0bef671f54b55db7b70da1f718c8e648aedd6da64b05770526f12bc43f68b95548dac50809a687db97d73f06f47ed08831b60a28e982920632058f0e6c90c0187ff44564f81efd8fd93e327bc6d80b490e088b9a10036c80dcdad49d2be074fbba31e06f7180e5ad1c8823d60966a9ce15503ce60dd40e91eef2359d83d70d98401dde7be3c6b07e57d4e47d04217633d8e263ca348f81fbe9a4a62f45d77c843b6b1ad28466d9dafb1b910b348ed87c686cab292d480c191d187b404a9b1d132ba4e293d3ada99172acc121fe66b845b98b160c5823f601c7758fb26caee85701595b2d52caa2f5688aa2bf2f6c4bb637f8e00f49ab6c26bc6ad89e1367fd28e4917d250893a7b32d39660bde8db49f086fb739e56012c36bea0b26cf6d9357940b00d5a4528f9059aaf08669e5f46c995e60f887b5c4ab88ac7442ed01a14c6a42006baf1f343fefe3e4aca843a324e176b2fe7ec7883d1cbd068bc2fc962ffa60244f654c77ac5650817dc084465545a9230a74826b0c50eb85252a886ff2b1afeaf8
+SIG: 85c81d6b0d8578fa58e13ab391001528b46a1d63a0327c7a4a04087fc668758aa65c01d5a150f935674ef307507e6f4c91e1fc3500b26f649beea87d27563704
+
+TST: 845
+SK:  883cc1381757b0fe0455b77bc9cd0dd464d2b4bf0c7a3c0c2dc775fb78aa3732
+PK:  83a8b669ccd01245ce3b818dcb1b588f86535850e6c710c79217fe439824f3fa
+MSG: ffec293d12ea636ca4c4a0a5e2db15342639c476674d2ebdab4aefd4046b5ddb56aeb210c119afdfb8a89128a34f6d77f261edea0772a2f8db140a2640fd8ecadb0b4792169b6b2810aee2c5cd835288bff493bcebeeea28a7a248c36116540fa71736d66b0a475b5fa92c0d46002fca7a1e69d1b59e81a3a6d4f339769daeb20b5f9d75c4c28f692132d28d3c564c09fe3dcca0359c3c63ec377a33f9ee874d8a789d77c96ac05fdf3ab38b2c8274a902ef8bb7f467fc7e073c77b1db5fc8ef966c120c4dae3fb7f5b74abb990166c812a525d123f76ed512125080a1534f3d8bdccc541fc97590287546096fc880bfcfdd00e65c0ebf4a09fd6476ce1b7c8faaa5a1cc2786719a30d8255811184752a88b08ac9f0ff1d6262f2586940afe1fe45e0b563448a55f3030e4c39c1f3f86a733670380eab088e393de09d1f508d2fbcafc649aeae6b8c30e329ec3fd2829be6db0ab8e637ea1095bdc3df3acc23d3cf705a9542c19e59092ec413a4e2bd5ded28cd34ddb3d32949aa487f1c337d6979cf512622dbfb7da1cbb1c7e5abeea7009e2943ffba2252e1d86eca9d6d5c246cd2e134a3e5dad37efef71ce397adafbd9e72b3f9a86ff0f5d812c46225bebd0703bc5cce9c64582008f7e558c40a3b3522096d1aa2b61bc90cd88c6285d942087d8a4665a0e64d3572f74689b4f24ef400d741b57140613471444decc654af0ffb2edfdf9fdd075098190b34cde28dd166872c6086567a68761cef25da40bd4c3d34fddd72ee565b0b937678ee84349d1160f5f0705f895d0f141ce8f51a1e4fd2dc4704b527a4025a939cb2bb78857eb18d78872edc9ee70e60b2a42700a198f4fff6c31925168be077dc23c322abbca97361fecaa3fcb196e656c128f3982fe11e551a4a0885da60d397d0e40d0d897262f1b4b672f78a2d2adfcdd6e1525c26e7195fb9ac606bb1ba4a9890803b4bd84346ae8d8c7196c90aeccb296a4c3eb4efacbfcb62e383b8a494ac723562d0d8c379187a92e3bda6b1569476aed21aed7a056b4a5826744017cc0060b4d55fa8772b5b1c15f5748ad7298005aecbcbd90a3e5c6159a8674abbba37914415002b5a6ef5df3c649426ea1275a01d80adf490ac546062d93999a6dccacb96a0904ad33d90576dc6a21b672e8ffb06613fb3f14e6cbdde88c2437c9
+SIG: c7cfd5c9fe930d15a11ebb34e3431f489da010eb193edbfa6f23d5d14dd8feabd7880d2d5a5600d38546ce3bc64a86291a1ce31f272ff020df8cb6a0fd4d3a0d
+
+TST: 846
+SK:  5e40a7aabbb0830a9ab0fd79690ee0433901c6cb0676abe4bba06f5bbe58fac2
+PK:  4d4f28fe09c4aabfca01ef6ee7fd6372fb62db61aaee827c43fd1a6d1c259032
+MSG: fd4ec8b34fc6b743813f59e2fd1fefa870f5a970e2eb7516ef7c306f4b823ffee92d601f765d79ca146aba8bc6e79844559935cddc242649c059ecf2db84fdc219366688a88fc25b851c3661e51988c2bf73bb8e3dc16d22415ab1a7b35579daac7325e319157d7da5fee87c93a4dfcbafc92fba7e17cc68e3903733c6c801572d907320b2feb51710e856a1f76f85a7ee1a11e62d2e45a352938dd8cfc2bccb902dea444faaae6d84c5f391e10aef76928a45153db6cd25a2bf353d80d97bf4b3808605e89800d29840ea60978d9ec9b2c302749888f9debc84dd1e2a79aa0b6ba02a039193081bdbff0599a14d918c0c8deac4f60b6e99474ab53011741034fe2a20cff4e0f023424c8e5797768ad53df6d01a24011fa90f0bb1d5069cdb36b450f433110c2c56f34a1de4260914cd4696b14a09c0268b2ae2e98e6b4e992b9125f878f1ac09823170628388f0f6e256259ca786bbe144884cb298cc043d02f5c3dc684f787faf16c10fdd8437a8c3097463bdb99b78030f9474fc5c9951dc7526490586fe1c2db05411341460239d5e8bc53065902b95fba282c27665e869a19dae84606d1726675155d38039b9e55db4d5ceec95cd6d87f85e99dde54a04761e6eada6619da895b654fe3845e8a60f3a3b32483d6d27978af54502b220e478db78cff77a9c97fb79fb5acf56289f381acb10de64c3f23842b12bf5f1b283bd25d48d09128fb55ddae255beb7c66a74cf6f0695a4f828cb29e4afdbb3b42a235d4fdb66b963ac8f68e82b00a1c4500863296247178cfdef803bb7b114f0c03276f671669a087d9228a37ae7b99b061549c1cf8ec17246ea1ee03dbc88bf426416d586572ff10a3145606f2784e4357be4edeec6c3a7bf11bb5b0e90cf50edaf891e51d26357bfc853ce23b299155c82c1031dfa64074d72a09d29720ead6ebbbf75d5738e32cda6b6466a8def6b50a1ed9b865a9a88a08018acb501a4de9db54d0522ce9cec7a06bd9a5f86b0b46c07bf3e7f5a426ff6b4bbe1e00313a5ac2719a959ed44ee0a44bd97da6db2cb971bd68334908949ed850fbf73d0e02049da181cce9c2d9ca1b624c8d87cf904eb821dc7959295da5777920660b43ccc25cd389f157f67fa0390feac97a752c1ac204c21df56bb0f4fc01641b480af2b89b5d16d4a0bcb0a50b82b0e0484
+SIG: 597672ab8d3a60de5456fcc9c38253f5f37b80e74a007c9f6db909d27d0ead162789244994f35b80d61be199c417c7ea901b98cc63fe3c50fc3c6338490fa206
+
+TST: 847
+SK:  3a34136a973480d97006dc279358e6606293d8cbc1a44ee55233af2b5264b90c
+PK:  e5effd921be8eec530752fccc576ef0d9bcde4b32cc649d3f7954717562860cc
+MSG: 981c8e1090e396951b072ef8497062020897bf7dd7ad505b4d6dc11b3e1dbcb0da249984a140e164fc2e02b31da39846554aa8905bc8b3df8a76bf60eb5ffcf22c97b671227d249071da8ff6bba75b2f7668cec19a89e6475a12463dabf368b3ca2445bb3035cc00fae85b7072fbcf595401755b8051e6097065ae429f18eeb13ffa6dde59df6f3c206bfd9ce1f8a800c8590a4021d160f66d6740a369ae835617538b5890231f13c5667baf510a606bdaa84b8d10ee6015e12a4c1ec0bd0421a294c51cf63b5d1f058e1153dc425d10cee8b1b084d6c29347e96f0f31b839607d078b79a90ca3d1f063807a463b7c32f45a534498d71d47edc3b17a4dff27fedcffab301f34f1a64c0278a53589349a233af30b1ec1ae410f7b1630c7145ca42c9663f512e8a578267dc95e83289c17032e09782e2fe8e16efb87f03ca03b1195614f89961ca3939d3bdf737221a22d7a18ec30fc126d0ca663e88d6060d04c6a44e5616e556e07d6d4a847f1711cf43717810c70aa4be730278b3bd6555c954dc6edb09db08f0e211803596280f3c7868d2342cc2308eaae4da1913514664b1db962e99c8a8cffe57931f5dfcddbc1cbb36ce1c842e2dddeadfd7e7d0a5048cdcb961b14f35f435e73a683c8ce25c816812566fdf817e0d336ae0bd247328512b2a8567632bf20553d9bd6fe157f220ffb0b46ebae89a70459728a57eed1796256f1bd50b6d547ea3e25fa5913d389a22583e915eb49de35a97b5acc521db0d005c29575e16611a755f21a3a5a82a20aa900a707ce36825492c3ca15395f1700b4afab94daa7a02f1453b1f9a6bd36efb204d928ee1f4dcc860f3a859badc006fb305fa123d4c79b23a20e32295d040a7f8f6caca25d83f71c62e3af7836ef76b93a83d3c3b493af141753da19e4cdcba56617271034b4f4f394c7c6b7d79666f3afb692244f061c69a8881d1b52b8849fb534990ac2391909471ebbb728e29cd20f422354c4309717ebff3efd1833370806d5bfb53ca2da316dacb50ab7fb739673235a1dc53aa8893072d5b91c9f6db83fc4ea41d1eef49ac28afc1ced8f361890ab9f779d193082831cb8c42fb2792bee3b26296b6295eb78a8d853117661624e11f7f57afd6085a7b9123679fdaca1cf2a78d380bc4c360aa7c3cbfde0c0091fe53e2219c070f2f02f1483
+SIG: 425f272212835755adcc0522c6f6e05f68008a3be9ba5974e420c4c5cb56e6c55dec0de347b16caef8bd33b71b44c8357d05b6321d7bf493d25861db487bd603
+
+TST: 848
+SK:  cf33e7974d8f0bf899ac5b834c7cf96479ce1cfd453af07f970527f36aa85c1f
+PK:  578f60338b1f041a97d319fecfa30cfaed369303cc00b3ec8c5c99041158e20c
+MSG: e813144bd116f6ac36389217b5171a902f06b7dd7b144df4f9091553c7c7835753a296cbb0d7fab99cef77b61f34a04c8af04e7d5d1f961302de89e2005f299f5a4aa17924617d006693937745539c3048ee36b8c23afec0af9feaa0066c8af8e0a7f09093498210f6d8dcc0aaada5668786910ff7c5b348d4ccd6eeeffa3acd1816d9011a4c4025f6c2fd2c020a10593627520d4dd99e07c62d2dbebe84139e1c7d867c093574fa601e4ee307ac926e5d36b62d7ed84a261588b7e2883c7926612b4cc67e2bb72544a10d6b4929c88ef6c47c2625d2f6816bd73c3bae89d2e0c86171ac4bd080ae555d62740d1d2a761ced86dfc328ecc27ee3db6d404108ef4e0b64906253b4c0a771adefedc8a2c5b53c425a70cd6f63956f7a0a619fdfbfd00aa078418eb4652f8bc6f3c253beec9838b77f9cbe2ef2b8055c5773539e356bd8192606ec101e3f6058b1dd08a68fdbc549dfe6b7725dc2549e8e3f90dc5be3ccfb0a38baf9377cb3f6501d2e15ccb3556a895ccb23f0b6df9fe59311cff55374c3fb3a32981ca26ab426f3663d04e3167e53a537b7589a9fb73679090a205532c132906634334a7e8749793f8c593f3fd6278ce0050383487f3b245067af94881aa1ae968d0caeba5fa5c7be5f4e4b7257518695d89bccdec507b967b4fd64b6893b3ee7803c1d36ea8a02fc426f9afc8e9f24321527ec9844bc3c54a0f7667e034300bbb4fb020f6d5bb954e7b5a3a706a4939db33c154892643476a291d47dc1e6f72ce91d136f11db26b9c9ba736e40df0a15c1a89149996b251dd988b39004e6ef41bdc061db580b7b74de2a651810bd891753b97386d7f8cbdbb6ec386fa2c342f5ef20e6e3a8bb4d5149a7d4de1224dff1d172c87570f776d5ef45959be0938ad79f5d3395cb2721627122887bd7a8983b647797bd41d882641c81431ce8d9b3067adec4cde926c51313f0cf84c5292562dd4908642dd245288484c5568a787d0ced36a352f032da4f7e4de06b11473f650eec65dda99639af2d42d84ee230f4f83623d9c9aaa3b16bda10ddaad25af5c1c10f81c8c51c811a3aa3e3db58a7025e4380e285da474a61ba59173ff042a46a79ab184b070108416f9d6158cf96d0e6db447614a0d9089ebb6aee4ef107be4593d71e79f6798668a740ae4bac5ac7594ecbd5dc82e7d0f9cb
+SIG: 97a5b6d268a5b4175fb06f1f37d0a633519296edc30011c954d8f0b9bbe2641800396c4b35d4b0d7d2a1d17cbbebdc55a809462d6cc19a6fadbe1bd1bae88a01
+
+TST: 849
+SK:  51b1ad0ffc21497a33dbdb85ea2bc1ce3d0c2d95d9461a390973fee377fc75f4
+PK:  bad0412575d3801301edee6bc0f276e787357b4122f52de981885851884249cb
+MSG: 7882e86ef3402f6dbc65cce8315b39765faa4b1fc876fad5f8220cb22a7df2e3580eab3a7e8fa7fbb6b59482ca0e364a131396df792a3241a060e44143b6767493c6bf75f187a9643aa11e11eba7b0a80f0a68b9f1b79f75b66cc59d9da77955fd7e8799f99d6eb08f90d318f4efcbfe71159b10a83aa5fd69bb75336f5df296ea060a426c9545df940bc1454efc1f9dc965f1f22d947303fb8ec12407fff6b1dbe47e3421c31764fd90c83ac711d19926e229a064c61fe3676af300a1716fabe4e3842264adb32e0d9c9f5d4a65d0d7b5c3770d737ee13cbed21d7a1da36aaf7ec0f36fcc476f659681e5160a5a1f49e759b9d0fcd4fdb854eccd99172a47d2c4efbe0b3757631df1bae175f0fa74dd048bb6a5fed8430284349da3d67df2a6f7e8269bc79fb2c5d5ed6084e9076f455ab638919046369a446d57fcada7011cc771bf6d874a8e5d23c687747de41dd04bffc717d6128183846eb594b3cb1c1a8aa04f0d7eba53af39cb1d4e6fecf3113bd8422416f4c44037aeee9e0fdc517c48731fd04ee9c99f5dbca3d574509d7baf3288f2c230a02d1703bdb1611cde2a766dac193de167443d20090dc34d29277a86b1e998b245645117e5111f12f14606c55446dd912d3475c19876e19ac536d317876c4b0a2e0f98616129a5683732a42317c5e809dca956b2abb484ada810a15c81cc8562b555da9458f9b44338490230c7404f3d48611f84127e73e277d88c62212d2a3a351fc67665b18d77216230632cbc781288e15cebf3ec33a7205eb22b9abe4cdbc7ddbaaa53640875eb763f522c36cfff2eb23ee586d775286259fa94a44fa7ec015096a2a446b6732b80024267fe3d5d39d1c48509b3ecaa2e24e54de4d61c097b70f753b5af9a6db6f975d25f4f83d06f879e17ef7c509a541444ba3eb6867838090e22dafdbb0eb3b0565be1579ceecded20f544256c7c4ede3b62843c65b0466be6b7e27305b963ca914e3b7d21736118edb3d658d9d76f509db3b9ca2eae28964a4b3b3c384a81a4890ee96fbe934a6f2aec8eeb6cfe59ac9d3bbc1646ba32a1142fee59fed6fb7bbc0498cc27dead413b7b4351ec206343c0ab89fcf87243b1ab450e58ff11a1140a383f196aa3976ce17cf34530f049a1de90e31753cd85e7f1fd5cf20426c9379feb8c31b4bfec35ea5a78953d75c5cf
+SIG: cfb65b6ff0377cef511fd97b90c3ecb80833f142a7cf5022ced30b3fb7862086d01339b8866a238cb070276e1944b5fe32cc409947cb91deb1432c291b60fb0d
+
+TST: 850
+SK:  fa2f461ce8c7126218c47c91569e8799797c83368fc842b6e1c22fd52aec70bf
+PK:  6b89b23f1e11a75a53f992f6ca5775008c6e9e7e49c0d8510b0e8369b7a20bcc
+MSG: 799b39802a1827e45c4112fee026034c0e598affce2c550c193fee73f1df8c30c8d3873340088ce859de3471e9d057686c829b5408795e08b3dc7aa3b637c7de9d2172ad0333c1bea861a6232f47f05a10bf5df80815a271256e37e808a0e62f1f07d9e10ebb947d3efabf8a28fa9dccd9a1d599f5fd6165508efd679cf356015058bf4b34118f83aa3e5bc2ce19eca84f718398adbc0a5276cf9d8caffc27e3e6abbe345b0e9ecf89c6771b0e75d408ba2fbb90fcfd70c53f2e4d52ba54d9784cf71c349ef6f14ae4970def6efb5f30e984d6016a196deaec7e04b47619c48bf49dc02f7fef3e13b756174e90d05fcbdd5e13f0e434efd5421b091d517900ed0d5785968862b4bfe5093ab67217180d97554ccd9cc31429326cab42f3f8398060c19db488b5d1c80b29090afd1c6bac3642264800211bc278fcb99dae9dbf49daf1b24ab569dcbb87d4d3547335e35db98400cdfce6790682e93600220ec499245fa4ee15d843831b56cc26418025bf87001605c6691ca6bd40a4e248c309801b76a795ede8ad5308bcb6d1754ab3371f0003bb8c4e4e471954e28b1e9866379f82e1fbacb79d50adddad5b9778b558cddbb0038a5ff3d5c9557b965de3a7082c45a8ecf3e7721eb690b6c71f3d8975d5300f67c4dc4a736846e4ccd26f93463d5bc6f46edc488664be9696be12b02dd104d10cc6b1d82e8117811214a6487d17367e395ade2ef6b26a1783a7e2f245213bc03a755df3ee8ef9f1eff972c6919065cb7b756678d4ddfd193eddc0b42e8689613643146d7428ca37bf31bdf14e31867858f39d2323709eb3b7d7f4e397022378424bdee9bcb74e9d5dfd371f4734998fc18df4cdfb4b5c21c2e50f8d6c15bc14bf4fda6ceb9d8082cae432dfc98bfb3ecd16b8d74f830b642b042875e921b054bd1aaa581f60d718df669f56dc2f10d478997722162e83940e61a1b6e42df2a4a3a7cbcdd611ce96cbcfb5a95cc473231ca13c0609d0ce1ae5ddb5466d6d65eefad9daf2a36901bcc945847da1ed6e2e240e848b231b7d0e1acd06543ec93e768e59985d7e96c8c31fcd1210f0964271e21877525cb134bc3536257dbb11d30a3c4f949fb82ae0c31ccdfe41943251e50aa4355392ac309ef60fc17432a2be4bdb2fcb28607cc45a52b60016bb1d2e23972ff2c2a247d725585b1ef2b15f
+SIG: 84f79d9e8f30e5bb6362239714556b04736fa44465cabaad23beaf5a99fc451ad4ae5a18c7f6f964fa41039216018ec5a2accae1075a6bb3a6ecbc1fca02b904
+
+TST: 851
+SK:  1be2949d51e7208175826213ee6ae3c091172742e88caa02ed0f313ecbe5d910
+PK:  d7bf4748d6dded5b57a2abf797facc560b48563dfd9dcff4be522c717a6cfda9
+MSG: 045e2b0ec7bb203a49bdcba941e2b73c23c1fe59a17d21a0124ea24b337f92ab9c923a20576b62d5d0f624e7932c115b5474e0a46a4dc9ec51f6a0ce8d54744d1d52093320e39be203f74a0f5dfac52cf0f995c66df2914b68ad871fbe81525ad2d88ac69933a75aea74ace4e36343ddc06d3208f16d805f5dd786b4daaa166748cfeec5714c85c10478b597ac7f6ae2c98891e38fd414aa811b7621d805eb8fcc46cf4d568a8a92587cbbc1aecc12f10d90ac1e01ae986d14fe82951c682ceac8c925fc6654d838ac9353ae2f93f3c88bf7b82cbc43b1e49e5cebfb1949ade4b22e4bcf1b400c0a8fa8a6fe7670f69fc3faecd4805b8c954c01a540d1a1e788436eae073ae956dae3176905a8f0a3c60fd980dab419d41ec06e5273fbb13db9381f89b663ccc4bd753fd90f14a77b3d81c45dd3561cd1fa0e94d234cef9d7859a2ec942bfc18849d7f2ada3a5d657bc193d2e1491682f1665a534b1ac2083b738be8f9e963f5941ed483c6acc82e959b81b8af02f471c08f5f8b12e10e008192898a4450202af731592e74efe2a948e51d06e44de9b956b7bc9a69b6e74687ab206dec4d35b3173fbc438829d5064bfbcf743c1e2d46f628f2e51c626d8e416d7be6e555a249691abb167f1d92f4fa3392fde24e993ce7ff5c1b8e1577a7c0e73025cc6fcd727a82ef0c129e91e5533e021a3cdbb99d54bf7cdcd3ff119154f3fad9242b6ed350d10372c976ff3a437d097867d9bfba91d84bda55a6bcd6e3641b213a218b3041589c55afbb344de6e97d8c35b5c86cf3be063f901ffeea8cc91069967d2346035a91eb5706a3b53f6d1c34d4d2116706b65c298ec57de82abc4003ce8cc5e0b88ff710dda1dcef6f154277106b83eb46c045b082d113b361d6a625808c9130584dfc96707ef8955907baa61cf88c66b6d1f60581119cb6217a852157336178c685e6ed48526ed5c4e3b7967d51f99df6876a1acfb845c571b898656e5e3bc73980b9bed1198866359c9e9b1efa915f810d1ef8ad6cb3fc21fbfe654306de6ca13a3a6a48e7a13ed8746acbd07f48eb00c36374b1eb4f3f01c19e2e8d37e9fc064b33c0d669bba554ddc6821a77b4089cabdcafc97f60e6050bca444ae8cfc44d93c40ef5318bee6f8cf0c067b85cdddc45974a4eacfc3ef51315ba0f3f62968c7003a7ff444612400b159
+SIG: f41f2ef6595f17660bb2fe93e51fc6fa9c31dadc9db90c3f46607a7fb4800bb75ad96325dc7eab782472b04da6d8e6fe64655dea551fbd5049e876ce5a405f02
+
+TST: 852
+SK:  3b6ba6d5cc9cd6241d8b0097a3722e4d066fea3d560aeab4673e86f1f8ec6026
+PK:  8ca6520717cf363c4ceffa76328a0a166ff83e45ca7d191cc8ef6ca6e5243367
+MSG: 36de930cc8e18860836a0c829d89e963a58bdd9c6b6ef5bc61f75992d2075242dca23e28de205a33dfea861fc44a32628e8e7cdd3ed7ff49ea6a7097e0090cfd9ff5ecab1de822fc0a4c3776dd56c1919204516a94cec5638da1d99e52b866f5ec4162a912edb41c1e92edfc353f6705e1c12cd41cb62ded4ad8157940059bfcf50719d3f2ad00848540ce89f3f9afa610ccba5ecc37e3e2c1534fcb38fcd39a2d14d5b5da6fea24e006654e309047a29cad0ae4da8e708f97a18cad5fbdc9ac84400c532ced548886539edd6c541074790ae4502fdfe9f3273a876a218623a25706a1525e67e57a16d22c21b6a45e2384e287ac4452aec4e063056b4c178ab0e5b2a5bad3f463c472c4ea1f9c1a66e5270473a835094e8f0eef680cd7b20d0e70f4d6c958fee08a9360aa6066888f4dd7ce5ec22259fa0b53fe9271c083c6fcdb7283b09061088c52f71bfdd2777ce0801f41a6c4ce90ef131de1e183cb8949ce323c9eb13a4b0cacf99defdfdb68d5ed1f6891b48e21047668d69de8a80f8e5634ded08736a4fb5410cdea9c72596e36df6841f2eea46850c87473c895540205b0921960ffa5d9d8ffb8e29cde96a3ede015acbc26974004d3e438a85b2e3385f64d1814003941ffd363992d3940c6e6d81ff8e45fced6d36ce198d8ccbefee432a77d8fcadd73fb799f6bafefb51a2da798721c3d465b163ef13e6ecc65e603b2893ee4cc9e1c6d1de7a65cab5cbdf536855e288c3ccda8d2fa3ce10cf49358a2ef4ef076e5bfa91bbcf3d966dfa3dc6e712f1956d4e58aa36e712dd3347169b19c8d44bec5bcb730778fcccc589ed5d350d44c17bde2eebb6f5ec59fb240d67d81aea9267f34f15eee2de3f4fa67391479bdbb430f484370fb0e0895b9ae065bbdd43e230c62ac07184e8b06b24b8b97ec02dc6f37ef61641ed56e3f5eb8d2080b5144ef760b518752e19754792e19343a3855e1e2f7a7dc623517eed2f5d26548a68eb8ffd7bf70f78fd186db634928bb98138f2b8fe84481cc53f5aa35e2666c6325e1d2b8ac5e2df2935b7f6413952d10d6076ffc75bb6af63b29b0b9663bec37247b66b508dde41f2f11b84333559dfac73f761bcda84a48d266073aef1638460849e7a17206a25f6800770b914cc026baf9e3255914e13258441cef35ad1d66833e987ebe4431e6a6bb222cbb65af
+SIG: 788c9f4554ddba5c7d64ba759ec45694ec79fb85e82368a074bdd8df344213a56dd09f334cd9acb941be283d98c4b15dcfecd14e93f6a2e3cb0c1aa2dee7d90b
+
+TST: 853
+SK:  dd9987b18f9a922c0f6fea18eb00b896c7a2d3093db3ea31d38421da0de51231
+PK:  573921a955feb6dde41b055c8dacaccd1db7fe9e36b509d3c9e36f9735752324
+MSG: 48162fdc3abf7319c6caab60cb8d0520875cb4ee8a07092783167d4733ffe5204e5febe7d291e9536bdea3df0637159a653e09fd99af661d8300ae741a3e91a8bd85ead05dc7d9e6f929323316edc4ca624ea7818b25bdc061f71492fd22d465ab226fd9a10d8babfc074c686c436c24a3a53f8ff389ce9ca1dbc8907445889241f8fda3a7a3f5024fa8cb0d044bdaf6716d983a6d839814ffe70ddc55bbba11ac97887bdb4dada96565bb075d5fc1d3c5244b9fff77de58729a059a911fb3e0eb164fb8429e265685d14a63233046d20ecf289c55723169a9d63dda0d5255153d9ef4a61b9212f4b820697ae7c308cfab403b2c3431906226e45ce21920df5201609daf830f28ad796005a9bd8eba620cf839c3ba227b963c7bd0914822df2ca03c2254d0cb8acae0d59e4c3e0ec215c836969dcd1d49bfe197e2f3eea3fa8a373b558d0fb9063cf1568e739aad8f09fb437cafb5a272375f436064eee11bd903d3aaeab4e3fdcd36bd2076eea179a4f0d4fbc8df42bf2660f08de7d5c6397cae10b7277458aa6cfa01e8a6737eb126227856646691681c106a157a26aed21b1aaf0ed2766421cfc3d1c7ddfb72fcdf4b8b490fc09ace49aedd7712b21ac56f8601f625563c784306f3b9174addf764e051aadfe12831af9669e62cab121c74df343724429d6c26660271c32f40cf7c2d08bd0afcc728def4135d4eb55b6a3e7629d806864a85b36a32b9b21ac0d39680a2ae4ec4189709178e349497f39399fbc78b3c6cfaca6edea7c33dda3cc11e4384f1583d6cfc6b58f4eaa2bc56aba42f738a429b93580850dee3fd253994f8b0fa66ee8e273decabd532095fb04a4a3c340af0e55b57efab43630fc02ef20b425ca2187e3c6c5e10f12d618fd243a224f6501ebeb9d321c6385b8127ef9cdcd097ce7fa021cf40d21c39912343f67acce1825e3a51b8a718e8c340622fff65fe0053d24aa3351b6a2400185d7aeb88e87ac4a1d394909d49414aefc22ba009aff6962c9217d755694e4d6aa8a5d6a803cebb15de8f541634b6fceb0cac79dda8a18eefbb537e70ffe9aa5a6a6aaf9240fac2eacbfbef01ad6bdf50758780f86a4e488985362d5825011f5e8b66425a616b7e104eb23fe8f100cb0249823662bda3da47a4c3c1ca2f914b25b9738534026047df6d7ff631df2c4131f680e13743c9ccf2
+SIG: 3e9f2b007c0e29ec875995a6309b973deb8baf113ded13f1e0003e9b9bf93916a4dfe47937dadfc78aa663c55f674ec35c3846258f18e7bb93fbba3e826a1f0d
+
+TST: 854
+SK:  38d2ef509f93051f145167737c22e1a5bfe8f4a91eba0bb87c39ce04a89baec6
+PK:  01115f6d89a5daab54f892bb4a4bda1ce5d8f6c9c88a50cee83bd987a2c0ddf7
+MSG: 427b5a01e8597f04fd422f0a662d0be2dfa853ed5f9d3f60ff90f2c5ee08bb59fd03d402b754caf54d0058f5a2cf87af4fef2177d59e18226293fd2af376bc987bf7b320b9d1e249ab9efb75078e6d3df29e03504776354344aa69e72e1ebc52a3c38a4c2a1673b4e974a2e4e12a2e78ea3e3fe50c53630d096da3e2fe8299f71a1b441b4cf0caeb937afa4a0e3915ccab3996c9f6a8f4fd37543e8f75900cfd47175370efb852a5f69d673683f998fdcff85ff8f32baa807066604422027d51a435ddf988ed2fd8eb191f10b46807420008756eb4e300c4099c2d6450bcc6a4e7d0673156b837f0506338f3d1b5734b166ca5cc2f24a4ef026cda2c4ae3105b63ca8570d18546cfacb86042966a00ef52c7299019f68a2df08c8b704e85e713c348d7f1677660e18ebab59bf4e12e6ff2d783d8d5d42aab6ef017b7a1966aee8dc14ddabed49b4b643df4e9b0b60383c7d8b4b88c65a898c1c77d43d6bd68b2a5743f1fedd654dc84496da02ceb69b9b4d3a8e00ccd72e7c75fc50a8dd087e183e6c1f579baebc5c63f2807936791b5fe4847cdcf151774235205cd2d7b8bf4ae8819225ea708b7baac66998f0cbab2c7ddf251f3b1de1017d397692205eea639f12d77beef6c13bb12100ff8906470bc7b21298053be1a61b7b3a499edc310996c8bc0871907ca468e89ed311adca2e2b82930975b3efbbfc03cddf4d948c4765e8c10590882169acddb8f8c36d84c2dac3b798e7abf844712fa458d277c24e814047d742319a834dd9f927a2b4485ef13745f7a60dd6bb337936304c97d3f9f144eb29bb695b8dc31b9d84910611d28d581caa9365d6dff52d410a4ad52bd121729fff52888f4daae1707f6f56dac61ffb9961cda7176af4460a6d5542a20446fb5147fce727204cec6899b9a3d4ff6226bb8a1c78e36fcdd9e50c040d72d0f4007d3fa9aa767e4abd0add62fdbccdeff6721eb259e00a721632006bede0d173d38344dea44f96b67d9a2eea1d2af5f748e8ebdb441bfb4e58e2d42fec740566acf73a303358f7d89c8158cf21fe85b0d4a417ebdc86d0469f6b91c24ad610d486dedc218b2ce7a8b96754723151f0d0076fff9f19d112d9c0592fb8d92c99dcb8ddfaa46fbe0d92df46b8c00ca4345adb69a5aca694a86cf30646451bb17ba6e607a912bf109d5fc2d3e27d00d945600a8a57c
+SIG: dec46253509b11e4b52a6ae4f366b680dffc280d0a044fc0cb790b6e751381461e1e602a89e3b3d3064c407f602f1c22404b6823bd2467549314a00001664a08
+
+TST: 855
+SK:  43bfb3dbe4d9bdaa82b354dd596334e660d76fc0b2eb698993aef3767f1c7c7f
+PK:  d00aeceff0ceb832c251d1fe6bcbeaeacbb4113f5281baba4e878f7b95f93f07
+MSG: 3f3eeddcaef4e1662adb66bb1b207d793fcbef815005e82643ed70c9855403dac28b520727a901a532d28b9bd1348db2f8967bbb8c9098b07f570a2eae1ee482640c0b67a52a38612133a15e258ede38cda878ff36ed321dff87cc6a01383ba84067d60af41776acf80a8a4eac77f7d87c37a704a3e2aca1e8815e49fbcab797c856529538be07d51696321f69b09b5dc5a15e5f0e4c22d22837f62ee4c8bc7f25a9487b962cc20f133fcb870ed125cca585d181bd39f9dfa661f19be76da7f65f22fbbc80752aeb39e8d59ed96e14f595d04929402b5029c60cee37c0217bc531d80db341dace3cce76e643aac53887473edc6e19cb39fecf6af424a2066393d1c33fc7b93676d7e6105b9bfc967d1e29afdc4cf15bcafa09c295a6f9deee331ab3b0d493126e2b2fffb42a6b68e79e138db550827262e487a83f37f01dd7922be75e92fcf5d9d4803b3ac2f35da210fb38b263b0ffb6c2708d4b55b757af52077a7e3184d01e82f64d32cce4fdee0f8d4e364bcfb958ebbfdbb622b38b51e930271c7b1b70aa9d4bb3aa4b997c52144d3aa62162573a3a1d9ce46cdbeeb8449f1225c449631e8897521cd0f637b721a1252b8a10ab0be870afbcd89d58b2ebb63211950cad7ab82c8195026b50ea8b77b9e90ed559af4484308851a3a156716853a8ac4ecb8c5cc7d935b0f466124143b1177f05d08b97d1ad542ed2c2465af185e7db42b69cb802a71794a3139883029670c956742aaad7907a71d95985fc1d45b65997b4ec6ce8255de959270afa7de90f2929de63f9b17211d7f1ae820ada9ce3e48649179d60b0149493481f01d459db7dad0526b5bd9f4b3380d25ba2c502ba8fa3c4d4131b4662addefb41827f759fa71d447d5f029245f48c622eb7c68c8e71081f7f789de7a283d2eda83a7d1722a05fb72e1760c24040c4d834def5df5f742e02b30451c893bcf7d771db784cbbdaec876d8ac86743b529a292007ac753c99a5799cc324fe5ebb5448ab554b10d4136974a12542d25c6147c67c5d2336c9db75cba2fd608cd43ab95beacd043a1349cefa828e23b5f0b6e0e2951f3353bb92bfd1f0a49c33fb3cf3799a0b543198ad5d03d263c1a06c35a26ade1518491c8c1d27a2db033808932cd1c47b5a126985acb8d888360eeccfeb3bf51b0d189b4190440404d12fba65d0a7a14c620c555f822
+SIG: a9995523020a0d222bc48f98d05504e3068f304a6d197006cc9c035eeade099e7aa97e90894ead17e8c30b0aa4a98088f038b92244c4b20fde964f8534e8fb03
+
+TST: 856
+SK:  514e070b0190d18cbe981a5a151e7753398a272bcf014813ad379722c36e133d
+PK:  6fbde0474cc4810effa50a07820c965aa00395ff3a5b3e2edd7d356b7d6aef2b
+MSG: 831455762a5d80097bb2845042f4c876e7108535bed683e8c44619d08154a229444b101e3ed7c01507e870941446af978c0f5341d1ac1dd15b14e8966712df19f52feb5103cf62b6632756446cc754df00a3f6dd719968a2cef66c3adfb7d1fc491fbbf3d59294ab34619e176db0d446151e37eaa3daf172406e983d9d23a6b69e92976030f5ac7040ad5114129feaf97af15b2296fae70492dbbeb2b4827687fb798715c9bb2c32557a81d891b897052900707159751f07db074c77f0719671f1766689029a3cddf39df3483cf2b04f71c25de05fc2d02bb48e539eaf1a321646cd80ef2f0ac703f45e7389530800e5d417ccea8a5c086682f04745d50b5dfc8f6edc87a95c7d202a9cfd998714b746920ebbe2335bca1a0171762016f5e4bda89c57d0edc6910c6d22c8f909da3db1352f0c8bd18f3b5aac25f193b89470f976bc4f1affb3c66bc5876c6fe2ac7508533d97bbcf77119d9aae193f07e0b64b461c9c6c3b9d293bd37de3d8e1ab1e8d872cd94e6cf0eb68439fdcd3b25ce8483460bd8b7cce889fb722b4361e118da983ef4a9e45cebc0c1b8229ea53e6f55505f644e09acaa4c4b8cc640b2cd2b312e1c3a2c02669e1f9c06311c78d360009db9e67c39b49d1e5d770c01d284b0a17a41b4e7ca745d665ec07500e4d9fc8ebc1cc6af53a3fc76b0c3f1431d49843f20e182782c82b3b5aae36fe20ca642618068be233d4b5ef9eaeff401536dc593a2bc18344f55ac5d5fc7b3eb506d11cb375330063c620c5334d723c7d1f042816bc4785b35ac0e6f174f736878b7b491658ca67d8fcab538fc6ecd277ead90d954b460da4253a1c3a30b3d8928f69ac9876a2891969fc2d06a668992b8e2115dfe5358a7124ba7ccf421d8054ea043444cdeb40b716dc7a3659a3ca94347293489060e2cf6712a2a6c7b8ad146785fc40ccb9da287830d011d0d24df3e7afbe972d6f417de5cd75f259ea07cafdde205fc0a365135c232cbd7c1bc539fa4b7e1cce35185237c23f80ae97c186d0d3b10503d5984a20ec41c3cd042c28a4c31f9574b06a872bf959ab0add1f5dee14a1e741ef238dfcdec085aa088dcf39a36dda8f2a85ed0d362ccb005d02e5accc092a376dc11a566170d583db35f1de0be3f15908596e9b781ac81be07b9bd2af46c56fb4d9d84276011e4618b7f76f96794cd0fd57ed414b63
+SIG: b6c355c958b5baa7ebe977a93fcf539589a366d40160e4e031b88ab96402c7bd577ff635fc07782423598dca43668124a8b287510e2cfd07a1e8f619f6c8540a
+
+TST: 857
+SK:  bc790a7385dd1dddc762e3b20221dc078b6c3da8986d4180940727257cfdcdf1
+PK:  c9264626f68fedb5b39c28f030453b54d0d51a98b17721f2611d7f277ef48b81
+MSG: 143dd7bfbff2adc71f5d123d474ea069df14ae923ed9bf8f9891e60bae43f0c9f55537ac9d1ae523ce4ecfd33b20ae445e9c426372050fa5217c1e4fb01353ebf2e32904ef7eefcf72e8023bae06bbb640cf777d5b0e11527bc835493ad6980a157bb2d50be23365e72cbf0b3f209ef0c44a00b41a62262488096cae5a696b4d64cbad34500d41fb4e4bc70f8bf62144d01c2275d6d29f5de75b1721d5046b6829164443ebfd9c1781319d88f54010edc296abbed02b7dad9ba585b552e0005dcca400bf4f459eed7db86ea8612be9e918dfd4e2700c4710083283626fac754417e0087d26ba145dfc45b1c9bf7b4dd70e6c508747ef805c9a02425aebc6421e0deb6a79d89aceeee01ececc9f3ca365383826584c430ebd39ecf0a72866ae0aceca5ad4f0405b67779c04c5de0330614da3470b805d787ce79ac5a696dd6f6b5539b1a651b424cefb19491da6e0889223cc98398b42c00414ff8d6c0627eb97cff20a8cbe7fccb41d810fcfe858ca7475247ef628e84a09d012fe12235b38c1cc9d82e2b69d01d6218cfd48e85f26aeadd195408cdd4c2f806a89041fd0317fb1a7b6209f904270d34e606195047288b0fb11a5722938f67c22b313f7f74b2025c75bcd1ecc5a9add4a640a41f2996eb66e5af196198db58a3fb9938f349f922a24d86f4ed8a96a09a196c24d6d01ed76f3816c05c4f26baca9b9d6dcc79b580dfb75d6c905d480dad76951854bda1caa7f4a819543aed01ae956bf3058fe8b3c7d5d724962f1a6a83143ddad274fda3ad578e98aa967c410ee57575ef01c0258560f0a1fa4b79327796de99420cfd0a415506360f1242ccc58a6880927750dbbff13d7c1b4ed519cda357210f12fb0d1c4d48f0411bd7e058cc4cb93d3c77597e2653ffa282d3c2f128ac33a237af2fcbc9ef9c811f37814ba2b0b85093d0fd18b8c6fb09a43ce52254d23d55f32e1d3242aed1f23d9cf204aa0dfd44a346fe09e55a4a06cf1bef8bbf37ba1f1598a58aef89501ecbac0453543e480ed0adde90c841d95ebd6eb23baa9f70f83c149eab32d0913c79b0993d0e1d3574f0f542e56a20616cfe4a8bd7aaeebe0b083dc2ce0146178c07482a01129bc6fefdc8141c1384894b69cbe2f29da188f7fd4ac341a2df6fd90dee6a446d2746324c75c1ef5b1ace187d3bc16d70559892975d7e47138f0406385ea
+SIG: 6d6bd65f372679fe9d945ff56516333ece0b7a25b15ad2487381670e536f5246775eb39a114db2b9cd50f312b360d9d0bea295dc37b817b332890adb65e4c401
+
+TST: 858
+SK:  db3a44df40d255a25cf23f53c45223b7d8f1f1f111ba07406b71e184a8cd0612
+PK:  6b12bd9580ae207a9b0baa8287b8bb86669373ee5e5a625ab4a6ef2d08712597
+MSG: 52dd8ba4fffa344d1e0811d9675c313f9cc0e5a138478691989d2b7f7389025068fa35f74f9aeaf1e95665ecf8d5707f75f65f2256eea93398be59c0d538f5e8584bfbb3a240f5016d7927234cb3eac35b391b8b53f20ed8bae0ba11089694bfeade11071656d4cf18ef2d368192e04e08e3024fc1d2fda6312afca68d10c9c336a0e36850be1a4f35b033a85a2a9549f2673a995f2a9ab4bd46c8fd2d838e64f761713427329c9af5e4211a22ab208aaab80e194cd0f6a502b308fed6c583517801a48ed4330e2faddcd41809c3919b30e84db3c68731031e79857dd9f97ffd12547da7066798074151ec88a5fa963b9d9d83ba2fee135833950ef7bc62b3401ea11bb36f25561bc0522bb02d8dad0543f63d547be77d0a4c9bf65d42f3a276144d2e474e2942f3790221e26fbae7ca91efd85921990835fafb6dc674635c9601821038b52711343d1aa25f1c46ba4e3c6e712bac19e53eae30e5246e4f04ddf2acdbb34163c243677690be0bf2e3fa164870b5e6f536b22fb89e5e8e1d87cdb34044977ed2836e544d7ba493dd42a2b649bcf313c5b39a1dbfff3e7f2a59ade87d3e7b258f58e565fdba3e4d92b1edb8bff54dc49d86c53c030cf58b97ef066d241b540530213905739d8e1aa72ed90f685d3958eaa242b0cbf7a2eb976ee96a63e66786464169a742d457e4d9117c7d66428445a46930c28ba7a2658241805ebe72c78e02035d263a211e590b490cdb84415062eed14f13b8a1a9e77c8d7b75515b18fb85386e4a7e053980d30f4899e83863bee875585887c5f48b516ccb731c4bcaa3df07d04795814096c79d7c5fdc4dabf5e26a4ca1838e0e5d87db71309b81ea7ce461e5e44c7ab2f105ad75c543c1e9179c36a5fa555ec922ffed1b76d25801dd74f80cd0a6ba7bc20db0ad580b7bbb9ddcfd93ad1c5f20f3e27c3ea3a1e71eb74ff5f944cd3b98f6d04529593011c4aecef6dcaa60fb18368cb12b6e391b3f5df765cbabff15898c84796fc2b53fa4900dad034a13b0ce1445adda4ef719be741419e231e92f1f667a32842a42db79bd7a014a809c81596e826273d16fe5d40458242ae10e12e60b3489530c6622b5bb44454f29616e47e9a297ce1ca074137fd9ae13e3ee8edbcf78af265459db1af342dc0b2fc809bda015b5a82b2b7c54efe4e5fc252eb13d66e808936f1910f4c48be0ef7a
+SIG: cc28b5ef4b9773637fae7e5f084b6994aa3598f8f4a65d0bb201d172d861a30149b3338d3c3ab75b32b25595cd8b289630c3376acd10ba2ab26bc1aba900840e
+
+TST: 859
+SK:  77964dad52b579b8966753da3186d1c5e9d33d33a4db38bc0d7a1a6c112c13c2
+PK:  fc25125e7829f64234375e52ae9f77ae1013f99df5f9965ad2aa16589596d091
+MSG: c339e718a757f3f3bd1babdd2e00aaa5cd7fc9005ee34b6fdc09d71fbd9c9289ab1dd14dba2cad58cb805116777bd80c85966433ad46f9ca6e54f13dd3ca7e56e47fea41e5488a45ad53bc5d657427e1d7938f5519f1b09f5bdd98aae5ac9643ef78eba4934925339a155dc66828571002097a11a5cee7b51a441b756b0ce65b779afe19da6a18efc145f6090ce770de9e0e91f543270a0985eab475293ccfdd3141c4142e4722233b267499447641235d728bd75cd1adc0db142f7331adddf8c5eea3d576405d869915b560f964e3e0003c91f5e96bffbeeec73e51024ef52c55c6dcb54d58203e62f4ddb6e137eb08e1bf1326018afd1a86cab6c841e0661ce0a1a7ae967f24c1a77fc7ca505f72e5f7936e39c6f4837e2595195a69cd676510a7161a4dc5e318f3d4f3ac0af03f8c4ae5bce39324e9738aea49f002d32d16de2317e95a9f32ee604e13db8038b264cfc17aed29c9debf8191de9e0efc951ad6d54867068cf50a269c37a241f85206788d23143177f659cca66cfce03bc0502255337f16b3dad6f79132abf80ff12b6d2281e637eb6c71f76e2633a114565240eed00fabea9ed8de28c83221f8cb485f512d9008bfc74a366d4c2b4ed172d367e0247cb65098c110282e831df8e9bd4fbd5f4dd2b7f2420c23b85a637aa2262c3cb88405f70730c9ab4c9d0f227ee4fa4ef91efe9a59b3e6d843db879f5650059e99f0e4a0386838e6f9876f67d50f89832dda5f30a9cbfd710134f9b5b54627496aa3a43212b07f03db11d3d4f875d41d1f4ac45969ddef69f81a06d2b0c646c9cd931cf2502fef0dd32abbf0951ed303f5284825934397fc22e78698d35ad81d82256bf9e15400a1091623a9826f1e57792367417ef02586d64e650da9ace2f18aa0a126d867cac4b5d4c91bf5209e5359556386f827083eb53e8b4709fffabe92c61d78ffb5daf10274e242a70091f3f9b9d596c1258c9a63384f4b05b028661222181c0fca965f0a2cb56e4b556d6fbff71b64d9b358da31aa37c74ff5962fb8d96a383d049724c19e249c9edbb2a375b23ce3104da0ec58d2635ba03b55423fa2db7eb349a4fc58a1ef540ee9a02c2e703c68d7f8475f434ddd3200db1f06745791a3acc3160dba50a393447ffeef6dc7b98fb06684cc90fd85203d119dcd8199e4d9a89ae3467ae4bb19fb71cf747029c24096f9a50e
+SIG: 3d1b4b4e820d250be2a8fa971e599e1e98977528b2f930189681a93b05e1a706fc80effa94e929bc43921656897388288a9b29271f37a14be014b873c68fc904
+
+TST: 860
+SK:  5cafd817a4410ccb27121723ef3207c1731a0861945be962714c0ed95038a195
+PK:  4ea086be43ece1c32d08059bbadc9e9a2b2f4f3fe370f1f5ccd7dbdec0aaf303
+MSG: 50b2f05342418046d16a30be4fc62b67daf6c18d2a74242b7cb55ba90ad20b6cafdd60155737c29de48aa5d799fe5495fe59df5a9b8c0a8e5418904763fbad83ea6986651bac31117939cef4e0c79930d52dfd7db43c31addae3cf93e3efc5a916efd0d65fdc30909fa356ccbc5247d7aaa067131b6b4820fd02f8e395f5a9704c9bdd7560a611d62559a8dfe1d2859c52486cc11ed3331992488f417520d920dc73a32d4f08110082500f5a962a306932c6a7802955cedad7abf53b0f19fe4794a31d6b855380284306ccff71a4007859a2328bb19024c43e10d77064d866d9622d142c27354b84ac3b4f8232f7a2f8af6409d5cc757a18ef813dfaf4b9bc040cb006d77f143641aa2036ac7bc928dc96585d9e36c7bc9c564d25f1c2cc0beab9d5f207e84b215f1e7aa6fc328237b79c39923a4e09c7c73dc6b24b1416294d798a4ed5f758336d915a870a7d6b7592b5b88aace2dc5f267bdb491141cbbae2a677407cc0955f961962599304ba0b839671a5c000e920108a05298087e49770aeeeaab3632724cb0fc2285796dc414814fda78a54e67f00a02f77d3ccde1ed9d7b1def14ea1f61910bdf30a1196fc6351b62254d6445e6c90445b16efafe289a2784b92e42b78a4a900c35f55630bbb7762ff9eb7fef7d04c90b9571c4fc760a410dbfc252991d0ba27f2d414fe64eefdff4abc18817c9706c631bfa203821d3b92cb338baaf5d1232b462647954d0902462fb1696e991f07fa9c3dbcf2872960831b4ded92a421cf21b753165ff309efe2ef5438c01270d10c6a03d34f71ebc2dab1da90daa357984d2462bcb35ee3de55c3a55f8b98aec2114f74c84341a64127863c120b5ecad9e329a5756ae4a2555d8492cda835225a8deb3f9c1558f0d425bc172ff7640cc79d97800416fd6294cccc70cd1cf5b6a8e2aa07289bd522bf99dc96c36bfee80e846f5dd746dd4c5003e4bf7d29efeea7508a0161236882c9a82a56aa2c2574669652c630923ab470ddb95d456f7b8e8f07599ba0d1d38bc7f8176e3fdf0209bd6f75d4cc11803afb1856cbc0e91c73730e4fb98f3c948a87d5a7edcc0a6a8ac810ea3eaa6e063cec5f5566cd6dedc537db6d686b8021f6ea825ad7475ec7f1c5dbde45d3ff4b5ee51c0d04f1d74018eb91e5040d01c8b71a4aabbde6094d4afeccb18dfcded73ea75e3b9f8ce167df6209ae
+SIG: 288515fa7259f1eb587fe8a2c403434c46f8d7e75b6d22bb3896566c017d09b698c2c807799c2f65f9cdb4eb58151ccfc48d108061a6b3148432b2bfc1cdab05
+
+TST: 861
+SK:  d5cac85521af781f3d5f66862a04b087d0ccdcac926cfe9e747be8d5c2633f78
+PK:  100dcc53039bf05ea0a9f5888212693d4f9e0e752595bbcd020610e0ae213596
+MSG: d5e7dd594909375a4be08e74825d598d535bf46ec084de52b57391c127eff5224ab2d194dfb26633478d02fbda74d1dc5821f791bf962d8dad9e4ef24224891907b0189cccc8b133d3aa2078926daef2898c19c2e0bfe02041a904b9f04be7cb50aed0d962d1add20b40a88ab7abad626cf4da0a78f9f53685501fdfa58543ddf2ea0eea69e7ba160f8a177a25fc21e8a29c661633e30e523b0ec01b2aeee2d426e4aead457488108fe5f569cf6e2fdb68c28f2b3052823577cd934e7b062c8a3424cd4367fb315b744ca35255d7f1af4edc9bc9d8837123d97903b43df367c7d418c79347ffafe7c7b1724bba34ede8d3568db505983ead47f62b56e3618c11db8ff0bf492ac67597d2f96a6f420ff985341b786ad6ceaedd105d0d1563b2d53543d78e7256725d204e82ed3a2e6a6e83df61fc282a62ca06e62174b55bef40a0bdf8d23d1c330c71441485ee85e70ced121eac607f580678163e4bd75c6709ff3b41de80594b9e2f2aa278fefc21d73ee3f72854b958d9a8f63e3d70f7fead8c3dca8e71bf4b9c2a36f212b32eb3292e635580386559ee1a11df15293a0c21cd7360869846ba5b7ba85c994f5b2f9cc50e5eea8e4b3691d886062a18cfb182f1e8b611fe1bc263159cb8a086787c811bea4812530008c70ca0c47e64eb2fbad5b02727a66f2cdd6dde86f5d2a9645a1e9aa66ee0e15b97f5fd229596ee02e661cab9a54eee1b81f98fe256ed6c54feaaa0ba047eea353344f6e5c62be1e9d5c09a2a699411110c56d1949e90c07b1938ba9555ac1be8511b510218d7cde7e1d74a68afb642f81715fe9e6c96c50381ae5a9df306518785dc4dbc3a64f60f245c564b8029512f381b56ee787703426803c80ab1c311f477b891708b59fa748f32debf54d2413771978c265c9b87114adf25b8337aa93b0e632a5b6eda474bec16328159fbed067b00b87add61965492eccc6fd3461c1000e4037ab1e8ac89a8524f78ae09d308ea6c94ff883732b712eec0ef07718d33c011b9398f8cfea733075af331fb3f97cdc1e8c99f6a10725a68c5c58fdd8b0baa50227f34d73d23905203698eaff626654ce83d865108499be6861f6141bfa6219d7ab8b584519199f880cfa1b26d9194d301711c30fb446d6ea764a4310f70e4b859cf95fd44aaf8c1e240e80a71611dbcf52da58edc320311de388d5d9d769eb59be093
+SIG: 5dc03363414eeac0086fb6feba44217cef4c520db61926df680ca602dc11003ce6afbf3d13c8c5b05273d21415e67c14a2ee5d0b1d5352419ab9b39c003a510c
+
+TST: 862
+SK:  159a9eddea5de63403987b5670db6fac98ffe5ec3a6cf01516ee2c70ce3b3be0
+PK:  f61f4a04a5a12ccaecfaf44c1c9c1888475a2c89fb02f26bb81ab5f78f4ce3a8
+MSG: d195e5900dd3931481bc012e77bf060aaf31cccb0fe1a6c40eaf286a6166a166b1ea37053426284b920c67fee1d4b9d86fb861cc6edd34e10c52233734d9cd92f5dbf433512ed255ac6b26e56f5c664bccb260692cf49d08363ee94e336acc489600a6aa512a040f10ebf18f7d2cbee9cad14c4ff87377a3263419d8297529401f15337a4c4d2325ed7def763a0d479caa408266834da242f3a16b79a45866b9d9d71a4829317674cff7ae6c8c587ba4d4980e818613d3ad82507a7ab032bbf99c5e9b640371bb41b91e965dc31e8c7d4b3bafd49570527faaa87abbf6416c47b1b1b09d3401253126cb246ae45acf5f100bb1f92f11a5c6c937e0588d8b146b3e4d3c7e5bf57484e984fe3afc4772f24ebf894cdb39837fbd469a921a96ac5af5e070f6c9624c588e9d4fe6ddfeed1f8fe20eb9c460ce6ee38bf471dd56dcf2e3ee998b8e7fdcf612e78a2e7c7173c0160982bedecc2c621e5f6611b4ef2102e32e7c29803a7e25fee151243158a76ee5d8c1bb2e7d8c88871ba433c5e541c2602693d90110be795b523a8fadb605d8e3d7e493fe245d9cc5320d32b85d6135a44b1168729414c2ca21560fb4feecdeef0cf7d8e071274e8856c004033e80013c73af7177c3197816a5032d9059b1b6e4152c386192dd54b90f9d308be98ed7d0ca9d12e8aaf6f9d869386aa9dbb01593d37e72f090124d3455298e9b4c9ec3cae73bb8ee41eb63e38c56133efdbaf449b84e1e491e496f1c70a44d069986ba8818422069061bb6ebcb7b2054e63df381ba03c6a7674abd61050d693d41bfe3ca5046c65ffb06a0749809e58d4c93a9ff69ed30950bde1f99216fff299f22f16b07c254c265ae0b12e313163ccdf5036d49055f9a9667b0b71292bc3b6260cb87568fd267170bc940c33329d729c9e32d0f9180b134bff8ae93b1bfebfa3842fef20bc04a297b00a84a0f428d5f42fab86142996d4ad9efabc49852f8812f3bfb5e57539e2186eb8ae229580bc60448acdef5723c881588b53789f05b91e02289223252d753f79813779ace705e04aed15265d3bdf2a2e4b15654770a275854e64cf44390607a45d7bba9af3e1a2e283067fcd6e633aa2d2403bd81f7c792765510b598412f6bda07b2a945b9f6d46ab2f7c320075bc6b60a80daa44af391f4cd562131bbdd407d66f8db1259bd76fa7e4d5264e145546c942dfe9007
+SIG: 0543712cefa29a220d90f81baa4e4cf77ac65208b2d5ce9fd17ce214ad4a937b7fc5c786413b58051cca3bb8b2eb55657d89572bc50ea2e5ecdc555088491603
+
+TST: 863
+SK:  eda0feac0f2afe0174491552487f3962171332b822dc3da426f9a5f62bef7b8d
+PK:  eff27cb51f4d39c242f323019a1234818ef2e4cd1bdabc0f2d8d213458dc471a
+MSG: 901119da4ed181aa9e11170b20626e00abf0b548245e3debf94bf5ed50aeefe942b402cc9948947852dedf2b5304017665749cd47c21fc652ee995679ff931e30e94af98b4a98fd44e849e98470fe0a76ce80c61f83fb4e85ba523ee3fd25db000053b49d0930e3b079e866e153f7d86367f23a4c4abc63b3075461e90e4fd896da0492e27d714941e967f52c93ffaec44803f57877d866eb5f8c5281785aa4826792e3964c66590821eea66752074264018a571f5b013b38e152c95c0248ae6036822a67afc9e02694573152b864c56c2f730a08210f85ec46f984a643d516a15fcfaa84840f512047d110e0718d293955f0158257fba0d78eb7df2f0b77e6eeb76db5e71707310e827361cd4e119740e63922db42c2ceb5ee175d50decc7b749fd2325bce1e6a8f710ffcc1e1c9b33c380e52a64daa9585fabe406d9cf24488fe26f3a495fb0ab50e1e2bad82381aa22431099cc8a569813d79c9d78569c0d95da9aad2bfb57758d52a3752752e023d651c9cb66a412a5c80f6ba54793f7ec87b4c598fed2ce24abd7608708895c46727359ffeca6d6c62e10a678caa718b4cd263292cfef535b9fbe2756b7396d697b3146c551e6aac1f5f1c24be9b67a1e2a2aff745301ba6a212217c53d681681bbb401bf4a43656f5d15cde969c1780099a33237eb19a3b8585d6b5dea2fb577845f25ee2a82ccf4b28502f90fe80b8cdcdf2ccf93c434c0e6aa5d8752a44343c2b18d20fe4004c47038659356f87abed5445034d8e2d3d14768f5ef312cf102a9884683bcc0cd8a71e3ec36fbb6334a1bbaed5d2bf10416d82bd6530475380ab6e2577bbc69cebda75faf02ad827b54518213206fd4cd66f252b234aca9eede7e3eeb815ddcd8d519c5d7f5d9d1fb9ca0fa4467990095fa46220c20a2071dfcaad5f024dae3416f7c492d757488c49a2e4df483bc9b80098e0d5d683facb8c960829dff09b303369d46cb57331ff21791ee25d6be7dec7ebaf1b32479a7f514dc647105c944c36f7dbf0a5b589128dbaaa42171d642f25a981ce1f8379f91690b36af774648d5624c08dbd0a90f708716dfab2024dae865b9c49ab27473826cd4a010bfdb52011d8c7cb3f421ca8ca3cd0486889188e67df00fb8c2a643e7adb2f8279f763e5b9a81b6dfc3f721fc5f6849f66736788cc557c4ebc6fc68d6f6ac77bedda8acb362243bda74e7b2
+SIG: 6cbc7e6f5e12145b01687ad9ca6bf6e47f9417c2cefad3fbd68fd65dd74faa9750cba992de4cebcfcd35808cbb3ff12c8d930799af36efe7976bf2fea79e3e0e
+
+TST: 864
+SK:  ec059fc6be983c27eca93ddcdcb53af7286255da91e2a56a684f641ec2d09d6e
+PK:  ffc6cb751c70071b65ec2ac6b45fd1d55fe836965f80b3e7c784fc704acbdf69
+MSG: d1ac6325a4e690fa79536883d5c20eacb7d964c0178f742c2b23727deb62645af7c81922a0e72e5e30b5839a2ed5e567ec31ce224115b82d2bf251b7393f01b0d03a602bc120ae62af7fbc379dfcf95bbbba984aaba34fe212ac99003328b832c3532d42eee1e1874dc22ad67db6c91dbbfb2b45785dbcd39917d36fb48c1b5d6f38bdda5d28fbba64175575afea46c8ed6757ff30164e0df2e72176e8b6c9db5b5ef390b72f2d4d94e3b66f0d44a7e0f06e89debcdf1363c0e75d50db5bb70190d19f66a39c6f7dba70dfcd4a9fed02c2f1d067e7c788c58fdb3e17a2377ce486ec6582f3ba997bb5f70cd621002956f5131aa3a1617c0cebccd9391de1307c85970a8bc155f519872668450c91488689f53c2c1a7ed53f388cb13a2c3896fe5b7d3a0dc1683f27664c8beaea680c8cc54a90e4c6f99fbf05f2c22df60de9aec80c79b7d66207050667b452d7857f9a8ca723280dac7992e2079267ec3ad911404642c4e326bfb96b43c89434ba4bc78c252f4d4ca8d13a8874c6fc8252ea0b56c6bc786847d4318306e1c652c452585eefd0bd9dd3c148a73ba86eedea945f016713ed7df085d0066689e792dacb2bfc1eb5c824372a26c5e944aa7444ac9773d4a1921e49bdd4f8f6d788c263fee04c7b444c5305edb633e1ffe0ba4ea8da011a62f2bbfef4b895ad3f224c3ba3bff0c95d75750c9bcc66ff8a20b6c24bde7581a7ec3866f8716f781f46dcad45a9ebcb6ed46953368397011735d4b52d00e8db397995dbdb3d4f4254687f04688a268c305b2b1f622cf51b174775bad7f6674adc2e58e05cce865f12d7569c8e9b35bcdf3ccce6330d08ce5340a7c630f27a6c8086b5146b292fcbf50ff6aaaef8848a707b2543c618d17bd976c240bc79d33e004e4953482915e7e6ef94964bdea4e02dd7c2f475235f2b99e43229c9ac3aba0db59ac2da03a9ee4f37dbf247a33e6dfe5be7c7f82584f04a46d49f6621da31b91ac3daa4d68d48a56659b448c0ed365cb4aa0cfd908853df5bbfa88e60e10a5a002c32ab3333f2c39bbf3ee01a4aa60d2d01423e6097dc54305f81a2d93e2f6b4e8b351971cbf2457dc76e1fb89293384798ef28234e9b1a47dedc2336f86b8e13c4aef790f5a11239c747d9d865c9a15adeb071070267e5346256648adc0fa4dbdfd787ca1465fc240a324c3caf2931da41499e275fd4b35f6d08db
+SIG: a7b88e5abf132824bdde77c5f8df94ab26481f6bee660ea162247082a250d390c71d320ad060d8ef341fb69a483294f0d6de726f0c862fa37ea4bc6dab521509
+
+TST: 865
+SK:  f16abdbcc0bcc61a1aee3abd8767ab52e5f79999bb77a3976cbc82670dfd2f73
+PK:  10f451719db0fd21376e228a41c3035c8c2bc42e5aaa926fe608878dbb0dc7ab
+MSG: bfacd7dd4eea467dcce404f4a3520a45b94ebaa622197d02d61529d2b3bf273c4ee1fb95a180c8f87de190a2e5ea70b84ae1eb6fd4447d8a3a8ded10f6ede24f0eb92bd30bc65d4871e8f5da08cbe8cd3c0ac64fd5a57a6b064a89d5159b42f8b3e5a1838c9cb19d88106c0773a275cd2a1d609930bf6b30aeca62b97e319bbfa934f4d0a1e6ac80baebcba2d8ea4bed9ca8562b4acb56979bf885324ac40ab4a50bfb9f349049fc75a0e03de4cc43eae3c6a6cffb5f6ae6c94504415e6c7ed3045a932f47fd20b9f3483a77b6d449d8dfd4a638dbf56f03f0f031879059b2fb49767943f46b3872e2de567d5fef80b02925e9863e0f1d31a80f4e6451c325694b80cf1f1918c6e498878edc47c4530cac466f1a294d55df09af4fdc8072adb1bf26ca8c92f912a2b9febc8b97b58c1e9d32c780323052972b6fbd53304c05193caeb67c5bd3e67479725d297dffb06890abf8cd9e42458e168a6118f905b1d53486016f85dcd98dd339e3460533d0b8a49fae6dc1a071725e6ae5f294479ee3bdcaeb74061841fb2608e88a49fd0f3895b18f85b90f7241dd1387710053faa62bae75e9ae39369c1c02de5d19242efa16e11d44a4ba5778ce7722a91cec0bc0a08c069bdfa130d1c6c4b56c6e93542403ccf27684def57def26df86ced571282dc960974618f0a74a0cde35b653cc6e7730431b825ffb9b8aaab3c7a397c992bc2fa23270fb11ee431afd5f9a644483011173993f19485dd3cbdd187bd3d995ebf0031b1b0de4a8de9c14eb6f780e36b8925756b97906a1969d85e967d880e6e7dda42fd3c30019f11d7081071eee6626422836bbed27d46dd0df1feb6610dc859f513c0bc653d70220fe048d2e97c2e06af530e11bdc7029bccc5c92edecef5e4a2e0be2d251f4415dca3e55b3a850f2630b879e4e036ce8633bf20920b68094215929accc7be40c5778bc554e6edd7e54c9e145b2ee07b65d061c11de0e83f381ce4f57c6483f51069363511074c7a577353b45c6eb71199dce5059fd2c4611b054238aaadf2b6ba534bfffc2722ae3e31ff79ae2ebca99cc3507f8a033cf4fea70c52f7db5de442b42b8d41e99012e42ca0e85a9fb6d4f165b330de6383c5726efca2fe971340002f562dc6cb8f2faf0665725e097799d096091864d66a950a5790953ee16b9ea582009218708c4accd81381358a2c689a041d02d786121
+SIG: 33d805290869b8e04ff089faa2d1fab83743bada68ade5b38ae5f0cc58c3374eba43943c1f5110678eb39b4658611822a26d35ffe19e9cfcb9ba9589e4ec3105
+
+TST: 866
+SK:  be79d1aeea86e86f398137e62ffd79e50eff9f313f25192f89e52f0b4bbd5d32
+PK:  187dac855ca442fd9a3ddc3289c24eb2d26f7a40fb29d8e74431b25022c3a0cc
+MSG: 6d632a7d3c9be53649d0d1a5eedf519a413b13ac64e9ad854dfa04f2e17329d822be573d9e35ac066f022213a344620bba289f5331695584d1343e815405aeabe3861d63b3a5b92b8cd8eeed2280222abde30a1bccd3f3e411aab922fa1baa097aa5c780d0eaef94ea10fe21f7d639b76d4788aeb5924a9d262dcbc5688a3e43544bec088ca2e0d06d77a71fb641d55226614452b1e0807a9fcd3ca69bf7f25d8041470ceb7b21ead03ec037a1629bd500aa233b59be44978210b6a366f223acfa0797954007b00efb4ffadb5fc92bdb37863e502d7d70681039edf33770df3d1de343dc35f226d5e73944ba0255e2a88ef6c41e472b214567c249594a50878b6731c1aeb5b10fa91fa76a37e1f9f1c00fdbfe3485ded54a009ab6133927115668b59f5115508da9370f6bc92a1185c0d5ca01d291e18c54acfaca738bd71968a342a0cba62e4bb104a5bb379fc83ee1820d1db980253d6cb383e95af15f53c85d175890dde5e4ed03d2d0135e3d60b18293f5b5641ef83c6ece3d52598fc6353686e6f7b09fdec1f6f153672d34b489b48a0db9e42ceda71755481c047016c22534e90c6d201ed7859602636ea77ae8c6734b7c4c5bd99579c508731c7246a29586e406e1d932f6713071d4bea63dc5e2a3761e16024d2c3284f709a1f2ba085ead3200c7046275cb96b61a60b5ac559bc488bd106467c3de50bf5d740d05c9cd701d65b7daea29e64dd5a97adb6b5c82cf7f23017aa7ca1ac9a39e5827eb47e20d359b67c7d4e1a8e3e27c52d33d9303a592623484d797b402cbb458d1ac2ea53e1c4f7abb70cc029554a234574def9bc3b0d3835dc314902e25abb22dfdeddc679a3cc8f07340b15f5762f4407f380342554ed0c62f73b61816ea8c529461e1bf0e9d1c2d5e4c5746336bc0e132873cde0dc2158b54fa1b678a006b4d95eda8a955714273b7cc5cf2add9094d46e49abc096a45f418e2edbe99dd852911688064df7cf061d07aeef42795690f48c9ba19565475d5468a9ef45d7bf75fd71182dd6e640138f182a6a0c6cbbd00c495c4389530ac8e67960eb5c5763f5484eab1c1ab850140da042ba47ed8528800d41787f075fe0d85501a7ab76635d03410d286c0e17db4023a76397468ccb091cc5ac1f6434587913eab922b50ca5567016ddea32fb53255be67f2dcf9ffa85d117f1a655fa70dd3a54cf991531f19130eaa
+SIG: 6dab593bb1d448c974a65c6a0b6fad22b4732632d00489176ef126aa590109e0a723a113107b53e17d690a0d40b0fa336cc87fd5fce8f541accec67f7d1ebc06
+
+TST: 867
+SK:  269952172c3fa976defbf40bd6edd8f15cfd4be10c758e3741d74162d8ea229a
+PK:  4aea57c721e3dcca8239e9ad9b22c19bab8df72c88793b24d8dc47cf9740fcf8
+MSG: 7ccb6a0570c533737b9a534a341a7a96dc76528b997a9b48e6e0fde10f474b27ec989912d176cab742d89a848b3666e9277d695b022fd53a9eb89e88c720399e24ed25db9eb35d6da009e9f024ef8e655165bdef1c0d797c74f019cd591a0442a12d1ca893836ca2628b33e854f3428eec4aa5ed84f4bdd2eef8b6d225caf9496df9edffd735ea54db1bdea883ad5d47eb0bd4a6653f0ab037f040a41517a7741f91e82fdb6fda04f0dfa1bcf8b9b37bf2bfbd87327a636f907fdf968d0189d1a11809c4230ba69d5cbd84f561bcac3ad002e558c5b9b097a01902f29ce3f1ec264153d668c78b845105b9cd2ef3c943531b75aa428f179e4b3418b1d5a4aa7ab1203efa495c8769628eb1063a937b73e4b5cd0cda33dab01a50c64febd975c57a1e841508e8606094d0824fdd96cc6cfa18fa8209b30f0a2a78eac9a767176f573e78c068809b199a69ac6d335d7c920999c40cbad87cf4cc7ca5c644291d75ad7a74bc1e6392d1ce311ecfd2ebc916e39eb6aa3e7d89fb805a27a55f178912b157bc01a055f67aefa78e55c806cbd9c01baf8ef92cad2260b4bb14cfe61782dee5c59972506941c462a4da7eb899531cf996bc98ba3629effe6fcd1706d1b4ee4f2a14e921bd408f30e12e73fb7aa860536b03e77ca937823281a16453fe827935943201e6ec143a67eefa4f94e9abf94f7e3d41b70a82be69ded8a53060c2305f42f62fe6a2f704b67a1e8fddc7d98ba7f3457119b311d449663ed9e320d618dc2368d4950875b9c38c5d8c03104e2e32c4325dedd2bc267e2accb0112018e9c5a8007ccab2f6d7c737792002acb730d72e9f730829ebc42ca564c1d9271bf1869c4d35835589b7431ef7a31a070060fe4a089fb11f2dd3dce65ae0fb45bc3a2860917d933ba2d090569ef5ed43bc2532db879e0f1f225eadcbef1c03d9ed78299e233e4cf07b064a7baac34c5a0c19fc3a5542089f70167be2f85b4a10e778525223be8ffd5cff9648b1005a098b4b3924398fb0bcabcc6edf30c061ece7aea35fe98a9203f8711369530feb5e67bb2d4f59d9c8bc993854dd4747cde399bd0e63740c1cc839ad0f098a38a80beadd648e1436deee60e931e68f52979ce49f301fe39afbb615352091c8b6585fe88447ed6e59a020b2bbe66a9423ae5228c203bfd4847b5181e2c3b4dad83a6d4fa76985eef76adde3b34edbdd28d6a0b4a4ee
+SIG: 3ac80d1e8f68b4058c3a04dad7187373959f26a27002496f8afaaccd8bea0901c54cab87b2a2302e1f3625c2b06c7ebcf3ce96de3afdf00f5194a35e0552c70e
+
+TST: 868
+SK:  cc3138e502a5ff6f80d246366e84d65c59f12d4f496397e6eb99b5267b8cbe2a
+PK:  9e2d3e88af7b52ddcf00e6d0c7759c1238b8fb3eb14421fe82c34833437835bd
+MSG: 585ecf2f09eb923df20a8555642a2bc0b68c6a5fcfd6b8401c4a0cbabb4c6e6a206762b7a39f2c5455d7808ebfbed56d6760a431c7d20c2dc6ef1b73caa3c49488e30b1ca2520ad20b26a19700780e5ef3ce0144388d8407b6a70c1cda37db7f12091d892f2e91ad4078bb4db1762e46285a7b664b2ad3a34d26d8a94d64587a84527722ea83cb8aa88984e1489743b4214ea6041aa18e55200954efc7edb319df947efbfc6c8d0fea48a131613465d8f4c49498f2269145c6dae50478052598e1ca3be0e33611571fa384771eee402cc2b1d84836c8f1ad28f2ad23dee9ff1d7e1f2521635874115def4d93e89be76180bc55f761144360a8b222892d64d157ccb5d8f4855dca56701495a0e1002d340a4a46156b9b7fe06b7c0759e0b6df559b691ede78b55af64e7c8dd908b788dd6ba35a902c81dceb3788b615de225afa58a81181ab24a73705ee838b6e863fe1bcc26c1b943239230c27c6b397b23d13de6a02c97f3645da91d413f916473b018a61594b6f51cea44457da1e3dbbba6de16866657e92ef0202718a84ad0333e8336b052b004733e8e95ec13e5f91b3806a98d3db729fb735b8147c4a982a2d5b4efae9c09d0a9bf891cbbc3c8f531e76e4044ec91f4d7c5cf77310e2b2cde2e07ccf3e0a19dd6ae1b3fcb2df42186e9c72922d2d4ce51b306e81b16cfcf8f00d513fbd2c5239b45afc654f6fe21acb7e8a0c9aa87b0b605074df9576a6ddd900aca567617cb79656b3b5ecb9ff68b2f6241ed0d024ac27aa6eb486b69fdc0a0db92096abf86002dec7afd847a006a3f6955b49569053be9f1d0a49b793a5411e5916f418ecab953243553b66e6badc4e909be0ef5cc7c6d27199ec3f21423bc45773fb40b97b61185b57080e8f0b89a3ea57c8444ab27ecf7006a766047eeff54d8556cfed23def1da2cc8aebb48c94e779e8203ae2c902b51de0ede0456fb73fb4d5f514a4cebc47fec3f948469a545c6bc57b4138db34e7cc006de26ef507b54d28147567a8c29ac1ecef5bb84fb99aceb23a20294d74a85ae36b33450668a5c2609d3a93934586ff90c3b6d27329eeef3a754e9a9cbd5617ef3b09397bdc971370766589a12d890050d1651458b3fc533c843bffdf9754d932c4ed7611d4d27c32a087555b5eaa37ae90c4979ef54299c420ab5e29ae2845d4dcf2178920a865175fb9cc0e6b8c524b1ee495805d517bfe0
+SIG: a2700e3895ed0cc2aaf012a40bc7bd0bd29dd79c69c0b4a6edd0530cf3e267c0f82dd84edaf1744dc411d62c0028715258822d7b63d39705612b3fad4b5efb04
+
+TST: 869
+SK:  5c692c681198b172df2fac2aec3fcf7015c2bb6830f2a98e30a396b64af4280e
+PK:  33b169d4ca271040926ea87835e5066f9f05782f087fca7a556f7bf4cba2e886
+MSG: b160ee3a93cf6bc3456e5bd0197c09aa76c2258052f9a34dbc2ed589f8dbe5ff9969a61cfe846b2f6739dc7d4a1496e9ad58605b5a2758ca078c55a9fc1c4eeb5491a84bfd468a2ceb141a773493a9b3ee828b5dde9c00c236ff0156e4e2e45fa07931da68bbd2030a881405c4f78728813a5e04812404c2a19c9b87b1cfe9af95e273ecf9c518c53935f842563b192fae12a73cef085fe19e899e5ba08979e311fb286fbfc7b248aabd40dc61610e1d4fc9806dd21292392db2db40426c5d196a489c5db77e3e9cf0bd041e3c23b5ba1db781a10790be1fe07a2b00ca3af89cbd46efce880e1ef28b0cd79d53b42cd80eaa137eff7df90bcbcf95c9858dc0ccc6d8ca8ae3547bdbf9ff9024f3cf170115eb28bf12b7d3b701460f48d1b4b23d7f6ff72ffdc9a6c52624d15312d7f19ddb6026a15eb54295d331fd79509103bc59a3b6e1ba7ac8c112e4de2817e51c1e16507ba66f2547bc899f69c1207ae5e37bdb0e161b15b612305bc0940f9d1b382a37ec2da639a6ecba1bcdfc51214c3223c11bbab79f3fae3d55e2d4be584fd7601e4e2e558b3be5707115a61f5a815ec24aac18093457bc46c05cfb7a3f2533eadadc9e6c1fe310779e697f683035ce57873df55d791f6d2fb0e2107e6866f839c3a126e9023865ced1bcf6779955af547e1d87eb32a9bf322857fd126b0cdc5d5e904eb76c6706e3c897aefd6e4756fb8aca8170ca5b39669089af1bb141a25d6b8b06034d8b11abf1ff8f8d43375846fa8fa8a34b5f264820744d31149b7d57326c59b1db74131678f634e7232ca5ea5188760a70dc35dc89f8e453b4c65b772c2b6b62768d8373236551baaf24d3c304c41b62c36e6a3383b3a163b73e78d8badb75741e5001d419d30e2ed77c3096e8d8df713b93762c9707bdd0f365a874b9da8ab710495dd56aea93bb77fb222635c63bce9f63af91fac89c66986b8e2176dd451d583394c1907cba1725f06d25d1d0912b3e5c6c7dcd34358fad59dbc6f6b1c2ef33d3ca82f43518fe4ff31378016e578a7bab0b77676ebae0d48d0889d69029d209f283ce8fe0ec23cd832adc12a9c3e3aec2d6036695556d9313f12a899dd59a66bef28ede175f8aaeeeb2942bb90892a04b440d04b66f5eeff61ada72790294ce55c86c6d92785ddd26c7a731603b069c603c92e4fe8ff782544c8e89b40b8b55f90e2a5e9a0f33c7fec77dad8152
+SIG: ad8f379caf41f72dccadc3e915357ab0cd304e10f4120e0dbbfaac01bffaf2be893f70072dc964069181bec17fe0251055b21e23dee4363b27ef1fff67aafe06
+
+TST: 870
+SK:  9d5f85d2e7dfd03bb689d900285fd4461538a5f2710a13ed21c775f6eff6b3ff
+PK:  b86797e4be0286ae39e44df0a00c016db4555ef86f2f05d0a3ed89d89a4c3e5e
+MSG: f70b5b053a4672512c24b3168392f6a17dd77d8689c21c86efc25829a1a04fab4f76c8521684d32010455907a26908677b40dc6947d654f2914c30ecee724fa68446b59d091e258fc862411c964d668def83034b627ed416dc190bb5a263a6ff8d559e13b8936225fb4dab4f7bda0468e547e708cb04cebe1e5cfc69f76a1d283f28168286f24ecea5535e4490a0c55567a7345ef953ce426b209a3de3df595e80ee61e572a278ab02219551b73da41984808285a83598a02d9b28671210004e31d8af9242c16f90d5ea8f63a1ff66cfe60ecbe537245fa12a9b154115295806ea2d11f3671782b9af4fa86a1288e123cfd2409a5dc98f41b8f6df299bbcc4bb6447dc03a6d60e9b2c5b8ffc40d983956be97768dd0612d47cbfa7571c9969856c152cd3b473ace0b8a144aac2095c0f72f1d3147152b908ef6626d5222819b20bb3350a46452f675490c2a82150eec40d75b66a325d6e929a905ade1e3160ab950181efc66e59230865d5e599698a8a3ff560c4c601a7a9a5da3b5d89bca93f7cf5bcf5bd5ecff8f1a185c8220e4c77821e62adf95a037f2df7cef43a4c60ac75801e9fccdc5b08eed328dd93100904115645ec1ee085cc778b0f4e46e17298984a702eceb3e15283d820004f74a079520d63a75fae33ec3f4b836469e1aa99ea244af1fb08b00a8c9dfd03308dfc20235ea9c8283f4da47cfbcdbd031a02d164160f2a58986700b19526d41e4d7fd458434d7264bc8eb642e6d8dd2759ce2b85c97b3702e70da71f18edc53e9140a645627e0278e8e70539037484dcd18c62fa330717d6148a0d623ff8b65ea8567ec7fa04c892e3a1ecee96e832f4155074c83cbc93e98cc67f1fa112aa06e9915fa4d2dea931551e7c623aa8a3a7619ea24ff914e264f31fc73dfa8c430ac46ce16dc968c5a4085d5c380d30cdc6f43dee806f38d1df420a065574144737056daa62f0c098c9c52fcc04cca642c45d687345a094613d4a3c6c8788bfa218538ad7ece1bdb6c93924eec4baaa3eb15dc1494d65ffa1a23ff8e985263408fb02bfe39a8c55b300b1a02ed36c6714dd5ab750d47f021f65e08c635f1d6b7baf396cb4f93d56c1ca461bb12e94de7e5d98659a8af0bf019fc42280e111e04800ff80e0c157150e165609454281b20007e3edfaa1ea854465547a006a4c3236411495da166098af2823a459cf100a1f3c92c6390c6066cdbf
+SIG: 176b9592f8c25135292add4daacc9c4faa21d4f49b278480c4e8881c01624df9a37e23e18e84ca32d0d8cb851054222f10a495419f197e7b3d18df0adfb1b307
+
+TST: 871
+SK:  4aaf2d132884f30d1127cf187ee09388b4a5c44a9a9267e6728317398951fb61
+PK:  83727e9257349128559ebf759fdc82122cce76746639c0ada9761f0d60b940b1
+MSG: d73eaf11413bf4d5bccf6a2e809cd6832a51823aa22bd16e09cf56ff045eef2d1adadda50c2ebd67bbc4d70e493c968cb4de4977065d4463300694c9caa57206d6664693d8462c3c576b525cc7acf79f26f9055a1bcfa7d077f45ebe0b2d481ebd63f7340a33e4ab68f1604975ec1dfec45a791a2abb1044d75a4db55adf59b8394ebde6824c21145b00ef3b1b08ed11fd51dda514ed7e21e54dbaf6abb6d9e317fcf9fd375b18764e64ac9be5b08fec3b78abbab1d12a2ab09d559acdc7133fb2e0008e0c114b7cadb4bf763078674d03e9c807bec1e2ca71adcdaa310d587fa56950fc0fb2e979043d50f9ae23fa8f821cd9d6232789d0eeccfc4f47e3ad804e25cf5a425f94377d17874833e6ae3638178c78b79519d64d9793f4504606a0eab68707f6e1f7cccb515be3d1201bcd19f2f0e255c722eab12b43aff8c8c5561125fbca1f6542076a06152eb7e4b0786324c2495e79d79c0a8e295bb2e3dfd05a9033190065a284552a6e736006ace41f97cc434a2512051b727ce5bc9c4a75529ec53dd7d1f126e793857747b5ba8d03155d4555f59e8baf2f0cdba871ac160e7519a852db004f701641a40a422d4c38b6c0c3cc8fbbd05322ddc0001fb867286e296cbd69862cbccc7447038eb30f8a8123b7b31373984702c3be457a4b8c54e6e5280485a2c4ff84521f298ddeb3b3b2bc91f114ddce67030248044469dc06f362f2919a3fece5082375d04080376fe219d9b4575b1cf1c9ec4dcac5749fc778f515dda13fa0d586c264b9bb61503310762c789ca11608d2fee674c70ac4fc6d5ebcf68c4ab89bd84555fc007523c28a7e1dd08a9862044d5245b91a8778ec9ee984a41a9e13b7abd657ae2a46ae860152c644acd95367678ff64cc54006e36614805ed618a7c6d0fd33a908523090841c230af09846d132bb4c6b60e2441f9d3c498714f470f6bc03a80d14a294b565d1d5e781cffcb1304efdbbc7bfeabdedc857acc42e2762bbf97af839a166752da295672817f10dbd472d381f53165555ac8222a78535a86805f1bed422889f206109aa74772edc0bb51e8a9840cf62c92fa635b90cae076dd50e5aed9deac843fa8a6b539988285ff1adabe4c7b83d9e29ac2d94092daafec9f6673689ba9e9252d864d7577aa89505d331fe7809861277002a0b44a96ba6ae4a52b3548bf268e777780c00209b245f8b1417ee5e701a12334ad5
+SIG: 5f11df3906a712a953f47c859806b5237358d08ba95e49f9e530a37165835e9359d9769dc21fbb4d44497b93905bca8d9917c728493fee3acd5b521dbd1e2408
+
+TST: 872
+SK:  4bc7daabc5407c226d1920db4afd21b2a5b3e59b8e9246053f6a1a6afa54e7e7
+PK:  dc539885fc7bee002ac5debae16bddbe4b553fa15e81ee798876940f38cfc4c5
+MSG: 6acce99843b241afe6edd5d0ab78d0fb21c8c35aff881389d505f2f1dd91af1eb2ad229254927c7f0ecfb7a8141690573a655d69853d74d0708bf8b1e60a03963028a625b79f3dfea2b113ffcab46f3cfd4a621e8fd8ff0a968143b0ae03ccb6f42e25e2d74dbf515bc358699b635009b01d61fe597f1dc2c35a7ba4555278ee0ea456c7d35fa8757a417924b1d0a8351f226a13ec29d025b42696ec1d9925b769cd59c8e2f9cd3ce4e5c020e051e7a36f3f97c1e8ec71974bc16ac4de4651ad4df2e9c0eed686924224fe6de6c60dd4acc26e0aabd80c21d509d959b80b4353958d00e44c511d23bcf44552608bfa56a9c5ae79de62bb23f11d740f48240c27e101999751f2534742c0a6913ff64b683a18995abc393feb9d57c71f49a080557298cc405d11b7988d7116840c5adaf53bc672b46923cc457c7039940ad4d5bf073c6c886b1339525926d281dbd1a79739b2e36414cbd321b185fc88f18d2f81c809975be9a093644cc559ed2ae5cc0e35cbdd1811f70286057a3f703067edddf5eb1690a7427bb73fe3024ed0db82a5ce8f1716428a76fd292ba99a300c4b2f360da2124617590b10e3b162a6e67dd5d5a59bcca10f610fa064affd55f8483b98a68d076f278abf888a08a014e0ea499180fbc79840ceed13cc6b2458bfab9b0dd7ae9d86461fe215e7c9f63f768cee4a882df0dd84e3eb4f2d7f6b18fa57d8bc7d9afb63c21ac465e7903b9bfb8638a29361f7ebfc6e54e5465a6cef463ae22643ae410258779ca74b70401a9455a4d157d74a7029efe6b519a8c4be696756e045ae4081b77dd6031f0d250fa761e60f859d9063fc105aa0a1a7450af153e705477777c442586df407402ba238752faef74f3345c26a4533be9a61f5fc6bde48e3cba75c04d6f7b333e37006dd0c94fd3b6a130bd6fcdb3c6abe21ca60eb431cc2d8a2ece7169d2dcfce2760825657fd4c26f3c3b830acdfd508011d14764b3be91715571a3183018e0d221fb9532bb2e1711e725a273ae0cc2faccba7d5504929459c992517b05c1ddd03aaccd937b86eb67bc8202d01cab3d489586eea1acca7dc20cd0b6475c258ff673661496a22ea96b89db4bf3fcaae3bb04f67db096a47ff7e1ee239562dc10d40f053944f3d7bcc3ff4c0ff765654ba5ea64f0ea63e45a21d9b12949f14f7ea7074e9b659c5c5d44816842de89698a8fccace43eb6b4135e0b333ac
+SIG: a7a6488839bbae04dec92f96d728c464685d7a96df512b0051163d22538f74546fa986b1b60a6d8cc766a26c6984c9cd2688395898e2b2ae72dc6a2d5a9f750e
+
+TST: 873
+SK:  f26af210e3b20173990c7745922cdf9424773abb374d777a512cf5b97b3a000d
+PK:  54586abf041176e06aec5b6010e190916da54a8c4bde288cf24d8c107cb3b730
+MSG: 88e26da35c54884b47146f4e3f014ab65b3d71aa7e3c3391adbeb19ef2e7b9302e281991b261b6a0992e2e89a49f480ca2d8e684b12f9b1509b38f6a7a98a5ddb4c2d869fd0318e98ecd8fd9df491baf99a9294de49e1cf8dd41ee85730af025a701143e4f0c8e3d92d55b59ca7d4a6c89ad760dffc0c2189209508ef6c2214edf9967b17def123d8692c9e4e20b1e98268808704f5f9fe1a6d6055e32c872564bd17edb7359578629017f0c30feab8b504e228923adc7e81ae20a852db0ad676a78e081336d6b0402f9cdc5d5e90128ca945d10515ca0c5ef03f731b1d40a710741d41c1dd1ca16b1060febf2a0532e6f5d7651ef446375ec18090cb8418b8202f25a0389031b307f223c5b5f6afe36a9adc1068f2c6e0ea5b2b6cfeb8dc004f7b829c80439069b81a7bd907477c6135ef282b771f141dbe75a0fa056e06b8a1a1f98c25fa54d14c8fdb42d6502595c59d25bacf1a19adefcc13170f7a4317b6ab610b609d414b0073ea04ac29eb10ee73cd71a4ca60409f8e760e60f939510100d0c8cd76f264bb37811f97aa5299ac0b12d4168ff38ecdfa80b1e5c1b3bbd4d40d3544735df7167eb158a9a9a234d445f1d663ded7171edc68d172c92214b82ef13fe6b8c43aa89b739b4990ae947a34f020a8d8943b0f7a5d61dfa76adde0272e98c1159c0fd8a1de33f2cef8edd32857b2189ed96128057ebdea81f7a3a3dffe1893b5ba877556c90383fa2c5a6fd680e8a67dee4802d90dfe971623a7be22ab3ca56067b1e5c694aa84c19f16d69e284ddfa039c108d0435813812390d8ebc1e50138176f259dc0f26bca13bc943f50d5a3500b18d593574c620fc097ace430fb80728d3a1aa644e504b1009ad67536ceb011f2a357dbd009e4a63f524d5b5957f331567c5b4d185a61df22d7071d31ae92141e199c12289515aed80c91021456bcd45ccc634037dcf69b41d6b1ff53471010d99f187f04654f43622287871fee6dcf5f3023cbd0913d99aff43fa95b32ea2b133b4c9ac4b017b7cf8f9be5086fe92b42cb8dbed5b630bf097c18e2e55c3dd93271e09c2d1cc6af87d83fdef3c3e3c4cbafbea9b60fd5e9cf0011de2e9e26fbf09afeef5c69802a6c46bdf54c145862944173e017e30149ea5c03c7aefa28a9cac7767002ea3fefbdeae5bae005c370dbc064244d5b9be5500a35726a99bc9e8c2752d510e139af225580098c8189aa9c520
+SIG: ce454530b922ba5ea162f1a452e05c00363a49a9db8a569497c00caf1cbea99180770554ed4e3140dfca4555159ebf48ef5d2a50f394aebd782116ed6569a409
+
+TST: 874
+SK:  39bffe007f8df7ce4e56fd176b102b923ba48aeb8269fd0cd520c23a7b236e6c
+PK:  9532636800010b3dd4012e341fcad6d29afad484e6fd736e89d5bc02ba0ac853
+MSG: 7a8c20bf2eff69af8bad6bdfabc7909c58ce746cc4df78b69b33c105ba3bd8da75244758b5172d5c4501bc39970185ee3d437083a9959f81e7665b829a69a5d72e034d351adddceb3d3fff589988df182b46fa53d26e7c9eac062215788f2337bf90f0177d8ca744f95f28fea854593c4362c82e9ded19b904ff99d2bea82432822e52c3da6d462da754ff1f8bd109942df51dba25b7cde838d5f524239f1331f463194e10ff56795b296878feb1f55d43ec7daf0ca5ab3d684b55bb0aa4c720d4b5c2e830c858694d3d0fdbaad0bf67d873182d95b2412fce5e7b00fa6bfc38b132efb96f87bc6c10070a5716ec9b33a2692cdf5bc41c7f737e28c4220317a489b7323d5e20f65d375d769f9e79376fd02d85368671e7e081eb753f888545ebe5c000b2f80143eb358d43185e2f1c294b9f29c8bb91482d4387494aad176deb85540fd005c97d13e6663f09944eb43a46e6236794bf6e21f81d0a42090f9ccef90a6c4807b5ff541300e5934881a8d92196b4cee85d28092a828ea3bfc6b745ad219be9f5e9574117d079e02f4b748e2cc01a32826a3708231914d2772c764119fd99d53ab5b5a2e9d891a48a9aaaacc26338b18248db8ab2d525daf15ff53acbc3aa98d4f2d4a337bbaf6d1be21985a4af600e29bbb42c8d89e6b389c66f42270c3a0b051bdb623881e02f2f4294cec3476386747abae6c7700b8f9b0387cddfb73668fb57693d8474196b33abd12dce59a57cf72ee6cc1ddbaadfb19e90af8131b3a90f9867f4c7e15bdf9e218477016bd0ad3be8dd059671ff656cbd4ed898086de4d423f3dfb270bbf19d9f53f7f6f2d22c6ac9025cbadba442e31d9811e37e847dbd484d80cf743039ffa7048470fbdc6080f6d381dc7e3fa27122df53cc06394ea6fc446e1ba72538733ed3abb685f16dfd5ccf585ae8fbf9954b50f10b7e5432a22b369406a9b7088961f0ae207495ae7185396dccf292dc463f41f376a1ca89eefbae19269152031bfd815288e8b5baf348c4f8ff3dff4fd6d108f871daa352110fa64188b01b8526a845aaed133e456b4c83c4fd4bbb165b4090307e8eb17df176c322520f37599c2105aa8120758394a4222473476764cf0af7c55183eba9683d7270631443f3c51fb8ab0c130ac436ab603ff4f1d8656cdbed229a202b40008ea10b171542f74a70b7bbacc4016b7f636aa89633b7668058f13312f57c5162d18e399e
+SIG: a27cca4b9f5b95ad0e44e4740c15deaeb93f22a9b254ebbd2329365a00966c9f4ec1e55c5894e7bfc23d398d3970b9465e98a8d23e72dae8e350da3531ae6908
+
+TST: 875
+SK:  3c4080cda0fc3c03b614d980f2ff831f5be0e7a981d5381a1618e0b8fd001776
+PK:  f1c3269d870402caa43882135d9dbadbbb162dfca0b3dad197e6b8a7ee679a70
+MSG: 0ceebc0e8a47720f25835e2b9acf891bcca4bda38637f363274458baa9e2bbafedd0938f5688734e22ac50fb120f665f6c4c61c6531739b929ac83cd77f8963b754488b9b859c13853637cf025c14e8fdd118faa14cf3930ceb35f104d95441e56489440f62041ef1aa7c4b08b2807e32bb9584b9004d76e76533348506d64f112e1ff6f938f642230bf38af010e41987270248b13635a3567b355bba5b57448c6d13b74f3bebf617915821028fca5defa4ce5424ca191cd54a22944a3d940e4ee2e2ba5d504c85f959b514c4fab41ccb5743d9cb2f9bf33d1d8c2a5869e9f4660c3fb224b39141e3110c9ee8aeb871e14c62c6be38fb9a4568d736810bb9d2073178b6c7e87e3582efc62b53c23c5d46520ba33ffb3a9ca649ef26fe74a3cff6188427326b8c96f74354cb3ecaa611b12cded565e59fe1f8f400097e93ea85951b5b4e9009eea7db937e4349c4e5e00c4456c6c5f4e57411baf4e46e700ac400257765f48dab03e439f76c1499b5108047c830109dce7f740d1393787e29d3716d3c47e755cb828e7d440a971975197ebdb3f9b737ba11f7fd0386a959249017de7234d5e5a9b473bb9583a3742c774ee552a12a1f36eb3f26c885bed22e91c74cf32a8dd3edb08b674bf386ef427727912d57c5fafaa1cfeb740cd52b9dee995e3d0161cd9213f38fd681d538ab8bf97b745f54980030ef8b72696d4e27473fb0f1acd5d0aae0297211680ea0fc59d7b6d51c63292585a1d553d0c8954b42a4bd6fcd3a49575bf5c88953f1f4ea7fe0ed7a579d1697e645e2a61c69d1a56bc605bb04060a2778d509a8aadbf35d94697ccee9d3543dd01281a031f2a0eb3a9eb13ae56ff44fa0aed4f3488747d6af820f3989b7133f449ea56d3a7f731e791b7ed2a5db939bb75352de7daec5066fd57557165adffa631cd3f967c3c7cfc11cc1f14fa23defec3eb0239b45ed601a3a8078ccfc7f8380902a859ee9ce2db795efaca0a01dc0879d506ac97d10704d7757b3ccf3b37c339b42db23782278023e4c2e77d74246c9e544149a55c0c920ebf2986b4c5b4b3572f748c4b15c7f863999bc5132adad09761eb76505019769fb55422f603184e24c0d4f3761987b5c50feafcce53302a3a415e20f56a054803e553bacd242a5e1364aa3b2d7cb3bc1e1b86a47431cbd39695b67f554c4645b7236904094c11aa1b40326ba91b8bf4873e9a4de04e2bf4625972
+SIG: c9d4a4728b8fdd240d9c498aa35de95a4bbd51785b73c8403fdf040dfaed9447efad0069b67c783d4b81d966bef6e3d9a808a0584b98ec2b18322c4c920eb00a
+
+TST: 876
+SK:  45438f91465d74a2825b0f66a35bd7c8d005865479b3dc10a9b56f297d31b926
+PK:  f092b5880330871e5aafdd3ceb3850ee7e0941a2a1dc89f4fb4771d75a22f6f2
+MSG: 3071d4b720df1093659967cd4eefef2ef9678475f7dec58fecec1d928deaf802457a1934e60455f496cf4251820ed60a3d8133b624d33af26a262784b5a2fba73cca2aa5e519e1f539584780649864ba5fbc1f011dddac381f8d48d0d60ce8231701173c9d2a307a76302ebc69dcbc930d28431475b516f98f778ed2e1fff272909a272cc3fbb6b31c8041a37cb777e062e49649afad12c1b5f7fcb8065a99e7423362ad16906031265db7e8b89751f8a4a407f2502650fed753e42c8c911e50b94b3800695b0eba7dff06b7a710117e4920d4b1c605a3ebf32e06966716eda14b3042998a3c7a5e9f83542d7dde65e528bed6101deb331deb94cdd46044bef88c097bafd40d6921a7c484c8f96684dc371671d94eee7cbe5d587715314cff0d1877272d8190a90e18bfb321d52bf74705137b2abf9165731767a13adc9c85e0397b47aef96badb2ca7fcb8293b01fd1de316ee1e65f356b9d6e8ea1fdd837bd96081149ea2dcd73c4881f32b7deebc3715e2d7cdb643e0d98f4e846508b04b32439ff14b1164f46846df9afae44464cf550104cd3aab3817540470aaa2ab9559a68b7ff6b1b9c0ce9f5869cbdcdd617090942e353b4c77f09395896becddff1ab7f07586a514d81fb096361557566870f1691983485a80c3413da98b8d19c78e6379f943e5bd5a5697aa33c5e6bfcfb7b8df1e1574ee416fab3c8a7d088b3a057cf865321b74e6103526dd9ad15ca5ad3c0f69718e27081d4b34a7c6d1aab6b96c0a754b989b4940638c9ede3d17bd49f65bf783dc85f1c4b144876cdbdb2282a9564aa81b57092080d6448fb6580ecf09f82a755010d55d4a5e4f305e259dbe99508b479250d80ec17c8760a93e05a29571f6856073022c8706913c46a2efd2e9caae4ffa1b4222e3d70e979e81a71951d7cb830bcbcf901af244f64e4ad9f52fa3b62031e3516da50bc2bce78eb9d61bfedd9b3f57e89355f177db6162bf61da0e454c34288b967c3fb4c341b32d4d13a319869b8e36046f9e338b5f36a1fc1a7eda7d7b0d438e0a75d84bbe4d68c879ada80dde23f7155b532cccf7a63f1bedf84f82f440c9ec3cb0e45f32c92f76438f5b4b910441e6738af3f5d2050d579ee96b88f3b00810ab126ff3a8fefd971044324dd4eb3447dac5b77809cda8c71682549d7cf2dcee340edcf9494aca42901e2c11ed97790af48bcea29521ef0e3d03cdadecdc894dd0756
+SIG: d9287b7fec017f2ea40a14a1f62dca78b02a3d6632df7c60ebd90fc5e492c5c62c43166bf85658fb30a08b57a5813121b80397571a312b6dd11b653920541602
+
+TST: 877
+SK:  72cfcef4c9d6a1986d190311840e55cbafacc8a6eb5ecc72934fda535bdcffb2
+PK:  a94464d8cc8f3e43393947649f91c2752327e40daca11a9970c5181eda37d606
+MSG: 66a6cbe88a8ab9a33847797fc480b244e8a2b8ec79e80bc2637753deb36fa3014f843e22a47db0a31778385ec1f455672e0dff6ca21ca4cfd2b989471b7ffc307828138b0ad4e647c2d13cef724469054abd3740245aea4b789e244e95cf9ecfd08a0d13c7ced393332727a7f3d8fbdabd939de28caa41cc96c7081198e22653d94e024a61f5f3dc5aa37fa9adddc96cf169d35062a0a29ba45a539c87a68a3a0304361309d213e614ee8373dafba2a7d6ed7d2ad37704c0946e4d093e2d94d061364cc1231063729103a77ccb501891bbc3185457bbd2869eb63dc60f196f10a38b7b36cb3f643d35ddbf438a44bf0c8f570fad41bdde267f0ffcf1f2f927d626d1b0d980a0ce223f2f0054845afe41d39de5a457219f276c67e69be2d5c9e070131639561c26751fb06435e0e42e2508c5f49cd12b517c9833ff97f5e51e1dceafa9426d3dc52fd1379c64ccaabb26db1af6ded7153628842f0cbdbbbd6aa0cfa5407f409496c06532dbeac94dab9baba0b3c988fa03d36f911d80e49b370b6837037ff249e76d692cd17737e0d07965d33f17042bbcd1e990e040f71936f6fca2542ae33748367787c01bdea75c9a0e66150281c468fe5c73af9e5bec372d5020c3d37fa1035a67e224d095f066a51fe1f681c3073939272f6af7750ed8d18349178ab4a2eeb4e9ca82bb67296e9890f316c9d9495953d68436eb1c1a2fb6a1cca45a8e88a09bdd65a5558025618b36d7f3cb389d2e2ab1ed233228ec92a327978c0adceddb6c9632d3abd7971621713754758e21013a0c3d009b6e3193cc152c57ef73107bd4357d528be40873027bf1840f685536080f12c5ffa93ca629736780e015e86d1909f0d8f372010c9cb72c0989845fc88315e6b9370dc92d3683ef44d3f75fc96c4b0e89e13d682d1988b685713eada842be9d2bbe2a76bba15d38cbafb65c40c2159b0ceeb0d769b9be355540734ff37736c0f0facb95159309365b9646bc4b344fb19a5c1639a88e87317bfb3b5e7b5130fa7d5643ed4da06430c8a0c1858ccf2f9a6e3d62012253f0122dbab4a35475a6f65589b2b095992826e4f1b58fa050b8f95c4feba3fbaadd2c2244ad4abd410139adf4c153cb5e69337af176a7837eeaea99bdcd59385afded34ffba8063a35f4f558e4eeb48f1487b56b1f8d1f73067621cb548c808753e3526a2f2aabde126bea521cf673deafa792ca5bd2212795bd66b86
+SIG: db7270acce78d7fb09080a327941bce7eb145b9e3661866a8683f9a1a3de97fb02b025db9ec76ff32560fe638827742ea2f4ebef6b7cce44f9aaee434fd7c108
+
+TST: 878
+SK:  a6337e4d3b1a49b126316778c613516c03ac88c96d92ff5cc7e0c8527cce1a62
+PK:  f5eac4fe0ea1a5f236b49da33a24e2f3a83d4b260c54d3416c644e05c838bf51
+MSG: e33430c38c4a40b3c66e20cf3b70e9fea8cc50761f2afe249ec059c07bc3b37e5b94f4a43e310099b19a85f59dff73a7e495c4df31f74780cdef7bd6e47c394c1891ea3052e3ccf5d84bae082d24ba7178ac65d229ad18a84940f6b4dbc596ee63c181b57b5b49698979c18632fa821ca61e35a0d0351fe13d69e06ddcc8d666dca24502177f344e2f440575d39ebfe5e7f10653b65bef291dc813a0434c975de164c1a76bf6fcef98f23181c009b91830b618e4874847d2e21bbdb93f20cd8b1f4baadf99428a22674386a668152b4b9039ff06abcfe334a062f794056172ecbc0794df98271b9acfe4b7da553a87634237630009a05b257c184cbe23d9cd5a038658010f574899f3b2d154d185ee67230913650c3a05b54a2edc243a4287398e376928ea9c6b2cbaf371252540e2b8043fcf556813196ae572c27cfb5a46abb9729af2dcfc29e033dd11f33e86cc6ac3bce6f3f9577d36781a69ed7eaf8c8263a0f18eba0fe8a481f3e15a55599434195f7cb057dd364eaa07dd0dfd266b807f53a2070fd791e872422fd907134f4a8a78a876bdcb031ac860dfe0bb57e105db8287b31a604eb71269be5ba229985ceabc2bdf165ac741650b1f013a66c9bd243d03a8b1c5081381cb92e23f9057771fc07ca32dff1db94f5adfd2f4ff9af31d250dd4f86b22592f60a74575156213f10846c746a920fe39851b32fe4c8b8758765bc5b8b9d5b99263df36f97888053fd10f1d68f577aed559bcfde744bc6511076cafd68944a0ed10552d11344bc7e4d9ef936dacced527433132959b1c7324ad1c4cbc3a1a736b1f02aae8e0611ae23fdd474f5b8ee7056fcb5af6133ecc084bb9f1f50cbdac66244437b4348f4edfe237fc3c3829ab94eb4f14cab1ccd6caee36fadc20a310cf0690622cdca848aed03ff403a6633f4f657994b780dd6048149c3bfbc17889e37d90b1e5420eb3d4596b91ba11bc0229c65d05b93cd7e0454d1f3c6e1e8071983792c4d4368d0778aef4e123335fd2962c657bd0513571a5fce211de62874f27ca10dc15ba2d445f1cf4be5f833cf0b564c022576b98c0a24349b67085f92202675d7dac48b95e3bfd6555a9ecb7c72f08bfec0d220222492fdc9636f036ec4508a365b7b70979f9eb4a7263a8bacb1c1d0155738646cdd46ab9234a170311500d0bae6e55a863bdaa56f51645ad85297a7381f8d20cf96c474d1bb81fce132b14555d1a
+SIG: 781376c9512fa33c457047a1f4f0da3176e60ee47782869b7e9fa5841d964f3c1ad66b70c114b1771c324c83ff6cd997aefccdc59c114db9f2f3ca7d84a7b60f
+
+TST: 879
+SK:  107da98d0ee8e7c00f6d41ec265944ce67ef8c8ffb51f4f11f4e5f1a27fbe805
+PK:  3bec34b161b1bcff009f8cfc50d84ceb6a2d5b203b5238a8aad8a83618b442e7
+MSG: 1a7b7f3e1c7c41492a7ce799efdb2d9dc2f2489c84ae28bb7d084f32eca8fbb066885ac6f2ef7449e71226a82e9f153772a993eb6b6bca6491d26aca5dee98b77a1ddc59922b3145c447de737fafacba5a75f2a80137b5594697220d19617674a69113fdf77c343af2b7e3861b5b7822f58d60089c3ca54c749d27f88379c067598f063939ba8631d1f52dc9ab455045fb360cc2a5b6b0127facfcf5b1b4c33e3f194fc924b854168cb1169ab10997b438b71c80878347be887af44810134b514c806908201a3d3e6d0c56120c4314874dc2944d8444f01bafa34aa62ecef0981545e5d02f4016c0b164fc05ae18f535c31bf20b86f31f7a794aba148984c3ff433dc222c443b5d26c1f66e6c5f19d19cd6eadd4dc94101b2f52b58c9d4590cb10dbc5d6eacd11d42ed09f15bde44ee9271def292f731bf3b4ac6cd127e4884c2cb30b285fc9247638a299e416520624d1ec8d0df2498939c719a9e7bd29a3c5c32a3e8241368d6e4f90fea29dc3a3f147ea9f76c5780e73143f55d3dec7b66341d3f3eac1d98f8e7d4e877509b4438c3a52466d242a10b4c27c4a0db9232dad011414ebfbd57906f1a410207b526b0d1f1b6986b3ebd7550a2b3c15fc2409c7626e0dd330ef6722e3ba48b1d9205652ac194c21473ce258559db511efad3e5d55f2a796d65a6ab97d8631062a593a13aaa095dbc93e6217ced619cb16a57e744355a16b15e77d4979119299bb043e48fa3e615460e164882984a223d418ca95340c5bfcda673fcd13b29f2c47d2f97e3e8c613b6c58df0e62cf23061d6f545b755033fd3dc1405e5fef35a13e015f98b1cc42f71b99681f9681258229a4473d86eabb0c17927941e50c08f34a76b43bcc6d042e5632ef9ccc91b6e6950f5d30f670fb3902c3d409315a40b0821ce8a99a97feca5478bfd782e78767b311f374163f5896b0beb95838e645878c64990385123b61575dd842dc76354bac9c6d5acd9935b609bcccb8463d39225da1afb8911d36e609892dd1723852ab9f82758f3f1e4d28dcf02cb06eed26844aae6882ed44bce44abcd1dfba633418c9f155879c97ab27f8ae238330392be5491a078662daaa02a3d5458b77c549c49be201245e7aaec0d94e5437beca6e5ab046d694e96bf51e04fb44379b2b9b801675fe1477f3e089874a601171d8b68f0202014601a53f812f53e581c3b96312b36b9ee04fff11d9eab4e45148dcc8f0fab1
+SIG: 53252b923ad19cc39784d3a9ae59d62a6300dcc50ac8fd0713cb58844501d8d3805afa0fda64c73ea0f60e6a8b3445bfffe6ca6bfdc87e128baf99bf6268fc09
+
+TST: 880
+SK:  8bc229fc234653b13c924710cb468b8fa9b280e2adb49cb4b36bf59d6fa4a639
+PK:  46146975df6704cbf45320a5e6cb6de813469f3131e61d447bbca1a477a0c557
+MSG: bae2dc7f94ab5ccdcaa8cf49edbef0f6d7aeb1fa8907800533af4492611194e56cef37b1f033303738ae2c3bc4588f5cb3d55f345b9a407e787742a06af0b6ee20dee3dfe9c91d762a3ebd19aed07907bbb91cd776326540ded9f7ff7dda76615f978e9490f406ed2d9116e2093fa785e971b5062d31cb40fff9e3c551a73b20245d46df4d7fd1303a28180172d9a2bf5593c47917b58690917c1fb0e1e2994d1fa97735ae378de6eafd5c1a25abafa3cfd2df7aeabd6e68fc44edf82fc83694e5d841a15b14568b6110be644bf22b71fc47d7f07e1666957d0f87da17f13fcd63c1c2966f687d25dcbd9963f01eff132d5f2b86677816588c123e9457befcced2d3cd1d1bebe8dd8fbb1587e553cbcc4c8762064cd32ef7a1702410f77f15240d7e2bb582c678c0da88ef4522830b143660ac9c434d95772e6eeeed6014ae16824ccdc4df2df64aeb6980b51d118985dcbbd1961f315e6a9433f0b96b1e6351257ead83e05b4cc89c924bf83558ba7d2e7ca37c03179a8f85b831e7217bf4c553838761d32602853b81593b0ebf8e4b9ffaf0ec405b2a83af7de5554daad28b582ee08bd84b375550cae08ae4a5bda71581fc3b7b54498c4e1afb966b4af1d9c843a6b25b34e04cfd9bd2374244f1fe20ec62be3ccfab4edef79ed64e6b71aa9228127c6359ea1c4a8087890896ffa46e0092dec7efbc960a17b770916f954070132e26d98d9774a2acdf809d586df0252f67cfe8d985a3e248db0f90731ace7abd999c746b69648d5c3b4bd61137e08fcc8b2efc5676bcd856a13b362151474c4a1efdedc592cf3ead1ababcd48ee204d27726ad1bda4fe4b09ab51089d016de6ba259ea81807faf211c87e4c9efbf6a4c753e08f780ed55338c0fde14fb99b30722b5594b3abe02047f466242421fb81176c9c4f0fd2b5e7c5a0f65a0c59aa8c3a986087de7ba40baca77bd36ac21ce34e9fe97facc4e298330eece1c8ec623e66a4b0f2342d2c5a02c5f5abddc5ff1f1f2d03c1d4ee9b4b342ed3b1cc26561f3217bf8500e08f027571c53c9232605a53f2bda024e39929163a8e00791ac0656bb0783825e7105ffa9d90969dc094af46f702e85cc11e442b3d5534c1d3275207d6d29a942c358ed5fa07557c3c014cf541f9aaeea6025b41ecdd848512ba25e721e43d329185f8f94892e9e2d5e7cbb99e7ad25f69e5bef732cfceb078611553cc78377375e74e66f1b9d8d20
+SIG: d243b87d1397d594139d83c39acf8501d073bd4be718b4c206980729e720a4c5b0ea91a28ea12604a987e69591c543049f2973bb91c170213c32a64a0fac8204
+
+TST: 881
+SK:  3edb50ff074ef9717f4fb0b6ce252bf4bd049c9083775f529eaf51e975cb3245
+PK:  4bc21fe03e679abbfcd8c5ea2bcc4d838a787d4840c3bc39de4b04c417c768a5
+MSG: 975ece4e81f0015f5ac3044609d0ac3a8df9145b50c42889dd312f563cf6126e36fffaf21eb6b84fbda15aa85c66145f7541e5b41a8e81700be356224fc109327a6919665673534f5c8a4a001750b199dbfd630691af552d4d26a9d9afb33a16af391154124b53426c9f695057b1814fd6d310298af6c830686a4a007a14e0057b72fbad5b803ad353d1c3fdb890a9c81808e89f229187bcb44fee16a4ebcad5eba459b028272a562c05079fa7ae3ecae804a9e8c4f3f315813c5ee0841bbccfe4a95623b517a4b42b2c6d97a3bf26acdbe2e979633f02aac466526a3ebb14da19bc95f2c3fdf6bdb08be8bde97a864c907e918c679ab726f80177145840216b9dc3f981ef17874f08b2fc6611a6346c3da6a55ecfa753c9919f4f19e3c79093bfd78f861598e4666e1cab688e4604d46c9c582eadb92c988f478d160f5a15182b3340201797d0b955282e4a217b50b14b10c9f49067ea3e84e5274dcaec74474c5707c28bba0db8cde3e838d7313c171b85ff2b9a3d2b167e9061f84df3b13bdd08b2d501e53792d68054d048abfe3bce98d978256f2fd2c6c4e76f39688cccf0fe149af9d347e7b040ef241dd5a53eaa5eab35a18c68c754a06b03399bbe56a25268c829a5ba82b28192041d3bd244eb08bf78e76def87cd09f32beac9bb639823b36967a574d8960d1bd03435679d93eddc558063c540b9c2f609fed2e2e3576d19e6209eab466c206791c3aa199623fbae7d3497e80fdd3fcbaf5b89110ed72244234be85cca4b27a09bb70a26ece4eb8dd970a26e5b04361fa50e90380ed65f414c1be9f5064f71429116267edd6976422ad92deb2b804a92e81c9f6522a0f3b5d8ad36b4f87db516a22873e6f27284f2ca360a2f40ff3d8e23dec8ef8a17a43acbb61271a727cb8690d29bb82016736b31026201dd3d388d2c643a73cfbd0a94e20551fb5f8e1ffc39741272aa2308dc8d2133a3fa9cf109796d69d2cc8addc44ae2527781ee993af2a637a872f02aff474a7073f29d9c89507701fecbbfd5101353537eba17c29669dac0427e38e22dfaac91fc20d9e3fee791f462a863bb1908fb1e4204b68880314ddacaaa35a17af5f57a399f1931e78f5a37454fd38c57a68e8d367848a97345189c70077fd1aa0754e703e352618063b9e3faf3b14b5f0b27113633c5d17363741e96a67e816401e8098c17bffe9c6f3587646f40e9fdb6819fd22a743a7a6e10feba11
+SIG: deb3d9fc7b2d86ab4b926f99527970abb51838bcc2919e94cda3371fd0e7693fe37e0c40e1233b09ffa903a034dde287c0237dc594f53abc87844869dce92002
+
+TST: 882
+SK:  cda4ba93940aa0c0c3150b3929b95ee7769ce43fd98ecaff9c4a509e736d5c8e
+PK:  f4c7a25f1a743daf41417e47e027537f24f481bd1a75e6b1d33ec4c82c55a2d3
+MSG: 3a1d668c6688414896a7697f3c2e431098edfc457e04d2da869568ad5b3310e59e4c727c903cbf1817408802319a8c231b58023dfae494c013af0fdb78c91d5b457f8c47a3dc31d8c8594aa08f146203fa2c28b3dd796a11a97adede6a7a709b5a1918ef1bea83533c783473703356f5beea7fd18ac44ec6890495ed170d03f15b418608a7d9efd52fa10918638051c448d98d5724f567c8c67fd5b6ec8c3d636008b9bae5e8b1e984f8ffb8b64beebd6345a105c1c1083132fd4508d6ac0d4e9145501210e517d9b22478e215b602599f803762dcd5a409b3460e7f340f47ef77281ad2383de08c5b809538aaec922bfca0d6752f147972646d0a8d8340772c871d3b34abc06037de3ab4e37129865d5ba70b6f3cc9a059efb7dddc3882f4fcfe13f448c9bc664888589603ba98683a93b4b3b1014992a55c8e4ea1baf9cc00d1badff5fd7f5da5e307fbd1b4c984e0fa0edec5d30bfef5f477301263b5d752001b85dd52df3b4a7ac23b930a91c0a45765a66488d8eb5901857060067b82378188549288ddc61831e5b6841b344cae2250042219cfb4ace023e691f9e48d006e9a07c67d2468f93593b4afc161c0768b6ceb744c24c923da34af3d5ed577cc7f85d491560f4c0bcbcd1d5e3421bd1ccfafb373d651bd61ed71c09e99f612001704d0c630d8547bd970b66e7f5ce7a014e0ff5a337dc5c56a99f131b9129140eeea39397c48caa9a8086f9fd99150be7ef87b6d4b94b1bd52878bf3bbfcceacc2cc45e8971c3a4d4a3eb86af9874d4fa5e7caa7f45d1553ffbb41645bf0f5e9b29772e3dc081b25b52e1cb7e2167483d54fba690ddb29d5462d2a27a35d85f007adede2a3dd7281f654336afafb7370782b29cad643d9d9db2f05f281b53e133ec30eec09fb0d061b74581a2bd2790b137391f19328880f64c53be700d0faddb70dc165d2d62e671eb9449a2e6e9df2c16d8f49fa4b5b84309f7335133dbe872c5a8fdcfbc4980abfb3c9597d5d667ad2f688c7ab24c9e440298d72b28b0fcde9c6f071bccc93e8ddbba7b60a0b544a2e06c39c6723d4f7dc185c21135fd13a72770b976119e49a1f81ed476be07c443de0b0ee76fbd919389328b3eb8607bc2fe38f85745e28adb7482b701ccc6690e4ae5a9332ea44613179387dc6fc47c1d1ec366035e991e1404323bdbbf535f1c33cf57b6723f13ca6ca329e2aaa4b46b42607339906c7ef49b32db82cdf6a87ad
+SIG: 31048d334af05a4f275ff827544ea296a4a775fa59efa000c57613fa6e5c493c3a9b79e8ce56e7225b0fa326204f0336c213535ae589177a8eaedb6df8b20203
+
+TST: 883
+SK:  217ecd6a7fcc98719210c34cc2e14f5e2d6b5a22f268c14bc4d8a7f2817200c3
+PK:  d59191ce282d72fe3ac45878e24bb2f28c409ba05d76ce9bcf22f50b0c778675
+MSG: 9b5337e78fb382f22ea60e03c0bf3ee4700b6978a91ee6acdf6a409e4918d1684881fa1d118c08c9f6f2ca0cab567402c95010e7abdfe848ae79ba249adcb96eae1dfa0843952139cf49b588647895691a2e9880466b7e77e54f6f60815ebfd5e5748f413c0e15f9d576799bcf31284710636f6e9dc7878500796eed80c8af4be2961952ea80bbed1404bd5dae9e6d05fd4f325a3b83cd4528a0869cef84b4d30e02f941d749a8dac97bb3fa839d25739b97ec374536bdea500484a941db9f2299970658d41148295ca0846ca2366238b6201a48b3e447edbea7a4c8f71020142769e15fa72ae5f287140bc5953b8a9a242d205fc019091f2abed0fda47f52d59a0204ce7401c1829b5857b9a0916fcebe2eef991c413acd71b18d8590d6b6d0fb3994302678c29f2b6a53023f9187e46c36790bce73873c545a72beb553294b1ee5d0d0dff239e28ec63b01e4d8fe0d6e69b1601efa2411f0c0601e7e4f65c984f829f0dc2a8421e7f66d9330537151c7243ca524d7a54735c6e344f1fc938eaeea2779c940891d6d01aa55f40cc1adba12e8a67ad9a27fe63fb4f38dc0f01841925718427255bd665d5eb3bc869896db8625204ad4b02f5a22aaeead6e300471fea61dbb1b55c071365c58b1511f38b09a4671bd66b3fedda9c87e43d1ebf301764e18fc0cf16b2d2d67ed239b393ac71968a903c02477fb2df9ef01dbfc3167de7265f891e4fd24d02c63103519b86a7085b1ec2fb419db766bee7a641a4be429614ab89f20f975341072bf04419fb69be7a9ee71a5b49af83ed322bac68a429ff5c5206773be5438b65e53f609729f4f6a21c1333911264d63927017e8136b4725cd1cc964e08ca0933a561e7e3f5987768330e2e54f8d728f59edfe2c91c4f99aef97d18559195a3d8eb315dff96fe276da7137eff93057ac731e06a60a58bd8a9ae8c7cbaff0cb3372c68daa175c428d52f1073a38bf29465d2a7128bb40074006edcb725a831d812864ef43f3b8667c9fb71093a1673049dec05e09169d86fee92df286008ad99065a2929797a913d0233f4d1a95a220bd91c11dd9c45685dcad385780a0c48b9c4ad2d66303e8de4af1db3c04e4a3dd4219fe773f83a8924b0fcbfffcf264abce32832924036bfabba6546b1df4e3f788ed8ad5c2cd92b2641b47090a103cf5bdc46d8b2143174757da801c360a7aa107fac654b34c860bd54f76bbf43c48478df4fe7aa59cf91d
+SIG: a0b169e8e9ce557555e0334a0de7438e553675489ea4ba9cc63a234d00ded8ab6967a3be90ef69e076db9ea3d5ca23b3248dd25991ee1f4d80620bf4db438f0e
+
+TST: 884
+SK:  08d1d06f3ec29eb52293907b705ec56c5ab354fb78673773ae61253094b89e82
+PK:  c1b99a87ad15bd46f6c848452af0fa3ccccb5cdf6e348d816e36c5d0fca66e66
+MSG: 120b35573c34914b373051880da27ed241377f0e78972c98d0faebaa767eb7a7c7e7c6fc3405a4336ef95bc5da9225bbd09e9e11f2a1bf142af4e8a0f924d323dd5a49dfe584f090439c08e51511344d470c6200ac7e7ca150d088a91e47c4c9ff74e38a42a332155d8152ae4abd1161adca934c234ce460af8789e53f109d7d31eede0a909bd193fc8d3c2cfec10b143c31476711bbec27e196a54985bc347167acd233508827bad36e548c880642b86a28c6d3404b511da24f11dfaf6a8f46ddcbc9de9e391597669bddfca6560f91acd3459f329bb071dd80dadf35f0e50df5b10f88d267ac9d3062330dd99a6bcfa13187f45c0c214dcde2cdf9c3ba4d59e633a354a4e277c677bbdfa24191179cbcaf05a10d4078d8add93bc9ed8f6c6c499757403655341f904e37d927750c699c269dc90dc26d005625c3f4124bff66feca59d4abff4172ba3df45a874302231030fa783384f50999e3c4baa5eadb451452c888b519272e90f73c6872768e0de20ee2e5f9502f35e49fecc28b75201887fed2818eff545398392f5e5b6876bc556ac13a1903ada1b9d725b04a14204b599ec33d62b7dcaeea8c52877b2cfdc3558a91d2c9157500a3bb6d452e5e2ff093294fc433cbd63465bb191307ed801a15b85dc2ff0bb38312f8b817a436d422cf4607c64ee7035923db6b96a3899910149b0da4aa3e96685d7163aacf9e619dc60813ce4f344f3079b43f187fa31bdacb9a1d7720b939d5bd241b96a177d7b7768ffebf79044cd2956d6f88db1c243a10fede6814852cf404b2cdcfa774076dc125c70a57c6907e99afe39622ae11f557e7d34b39aaaf45f834058d2fe5f15b5eb70ac15a90a3de5850ab1dcb48b06b6ccaa4b42f857e71ec00b8a3d8974b0bea68fa0f665592115b4fa55572cf0b0738641fc868d4a2e714db3ad7219a823d54b7f7c2656ba5c5eebe3594c7db12298c16251d9845bf2f7800b4190b746e21b0c1a5c47a3df9a059ce0956674eb703decb0a0045437da4da10f286d720d1b9df05fb24415d68e065570e6b31503142d03335a807bdca30892edb5f55f8989d9e649659c0744c5433bfb4deeb11c2626a8650e54d4d398ba19b64f68bed06d7fc408f470ac704e2ac922ac1411fee24543e56f2f50b6b08953dc56a7a75edae430a6df28a227adac91ba26f0e198595327739cba303e9aa393ea6618a84f8f503d0056ee8d87e3796e036cc51ccb791deb795
+SIG: 0b8edcb8b15a8cd074c41dc2a1ba29d9648d6acbdc338314707eca6fb4714c99543b4907b9f85e57eecffe0f7a6b7073a80946f8087553f4683109273a604a08
+
+TST: 885
+SK:  f0c85c76b1532e89aea975156dddb1d3d066f6409f841bb4410922725f269d86
+PK:  fd75fc75c36f83498d8f0827f01d3b457f8bc4d9dc55e4a46274ddf0034fe16f
+MSG: ae2eb018d48dbd4f210b16778b5bd2fd14c94e6bbf2b3ff85518e560ab8d3e72201f433420f00f11bc78e0e9f3720875b2e9dc11e04325b8b3f0d465ddab21511c457d6acad8f2fd5fdc0d2823fe6caa66a191a3b6326b32a16befd64d15b361a41513641bceba26bfe93bdf854a4f8f8a0b29f7e28262e2d6e98aa24ac27f6f7883ac01a74c40cce947ebac70e9fef2a16e6289e468950e391e9e24ef58e88a44377269cebafed8987d220dcae2d8b126b6bf812167d023d9baac950d9db8cf52de6306bd48999610c0a433fa9e1771cb832d4197aa340dd0ccd0744fc6b62f90bd3ebb5308cab5f940e2916423cf0f3bf080c06a94f026910460dda809374e6457f064f178e308e7a1b5af4def319007d041778c3d6a419f51badf87663879302b53ff269df442d0e05c958d5baacceed7f5f8afc811c18900ee3b0f61e5dccfd5dac85332d32ebba371aa2d47a606f59546e4bbb605a74677b19a0fe8e95f9f77c0b8b71d07e983004dc2ab2cb3793a323c108dfa7970da00db198674bd34bf7310767f76a224e07bdbc62b9d078cbc75367e2ebaa2c5d274bf3427f2a0cc5dbef0af4e63ad889e131b12bc8ca32d827f7260b0449d0443fa288440efd1364e3c9849477e73ee0ba4240d492af5ce13c34561b45010c109d842c1fed1be3fa9e184aaa14064f43f6dea0b659c5b97893cf2a433bcfb1d2a87eb564bd9092c2666704731f83e56434b2a4299650c7060f9ff7e8aadcb4593f609188d8b467646cfe95270067a1d35cd759fe581af4e62602c02ef14744143eb424f2d9f33a60288c1b25f08e4b2f5feae06cbcc2b2052bf384e1a6fcd8471ce5e5658d77f40c35c415e2a9e09fb583bb7471258e7c806f3c21822dd10f56a640cdc00128d3ba556ba51dcaab47c3baf9f0197d3663de8d093e83173325def1e83a2f5f5acf12ae09f3ce96cd888034dcbe6147dc5998362a4bc406d28846ab1503c17c94f9afd903c9a58e1cebb4abb4ff6f2a41024e06dcaad14f5b70c1b26e69f96ecf14b8da31c621f9ad4e30aeb982378671f7d1f2c4b572c41bb8830840ac5ddced881f8fff210c3c7f236d8c5f2cfdacda29893302fde15282db540cb543737dd77852569221fddcdd68d87e2402179d3a5a77734c275a1d560a462f40318bb6819837da3d305eb49b38650efdc8fe409d40fb94cd5dc3eb02738f38852f671a0c41414b76fb436f3417b8ef300921c009ebbd7cf8e11
+SIG: 4218fe4c1dce795ca92a49a6f4798eb5412dc825860314ec469fed45de3a7bf8ea55e853a349584bd95a826a585a503fd50bfe4c635ef183d07301367e90100a
+
+TST: 886
+SK:  18e268b15a2501dd4c979dc103ca6a842216132b3b5081d775f88640f89c8041
+PK:  b34e19c1e208fb48a885079d9fbf37c74f92710960f832154fab18570cfb4c1d
+MSG: 424bdcf0b256001439d16958fff648cf7a8604af22cfa5b44331b4dc356dff25cc0563da9d640133acb70b6a1176c482dbc9408cd6793d56bc29cc408823d388ed88b24ceb6621dbac0023ee69f76f8296a7395211685b3ceaa995f0355d9aad3d97358f4a379e5920ec545f469621cf768abf55d2a554c949b0ed70187c2205ad032985c9b5b2e4ba57e0b4a47d344512b84bfe9f3aa560fe6ecfc5bdf8c3b41845293573f81ed3b70edc63a30c70cda3f455901313f6d23db309478f03e34e71356d83fa5db9280cc2b4369c3d24dd9038f247596c391e48b2f3f890a141ca1d12077c69344735a59b1dd4076b22e16189991e5f1be4fb7695af90ebea5df286135cec2a6e99aa1dda328e62c0dfb63742202d63624dcc0c5cf1a5df79e2878dbc71fa96576601af22844f545733126af7d3984c3ed252e6a876445c92259fbb470a10569b49e5791fd0182cfe1c3f88297facc8c31a5332f1f4eb4958db13b6c079aa9c949487263403190c83c11a43191ffec6023fb34cfab2525beb546cf9200a96f5854b2f78ecb2d9a53aa9d287a90d4d410a63ada0e975d304d5148353463fa805b4805fb4687ed8857dfce4bc6e80833c8f9a79cd4f029a2d802bfdc819ed0c0ac8f21023287f2b4bafbcc89993fe46d52a9c6246dead617df797d48ee985f0f0df9aa82ea20e0d0db28a254a9a253f39f9cf01e3db8f3ebcf7cb97cec58c4efe031269b4b37e4cbb361f73ab4b4980bd900849538844c52cb3ac7583b8f89653a0de65a8be91582c55239cb8f5d5318a88d160e1c871e5ea7e75f5a69cba8538221ab42ce2a2c4d9c3b7ec857f230d573731133686ae8a7ed640f42f31029489e4e6af2b3ea4c7948ed537c0c5906726c2b625fd5f949e3a7cf3b6e998ec761dd6e2b5171a68749752e721b788c3477fa190cd6ea81d579dce6462d9c662ad8962e79338710cc8d2738a5fb04adfdb3f1432cfd80e2e967da000d83a0fa85abae2952f3f3683e254d868f4bf809eb2e300e7b209734a3c894e966b16088d5ed354bffbffbbf2ec2be93a32a8be5cfa18fa5653012edae5afd8709ca55c0cf23a550d34ca0f32d8f666fb47a12f2b7353a40c5379f75366c13f4ab9f14cf80a94e1f13d8b09b76fd8d14ffa538f31fd8aeb49d33433f4df7c2ca67399579fe99078aa721d6b6fc0c50e8a91fc71ca25eac1376fc671bf6153e720b25c7e97a3d4ef8442ac67acf58b504b67158f913025
+SIG: f2dcfc06ef1d8eccd8e40bdf01307dd19683f214d4f084e6b6934f637278300dbb1889f2d37f53b3aef26fbb3e36bd75985fa7c8ea6ddffa72c8e406f24bb20e
+
+TST: 887
+SK:  3c393f9df1fb0b1eec09b7f270b85982ba0fd5e4b1795e1a7fa99137fee24d7d
+PK:  974fe23730fc17945670fbc1f80b93f94593c8d44bc75d189a6bbfaabaf5dbd9
+MSG: 54d8b8d5fac28cffa77a0916d6333c16edbc8bb74aa06e56dc00e47e3929e40864b8840d912079597eacd81dae43e2785dfc689f3e85f8c66581efc5e853d1faaac744400ab08cbdb5d16146fa60f99905ed84fd2936dd73f4bca2572b7cf5160560ffaa68da7a67e40e08a7bb7aefc4043ebed5fe80a414817edf2c63f62fac0d47446ed0bb584058f4872fecff621559311a270aea37a6296864e8d168bf1e2f55cd3b276edfa612b5d9c3362e618be6e82a6e5f82667924f3d1d3df825f9d23f4d6142d3100dfc70f70603abf3fdadaca69ef6a18ef9092b3c41ec658ab27216fc6147a080acda60a841984ee83f41ac42a80eaac91fffc8228391ef583ab3eddcf876523c20281355300d86c11a4e7c1ade8e50560f43906c9bc8ca5fbf8339fbebd02e33e8518bee5e806b8c10f8277f410664735a2bf556839635492452e6ca079deb9751cfc6797f49bca9613ff2e7fdd3646f7c5236a36bdf0051745e595dc0072fd6651d57627a6004c0f0cfae856bbc28a1231cb839665ff04152ec31c007b3e2ed0a973b24c93149ce701e6fd6539206ae91bec4ce65a89db26c7d38cecb8919f96fb6cb8f6c1939d90fb3f90b887789f29575ab20e0b08bc358153d8c03521dc891870b5f7eedcc1e62bee7da063ae66ff0a4b7d98d1cb758f69743c3db3ae2a2c9be1be094f17cd28f92d8ccbca983c749c75c610f840836e2c430ccdeff0afa54444f12b4a4f002c609451834244c0c07df8e12202a65f94447cd4903acb606d7725a86e4a2343984e679c4af1b3679c755ea50d0abe2fcc0c1c3351a9ee196b4644c424222be99e2fb373f9641e3faebff43170eb03fb8ec4557d151a55fab6c499d444c84be89f2447682de4e6f6353475efcb8fc53256763a948dc75c515fa353545d0cbad29df5e9db5cc457ed3086cffb3d75e846c4e8d88147fcd0d8aa5abab49b5e05c3d7feef637943347ad3f492ee356ef34881cfd85abce8a144ce7761e284e8b8cb08966049047a996e23559f776b1a9f41cba3954108486e2927beb6433a36ff8b2f03aa74b3d209c488e077f924f231e28345942c7dcc2e61d7c9b522b659fcb53662aff3648f66da3e83e59b0daa90b94c515dadab10d5a839cb3a2f1d3cd092de55d995138c3ac0b907af15ac63ec1874114327e21971345ef17031d52617e784da3771439be2e84148bcfea132bde10e6fda547dcbb1c4d8f74ddce1fccf8213e0da6e97b81f75
+SIG: 22333e56410fdcbf84f6a8de741337691684495ba69eff596db9c03a281210881e6c91efa91b2183c0eac916152817a78ca724ba7c8b51bb4caadea9a341eb0e
+
+TST: 888
+SK:  f8669c88f1685bbf0480cc9221ac2ead8f551bfa87ecba2fd4ddf3ba3476ebda
+PK:  34723fb8e253ad9c71cefde03628d204e535de479e1048e5188762a1f337fe5f
+MSG: 5b4941beec2241c9fb76d8484f4f3f3ab4ffe8ecc8e7aec76de2ab8c368584d751b0d3feb8a1dc8168cdc694968f66b2a0b052afbf8be3a7d95163e9da9141c59ca55976c292c5c74d31318d6a91e7817c5a8b2f812118cbeba3a13323cd9748bf86ed1a85dd4ebc0df495cfa3d4627434bf14aae8ab6781467a56d965d10e6371989dfa0f6bc0f7859f3771eb9004b34367db2705dbd60fa8f7895c1eadf59f53dab168b4f9363979025501ddd9680debc07cd1ca4a0997876e9211f307d9b7b9d904e48d2861a778b879ad590a9a2f141bd568e3a1bb2494628e9ec0c64255aeea6f0eedca30ad38a1f3ffec3b2b5e942e21940104e914d11a44c00fdd47da3e5513aa8530aee247c95ca66d08a2608c75ba9858da14f9a8a32be713d309e0f584c81ef5be040e0065f07b775ae175dfe2c8b90a88ccda17fa4f21c77eadf5d25b6e404bf004479e05a01ac0042b89937eb278c1c34f33028db780ba3b617918595a39c0fcad674b85c40cac8d345b7ca0bb48a28e66c44d8bb5f27941e40b0e9c7097976c62dfef50c98f17566ccbacc87cb03b94dfdfaf32f1e56ffa639d63611e213cebf54cd0a3e2172d811c0ebd75b1a8646264dd8b1abd46e548972a1b262cd95d511536dddcb49729fe7bd00b3838bd2f20a142640edb1b6e765b65da72e7233261c8892e2f4949bb51f32a1a5a3ee149bea26fdcedb991d2cd126637e2971e9b6f0b785df28a48f301707349423f44e8462289d725498230489df1b51be30f08d7e3250565c6ef824bc53a1ba74a57a25c0686adcb6c825ab1ca70c8a5d46dbbc6fa607461e26d16fe93bb3d3a943a3dc05f30ea6dc8bb12d70821d320f1adf1ceba4be657194f7fccd21990f8629d744601cf52ea6d9405aaa2878f1eec4003b45a4218d8f80bb0f5af047326487752e2b76d68872520bbeae7b309d78282a073fe0b1a1a7a98da23df68caf8c2699b1c7d0f47bd7de2c0bb23369963e68a6974c8e2b595b8293a9f4d98df7e9ae3add2a3f64e83039739642d192204e85e6c48d5d671f6c75a0a8957edbb74187620f2aba99c1c62584c59ac00647e3fb40292b9dc1a3346868553392fd3f11d6dc6f5f2f4e85ee25125cdd644743c7d45281edac6384c77cb98a67d9ae6fc9a0a76b9f6fa696fdf4aceab5f794ee521b1e5a0ee57af53bdf176801b4f45cfb3cae3287234234b77ce21edf8680d68c4a8eecf1b03537ea5699acb562777e42a486fe7cd
+SIG: 3746da6cd8ca108beef06487bee63584f812c8e0695fc863b86e5db132380b62ff8544f6f374825b0e3ea0620ef854c1331114d667df1f9ea776c3963870290d
+
+TST: 889
+SK:  ceccc68311fc45b6c2a2f1ff9cdde007ec787fdf25d02ccd2a1cad9de3fb4cff
+PK:  6f804734ef92824180da71e55cf3bf1afef65bcf560962e0b0acbb2d8cca5984
+MSG: bac186d9fe5abda79c3a35a7a3c2eae6ae6ab28247912770c84efd048ebd3aba57c37cf4c6c7f30a79f68a3f76b20cd8c6631fcc96670522080e6b62e887ae6f4436d4caf56943131c52dd282b251cd075f1f7f8e0bdb6bedfc9a0796f5579042b56e69374961b11dfd61b12de2bb7d49bfc509cdb3138f3356a0dded98f5301b7c4a748bf89b23df4f7472ff8b1f505d765c6ff82dbad74b9d7aef22fbcca0b7f35042f9a762bd06902bb21c7f9f7f66bef38901d75012d61d744dee7afd89fc7e908c40685bd440aeda4204d006f26307d82a496963115f90e09f76688291f4a67d6411f76d16617875b2b9982dfdc5ee9b83b9817009319110b5404c63116fb6e9464846fa009555632f076984c15e1f6081733a0d46f2d6a3cebf79ed9020c9dec8df158a3341f39eaa5fcf1cf42a94849b2352c1a1ecd4fb814c20d07dfda312bd4f2f58c1576b4aa315c96c8786a4cfbb736b2d23c38b1d81c4644ea36afa076e055be5917cd7a92350a7ed66a5ab2253f55c4fd1a0d0e6d4edab5f712edb440c06fac8f07e6d73cc90b2ba713d73c73802361ce46a4eb5ed1060c4cf53207d301f0fcd4f0c9d1580db2fc1059d372076438a01192a7f9fd6f7883f56422866fd9f0afe53fdc910afa5a751cbfa377592579165cb56dc3eb4dce67e3db33a981a56b7d9f7bdea74fbaea3478e6ab2c644fd777b8bfa72aa0f0a52198d36e5b634d2c9a11b7fe0ab2f9a40901c5b148a0192e95a170baf7d5350fe01e569542b93485a41971443485faf57f67f56dfe2c58e539c9f9b449c3f91249a10c1a1be7e0b3eabe8ee0bab1f11f89614dced418c62a07a0b59a1370d6531ba177091c6ad595fb59488204f63344736ea1017affbeb753a99786b1eb64510e2e717ec90e02744bc352d3f1b2ab7be0eb65623d04fb3a046ce7f4da697d829828a52c7b043b2a82ec97fb041bf519b4de316f4e2f5b0db62aed0eed95cad4320c1947c35fd8847a5867872883561119c01b0089213d84db99d439f0f6444d8783dd4b64be3577cd461cf753c8e61c912de2e5d7a7e2baefa258975d16ef3117da59a6c893f3339187df3168b89f0fb0b2198bb6f1594bb88f3d610fcec3e36de04ae10328112e6ff74f5a8ce68d407174b4c0691c7602eab1bb10f3c49dd22b8450782deae9a7315e3b88de79cd15e6c9268165ed3a0fb3f89b183e1a212152003f32a2665d37cdd7f6b56c2453e5580c4d21f9983f38798e9b
+SIG: 3c4462aa47010132dbb26311e444727279edade15a4d662cf647f3275cf3253e6de9333830e0517aa5fa7bc2d0e63ea2597a94b0fe92706ecd172c5ec5c7f006
+
+TST: 890
+SK:  7b30b42dc2c670a195fe2af879fc5de374024588fe3de43e2dd50844f48f42be
+PK:  82a2ac6079f212b5eedd0c19e9394fafacd74d716fdefbfc6cb8a7eaf41c0362
+MSG: c6687aefebc5c816d1a33453beca5020d3a97cda1dac5662f0af72bad444e2fd1176a7b04c1bd09d832618209bf3e33e523538d6daa753046e871dd3b3c7acad33e79c1bb7896407865d168d4bc3757bde4f823c08778626f8c71fb7cfcfdf03a82497bd8be7d8f8ef649030b5f36a339459968e246a1e420853dace41ca850a4eeae834ae119610ca4cd0662aac39621586998027ef2f61485c028506714ae09c76399d873e808158578aa59e8212f58865319f9e0d2b8da7ad529e0ac1f1eb435aecfd35f5abb92bea5073496bf4c0bf15baa273bfc5c3104474a2dcf132c333eb36ec2cbf04fa9580b768f5cea7b5617e5880aff63201c274d669743e1bc556b067902eee29d29111288969cffa879fc9cbf66fbf9326d9d925ac4102fa9f1a06081adec079cbc96746d79b63a012ed77d82c9ffd4e3f161f6cea28cc23fac2a543f5b1d0644ec04838327bcc652b858f93ff463f7e949eec8c9db6569a86984f831df6ac6d95f38f46cebb6e6583657facd2108dbcd0af23ab0101a1301beb48a44caccb91094473d7e5a5c88c644fd3420573b678f17b5174cb14e90fac694d1dbc6c9632b5974aef28ac08d720b2ea30440d2afb0493b40db24efbdbf53c430921e52a10b54661e149d165591a7cf91d6508ea472fb3be16395e30312f19b87c47e46804a0fa29b56b5ac950677bc60238b5e99e030b1e552146a0e88c294cfca835c101c55f3423874cc128756e73a5debe8e97fe2166b65cb44642770c6d1d2390af1b0f31b958c830e9ac4fe2f5ad590582fbb892bf949584477ef7bde23f7dd02b63f7c29088a57251009132ffbb78ed14defbefd9fd31fdcab03ba80a23f333983760abad4f16ddf9dd4414f04d00db56ba72d63a3a13d2c442f549fd66c988d2e4601d13b52f77500dd692bec9d6bd3bafa9242fdcfaeb69b98b0b5789b2803840dec637b49af4381ae3fa429fb53461a0c674eb5aa18dbd607a2b77a96d3ab464ecd97492f6de460c9f11b5c1756cb59cb1348dfd77956b71907c54821e303cb8b14906c003e3484be4ea05a6901d69b07485e858f7b471c635f90395b9a3e2247f1ad12b118ffafc7221a57b10e319b61af1c13606a81616ce3f1d62ba932ff4e63e74b84255e3af5210bbd571bda44cbf44b714422cb45c2ef21f98131ba96b7edb9b03e33d7d188d5b8d904cb4136fe269db146988168e7ee245356354f002a5ea8b35a3a99e83a13272274144b33a60ca
+SIG: 0a63b84f46935faf3ea164b00af227b00868a03f5612935e18619a84a2e57b8851d746e63fd9100787f5338d51c1073c2fc5303099e1873e5e3d3e5c036fbe01
+
+TST: 891
+SK:  6656f4d4718157c4bac38ff7abe5eb1f812c0b986d9c014abad5b09aa6c8ee4a
+PK:  f3087898e452be9e30aecc4e8ffe0c01169888683f62a45b8da38299014f5b4a
+MSG: 94d9e5e5a7b705d9d976fe71e94d3f7fa7866afbf7ece424f136327799b2b206ce4ef4c3f3e705553afc8fd5c1952a4c16658d4a78afbb9a97f27193c65b65b82e8f3b71515fac82640e0f8a5fb35ae6fc6a3db051a22d4a5300413e6e33d19c2013c2983aca8ad6cec2ce64a814164f061a1a3c5a8610a7650bfb5423d4362ce02206dbe4a6fa826f03b42ac3cd9ea4c651401b3cea82c3993f6af8b2c9e2e6ffe69280ab3f09fbe90dd547ccda9d9e8e8a537b3b360554227ed0709f293198982efb5efb0e73e00042d1a063b57452027dce1a39e4b0068f58b111ec5dc142bf419ad893d54f4260cbde7628f783de8496380306a4eff6d82869104259c94c54ad5aa8b067c42496cb88dd31150ea04d499bfac91f4bb3e68af5af7a568a3e4ce7f170d98601163f4952f1d25e12e00ef0a2d8f111afdb0fafbad2bf8e8b9d49363fca68183617b541270dda4609b2616729ab1b8c42dbdd7bf986af8fba52e733e42ba03c892e1e1ec06a90b163f5a79f6165eb7316972ac1adbfcf1dcab07847ef82c2cab1015dbb50aadc79fe11c832098cacc39820ab085b6963bd42160ed6613bae5e201f17c0fd7f32357ae350ce9cbbe926fa42dcbd422ac1bf09a19ad1f69469e4d1dcb124118ed4522d353c174298650ff88382fa2fdbb286c45b18a9baf6f6763ac20c9ca4767d348c4b8ded630076657b85b14c11ae2737ea29a43515b7f05674a0cd3ed4bf6a3d189ae972218f877cd8aa69499d5a08c99e440694ccaccdf1f642e14e90105bee6d98edeeab3b4f339f300188aec0c16bd64521d9287398e648db94330ed8f6b9ab6c7ad93ffc43e8792e637c61bff7d856e54ef4987384e312cb57017a50eae5952abe19d8999c8c82dfc45798cc17c8d9496bf520ecc5b77fe284915566c45685c304a2acd525ef12c86f38aef554d8a2384737cc4133fb7e2b65c13bef31668a6c2f60eecd8412eeff7f6b605cbe95083e233ec1a7bb36de236c8a71ba2872be946cd3b38935f5da64c8fec8e14f45ccf6124bab7f70567c2f2bfdd56667609572037c76146c991707659b5709b074e3451f921a2df283b96aa26ab476625016f181ad64c9919cf41d714a1a9a5e2bb26baf8770b2eba77b778a332677a7572ee3a2b1dc05f7356bdcae5f55e35329e34caa79430b270c036160dc9fcaab5b254543ac94b24681f17172b6159d16621d7ad0eebd895a1e1d09b916a86fb48e4c91661057eee95c0870ed54
+SIG: 9c2c39915aed6add004e7dd684ee3dcdd10d87a487f677e73c2bce0fca7d508796464150a52a440f5237850a009c72162d9d2985470a33490e66d3c401704c05
+
+TST: 892
+SK:  14383e6e5604c99c248d39be51d164b13442b05e51d78ecd999364221a45036b
+PK:  2fc16138220ab74b3bd446f8a714b58d5463d40d4367925007474c5b9e35d494
+MSG: c4753b7f7a6f6dea2515c6e3d29561506f4f36e0de84999221f228e20bd5128ed93bdb8d1193237d8e294169a2bc448af9dd36066301efb7fe1231353c0623ffe1115debb6905ac6946ee382a27c3c09e1b1f5c11493dba37da0ff6eea75d9fab0ee926d701dac2fc5b7ef578880a5d5eeecadc1f4bcc4cd4ec6f2f14f52a8c164072e6fde5ab2ee9cee0b48e51af055f9fec7c63750fedf72332b23863a1e54c52b461a21506dfdfc63880e22d89c894412666c929821c0e439e745415f717969e6058554d64b947a4fc9d16acae3e49aec08801a09d972f79ead68d529768069735caa742b45a5830581b80ca061a6c1515e3f7d5a9337878c19fc94eef22698ea6c4d05f9ed411b6b8f052b5ff15dc23a64beeaae99f84893de3df940a4e0b8e993930139052d99be47bca8775f8563bd4026b71343d51968f2337528f4c9db8bbd0a298af04b27695d86b7f7ba6c4ccc6273febcd8f75cff266995244fc1fa13d8d843f0bff49cc2d508f4a2b3aad1d95fb22a2bc6ad1b966b0812d99070bba07c923ee4d08107486dc01a06dba6f1d5f105aceade33b166510e427ebbce52a3e7831f0f78a3c6e072608334d8021c338a73cc0c47f19c9fae403b9716d0d15fbdf6466b08f6acce3f50a703b1dea8d826df842ca1ba20d29f4548acfc754cf011f570681b59e4da25385ebd6d5c3adc930529e166ce6705f6010210db106462b3333204e7adadee6606a56206b47eef2074b116e22a615418ec2cdc331f1e19e07e8a37b92d69df0734e085daeeb901ec6e8c35f103f1d86ef0d2a2652b01d183597e4cfdeedfe5df9a7ef66a1c796a37a27113b944dd7ba17c460015ab8ace451c57850ec6c290c54e5113f55e99a8e6e4711e3b7817bf91a5adb37fb9461be6b1b55d586046e42a54c5def4076f1ff6c31b806fc602474356aa2899eae70f5e5abf1f75a7f24c134cde11793bb162e03a583d5be046acc73456d12d509d92f7705768686f6c714a4e57ec88b71398e23e835d6d6547225996b7ed08f3b7443bb17c899409493d0efe8455bec8e8c284a3b149a5b4ca631ea620b1bb817cedaba50b044411849d260a6f2a0d3f2cceec3842719a5ea4fe18dde0d42dcb33ad21e6453325af6f3c009f2bb978d30ceeae9aa4928bf73767cda9292ab893ce5fa3aa4c232163b45c64ed7977779b1c0cafcfc2b9fa084a324f113adeec218b4735b6b464db6d46c2791af3455f1ca5ea1e9a048c051a54dfa0
+SIG: 45e8ed1a751dfc3b9b7bd7a10bf5bdcf8ca461865a490c105f10452941cf87721214bfbf3a35606b7ce35d6f70aaf2d5eadcc0de035e9b2f6d7b862fc2849004
+
+TST: 893
+SK:  59b07263b22c0a38bbc591059594b2bd927e805961dd07e1f94245b23aa2e016
+PK:  0b1e4cf5aff278ec65b405f5108e1b5b18a969ad1f1e6381912c82d698907cba
+MSG: 08ce0d4db5c2aa500a19efbc8dc8549250f7dd46a7a9a5407417b3d51820e4b0d61275583f56f897fd942bdd7311ad6baf738128567af6558d75906a02c4343a9955d59b11088c588dc7dd08f67965c5602a56928dda4ae164293163b517ca17ded04fe4ab2f9789130ae96ab231f07e09015b78f3848cef435db0ad9f35e0fbc9851e3ecfc9fb186d14d8da4dda45d0b3eb3ee4500c101e3194b572140689cd75da1287b254f374e3d93326ae5faf114018ac714bd00375d92a8bb659c32912831f4f20776e9e2c25029f0aff39fddac7241543a0366b84de7b1ff23e8e4dc093df0d2dd5e53e6847948cf3d0ff3f564ad94d9cc00a5ea5b695e408bf50f5bab2f6ea87ba8ad3a1940195cf1bc2b5b34847ad3a5effb8a7823de91ef1633869d1f04643af4d826a59e78b9d186312b3d972263654ac5587b80b717646f31003db81ac70860d3fc8cd3a6a0a0d576d25731ef7b8966263d7a05b55009e8a23dac0f9a21a24b06e13900e444446fdfe56cbc1a026df41066b201b1481e56158926c0c9ea90f0c645aab4bef12d4e072cbfdc3c3d5e0c72cf88f166de048874f3534e040c62b1662821bdd16b0e8582817461cb2689279b446d70c8ac20ad03e598cad4908c52c350d4243ee8aedb87a4af977f7db57cd947b47d6bb51409d80d81f6db03cb9a6a6b79812f470690afc1836a531338094cf26d3c1232fd5605d8f8c55b6f8a2a7ef1e0c78155594b237956d2abad6a9adcd58e11ccd35cc995b9a0aecbf7f5741ac051b04ef6b9744b56fccb46398528bb31fbe84e078843e69bf338898cdef69ad41872395e46b593904825547e00bdaf221f8fa587ea2037ffb9ac9307dd3f8f35ec5386ba966333e2ac8727b0e1b80612d3c7f2cb88baacadfe2163bc38c88842e76a394571d40610e8a297602793763296e3eabf720e984b2edd28cf5c4e0f9a0f76aceba28cc1f1b69ff1d35b4bd3347b7f9a95a4c1ea10734e1c918eb96249d0cc70b477f6f23809bbda901d53f485a71f5086002c1b71efcc41cb1aeb5122a3f3bfc96c51a55d75c02984288be657887854cfa738974bcd5440146f9bb14040de54f5444ad43b79af9bdb24ed6a48eb2fdeed71f31f0ece102e918e95635c7a038633ee348d8b5781652d5059d215ac97f30ea20d277ebbf15246905428a7bec02b8f926315bad6723fd64d71fc95f333364cbe90d4646333c40dda6d1d433b7c195a758dbb4038af5dcc7232d4547f540e394
+SIG: 886da33e3553285ea59c1431b6e86ea49bb68b2e0efd2b157e7791b74f35a2421bb359f3dc1e4ce5f11f73652e03bfc0b429c58f0f2d7418c7c20bce2e2d1901
+
+TST: 894
+SK:  5cc115d839e058cdb6518ee9c161c004d88bd3908d3cf6d52c8f296a1a076b9b
+PK:  1e8f3305bf2fa11b17d92416ab0ea762396d88f2f970ef0b100ed3bf5cc13440
+MSG: 533e49c1d5f33c5ec4be84c619f4ec649c25fd70bdcfe257a63c3373a4d089c89af6eeb7160dd77ab66b1ee7e10850ab4fc1f35132332b53789b2b0140c4f20f97f2142072d624aff7aad324aacd068c035aff52fa712f4e74832de031b2642314d17110dee6fb85762dc30d7e97782fd1fbff7179f00917f55af7503a5b7e23c6eadb65e104f1517b6624c9e5204b3fd29a6585e92ce3a3eee2c5ae177920f7b4ab2cac87d672ab6baac1186d904aea3498534eb5ab23e4ac4c0ddb0d82a5ae531d76549d367628577bac4235e897d9fe205522047d214ff6ccf311c4e397827d97f2868e70ac17d28e334999744d359376a482fdcb414b02b2687b962ee8086e573fe000dc51dee06879c684e25f94cee5e861347e7be7fca549a0f765136a2f4b88fede07024dd2fce1f6d0c0354da1a16ef366b315b3f7233031f979b70eac6e23bf3b349efbd0e4f53f4d5c41fc004276a59670659f6905ef03d2fc098d589fcbc1328282fa22b10db83c5d70865994fd19d760a39d476e02330d2c6d19e742267dd365bbe1fe5c711a95b184508ce48c1c96d7e63990b408d45089be79e32f9cb0162fd1e7d0d19d97d0ae78ff824cc6989486c0bd038352551f37499e9e9826804e9d2624ad0c7b7534560f45fd7d324b8e517e01c9b2743c14979cfd512bc3fe667279b3a277fb463e9d7349b64ffc9fe60884c21e481081ed70e6da5a3539c448971f0d9787289fcb0080f219e99449f8298c42475f87fd10aeb509c530cf6a57748eb8f3562161fa4875ea953f09659c7df7a9950f0317467cb4e5366e196e32f5e2696733a25eacbde49210490762060ea231370d4090429bb06bb867399e8d37bf5d21a0e72147e496cf3b7dd6fe6e5edea9668d802190a91c600e29523f8eb904e48b70412bc10a7020984c5ff0f5f383f214ae594dc85971e480372848d0d7e7cc5c18ff88ba9b262d7884698a41c6c7819c0319fdc6bb07b91dc1694dafe3af37a538bf2b2d8cacb27d24cdc6eadb8c6a2e6b7df8a4654ae937850c890ad930980afcc1492db8a0168cbc9f10657eb48d2ac87f5175d23caed4b5e6f10bbeaa5e33fc5f6418d63ba374ab1a3cbd36b729ddbdaba989d4645e3a66130bae417cad086dadd30843352514c375f2571abaf93e9a0771fa103ae92585b04f55c434769b43d6d22f753f9306036e53524f6f4d9ccbd2c30317a8e899f316149035894da945b76d9082bfee328e7a31b66328ee8b94e068c7
+SIG: 0371c2d64c5ec0c8276ca5ffa615eff42f9efffc58dd8ecfcf67620a9bcb38faf118932bf2cd5b9205fa551334df2a757c597744f791f371fbedd98b21f73405
+
+TST: 895
+SK:  75a503f48ffc221617672519111bf90da39da9eab2e2914fd3755f10f5393668
+PK:  f680cc0f6358cdcf537aa71128cfadfc0f3a89c100aa34bcd2427e248b6ed50b
+MSG: 7b01090423236cb4b13c4177fce52a7ff6580588cc2eb5a3f39ff5d0c73e01e01bf7bd74afe4151250c391426ea507271bea1d6d85f0b2fe35c40500f98d0656c6388fc9efba1837db22dfa29d892676f50e575fe89fd29389d09d080bad67ba544cacabf5a7738237c55e2875ed4916302a2b4dc496e74273bf05191137810e50e48195260bab6d81f9c80562ee73ccb9333cd9b61daf5b0038a4e6c5c958a91f68508c1d882519c1aa4ffcc53562463a0ae30163696f84b97ccbd8679820edd3617e7b896eeffe341ec6b5b03f73b625d741c655fe6e82d11d478a7d543ff6c0fa3a3a8c94a616fb847070d1fbdde6010f026b089cd863c3bd29b1c4269f77659e515728890c973be87f0b833ca5af6b4c3133ad4fa4f91655c6adb5b7235c27fe348284f3f13366a6a03ad22b87c6f5584bdeaea48c70325d6e33a475f50511063875192a87edc388089b84395390c2a3ad89a22595dc4a715a42a2c0efdef67b354b34fc75ca98df913e759e51c7f625ddd598ac22d421decb57bebd54220ec6daa5ece769d2e01be7b6bee2ff5a0b06b32d6da1d7bc057e3abfaab242a3f7e6646a159e4f505e4662982b13d0cc1fba91d10309a42dc1087cf10d36e31f170615a0acb508bf683e2de00c87640d304a947bc4971ff3619c72abd83c7b2cbb3464c4040c2662b58508b74680cfa6de06e8d21e3bec8511199312680009071f706b7b133a2487d5745ffadd5dc0eb2b553df440787f011dda37719fa71315e8b291efd77da3ba14fb995f03571a3db522b63c60be5619941699b39222b59d0f23e5eb37ead4b7f750ed4abf4db87c70da665bef4d7a2921b2c99897f2321c9be6075e744c8228639ab736dbeb2beab440c156a39a2efd261db50855e304d9cfeb99141c613558109f21474d272a2d906d4893934aff8e08a4fcee964a5cd00732fd33af29849c8dfca65979421857185cf629f86807a85973d3440a6bf811a58d041387249811ec047e5e8b343b2387d0181e0d0bd461ef10e8164aae357d9b29dc0ace3ec6d743ae3454ab9f842a28d5710217dffe50344e8d932f1801b0e8f966198ef1c9cc6969f34734aa6a63aeaab4339f75d34ffa8acb937ed9c73092a309a9b84a25011e3114c265e4f602337eb699b5a22d572b03e4dad03b0461c00db9679b72fc5b493ef4486f85535d813a58080385afd4e8d871828034334bfe441d18984e4dfcde024403b5ae66cc50a47301b57f9a32f740bdc7ff1d
+SIG: df28e3e630360867864bc41e43fd7ddeb52876dce9b234a3fcc3d8549db0112e176390a685ebd484936e25c08c8a3878a37b3c4e239ad0a0e5019937ffbcd407
+
+TST: 896
+SK:  d8aa2a0aa514fd845f7aa66b83c0eabb9c16023abc1695773450b2bb332522f2
+PK:  e4e8d6b298248c15fe08f87a3bc6084bf2d64d7f1e4b2d51599e9fad9cc91092
+MSG: 08deb3b832f52d6556f78c3f0abe46f1efe45e3d5d88e7f8edf803670ce4612921749e9ece63fdc9bef2ba483812bb622be744d40404fd6e09c9e1cb7ce19de81a9dadf556352ee89810c76a9b1047ac62b16ebb7da23ddc2d4ab76a020561d02d41b58b94953a23faafddd781b7dca7b7fbee706ec10a73125bf74436056bf3b4f2a0701cfef05bebd3dd8eef306c1ac1b00950881ff05ab5c8248ad1096ac91d526ae59ba0583b27db7d1e390f57a5889e2799a4a1519b15d93dbf0b21d450873c76ba520461e8bb5c83c9012eacd557bea640586efcb869007647d449f91ccd52afe3a89477de7c2b647ecc9bf967fbf5769d74889447d9522d9e8069c3499af6a8a1097a95d3bcc5f83433934484314cb30758b525fe53e90721df5cbe03d96f0d0f98521f01a5fbe57ce8804dbd18f8f5eac8f7dbb58c41789a44433f8a8d1245d2adda8c78d881c65ea661ab178d4fc2634cd6cb514ab6f2543e9112183f3ff73a3f450106b0ee8a347a80cb824ac1f80164e3bb5123698de0e747359ca35acaa3ba0c943beacd7a9bdf8ff73978e9fb002045e8fe5648cc0f9cfa88b0d812e81aa62e0d9c73fe613afd9539bcb615721fb497d62f65c83b87a6d2143f9b1c880ec8671bd42c8de957b1a68ee49226ff717ccc6e74f2eee49c30dea53fec3cd4d90f2cccd8f97c55d5c752454be2ba7b6ff2030be67e0df50c5e883843e71612f2b95359543e2ba1bf2e98debcf5768f2be6fd504d9783ce921a81e09416dbcf2bb655a924b1ef0112d671f084a5b690b0b64a8b9bf50333c359ff3fef199694f9b6292424f00666cef6d06d161a79e3a1b9b9629eea53505f5e36aeadfe0d759672b0ffe498397d90a55d9944b30541a7e1bdac53020640137dc252aef622f3819d36ab498d763e4327ba8580dd9f7e5f47c24cc9928734b7e62112c57e3e0cfedecdcbaccb0c45af8219455ee7223c71e7e20410c5244eb827af2f3935ce4755444747aa945f4c26db3a298519e75fc6bace91529972e8691b694d30aa8b5ec4c1a028d3bd10bd0c8a408fb7d9d703495553ecea598d0622dcc74de489ba7195cdae8d5cff9855921837b528433ee55c0b7090857a0c2784d9310b4825a7993ad9c6f18f83bca5cc6a25047168a8376b062e3a48ea90cad88e331187c2b6f281426f81f78804a895c4ec06c341fe846af4527ea26069dcf61d813fddf0fc43c707350bfb2fc1cffcee7d7ccd7d75f7a465a3d14d57302c146aba3e
+SIG: 146f65d43e715542894b7900a2f8cd4b17d3870a6100e37de005b0db5d8151246de4ee3842d3ebca20a5da22a363a7575e7a55128295f27211484af57cd53109
+
+TST: 897
+SK:  de8f1c99e7f8556df20b59b8504cff7c6c5241a8aeeb30b92eab97bf481d0fe9
+PK:  e463791d0f567ee73abbf47dd57167a535613b05cd48d92ebc7d24e6ebff9573
+MSG: 38d93e5c9801db901797ec75c6dddc65ae7980de210bed43b33eb44cdc6dc9933fb6bec7421db10f0a59320b9e642a21f1dd235601fcd6c53be4a877f4fed3fa4a0ad4dc6e9b391bcfa434906925ba45ecc5b435d9ab8cfafc394bdcca9b07d5668393446e3400e9039435a1dc78cbc08807a3fb24ca8b19f64ea08b8bf6c20a195b51ff8015f3e7c91d08e4bc62415595a5a882fba651dc3a675187af618249747b4680d1d15a202ea9df48b1c214fd403466fd1a265f2defaf8ed5a6bf0eb08d1864f2a28e9472143c6fd103b6b108c0d1d1363b99f9202d11f02056c279cca315db1ab6d31018458f57ba3316cd2738e80c492d857cb1749925e331c65858b50983cd9838cfd2188a5e8f05b471fd3cddcd30d96901194020f115fb469ab5849006dffa2d543a13b3b506ed65cc457532b8aa3ee31d9d8d9e5298d7ac707ac15b827a578c81d434f84cb1b56120d667b2afe6d1530afddfb966d953be7e32df07de389e2d04b232d3512c7db9358fc944d1b118078e6999e891bbfa4a4329f65d807188b59858c431211b29576f4496138b7c0c128f7bef5f79b0f446fc6b4a0e20bca4c40a83571a36644abffabd49cb585fd064c8e509d9a0fcff462676f0ebcb61cec61e512be6f182abd59e09f642aa619634853482ece8f89800f9c5bcfb841431ca0691ed8d80e0a2fcb797a036897cfb6537586b31c00b7965efddfda72861845026459157f79eba1bcaf6cd41d618aeb1bd8da1be98f0cdc7f2e09b903de49c0c1be91dcc177b298096836dcea4f601dd86691555128325438bd9ccbfc0e777920ae8bbd57634c6104fe69a3a72012a2360b6e552550cffb4e2f0b41fe15537ee0e6f37e7880fb4d12bef6cad266ce58df9816b35960cd0bf8652862ee789ccc31a7efc21a81bda46146b111fcfd94f04856ab61a557b1ff7c8e4ea6d9c4bcdd93b151aa08461c568defb2aefdfce96394dc822d4ef6cc4b9a3e6c332039f6538aa0df8de8126d90c312ff496887486111565534346a7462625d63df69fcb5741906f19e00fc8003f08b95985c38b8674af423ca56de5f881b59c466243a7adbadba29caf57fa777122e61823b4e708182aaf37206d7d5ed051c12a5c0f6b4371043f562cdc029d5e1ba9b2bf5ffbf1f5f523db06feca427db7a08819ffb2d0585242e20da58e320b16b16e448d8be0ef7402d24a7194257133bdc982314d83adbcd12e8af31303426c59ffd8269ce4b987ca9b6f0ffdbb4d1d12
+SIG: 30abc4e4e4b388581e668bd409ee18a6ede81a136c28a2924df5fc00d7c280d97862ae3a67a935ce492364135e659adb5fbabe689816591f49ac5022a387cc09
+
+TST: 898
+SK:  0736f801720a947c5c2f3258ce0d511c3e17e94e37b30adfa52095921171d400
+PK:  4f694255920d0c38de6e72e165c33aee76b1cbf6f4837aa5901475667acd2826
+MSG: 7f87b51f6ead2d4402a3bd3c3769a267ac8e82f779ad7b986dec82cbfc1ea51291884326d9226967cb66a96873184f0e83b3ab25a5ab2fa805fe3a0e7b190a622d461b7830a3f697c831c29ea7c0cd4b68d8e77aa69711cf864dc1d5394f4845e2fbb5076404e09a88b79f05670551bce2ef5468b79d57888b9852a4bb479a4fd0beb681fd523fc5bf4458abbc38ece72e106e00222015a57ebec55bf47513e25c3c4554843bdacbcfe9f1b8d0ae354e48d03fdebdf20d655b5268d8bbbf33b1288910f0444fcd56c0da7b8903362b7e37a864654277cffbe6c60857f0b3514d22a40b9dd2d3fe5caea5507a0de3051bb3a4015fa0fe4c462b98fef2357dcf6b97dc75def382f901f96f4a04a3efc60254200a2c4cdc8a58b25d94e32954eaff1511ac46e3606663b6875f136499da6a769097879a6e0834d564fa7fdb99581183ed0c9d48fd195d7ecd9f4dd4865565fd17a008718dcd76f68a54e516a2b730ed3dba5c2cf40630bbfe7fa03bb7cdd967695495a7c86e2e84cb017ec69601924631595affaa8cfd048d14267c73e54cfa539047e717691e399737fa50cc4844961257c93d7253d23226b7cd0d1bd31f3f0d2d892d073d8c5073c602f61a04d6437c3903eb4a64a01fbcc0c7e159201cdc4aa42ef3b1ff9c78fc275cfb11a05ffed8f9f22d85ba924d8d32231c254d898da7f0679a64cab84026906e9e85f95efd8ee2a1725633f4de2ba67d99aa7f0550af139e9f8c5293786727d82630296d5daa9e830aa1b3b5b302b8b662ac832e9213016ba493a03a28cc3e9540d0d65acddbfe1252b5c16a84a445ce75415c6cd8ab16fe5eef117097d71eb5676b9a95b35882a7c3506bc5d02f03910a63d46846b213c3c9bb2fc34e6c69017d2065a1ad3ce3fd14ab0014f584e57ea9d903e40aceb230a8693fa2e63641c25438ff7a1638760438844cdf001180f5b177be69edf7ef66b39312805214cb17706cefe545be5a77019a5ec52bbf78850fa3d97de2d4d74aa68b58ca812a1b156a0c4001129f067232a6ec91a5ed4270f2a4c6efeee787004770c859e450e837efb04dc998bd273c27a09855e4eca1a22a9b88c17bdbf253a79761070a76817a7f74ff3f07fb718bffa0b4f326f284e62f836832427be82f483373515b9bf59af4a76a57e2f40b91034dd568ec14ac10e2309b87e2922f9cd9fc1a46a47ed3bc7e1b9feb9ee067073fa5dce2a67530526de67ee0e509663c44467eeb59420103ebcdffa709
+SIG: c03c0314851279edcde970c23efa236f235eda960d2c27d3ca946f650c200b4eba04be668ff62eaffa6cea351abdfc54401dccce3dba78004aec9581a2ccf40f
+
+TST: 899
+SK:  fa75650491047428d363b5822222122dffb5a9fddc603c33c8a608618375dcf3
+PK:  98c9641fa9dfa8ea13e0d1c716b8679e264be15dd2d4c06ab43cbee47916ee01
+MSG: f54e41b939e37df17c7d6043fded14a915d934e867c345269fdc0177f5bd10c4348f319e0ab9a64cc0b7d4e0c91ca9aadaab2edcba544f14ed2cb539ca8975097d87927095b4ebd490344340061ed93c38167edaa096a230db59624c67fb9a1e1ddac402133f4d47cfc11e2fae6b3f3c5001cba9a8aed90073103240227e716ff71bf68a591ba2ceff2d31b86ef21ab012eccd409ad5c29d659a1b37c4d85505304140fb2c3437a206868b1352c102bbfa3b9a76522a2bfc5406b257696de74ee7d315c8e99caa96bd838006c6da2a4233315a856acb8e80c33168b333551d91d074055734130bd7d14c56811ebabf7d5a250e6072593d9f2f8b97c12a703c2c479cb0b15b7a2775c9dcd2ca4624672368a2e6145467f3be6615f93b8120a0a12da1560663a26a61731966b44b299ebfad2a95c62360f39ce05d9558e305ee23a52fa5ce20f6be5e262aff3a864d5ddabe23ff943f71d5998493d99fe2ac2374b464a69183c3bc4f1ddb883611149d7ddbf1e8380b544335e2b89395054c9f2558dfc56ea93ff14d0f15d2e0bd8937a556387de96e418d8b3a7d666fb190364b2c2190d3c25f1752d5483dcbb5960064f0c87fcf8f313d28781c114a169b690a8701c50d89c77324531c0f849dbad1633d925acd06c16a9cea19a434ebc42aebb1fdb9b0bacc93cec39919943664ea1a958406ff9e4935c92ca7c39708f9cab710a583096b4ed9f48d9e090647240d76eccbaba591f55fe7e36d72c21727acba0f8030954e62bc580b8b670c4457c3403e369ac20e660d662f7f6a414213ea43f7c0105009c1de817adf6ffd9cca3b45a63a822281c6e2772fd7b7809603184b4879b18c887903f0fc8d8e1e2dbf6e772f0b2d9b8a29927acc81714a2256ad8d7b7330527d7dbf8befd82f8c9bb401cf0a90249a64ca6f8833db31bd03b9e7946d06dd04383d7c082d70aeb37ff84c2b057d973b894b4a03ec7bf031aea656a1908488894a4ada3fd7fadf91ede9550d38415f82a09455c0f432fb55987132f00042afd60ea51d1f1c6c1afe0cf87c346e31e63e26f49b137177b2d47ab30f07cea071931274cf010836d683fff3be7134c78b8bfd8b1b8fc2049e18ccb1e18a0a9585a7d8a1e25492608668c96d62a0aca8ef90e048d20378c108d06b03fe3ec4adb27528ae08f7ded9487893ae64ca4b939202aa4c17afe718cdca49ff9616d0cdf8334b6aee2d6d20947ca4bd7df531dd1da99581ff72ea56fe62caa2c95e3587
+SIG: 1effbf9299a1b9354fe1f1dec1766595ea767ab8e4da9bb57b4f69bcbd8cb3d86f768392f59b39fafa8a210a6509fe0d6008d6356111adfb3799c1d559c26309
+
+TST: 900
+SK:  e1c12946d221a194f22f2762c0e51cbe3f98b914a47d3dc41a1f45c54370637c
+PK:  10408136a68fc56c7d3b36b7fef122094de081031189cc84a48806aaf6cb9185
+MSG: 870f4cd97cfc0aafada40072312fb54bccc07628714e4962d4bef4eeb5de40a19a246b5b7d52d487b7e52d656f2c6403b916d02e02a6d291c1e1828dd945a583b438528d1c39765a572031ffa916b68321f32e6646f0dcc1c60235ffaa3235f484a5c4978fa3e6bf14301d53e12f4cc52118b1f6f07f5336f5d0a93789bb01d162fb3126dcd756e0642e7e698963c0345911a5cf3c9953f77319426cea2cdeda3efe989ecb63cb9eb8b920de766c4fcf6336e5bc4371a068371fed95c8c2b61ee9b7c3e3831c20bffe8707c0c98be96153c8a873d7f28afca1bf71085ce0e3899eef5591bdd666dc2d07641772d745c51644a260815b208c4dd305f05fe463d0d9d5a9eeff9779f5b1d44f26083078566d0e5ff56b3af0e64cc38708af5a65f654352df10437f1ddf945a0da1f4def6a71a060e0c4adeccaacf85e090f7090370ae24e5238d768a08fe6b4bb5ec497a6603198608415c7c6490048aa36737c08503008aece0f494219ddf89b72ea77171c6d3117089eb88907e8c33fb9e70b0dc281f664b5f965b5d2adb1250710ef2352025fb293395ae1d23ee3b592b4c5f2d55569a5458654ce3fc25dd0e3f7e6757aa7b347c1ffd3ba4d4f2c4b6d36afd59863a32a594e74537ece9b8b1ec269bbc4cb54d76238211f62a98a46a4af662fa81eba6f30f514b866b7942bc173f7211a6c014da14e741327a568623d14b8f835ef1d5d62b2523cfe6a85bc69fa05200deac1568b946a816b75c5d7603174fd4e2f9101a79063791bc3d59297cdc10bdaa663abf3c1be2fda17e4e5ce394e90bd76b1f9e0405f5675b99d638abc2c1b2d8b53a6fd3dc8375855ec54ccbda24e672527723b07bb599db54e38793391cf09ef3b1fd7614990065bbd4a19e8d3d1048253ba4c971c2f98d2b359df509087323aa6905029f5cc5e1a0aaf2f7c0108ddb1a40f562be64e57e695ed21dc7db17d533677ef12fcbbe29f3b237bb6344b1109b32a9462abc3ad3c0710b04f38c6f5952db275e77e2f37e95d55096bbaf3e305d5d743d36595bf0567892c210ac7bae7371d164584785dd890174159b3930a9a6ce3a166dda2383e6e2af28c1bf3192447e90511dcd80ebdf9ee2c9bdeddeeb610558641532d07cd13da61254154cc0fd9d481e3b0a237af2ec26256d4ab219faf15ad2b7e8e57ab726ff2723216a574585e2a639d948c2c4f69eeaad283e3a44ff268eaefd7e66b73ede473a8397c76b48d56cb3ccdabc91a8929cf42998350e0
+SIG: 8fd7fa400c032fcfbc402942fc78637526be97ab82f237bb393ea39e35738c67d75409543a8b3c055f08bf69199af63b6911a482fb4f6580802ec9d2dc3c1106
+
+TST: 901
+SK:  762f06ca01e314715f92c90bbe72a25bf26212c81eb1d1a0dae2c31130f7cdbb
+PK:  f9626ffd692731925e5aacfa1bded01aa8f730b772d5e46adbc315565b9bf2c9
+MSG: 9497483a4fba78433b38e9deb8915c750b6da0f78af4a68b62f9fc0391e338873b1d64b1b7f09f12f056a3c91653498ad56e069b8b160887e8e378a76d8b3c667083c0a2b2d2317d3b874857e57862ef0cb70436a9028f0191ccc616e9d7c9bd869808cf094835ff518677b3fb089f4c9d077cc7742405b4863ac7a59645c9cf540d57399da6ae9d07fd19fca95bc8a86d8b8e24e48733f32158fd19a8a1111d1da1f9b580a39c10484616cf2bc0ec29f63f77c85356158e16da594b5a890e55d0b64599b30293e900ed92ad261969e7df4c4b1d0b6024bdceb69067ef486c20fdcd22a10d5da45fbf905ba1e935c96f50afb63571bcff3130684eda0b56e60b26cf4c0ef9938a92768fc8631fe308236b012f92af24a8f6e6ecbe76629bbaf8ffe54cdbe8671de2ba624a7c0f6193bba4110412902bac2990922a9e5a81053cf876a4c805a04c56a8139d3419e454a622d0342bf426e9802c3dc1b4080c75492afe9d7b1545fe086d963541324ff52a48c6bfaea26668b3e01e5236fd45fe54594535c0b23e287ebd1428c8be0ad141600e91cb51e1ea66271a6421fb689e88a0790a651dbd21ee2089b274666f660ca09ce2d60e39e2ee5f03b6eb82d19976966e79900a810f6d5b5c1a548e5064f5c3d8a9f2def0179df99d143fde69b0712c091c29e9b25f40cafd57a024658d7774037610342f3800fd51f49e79a5b3decc112f58d03e3d2958758588bc4b1c6a6cda7bc5f5be183e41513c1f230f3cc364304bf82484b7cf19a002e150f98c5e97c6166ea15b86340b8c5ebe5c1a183e5588e66f55905086313f37a409e89b47db31ae97453edf69fed7be08113071f374b26ec6043f2a0e9cf8bad802abad69e617e76243b3cc034b099d8729ee407a53eb03bdc6410a039504b3b12c819b64545d405c6a4f084921935bdff4130ae629d909626b062676e538eafdffb1d6229c0889d3cddd3365dc3d6536f7248c49317cb50c56fb57855541d6feebac816c9928fa662d0ae80a0f39e570bb7d22416f98f371b64247968951a8a246f74b3061743c9af7684bbb966ae0bd78a810493ea4ccd71174871c82bb652b2748e5bccb0ab6388a50f053a048087fd97eb15c1a21b1ee1825e54aa130d66318aaf661bbb24763577eb37d310e219b0a9bba0375eb9c9b4af8c4b99a3699e0d3266733b6e4e9c534490a1341cb1990ca5b1c847bc8126026fea903a1f549d65af8fe02a9163ff8ea281e7226243e2a153b921851de10f7
+SIG: e842b49e533dbc92998dc078e59793a2c2fa636bdfafdb48934c93cf34797102938d137ab7ead1a0f70e94a67d57ef6a02c9ec77d71f70cc57f1533bec87730e
+
+TST: 902
+SK:  c5cc0b95818c4bf38da1d65f021627e9e57d262b02ec6d917a7d46b11c7fe48a
+PK:  457da4ef14519d541edf92cabed9b04d8a2f2afd1510a92f009bb4e8754f1eba
+MSG: d6608bf5ac000ecaf95fc09f9cb7498c518a6e0255586e6337853b1d7d9d7de4dfe1245d59031a317d4e2b6a73c4c3f95b582e72a6420221587bac120fb8ed7348070f2860d85866a09fe756743497f2119bc1bfdf573be35d1091be37f18bcda6741c90d566cc924b72164b749af9a6f40f71d3ea5d8764cdc81714bd7395e5f679973636eff1db1cf0012983f71a2f2b12d45a294e5a389f4cd2483eb39da0df26b736c7af6e41dd35a78e45292c394e34689532888721f863c56db97da1cd10a66a20a670b27fe8ce5568a42b8937790c7be1aa420d203d7a885c1729cd6b8e197189e479d542cbcb9b53656f2b9f539c325c34aa598fd91e7df70f9a74abec467654b1c9a3d14438e7c0836040b793871ecbe9e5f6680ccccd5d4696a87e37e89eab28b6bd679e8fe1627bdc9d373b82f52cd8c49be9bacdc630a32fd12835255a542fb7b12393779d4498aa06a0e7e1a4977939817eb2088af1e19bb0e5aca854c125dc603d835736a03d938051530c9ab1aa3bc779b3bae7450ef57d1b3fc093a37dbe9d1bd6d040f2f8eeba77f7fa88c149f065c7ace33277aa9969c266ea6d85cad62cfaf5508e7032716be684a22856413e0e65e42b6e9e6d865a87363cbb62d5bbb6a3731ddda0fa6ad0293af9893c09a9e743090f2cee2f4437736dd433e2ac7428bdc8c77cb9964355fa4415cc3831d8c7ca5af93d51752e718c6066eca1426a87c29808281a85ac7e0b4044ff6e280e28014b9383d19c9d387d29dc14de433da260784a4944ca76c2fe8a080d0996d9a6c2a3d3a7077280edcee0389aa8e5365d1d9b346eca0947b0ff5265943ccf09939a4b4a8f985f6a5e72723c795da0bc360dce501f673ab6ea8443f129427952453eb72b3a8d0d976c278c5bd1a9853c918e0c240c3c734932953fdb5039fbb04687937c9ff0ab74a16eae212bc6f20e700a77c092d23d2efb580e0c19d65f304129ab8e6cc12e58052257ba09449f30d3d974391afff5633def2f5c4ebd573a9e444bf3a3ddacedf02c05f3cc2e750664a84a1d24c5d28b49670de8a2f2090839483ca38959991a7d3727e21a15e82016c15a09ee71f4f43c0a608b48485c9934a38614794d6291daa39c01c45d3debe579b5823bf3406404b4c80ee6ff342b46b334b0b883b40bfd2f9a53595ab62fd1351ebc88308370497218dfc98ce081407da812a46d6497d7af9ec6d83e1c60eeb712d889dfbed0c805aa11cf817dd8f04396ef871a26112dcb7c0e1d2e68
+SIG: 3ba0af8af127c4584826090ecdaf485ebdf07b82bc499c9a2befca28d49344974addbc8d80a52560e0f3d73ff5cccc72c74b5b47ad2e6de9612d1a00aec92701
+
+TST: 903
+SK:  61fa8677eedaded69b165c8d277c978249663028301df6163e39b06ac2f5625f
+PK:  87339eb57238db2e4e60f3c28a3fd5fb611c65fddc81eed7cf7771df34d92267
+MSG: 02c581dee03f2c603935af5eceecfa677134a3e0aea54fecaf4271fb52951a27b76877ccd49ab486dfc227cf31c9d957cc97306573fc7fe1d31b6c7df3d780f3a05ca6395657a9424342c9c6b703127e038df0792154e30a49476112cb92d0d5a2d22e895752a86edddd912fdc81b1e64a7bb750f099182132ee4823fde845802a944539d412b2a81a15b00071a950504c5b55a71bdb8c5a582639e855e8be241cda1ba6b3b4f64554d17824904cb30cd7efd9ac049e390bb79f53598ef1e8fc27dd7bf599c9028c9ebf92fc3be11df329612a228e0f5684687bf41ff203e97a7686126a39366bdc26d50be025d5187c6ba0666e379be4a80a9e62effcd916d7f98de651e00b97adf5d2d53daa7f8d695a291560755c744482364c4f1fa47ec0b1da161aa388f9597989a97726d3ed2cec82f1a1bbc4ac0be0a00cb4a8db1fb7c14ba05d896348dc0559d2a90beac2041dd77f82d6b12aeb2243ca0f419a57d3ca9c7d25a30ff0e8bb0d945155d1b36ad107b55beaa95b7d5e32003407629f1515f8a7089e2488d0d7544c2f7cc7c7f0985da42840d4368ff4f0fa4fa298e3b7229303aba514ae94e7026535a3f426ffbb4e001cd50ed12f214b3abef96e301635c987b133fc5e6184e7b7572bc3d99a4523cbd5afe593cedf4c9cd02ff2e36237e4ee12ef1a22d16d7cf4c072dced91cdd26ee144cc2bef4950026349e9444784081fe4e0498bc75f72e6818f459bba9049c561316c9f498e7b1a994b0e93055fe73e444cbdf96ac35e9c4e92e6b49e3bc0e99de1716df8eacaeb8d2fd74870044cb39c0e367a1fe32a9bb2974416364e730d5248dfb1df164a8d58caa1005fdc91bac2bc01cc77decc14893ef946fb3c81be0832c72fba372062f8360f4d8e6d5b741cf7032d8d89de2edf4c714a29f75abd8f5ff43ecdd4b7a04d7db0882d16e74473a0fb79db444a78ea44aa2631b8c0d7b0300d55cb6ac485f24c0acc647747c43db3b2a8677baf656fa735a575f1813f3668a2aca9175711b525eb496e9ef9711d75f590c7d9ef99e0f59e8483cbf9f284e3f5a33ee7781e62b8b05551777efe0fbfd19e54b6bbd142944bc2959a82ebd295d23d3443b6ce658c2d579a7637b549520491908e34282ec2716972e6f0353929547ef1537aecc96b2df616148599b09d9b81394a13fe7db86760b1e2a060efd484e8189939ebdf6f21640d89d8e736dee082ad72a0184adedd8df21474c9f526bcfdf7e85658194bb6d942e7f3fe96c23f
+SIG: c04ebd11c3eb09396fe8d68279510a9efee391abee4081f0d275674a304794835aad7f3e345bcf0af8027f97477e79e6792b8f299846ae28cb13bd887537990d
+
+TST: 904
+SK:  7048c6521aefafa4eac6d6c3a702b9525480a66482e4969896757f2cd1ac7d5b
+PK:  ed93113c1643a53aa064caa631ceb6e20f6d6ec2fc6c0711cb8a1fe73139af93
+MSG: 53f74c724db1578a1a296a7ccac904a2504dd9005389b4f8d4ea4b6307298fc6dcce98a6bc07280d20364e405a467e736578965269c81461d61fc6b7e4bad68d2b6dd0005850105f0a67bbc6ee223ec1754af4e3b9afa5062d1c1861048f185b128f1a5c0fb25c3919b4833e29e202bc941a905e63c2c05b1014647bd7ede5be9f996615187a3d3bb2c7dc4c28f7053def9b28b29e2331f16296dce8f1ede484caec996702bd9902e52684c812c87440f69bd141c7e00c6947d1fc7c3bdc0bc5506b6ea462e65f9e743b72c007ddc7a377493777d4eb12620ca6c019c8bfc4c29ec8af382fc3eac841021a74e4674ba3e43e5d7b41e3feeb17da00a7ce455a1cec70b0be6e56f85fc37f64cf0733b7e31241de641a8a8e5b91897bc158fe93d102c01d1f5e166d408165fe3fcb13d5304590ab8ef0dc8d5a8c1d8a93fceb854fc1fa36d0cc480cf8512d80bee69b0650a957daed283cd7638155ed773086e86a8ffb198acc7423b5d1a609a175a56b94c96b731851b93a94977101e255f1ce92e232a05e2e3387fcb4dc13a31bee6ee25507322c73c9883080a74c00f803a998dd530a79126bb144ed5574c4b23180e34e099283b4bb1d28822fce3717046ff32ef9e2cdf967e318ea726a2aeec57806643ad4801d3e0da52a1d77bf043f5ae9f3aea9e4bc4fa795d08401085ca94cfc4ce719dabc7b2390d03d294a65b7af9bc39072285b777b2f133dc11a70c0a9f060e10441f40216acb641637a2eadf1f7b8d262fec1b4d0f0f4faa93f3f732cac382d8ac42e178e2244999d764a9d0e981714686eb4924497e56b50157e9939032c9f88eb657cfde44ad34714af4a51324e5e77d0deea99c9f244d2e09ea425820a746d883a0cf4b705c29df8c037448154dc08a4d4337405fb8765823114370b37ed86086ec5f8bd6c72abf13f518430710f597b06108f65b30a483496e2ed81dab10fee947fe04b5485f2e3074049d22284266651ad10dd086aaa5d452e0d1a61129d1e77c663c26d088962b5545645b7a1a8713d51327a7a359b12daadb85a2cd4b5410d5c20267fa766b8c42a84dc42664588879b3eaefd4cc8dc693f98ac205609e570665b01ea4655e39429a7a7e542efb4f7890dbf4e34c6cff07e4d35bd3eeedf5b46280f4a0da0c2e73c94ea81cfeae7f9bd04fe2d45976500f7dcacb0df2a5dc736a823671db679be66cb33c162fd2c74ae71fbf4d2b05af042b3a977f5b944b9fdb6c34424421bcf4f6223768428fa140fd4
+SIG: 7c45703ed3942e44041c7fa1858aa5f1dc381f493a452dfb52708017898f710e31118e331f00aa64cb738836682b7d177e97955c00319abd79a49e0fcd16fe00
+
+TST: 905
+SK:  3e6373b265b96789007ad2a10c309a567638f25587d77e28b0823a4f179ae4fe
+PK:  a3234e5d13b03472165036404f6de80e702839500f13d9c985a077d45c69ff45
+MSG: b9d068bbcae7722f828b0f8c98a738e36a7df4c997c724ba27531af34a2f106c7513a44a461a9aa4309bc15c4e0d42759193ea1cdea956bb815985f57867145e9e2c7585fc8d61027e47d2d735e2448af3782909404edeaac0fd73f6045dcdb04f0377758f02204aae3a7220311c0f4723582710cc440c36c9587b5c9ebc4063fea8ca3f43195894f79a365087137282302dbf2e7a0d411ab58b7026ccde198869aa734334c05238e275e3c3ab217083495769e2fad374051452d7f5b1db0e785836d4bd5e2978a3e991af0ff716f43889a07f5df299603621c39e2cdee089985d9e6bf7b2fbd02373ae1b5e9b88f5b54a076e676d7790bfc8f57dcc59ef52850ce992a73ba7bc991deb4dde5eb0b21670b1b3d4b64f36cca8e307098568497d8916f6b5d0e9e89f99f86006f39bd3a810769c8f7801773c9638abcf5e2711b19d1167593acbe85e4161428997a2194dc5e7b7640f0d2c1eb205553be9167ffbc22b7c2e7698f3afa10754cb44d4b1d45b837303b1669073415a22606b50f21f8265e139f2305ac0e0127ae056ce8abeaba20e1d269a2b2e899c49547268a0696ae450dc0267f7f63a8edf074c47d3c2db1da36393737304e6dd4faccdb6ab55e5f8520c3dff5f6beac30ba85b86082351e3ded8400aa57f650c0c33036d65b39b7d2fb6112863d59b72558242e8b045addd357de6fd37a8f6611765c9b5ff19cc4db7e117c65a00458908b0245d04f7908fc73b165dff6e4be4b42032d8cfd7d6f7772c1bfe721d4bcfe2fc527998f34fb4418a1fae1e6c3767c4d0780621f923da1f0a0d3d219c036acfd3709dad4cf24d90bc691d700e6a9c80ccfd10bde8e791c0fea82880c07baaaa311eef79240784f628a7d2a09184e016f81008e77429a8658b153e44e79a98ad248f7fda23b590d646d7c1d841f4927d6e8bc73214d10a7f3c29c8f839a8908d20a74e827af467ac5abf0f1d0ed39cddd969dde9eeb4a4b7527ab3e2475a195e24474a4e36b09052e2dad4a5eb4691e263b8c61bbde87772207e011c4c1e14235fb24e4da438875d18530fef902619dd485d77b545abb56b69c755afe758606971ab97dd3ace1c1a34a33794c8156da799e8224d885e1868f9cb466d802c827cc3e1ecd0ae6e0b01f8f791b12208fcc0fed385b796eb2f2908b58d30b3733f1470f2e2ef12ad43feb72d0816de3c13a8b5a523e14cdf5ff3720bf87769cde7495d226bf38238a825f75a09f6bb9afce516a7bc70114370bbc40f17c7bc
+SIG: f51e0f878a5a709647e85fea839fd566e6f35c8a6185d0c9eb13e0d5b9e6e8aa95c333a8f50632a4d6657b518ce4cfde40b8f5a05b2d9f8441fcc9d2d692d509
+
+TST: 906
+SK:  f5e8597eac0ebfa9d385de85a1fbaa35146395b13457b5b14d3670daca6905e7
+PK:  ce93e642c2f15084bc83bafdaa196763de2a3c513b0e44f68ddbde378514c441
+MSG: 273341f219ff5cf381c77b2dd226c58f8f33c4527048cb006affef8cee151e300efef629fed21b70451f729292627d1f3f1b5257359ee5a671cf62ae57324940f2d0b15aac76ff398220c08024e29a8cf36504e12a4e96438f42c3da0c000541bc11f091381b0b72b58a92083f446eca1991996878de35081cc4ab90958c96cf5c99796cba7951ee186f26527aede69db304ce2941ba15cc00ba2f1411f208dad45e87bcf638792de0a68624b667297c27a343db4baf34a0228eaf0d1022009b5d068b2534d920302e71310febf0df1bb02c2ef0ad1ae149deadf8c184373c0f7eb6b25695be82d12c71b6c83267d9a233667e77bc205983f8b8d877d85aead3f60e820ffcb17adddd92a7712bbeb34ee71966dafd9907d193dd9d725a31a613d29e32be72132808926d9437477fee25eda610aeb1dce12ea316c6aec6689e501c551923825a34b42c4f0675b86ab26adeea2e60dae6c6d1cdd0cb3c347b16384039a8e3fd6087381387cb4bc72ddb5f25b374859b02e5bb1ba06d3cc69ec44cec4b985c8476e35032e99abf001a1d44ddc6e2889c3c2c3ecaced609b2b2680e00b1efa7e9d26d62f2b3ab36f921044790abbd49360756dcffccf230f66dbb701aa164dad6069aa2b8b3309f2fe44d5e0b25bd556431f0df4c2ea97ae79ed4a57578d66fc6939c57628a90cac97adfa8702a4a1c8965ba1a90262567286664003003533cc9314caf7d3b982e0a432ff5aa4ed5741983d9b54323ac7e299b2b4956c1a2c191557b27d86be714b5b68fcb1d41f78ca5ddb6b53b3dfc8e7d6b3c3db059af9f2dd765ef04b6d16e6737c727aa11f3df3774a3fc96182e282acc3d233eeabf8c72d3f246ae184505288fef39b36766b10dd1bfbfbfa70f97b3c901726d1e0d0a837d11f0123a34abad1a79aabe80b125b128ee160b511848f7f04c49c8d5c2f2041da7d9599c29b1dac8c68077efac3eca58bbc1637aadce21c774fea42d2bcf4a0b9892307e36fa250acee795ad2bfecfbf60319b81663e2a26571946f75a8d969af16b3b57c3ec3e66158aaf42ccf5e58b937aaef613318606603317e5aa318be70f8da3c0c16be6c29e3ec9fef4e46e8ca241d941d58049a063d90afc953ca32e8a50a6473632588ac41eae97f20ce9b741ed41c9a4aa6551fd823ce0c811a5bb5a171c1ea4238a0246811e469cf498b79621c323eba7985344fe11e67499edf4967491aa749f8f3fe39961d76892c93aac3b19fa4b4fc174d7d4d4d8bd6ee475475008
+SIG: 576543fc21ab0a7c5f63b1cff01bf845df91792e7a9750c5508b51665e7f89f17c6ec3355a0aed87db8c77bdb271fbedc714ffadb78b5e0f978116771ba7cf0b
+
+TST: 907
+SK:  cdadc5b89cb2b6308a006f2f4e955a91aaf3ba70165f2d444ef1ffebbdaaa221
+PK:  0541415ff5467f28ceac839b13a1766e72c99e6545207d9d5d9697411eb6bca7
+MSG: 911727036db309d6e2e3369e4f17d98d99ec070c33283bb1244efd62e76bd70a69b9723bd2b520472b98aa065924366de780900bcd8b77b50f87c3c36187024bbc59ccf4482c7b4aadb56e2e5ecc0003d989d6afc63ec10242e57482fe39215261d5fc95a0185f95e9540c55f74d696048bca7ab112681a5558ea93c3b1f1cd364659e9433ceeebe054ee713c47760d7ad132a7f3f8fe3d5041b811a26b65efb1f340e181a4ec720ea136b3af3d9e5461dd24370336f10e6354c8c17acf9998544cec0873efa687cb132aecf70aebbc567ba03c536499ef96cc8412e7aaad5bf96422be47cb9413645df2c1703192347dcbb123127455971ae157e9fa2dbff88745a96c658b865e41f55aebf98395005ddcbd5983e6ae02c4fbb5e17916796325f76edf5b64afa4ec5a7418afed23a97efade68b6a5b3145f08a5d3db9c298a512fabdac68562b3f55377ff44b00c1c2f3efd18132da71f971a953a9318c57523361a160f9b7e3b51c524e95dd5ef4568ef18a800775e9d26e07131942d2be4ef22c0cbc13df01c68b1bcd3bce9bd51c4ced652adc4007be43b37c67a5c55ed4029e8ad15def8305c968621aed4cd4bfe079a6f48884d85680392ca92ba6e12fea6f4a056f79d67b19b05f90d684be7d45725f7967c6a467af43b86a6b1b9d9eed3a4248971c76a7ac29c292dfba4d75c5f7ba709a39058e96adf6dbd760d3cef4024bf3edc441efbf1147a2c108bd6f9eb439c1c5c4d3a6ea4ec3d92cef38136188bec9e0b6c0518d8b79ba59c5dcba393aedfdffb0b70d779c2b9765ce4452e7e3b08c4402b1a608320840fbe96d1eb8656eb1c20d9551ddf533b9f15e4eb5783756c53ddd3b14d807f838ac9680f89f1adfb78d68ccb06731a90beac5f0d709d5b88c75437a663cb962d37f96b8e8928477b5611228015d337f049e8b62e4dff8d0bb6cda24a5df9083e348bef12585f5f4c4d3bb3c7e78d550194a45251a0879a1624bf9dd35eb655c3939fea8909f6df395bebd02b68a17a897c9aaddd6e2e20461e303f57cdeb00ae0f23e60a94c19c771d8aa60533b93cedc1b76d2290a01bf43b2725f125befa575154e986c9c6205a1596cbaa2d13470c23422f2df7bece4e6ebd752e9389ae60857b52969d2ddefa9c034f1bf35ae3316304e949c8990820e26e6cffae4b388d1505f923706297f8db556537919ebbe3086023f12f4ded3b11acf2a6d973ddd8eb27b07c580bf448caa5a2ea116c5eaf36f7a6b17a85b3955dc8a44a620d8
+SIG: ffede701eb1829ce2361cda2c8bb63338539d8ad2f6677585531e7bf1d3922382679a1ae84ffeb753fc9754e50c01852f955e3fd609ff64bf05bbe7075cdbe00
+
+TST: 908
+SK:  2ddd79e76064c2e6b322afb0c5c685cdbec62821cdfc0cb14db7d01ba3bf21a5
+PK:  f55b4ab64a2582212b96ccac0640e271944a34a286d035833045810e341824bb
+MSG: a56674a1e1f09795251abe54ab43c298208fefc9bb9176fdb23e1e9f60f032647915567ebdcc2b869edb7055f4aba67ecfe7fa19eda45c06047c7a51848be9973251f85ff76f1c59e3654382858c9be123db8a9490c6c9b309b82d1e2ca6f4a07d00120283c6c295644995a96628612b8d6791573518e2556a688a09f149bc846a68bd0ef79279035710031ef0a8fed1dd0bf026125dc6648f86f64309942e18f23b12d1dc68c6f2770ca8b5485b369b0c92007a9461c139fcbb41175f316d4467060ab43d1222f5802404bf63c2df7e004bdc400ca80fe0d2cb68a210fbc3fc0b903209d5476e7a56baefb8fad7f328b72f327113e139414ba6f34e99c2eccde044e7a3ac70c580cd26c7450192ca4c823c7ac5eae876c0d1c8c768c1cb0b7ea41fc9b7d29437bbadab18e0f5ed1defe0cf6c0ebaa6b6d777f4dad9abddbfc0fd6ab5eeea803cfa01c0bd46f65fefa46901abbe0d89104e3bc4aee1f0599c69b67ba545ab9b54f5dee340ac69d88299e86822acddddce601122012f99299774aaf17c964edecb95e1277d462de64e9115a61ad98aa3d22e3ba6f8f1cd69b6b52b83382823f30e966bdad1ff5fc198ae32e9b68055d4392bc7c3df1015f128aee1e4fa3d4999e329f22f0ff6aa778bae0294a1df7436cb16a2bfcd74b463abe7cb4bac5362c89c9d1a378a2cb885cc3b26ab4be881ef1afc14430e10d26539ca358c3676286ad81ce1c9e78592af66f182bb1f7f862fe755bffb5be5c5f2b731c132e2388a76a1a7b1cddf05aed2ac9ec408475271942ccadd32e49d8791edf8b8de117551ce264a60b84105eae87e66f6a401d1322bb21a98e8acd277493254e504004f72c76e7903d2fa38fab717e94ce627947c4ea326bd2575c37310f3b4d843b90fa77d32d9952194150b62f850187a4fdf38466dfa0656c0a2e0b3f07492ac8e37e5d0df95cc89df3085a269291dc2512210d3fe44248d7ab996be099af64c22756666f8dea56c00b90677d1182500dd274fd0769253826d677ab16a557b08b3c52265498d85c4cb2b600ee0481b7c1c476a9daa8b88c71fc21b6f89bfdfece58da9e8d565652e4395bdf4c811b4f4f22d2b9613261f88c604c2974d3e977d140d046e1b6625b7071640d352cb7e7e65d46c613447be8dc5a200aa9acab46afccfebb6b1c31973246c34faaf8d26ea5e83be15718f8fdb0cfc444e2eb60f3659b020161c228e6b9240b7ac394cab812de10515766f22473ecca535594ce528a57cf5dab2eb32ab84
+SIG: a4c396e19dd42e039184cd251188ffa245f0367c69c02d12474e5ca9e5c768a7ee3a3d47eb22d1ac9e04b704a74f416947f3f49a3242594e7b6390e82b60d505
+
+TST: 909
+SK:  3abbdb0ba11aa1063bd26b02c116037862285babd215d240bc9c0926f4ecea81
+PK:  b8fc59438f8ce9e3785a473b22c8892c51eac2568c681dcc77b6f0e0799c4e33
+MSG: dccd55f922cd274f6975000adc8d98630c6d752c1202a9dd121048b93945af2b1110967788f99ec028e3d3b4cf82fb07173ea4401e3bb4b07b7b0b24b059a766339532d9df3e31b72c958c119d8dfa15a507af6c5f7e78fe270fa81b9df0f2e4af24bd99fbeb14e0033084d7fbf84ddedfd5ce56751d15908475df8af013d091173c1386b9139426cc6081ea165b8ce48194b8e18a9b91a4631344fe29c8e72818b71fa15c9292d13fdf5f9d18e29bd0291b8138de738fd3a36c35239022368b456f1facba90a0d80d6e311c5f6c6f04677e92373a5fc4738894dbed206c30da341b3b196c947858a6d2adc68aac3f20cfdbe0497961dae33470266d17ec719a59f0586f82f99f1c90ed7005a207219a55edc760f4eb8f2402647f6f77971ff7b634357b6b29bbd7ea05e2e25854e99c620f4b8b64739022ff0b338afef35fb6f41a53629a518eb93d66020fb353aef8dd071e09c916d4704acdf776b38ca9c59f211ff88c430a57e8f1713923b3f30ca86970a14a52db4bcbe60df4bc3cfdf254bf10f8afae87bd61b358f43cc296c0412964c4e00f71213397468517cb01379cb729c7b9e35bd50bdd98c3d3b76297a138b57ceb6c77742df0881d07668c08a630a44e6ed7eb206d6a56440710438a5111424b61aaeece40e900f5e3c457e9d6e31a79ec5b4b42b68e66e199309287cad65336fc7fe43f43cd8c773d3c6580d7217e2cabecd3eabc485c4acf47718c39b02c7858ff347cec7535eddcd4fc815df814569a88ae70f2733a6539f208c79cf4e7c4f9ea241a92e9515171361418a4c2e53c076aaabc47e4c971bd04b100c26282308857e06e7e5fbc4342564fb3b1ea4a17a925e91ee69122321d392b246965b86b54fd5c83fa5c474163f98a9f447d88cb59fe2cdf9f5412fcbeb3effac8976791c6a47b669a2fc55abe8e09e74157efcd1ca78fc10fa687010c6826c6e896ef5cd71d0fe4d1bd07c10dac3b03485edd2569a7eecfbc4e5d2ee2379859e265267bedaad69d93b7c1bd18f27ea42483c7e4100ee05b283039bfb9891d37c467ed83b88c794eab6bab9dc677892650e2d896fbfec1b1cdb721be30b0b8e5358709e165cbe3a182c93bc0a0cea2f8cf3a6257adf764534041202241a5279b668e40125fc094585a3c588aba82b67cd91d483e54300428426863a42364049d7c45a169385aa89bf377f0d32b07809b5871395ec053a257d93e48bbf407eb6091401e256546e31f9fcd24d2c5b333cf65785002f08d548db26ad1f3
+SIG: 981f20055a457525aee5616264e6af42e8b387cb08f8b4a73f9be0b366f1035bb30a1c874894cbece0a846d849b7ecc556585d0d3d395645807ff2a3ca5a590c
+
+TST: 910
+SK:  8a44d6afc6c8eee1bc7d5f69e495b0b18ca7aee007dea7cf0d1714d785a9f4ed
+PK:  d4f366b3377fa39b36f9ae14da404e2240490dbd8d796b1ab872dfcb83a59540
+MSG: de80326966536ce94996af2de7a07605cc4fcb9e75ee0a67a1e20932111de9b356d5beeae86cc5f564c10d66e3de95a5b99e844928ea8e77586cf3c10ad3633ddeeb1d9dcf3f94b70bf1ef63d238df204d705c0b174f83282545f5e4075f8d69a48179c29eabf5c1742ef39e1ad963bebbb66fce9491a984651215c2e750e6ee8365766440a84419e52dcf671f1c52eaa2b9902bcca4b37cffdbac8e7e7e6b0a5c8748efbf452df6163f4ca07b61f9a05ec20a2bd633389e670bb5454acd6f3a06335b5da9ec326264e962c7d9d06ce7e9ff04a0a5bbdfaa4c410866a572011651439f2dbce5dee667924ac4934d205496bd1d4df08bd0cb3fd2de73a2ef342ff0091e10e15b3b760a575df93cf1c97c01c5ab11c094bf34878206718f6b285aa5cc5127bd7f988b84a90495306fd9e99d8955e668d1a3ff10f65b7c479fac24119a3c10122d4d18a805b247df168c0a5100169b5572d17012d751a42e83376115e11561c160c15efad76d21f7abb430366475238631f84c88f838b0ac404c913d2fa12450238485c302fc201f44151c19bcbdc1190c12d1540831fb19581cb93172b0d2ff5c65f31caff20f813881f84e5ef9d5c165e096d254cadf895249aab8d4496c940a40f907bd40935a94f5e55b6dd051154100fe331770eff2bad6545619b8a33ef6462a50c0b2c4ed2fba4e4e383ebf2932e6192766a4aad1d6e2b692d9f2bdc23393e8aacfba323b534f84edf2dced7c94d51687daa27198a9144b312b716fe17014a7bed0c14a2438733d555c6564c8c1a3d997ebae7b3de8877af53c1d1a5029158a80aa0c87489fef270cdffe10d34b15c1a9693ae0390243e314cfac06ef6eefebccf43d42eac24ce9879429d2fc7253b3ed175825bc4da0762b4933a98afdb94b06f4fcd2ad3611aa999d7c1c8d852d01dd9e52648455a04eb2330a76fd942c531e514b5ec0728a89d34ca590ea99c88faa20dfb7bbf65654aa6c212beb8ad6bf7c777391cd49c39cf8ab51b95b419e3dfc8d94a93a1ef0223c6de90bf96218d8045bd4952a0d8372a5578c6aafa74ba662e3188e6a6e567e4d2fe8227d0743982a41ebfa0d310fe79fed27041790efd5afac2243e1d150b145015d9deab0eded6394ac36fc5fb201f5204fbd422a3604233015bb0a48a920e2e5e0d4deed672025f23cfba93889597e504c8887add46cfef4024afb8a26eeb7dcddb2397b44a1796367340042137028c3307626816c2931e61ebb6b69edcbcb612c9b181a285301ce46f82f
+SIG: e0727eb72e84d2b82cdbd0a6bd2f49496316aae8351e4902acd5e3cc57346e7ebafdd92a90ded76fd0c6690d68bb2fedd613e44fa222be0126da520acc2c4105
+
+TST: 911
+SK:  8a972dd0f1190c2b9d548f4ba58264bb04826775502a8d5c2b209ee88dcea5fb
+PK:  6d80375f3cf1aab283551df445d17e7d3baf9bcbecbbb267052e02fdb69144d3
+MSG: 30b28948939aa263437e45c5c0254fb20e617ed0f3fa7dace5a0a8e0fe3c1fc4adb2809b61c5e8d92cd2f3de93b173be707bada94240c6262c160e8c782165beef99d0be8ecdad6316dcd734bbb90a66cbd5b1cb4fd8f2226cea948e4df76bbe251d478f5c3fe0d6de4be54f67f502b2804f628b79a550fb1ac483ad2ba16637c4bc9da67fb4f98659c4c4394d16b6d14b3e0b0c1e625d710dcc1c11df5d34147b1ec5a417b9e21f908cfc523d43e3f181c7209cc56bdb5a21628695ed320f8d4c07fd6d84aa03426f21644aaefeeec311c74e9499936047350a9bf5b703962e77ce551336835fc32ccbd2c90ae52e24d47d8dcb987abd121d3f746b5de230f26469603fb0c4a8f6cd7973d7da882ed1d6e4d9c5a46ec2c21940ad3389a186014ee97278e5350988b15ecd9ea7456b3cb55e4d3093f13a875b50d6516378ecaf58d752c6374ed15638409311fcd379d122c8d8c59b86f4e8dc46adb730a933846e0bd248d3608252d970b504c813c6dea9fc88a3de641956dca291204d390b6b39981f8c0a6bcfc31ca0744420662a9b35eb3fc211f810a3e8062500b1e49bdf857665ff32a9ba76194bbb77fb9c15412964244b9865f73ded9f25b49b425aa253d807d9818292763a513ec80747344fba0acfe593cc26b1330bb9ade66c4e88cf1baed6d6e7b750e6c7239d7bcbfa3fbe45405a63b96d5034cc0c07ffc3b50858081d1955e2d2fe5be5fda7a8996943768b055170b7fd52f0a32097fe1b7a94f1bf879a0cbabe10ac9a7cc1f9f55068c48e3ccc065136431018d38d20109dc95d99cc2bbe7c627ab1a8aa5f431613b790c2e6526cf04fdc9e55f51c055f3c2045a675e3a1e54ba409f7aefa7e4aa07a2bbd5e4ab16321a9f099694391fda68a74581e2f1f11dd9a6d524b1b83260db57b72ef29c28c8db5c37fd185b7c2d8455090653af332dbc82bfb0db5dccabfb6b28caa350525cb54cc84e553e1cf3954b612393e7993ff7e8bf5ece3f145094dd7a27cb47f227476f289235251f772b3ba776bb773af0cc5f786a3fb9e931a530cfbd891cb5a5dfe25169ef933cc82c9080f323961a120158e4bbd71134ef1f90108b815c289d4e9a9589ec64c05fbb42a21b23d16e2a64678aecfab65cd9a806c598103d41f7009776317831feddd1c9002d4a92204f97ba9490c61469803072102524b9df519005f98af54d60ca5ba60b55b096a4ac2b16eb9cc81973c3135d3fb6873dd9653800a22bb5d0d6117ca5d916553be39c9a3b511eb3db730
+SIG: bd45b3c045850ebef7b80dd1deab48037b1346c71deaf1e58f2a7b162674f94d1ef3d4239037330bd6335fe4f0149250901f00a8e46be5fa0aaec69de06d7304
+
+TST: 912
+SK:  12380c45a79ade0f483c881aaa3730438b083590f404dc9e601f7615f375a628
+PK:  d66fc59ae917f76d24ce8ab8ee03fbcb715d5eea4b08392b591e648591c73c89
+MSG: 684523c2e7fa8b4bd7548c4bacaa8678a330dbbb960632940166b2cc9afc1535c80c112c8dc4ada7629233fe909055237d513e292af15ad7692f115aa092da657532f51899c3f7f5d9d407ed5c163eb3950480a4122a0992981f077bc867f906075407ba9849c4ea0473ce540a796744efa3860378e1b89343e583d0807e5a67c4d5bd7ce64129fe902b8cfabd2c21fa3d2a10e9bf9ea5e5473ae250c9160509972678f9a740e6cadb3b52f502fa616cffae1def893d54e41e54d326464c9f435c63505fb15e3eeaf5021c65dcd010f840aab317c8605dfb1a0c8a3d5549861b69af2c93d86c981df3a51c5bf5785c2f852610e44fa4ff1c7161152e5618384744fe83babf0bcb7561789a023125f6242a183cac9549c932733a868aa182656e2ba0a8c0be106996a85cebf1bdad123b982b4e055510879482021daea9d8f26c588e6cd10126cb3196880356bee8f298bca306ec5699c7576b765087c253a60214010c6ed70d871cfc8738018a0edb57f106b4218d855eab2c91f39f858b3f25905631a0eee29856fd34f7b8c9ba51c1c4c6a735d6c7a13d220d7a566c3f506c72bc7417ab37f0d6d796ffc71df9dc7c6e137da56b7a3e10cf0b1abb3ffb70bc66293b5d75b405ed8bec0d6fcd06925c381168ac188d0b8a1af0839f5bde843b6991e5a5d6cd66fe6b0fde867c086ed43876919a1b7233d8d7e1d2742f61c77d8e5991689c8328676655b76a3750560e75d1c7e85e3c0085059331094bba5710032cf679a525c78b31700e6d91f75294c422489297e1735943e417fcd35580582fdd0239b51146530cc09d83b28f0a1d642220dfb99bad62f39541035081d65d778ddf3239ba0e6fa9914b17b397a534cb8fd3b4ff42a8d8c8ee66153fbb1ff0fa54f7bd03278516e6341af80fcd1fcee70c359d205368ac490d75a354512da46ba7634c15b284b24477808f17633360a4b49fb3bcaa841841cf92417eb24ce482d5a24bfd2dac372231da539a05420002ff7a20c476097da06f59f03314e6059fad88c50c3baac03cefa7cd8211d2461b1660ea6bcf476838c91a10074eb4b40e6e974a945a67f6ee6904231ef04188f1ead5baf35694efe301edc7e866da23b5a6c58f01b2a52cf3ab805edc5c1368626b95b94eb4645b693ec880f2b8117a693afbdcd2482431890f410bc580530fef375879c2e46049ca891a2c3ecd6043ae80d8af346634674c6dfe905997de5d05d62009eeed277502fb5a5a3155eeeeb67348b60d89a34a7812639f541ffe
+SIG: 02b25174a3dd5219ed48b2c94ca212b63a6a3a2597703c07b7f0c965c3c6ac2eb450efe38716a2a28b3f89846b06ebdca4bd09aa581f24e84d80fc10ac1a000a
+
+TST: 913
+SK:  d1b3430d4e63aabfa9ef96bcbaf1fa6a9eb5219dd44df3b1a61563dffe1ccb28
+PK:  c28a05195245290ecd38535585ce51f3c235c5d650c8c57c2f79bb0ac0e80834
+MSG: 076c0c8762e4bc003c360a12a19598050551d16b4b8da0fb9c4afcc81adbe61995f25cbc28dca420bfa9461054d3ee00ad78183e7f26df6898af9a4d225fcab67c042e9a13525d1f75ff0e3d8da80896b728f3e2db65944ae0717d775990b59e5b70434bd4b3ee452f10ac0610570b38220832968f544d3e4d119b1d4b5015c6cdf4cf220b56b5c0ccd8e398d5e4a58da3b0e2b270a5d39b82abb7f9d27a419018550b6200ae51c84882f086ae7ea5351671b6dd960923ad6befc13409879a8df619bdf6c88a6fe1ecc0f0f3aa219fb61902be48a53df2bc66c56f1c1d17f7e6167d255165f174baa9caf53c73cbbb7cc2c7c087f43abe2aed5a21fe4290b8d67960a8a9cbc2a57abe22654dc184cff9168bb697270375fe88d5c49cf95b06cf9d0dac81fbd9c0d7b82d05ed2c3fd49ccc29404441712545f9a991e4f0ddb62190838296f967299a38607226d8a681f0a8f3c4384fd18b30257c463c0abd0f4f6f1225a51b762d6d0ac7d59cd2efd698b8d13e23d70409f6b07d695c1671cd6f59443b1db0ab35b9dc0640e4c6d1ac50475d28ef94f81790e2e5b2545514b2a49c5c2153459be540890f53bc18e4a16dcb5dcf50f37a95c606fdf48598e52af3179a2048615d93d97e0599b7088c1174bb9f15e37018f99acbce5b1302f8d8ce2ab85437feeb0caa7784dc83c9e7c36fe059906b030a86a3ded0ab9d8b73529d475e661a0808d6d3f0907f8528873f08d5748be1d69712e85262d77bdf13bfd18a5cde6f71462673ab29b1617315a9a6e936a8e81a8e43bd0f6644a5c69eaaac89bdaa99cca803833705e5afa69b3bd1d0252b854650f2199791e6aca7c75a861283216233a2633a6aeff9d301ee5cb4dd72c08a45cdae8f5458c095b22e759c43b49b98e9f4cb33d5dea879449eae73cb874c73594325ebf68c1ed4064b6f61ab2f014a2f19f32e12b33c5eaa8a29204d5eba58dc075072fe399be7d1ab1808208fb408123bdc0b4ab3130f9f706dc3eb194b605e73a32f125ae491285ce6039fb623c38b81d5aba0f5599f6c86e872486b4e9649daffe3a3d06cb073dd3bc6f4e10a18700e45722d78a6b0972dc94d5c7a7b6641757b796075719d7b8ec36a1e796fb5f8fe6f1b79a0859cb4d67cec05ed914cfa32c1ddfe218ef963436c3a1148ac2cf909df7359890657463a4ea25fed59618a0681a1217e22d64ef9d9b4559d0a0f6b3ce8d847930b232301caf44cdf7a3f18a2ac130b92cfd9c03360557b5f7c4775462a1071f70344c718374b
+SIG: 4cb6ff5dd706b1ae816cdbaf9e9e1edc80a66284f94652d50ec14e283b2adc592fd084337144ffa712dc34ce8e610668a65e969f05ceb54786304d0d58d31a08
+
+TST: 914
+SK:  033e003d7aab7bc7fc8ac204c733799ae553c3fec53f10dbf795b5f4b87f1c95
+PK:  682f46f5c056dd45ba0b5a782031f9596a73aa292ca2326beda74a52fc32b716
+MSG: 596aa2c40b3318878938ebc138db274bb38a5201eb7caf875e6c645791dae012bdefd485e6bd9d8499c42a2ae86cf32b18002e76bb582cca0dec4815ded8a1211f8fc8857fce1d57f6151d88787b978fab56bf926b1533e19499e8bb99158cdd6e980f6ba543ae831f9dd134b0fe6d5c24887dc7a8d4781dd9b7fc5dc9464b045cbf9d1ef5036b5bf28b549ac7aa8fafb91adc9feca7a14554d110e310c749e48533f359c70f05fb7aedef136636b8ef7223886539864ee52d34118b4b8b74e08fe6b65896e4b19b6d7c3f2528265585481710d2d74948eb4b1708a50fa74021bda4b361bc68d2a5d202109f8d28d8aa67d78c1136cd2e903c8dfa175af7bd963b73dae495873ccdae62bfef885636dd83550ff9c05c37ba3389d1543685d89483b0c104e7efbb7702c5a0398ac720484c50936835ee9df253f0ef8cbef3e07de969511ccbf87557493a0b972ef0e8e629cf3822db21286ed727661bd31786fca1421106dacdee1caaf49454e854794f704d22a95a4c8e6b1c2feea57e56238c2096f1cc578647fea544d6764482bdf5148879a25f943db16f29021b9ecfe3e090b425c81c7009842e1c7a02d91ca60c1201c3bdae9c5373af03f2f4dbef40de8d9b21fed68dee510de0427234caa1c20a3ae549954834c93373d913b8750f23a03780d7a9454ed6fe51fd2d276b9d4aa32de05e03816e64e9466f4f0e224651428d342cbcc697170a47ef996bdacbce91117ca1f8455b25b2b08443e9914e3d90c489eeaa7731ddea2123d55d67b16683fb7c8236aaa5a1b0fcaf8d170011dbe9aa2857be612cbb85ef69e56831b4dacfbc7a59b465a66dc7412ddb3d6af4ebfd705864e7d4fb99a6ccb48b118368feab02a340c432768de0e067871e9ea808d6d993815829e71f6c042b664995098fee94d543df15e5b16957031bd238bcadbbdcc576affb640303d69c5b250b3a539afd127f7ee2609e52e5154fbdff3e45f9c44066656d561e0f64dff2805df88e30a380530822413a7ab76a1b9a865378d24763069a814002a9a9d03795ca8d2b5bd1090393e9e4b1ff7d7f0eb84e712a018f68c9e384f0a0aef3967879284f409e30d2365086e66952278ca9b6f90e8f69a48d9b28bb4c4ed632abca3af4144da7422bf51992f734731453c7a33e15e59f5308129d6a774a94586f723311179176c0948fff4e30c1b959812cac977cc74347b007940f2fb962a90d66066a6de8801984dee4a532d4b0acd6dcaf06727bab70b3866232234c9100bfdc669f77ca49
+SIG: edb4e020d676fac6a845534880bf6136374a8b7f2c5385bb9ee225381f494efb74a55b413ae0ea70add61bfdfb87fb42d5bc0c5359dddd573d538ae93a6b3609
+
+TST: 915
+SK:  ee55fcf70a275c726bd4856683b347decfd422f1826c07a932cb85be9fa4ef3c
+PK:  dfcffb5e1553789d56a9f3914bce500d07c5ac311f927854b2cf1e5833c03237
+MSG: b8c845cf7c5485f0622d1ddc17f7a0f6f0fd7074fe194b0e0cd42650cfc817f57f095f8cdfad1ebe0dfbc1bd7617ab4f204e9d55d81a7c8a433940ec6f17c8a8e3d56c1afb0af374bd32d54ef7132d26b89c470c2ab5be16fabb4c75193d6da59ba2fd157e9ea4e0c5c08a5202f5edc6a61701f08bb344ca6455d75d145adb244c534c8cfc623f4d4b6767594b39a7690beeec4df9746a57ffee051454c4278ea43c810ff13cd769615f9d05d4fe4a51583e80c015dcfed9af05f93d054d34ffd939bdd8f0518fa3030a964dc9d80df00f1635824072cdf29bc80259209d50f56fca9fbd6ae1514a671989cea4f6846bc19179097cca40c624d7edbf91fb5b2539ebbd502d3646711430bae423fd115848093318b7d087ef1e3b894bc3b9ea27af853fca8595d36fb7299969162f2ed6a2b55075b2c630802857176dec4cb5acf2b13a35a9949b912bb57d81eb0c8a8adf3cf64cb571bf5f3d71f987d64d74e919a00336e57d35ee4eecfc657000dd5b12995ee1b116591ce58e56de25b29c94829d1d68521b9558e4725ec77039069c0cd17b2a003359e9e1e112c7590176cebce7f001f1d136e818f4818cfd94745afaab56f1a406f97dd9e61b735266d682ad7df26dd70cde0b57fea7db2df832fa88a35f539794884ddc41218403016cb6d5221f3feb5d3aee4a9840a913072d29f8d1a9367bb0bbf545f7dae7c00a0d0c0342231ae462bb742e1498ee584ae6c83f2f1f2d0452bead982268cd3cfde78ff422e226bf7b2af1137757797fb02e5275c34809d54ca9ee2a65275e6e5cffdd20ad1fa1ee0bd8b21e04ce829e02cdb63c48bfcdd86d3a08c59789c9d78e36181defeb7227107275ed6b5ccb127cd72b374e17f5ee0b5e47b4b3e14a8ec6d86bb7507187f28db32b3f3fa1ca13446fe5253ee783645e794272799a863b4fca99e443cbaa05de3c50edf3d5cd7c10529c6c09a0c1453406ac7ecafa9b3a1f369d68f3c618f58efc359df2f3fcd2478b55a41a11f2487e7f70ec293b3eccc700ef444a33d1eae9849c5b76d29afd5a23861aef4f2a7ba3f666301fdeb5d3d8f0dc9ee2e014b24c7465dee3c0964edd49ed49edabb5ca7afb99574d001e5812a085231f241b6b08c73e80fb44bb2adf554f14fd6dce94a6f63623d9c1deb41ad101651a6b67ae5234daae81979fbd823389649a3b0a06c68b80468a991d3007748751fa69281db1b94d6c160a1cab50943cdbb8dea5750906b3c6595bb580dedbfae57464cc7a651d4c51dbb5fa980597d17669
+SIG: 9d8cb2eaf3ff3e0c2bc672e1d255c5b8e80731bff6f6aba517e13354e851080f4a8bb8121b2624244c9ee95c8a092f103703fbe66f9cba100d2e91ed774ac907
+
+TST: 916
+SK:  49c298a2db3d2589c9fe16a4e571e5aa23cbaa777b86470290a3eda7a5d3e96b
+PK:  dac523d6374c8ff15fc4ddc713715ac35cf5547fc1b1b2646b63fb41a7f21621
+MSG: 3582eeb0d371df385de88baad380cb0cdb60eab2baebb3c79837753d08e1cb78c0bd76dd1104454956d571ceb7e6b571a5236835d784b50ff66057b13595e7d0c8f25d08ae8b54b6123ba08151ac7db0c56a980f7f0bb39a54b437f54851979986ab1367835e5c4f3a3b3d760d3827e76c568ae7aebbb612e775bddeccd334ac6bcd3253abc29d4b7c3f10362666f6ae75080370a36cba55db3a91cb5789e4d6f9efea4df1dd7730a5e27960d53b5121948cce5af653fff1d5b4e5b0a88c718c49b31c793d88c1cc45ab8da29d05e906cd0594b5f6638c8ec3f1760ba423b5ab1d08a58770afb0f139abd349c1bf160d8902239ce24f19b4e1be095f7ed165f3931e3cbcc307e9fc5c658031228e55cbbeec0d0bcf8f695154a9eed1bef35228789bfc0d238b8372d318328c1339fea08814db8621abca3aeb82098b5aa87bb98f5e40522a0888532c1748453db2d2b3943e4abb312de319aec48cc1c94775972953fb6496b8168937623510cd48c8b247956d3168486c176ae7a4cb384eacfdabfadd9fba30a23b811bd779f3cba54338c28bb3382238ed3b8dd21beab2f5cade28c5e09b31a454808a5348122e3ae3812296f7869c3865c3c9d8fe18bd812f2e60e914975cfe1bef8dbb8097006f0d7cf3fc15eb95c27854b14312b88d528015af69fb7505b8f32703f64eb1c958f046dd251242f8bea7467fc7291d095e9696e11aa45abe7924e856351535aa0773d3d9e61cc9a2d89b5b0774d7645ee1af7eb6fcd440bc69d43edeaaf935fd2a5295ac19a97d70af9298830f81c0a509f242f473372478fa5879fb2cb8511080fc2ecd8259b8c3ce9e8b640761dc7927c32e7f5bae97a8b8ac935662e5f45d14cad6d34affc9a19414c4566f45f977396710894c5399ed4480f18e90957faa76ccb512a2d07573058a95b42fe1810249d1c85ec431a049d1aecb0f118379bdc3f1ee490bc8a054c32c3dac7659966cdb66f995ac403d5e79eb6b25b3f3f65a6ceec220d66c05f8a8a98b80799ba4f2c6dbbb4dfb5862c9a46bca013ebdfaba7494a30ce14606afc0b0f993143fedee7896d9a6bb81499166ed02e94186aaf32187aeb6e282501bca43b57b7efa0939c934bc8fbbd26c44b618335a35c692ff996a5b95d327df9b2a6621b3b0f190db1f36d911d1a663a4ebf9a2854bb4f4061095b69812c82c2ffe3f92e9b44d2ea63169881cae8453d6eef7cf69c25a28b3f8ddc70148ef26721a3c1f2e62d9d10cea42fca3facd74673a4e7f33507364aa286c0f38d7
+SIG: 2a439c73c98117fb2952e2b161f7f3b99e7d39bc697f794075db7b634d29f1ff5724f677f8312ad515b097cca9dfc30e79ee8a7c9dd728bdd45df859c7bde30a
+
+TST: 917
+SK:  823f0c29fbfdd3d1828f3055e9ec01ffd1b5a375118ddd7e4e0c43719f573ff7
+PK:  73125fc83abb8b7c658559fc127393231d03ca5846e0c88118d13d55ca44789d
+MSG: 802c39ce7f2a50bd81622add0df4e0fe03ec3d2d305a45a6165271ed79add243b9a00e52183192feb24c4fdbd22c807ae100efcf165b9c996194e00fa817765ea94a03070e486686b445fcb263ccfe1f5862f3b84b10f390080bfcae447ae0069742b8618fa9575f7e637ad54e834caf0394d745032ce1e255c0273250f1504b37a0add94aa245c7de52c80e05d6e0a96a14410543826a49e9b945626d4e89f55027163d4bd6d0e9bd1a2477f67d3d5668a42e94d8b61193d821e0d1b230fcadc53613b75b02cfb8158456077ebdf5a5f00c3b5b186370cafec4a21c69dce1f01efef23c37ab90f858238aefbe212b556d2f073406559f1a51d84efffdce07b00d01bbf33771cc12c960ac89365a9c82c52343f7603381b89023c1a6e702a5b1e4bd191ea6970b5ea451ea05b59bf83e55f29a1f803212bb2e58f0616333d9114708529e8b6c6081deeb7c299a5a2a53ccd24ed58ffbfe503d80614adb05ca11cf29ded00904ea1239f82ba40c793ebc339775f8b0fe3901f5482e310c793c6e2cf01dc157727af238f49c9862804b047551fd886f4a4899e22a6a65701117a3858055bbfe966e370e733e17efada2859fd8ffa9e01fce5606a255367678f4bd4e21e5da0fef30757f34e389f76b7d57c4e410a002e900e48fb218c8f2778f148fee56965f5b473e25256c23a7af198342cf3ef02b84df2cd5800a461c1b07bda2f42628a68ad29dbb82a470967d7302c993b234136e5bf255e6248b102c2bffb20172371f1ca3e10b0810e8649503546d9a731cf19b083357d4cfecc89bedb53506fe199b670391a620069a3081f253b4d790880aa23b53e97c75dc0c360540e5b0a3efb1accffd137414ff8423d54646fc56ba5f53bd84c7267c2f7ee3e37607544154365f9f85081dd7d2ee75d302275c799ef2427ca6496355dcda1d44e0d977bf68db3006500ae3f400d6a8c7cf47057d4fc87eeecb02116b73eed6ce1fccef6e8fb8aea363b2f6f5322a5f0753f45899537646d58651be9037bf91423c2986f5cc2bcbce4faec903498b40fc2deab6603d6eea585d2720d21bb2722bc05b35aed2bcc0e804fe9d239fafda7ddafe1d7860abb0fb28f4bf2b1fbb62a786e455be024b193b7830be0d558f02c9f3ae31dc107ee9421dc5f0b0f89402b71a4581401536bc47308506d96939a206362744e27dde944f4096a12b5f63dab64d041484d3fd91a62c2f0ef9ae787422eb27fed0802e25f9bc775c4915a837fe3eb7b9d5843e4d8210c6b494b61281637a6be32052
+SIG: fa747b6fe3381ad6bc82a95643c1f4a20b76ba73bff00e635d64202d8b0df03dbc56b0138b3a6d4198ffaf58ccd3d388ed25ebcf770443e41e9d2147950a300b
+
+TST: 918
+SK:  65676633374214c4ac4b7bcea9f1cc84b1b7e79411e310525ace385f4566c1d5
+PK:  0e6ec5801d8bd6b1eb421421a1408f134cf712338e0ffc24cdccdc4f7fa31dbe
+MSG: 9d622c206787694093c6f29f93619f21bb64c039416d20dc708a084a9d2e490cf5658e13d62cb0d21eab00e42d851bc6ec75daf405d2373246eea415e866291babf76497680aaf04425a42552b107d58cd18561c8c9483f740744cbfa6054c1b126f5a76659ac19dddad4ab5a09155d8c050b5354e06a4dd3ee3a6f9c91e8b4c7af2749664e7abe97061589e153c58e27cf299a25f2b530c060731ec0f4366bd1debeb4d4e912e76e508534d433ec48f96b62e150de93963a1b3e6c8091b495a96518ce3d3b9a8dbdc2a13fdd077f2231de8d76f56d9ab1c2f9efabce4638364f8fb2a2c683ca819b703ab453b11d37a69fa4bcb8023980834f7b902ad1819fc029212fdea0abf11dec88c55d68ef87a26dbb15dc3d3dfbcdddd5ed71be86f32c76ee2221d9243683df9516564b26bab5c845d4dfe0adcc7cb9fe1ee2c051af5908ce0cc3a90904dbc0d3680ed4992f46ce25c2ee851c414f0187d893e5c3b0189a7bb6893d683f5e3394cc046299a16a1c1b5695933a89bb13030855b81b3c74685f719de0160575a0ff0a91fd94347b8bcbe125d1d3f9ce772a8126e00f563b3189656d5522c187ab831a7ade7ac06fdcac7f1d45882e51f9bf5b44a2daba4a53dbb31970b4a0f1272fe14087e0c3c7e4542312fe74d767f21e7ea487d5284284f46f20f32c5b16e1e0ac8d796ab2f80b344e7a8d84d5de823a50897752dc549a48fc10bcd436a7a93e97cd05d7830138f323879680c343c16467d264d749bf45e40f39fbc3a00c43b00693b0156768ff2e3f8ad9eb6405022f5cada6694e8a33cdc59c6673c44117244eb03fd7fd675930c294edd2940f5f180953d910c55485b2057ae0c9302f4a8e831a5530e3cbbf6f472224083a952a8390ab00dc0f69dfd880eea2d739d218d6a66f237f10d4401aa758ff8120c0ae2766127849024f5a4cc574a5b02b935966812cd1fb6d79d0c4f59ff80f035a0b109cccb22fb08535b874149edf2a0970c14888427d07d1eafa684a6d3454e49b225184c6b993ec8ddb8b5a35ee45f87f69266d49096a317d86ade27f4529fe72364d0b958007299d9de87d6ff9fb04d573aea46bac8eb764752eb465caaaba689a6460c110730bdd08b1689de7b05de59af9fe244ac363e95c98b669359af9031a3a93ba631abf1f61d20ef7fc6883b4840fc926712e13d874b722f6a79b16070c0311325e9a70fcd86916cfa1da7f9d0563a22fe9bfe854b0c186c8663b061b65bc071e839938d8fdd7cf8f6952a6467fad8e58490ed2b26813301
+SIG: e0b867c9dbda35323433c046e0830c251b4346c5395972286b3a72310ed4526e545dc09d3918f2eb9920bc9b241e9050d848d3830288651591f936d3bae45301
+
+TST: 919
+SK:  d2ededcd853206cbf59bd74a25a303fa2d6c3936bb48eb42f6d900cbe80772be
+PK:  2244111e2e769eab81871e06c580178c235c7bf4a52d2ecce11887a9b46c45c8
+MSG: 8070bc0db089a5925446019b7e403c74ec78903e4bd54bc1d08a54a6f0ed75a85b763ff54dc33a2600ccb457fdbaeae548477f6d6947ae26deb71eacd1d2d62282a083843be4e5931d91c93b6282c58807ce8f0d880b1438dad8fdcba8612df73b9faff3a9f7db3005250536aabd98ae027a895e10b5cb7b69875c0f3993af245192f4393e9c4d3405746e311d3a91447fcdbd7306b6020c933bbab9e39d13491625035c9c636efa1739c3588710a879d9e3ce1764616f1082e8dff57559c3f5a5d76dd301124fa489fb949e9e039dd4621bda60f0b86b311e78ed0ab3b528965044b23d78ee2f81061f8edbd6929933d18c0207dec4b5b6b2fa4aca2747cf5b110df00b0c9827bdb3d9db2c7b0328d40d99e1f6b228e40dadae78aeda0289b6a23d4eb5837088e5d88413632ccc22e21a73768c673201e9a8d8dc6eb6f7397fedbd398d26f9692ca72f6d6cf056aaac50ac2f3b266dbe5e7be7a024774578ead585245daaa73e0aaf833c070ba4b2044ccb5e5cd16f9c0ad92ea8448055dd828c79935aa6c0741f9e2b810324fdc6e61e842f94572268bf7d5adfa7ab35b07fb19e7815a8aa5d81130130ac5cda8a4751ee76038c0a6bc2faba4c497e62b9f1f194b8a599b07701814b6dfb7d84bcdd5b7b5bc2249f1d3845eff9ef8cc7328535d70d53c7aa0c7305901de7c4ed2fe1838265d4a417b876adbd88eb933f27c9aa48c8c7e34e48147ccffb2fb61a348fea13ef67cdf2e039e33fd89e2c1ad2a4254e3bf748452aa83efeca46e780ede1d13ff4cc5e7d01ed45eb8c74818d4860af4759a83e148896ab68734395760e00146b793c3e72898aa0b3c5e0c1d3fdf12158d2e8ff1123a3a0c64cf6374a7f44f11a575e48a379181b30a4865cfd022aa983275635ce4f2cc40bfe066067ec4fe241fa047b55270a1ad0776c5f96861014cbf40a0432c559f22d79342b79f8e7042dccfb1cf50f83085f8063fb1887ed2dfc9db7efc96daa0ff2bc4f52335b02112d16392e134c0223de458fc072cc22bf9e7eabc06208180a57e7ce4805ee4e0fc015840998fd568644a0386b3d8e7dda52abf64f7dd00868fc84f036ca8a78e9ba8171ca90267c74e6159acac7af5bf23759abc53d82e793db87fdade1363354ffdcb0bd4cc9213f5c845445fc649b2a1f329f9d41d8a031ab46b472160f03434b4b6bc5a401524d6179ad66f9e221c9067fc87fe4a77e21e8023b6169ebf1090cd556a9be50b9187fe4607c5925e60b414f6a5cbf8afa15ed0eb34b67b4c9c5d54adbe640
+SIG: be3c2b567fe8c208c98e7197117eb01b3c197bdfc858562dc5cd90f8e2c0357042303995baba2f40b7345c56db0b4625580aa8dcc48df6019d23a838ea717202
+
+TST: 920
+SK:  b569f7c1aadf56ed1b5fa1b6fad648d0dc544ff8fcd173780de41a7d4de60cb6
+PK:  9effa4aed9c658e4346071434468a0b8a04ecf7841699d63e8887ce205570cea
+MSG: 7c5aa4dc8078aa77e8b3b7fee61084cfad764762f1ef26d8deb7f2f3b186dfc772487550197845fba2f4c23c835b9b58dd0b635c649135137f248f5ef713564de3c966efa5f6db6bea9e30970749f8e872d8d7ae4535b75e176ea0489b915f3471d827eb5b444586488cfc3fa6a45082dacb826495e50a3b5dc6bb930a331f30c385bc3b24ce70b89596db6bfb687d99a581987ca876ea0e757696b3fc03779a658130c410b344edacc4277d44845499d678e1414f15f36e166335189569cef3567ac2e3ab821c91c93274f5c28a5d1f7c1bf5099b10f84ecb13a4e4538f6649bf74f7394b703ef53649d81516cb1db521416065cf9f276ab80c9308897a27dfe37e5e142f1819b8d348df50a046a12888e3b7f2dcc70f5218d15ebb9aa7291a1a92ac445c51d3a53dd691efffcf5a01e876a72aa481eb4f121a072397d8cc93bbc2c9a6c28cc89b11ffc0e910d82d9d6298a367a0e1e3e8c865e4326a319b22666e529f1998f1b3c8efb5fc21cce97040fb6247daa0000ac5554d89e7b27159dd0b1800b760b79c91ef6e970b1e6c5ff42442b1b3ae4d3c439e08ec2f6b94177387ca5c01df6f07f8e34d25edbd49d8b74e31a5e65dec1f8760fa22c00e6fb1cd555be68b0ab43599f0b9f4a54a7ccb062683895d5ef66d24dfb1678cb0d0e8c801d8e5ffe79b9139fc96d118eb39b9c8d4404489325d45b4a3202beadca66f831c68efb815941581930ead29fd5f211b90e7a39f0d4ff48c62a545e28ac2ce29bedc356d92fc00347176d77623e0e1809eff3fe62b75a7d9deb727d86172d14edbf2789a57143c69925c917d433b4683b0693b3cd9e7e377996410727f5e6fb8f5ccd1860a20294ecf33faf97a1e0f85b761447d4761b96e4df1b312bd414cabcf498497b0ead67cd1e5901bbf3a16a8891ccced8a907df88726952d4ab370a6b7df2942cf13615a5bc12b4e106dc3013c68b8fb906399df15f1aa90d56aa974b1d2b28c1a8453b9bf0792a51c97ce8a12afc9341bb4c0c37b12dcb12c639449775d9ac5c2ec49673da5aaf7493ed5f1f2116eaef72bb7fb1e093ede2c26317f4f4b6ad585346205df91a6e96bc66d3064bce952398ffce88071ed9ff2750c65c0c304125ac2cadc4fef71a818732496a84ca574d482d5a3bba20e16dd2fa24d3270f6c60992f7f63e88f52eff6222998eb4416727384375f59f00e47512ee464c3184aceaff3ccfb06bd15c183c5e485926288b997bfaaaecf6ecbbf7d2abf4906df76b1277c5f5a87e6817b1c636e91efd7eccf64f
+SIG: 2e32ba0556bde974d7a19b3b9a1e92f183924c4b74c5d751b5ab3d007967016ec03afe91d742fb22b63e5e55b2fcb6c61a46e9dce7fe9fa30bbf66aef4b85f09
+
+TST: 921
+SK:  323465d0313d1001a261abfd44fe65c38c9a00ca0f20335d6553de492699fc46
+PK:  e22f16bd4cc7e94c46ba31961af8c583f9d2718c68f73d85069f608e15ba8766
+MSG: bb1082e1cfdcd29bfca2464d5ce446b5ba654ba58c22538da926b8303cabfd284a7bd5994a786fa66aedf0e15f20c382cdacf3d14557ff7a8267fa04672cacab767008650aa9b4a7c9071c4799f1ffa45ca4d586e02047444c14231943467a3abaefa53959da226eb0c15392019760159697748293c025568783588a3910e78e5ea427c4407a8901061b8b992b82a2df58c04a1b2c5fad11c6b379856c2e0fef8a950de7e0fc22310309e08b132b0cce4fc1ecbf94574a388d4ae36675d3299a951554ebf180eb381e1b5df977d938433891bc478d7681850b9dc9c5c769d405f5d8839fc97361d6cb306c203026cf2e2b3d39849e1f4b1225eb25ef8acd40b006f20c644db650c75d38c0fcdd48f598c7b4a60106e69e19cd712589cedccf50864ea5f9e95e01f1dd85c7514f2c94b28359de4132b88c3ee1d10a80a9fadfb690e3d88641b3168f0b896af8990adbf0e4f8e9d3f9d4cd314e12c3bce0cc8738e0cfc1905be5efa071f710b32f8e5898c60eb1bb8feeb74000560f41cb2ebc32b2600b6980a2a4064dfaa3797ec44cfb72d379f8097379cad67ecdc0c32414fa41c72b1b9e4edf5518cb39fe9092b439af3a4ebd5afe79bedc0ea8bf17479a2821f5e9bd91d7f4aa5e384699523719b6957f82367cd85fea9ded6236a207c94cb373e3393cb4fe11f90a1b8779e4ab4c3466136bf21e2aab78f7d2726db6414fa5c4a3f7313ad2116a6d7ce40aaa1001c2704d5b05ae54c7cc6f567217f1a47bfd0ee738eaea5eadb5371075be076c8750aecefc417ea7bfdaac3cc38bf16cc26df7600e3c7e8e431f2676fc2a8c43a6a14368ba62bb32439a06beac38a047b3745e26f407ad823d6ad1c0b6a44341e15fc9b331214ffc89698211b05133d6d3433b5d59f7ab4d109e54e4c5d6f32fcf7230fa4e2528c861bb21ccc9e310e9497e077ea675510da712b1a5df575c5d1bf7362d071180039aecfaa5c8573c24c0f4ebe81c2f889aed3de5a000be12fe3d0af2dc2cd4240e314a176c553efd5cba798d9ff1e3d4bd9e90bb8113e3849d735afa4af6945cc57d4c378db84f206ef7eab11c637a7f7260f122a97dff6747e9b4c174ed0d64f9efd7fcccf981519ec580a8182547d17968c40151fdf6d54bc57a9115f040fab5c100deb039122b7d2bfd98b6adf38f42b296ea3b378a904259b75d60703b4840b3f5da09620a54776280e9ca9e8cd924aed2b5dd2b49834e581caed5271cd78ce08e4bba49b59cd77c1b6276649148ab7247f97fc0131635de474d3c23493ca98d
+SIG: da3aadb34360b2da0c26542ea71defa8a0bf7fbdae3ee9e11c84084ad05cce7ba7d94de25d8563982616bcdb5bb6395fac4a7e84bc77e21ed36df75dec990b06
+
+TST: 922
+SK:  60ffdbae003fa2794fcabbf8f5b41644fe3a7f44ed6c834193da07a9dc5e2665
+PK:  35b5eb31ab556492578b3dbd6cf1687d1fdb216a725818079663482f221ce421
+MSG: 3f8ff20bb4f00834c80f2ee6893d6f73bf7ace2729601bb26a0fb272a4d0eea1fae1d306ac2c5f32add60135851da27e4f12e64ea5e9e9960b1383b04ce05a98b0414dad971ea98944871d415cc2c46da403976d9f21938958d4ea8c7903b14f2a4485fd69afb24abe102d8fec266fb468b411eb20a339677d88eb31c997b4dc885613f0be7c70daf856a3df92da9602fba2e6749d2f426beef68662d5b0c2fd31321b22b5ec597da5d7e6a288ebd9443c5f39eb87dcf4a5ad9d56c6baf6080996a77936bd87dc3cb42ed4c4d42688a9e193829b761ff320e2a66cc67648e70eea3a1f2f9b9d5b4202fb5a39e9adc609086a9be2a8323ac66931bdf6c504d3336211e46fdefc481fbf17f613dab1fc5c097c92db0609906d78b25a455a3045718efd3e3b14e252b1ae59c7c3893e31913b2c264c0ffc3b606ca1b01dc47ee828a08e46af604e590def44d27aab93a403251fca0772e9df0fab7af0cbc5181efda4da913d8eb6452f6cecbda204bc72d7c990f60ce0dd83c634e912236091b0a6673a7c89ea59308d55bd7e63a8526774cbdd7a1339fac2124c9022abd6fece7f2daedfd87fa683dc0e3ef40806a0ab198769d3a99fe81a99b68600319087afa4ea79d7ee45da9cd40809f4ee8f4e25a0177521ee9dba8b56212e88719bb7367336f4a7bc7122b41a7dfaa2672f92f23403a10c4fb25388c6b20081093d49f3be8a9e1c634ef7ba96b6d523dd6ff613c0a23b60457026cd485ba8db61d80a0dc659d9af42a38cae777fec68e39c52986ff9fc20789c10585107c04047b66ba14e93fb904ea90df7ac9f0154c96f3236acf6dc8b44f554c0cd513193e5dfd87e085ad4b38aa4c5e36b2427722088816ecd2bc3a3dda01e4fb3ff5eec7a6417322ba6a27773d24495a839194a4a582fe5abdb8b5d533a24262589241fc81fdf5e79fd26776428f8e1ce9e926cf272716e7583abfc67a94aae0816c1000a196170bbff1f45e5ed9e267ace1e4d915dce7216c5f404def6fe2bd8b28b2eccf3e2aea0c0d6626390274e47e745ed3a23bcfd21d284c395379dc02080f07936bc154e7b99ee73db188bd2a394e03a01ffe2d1b330ceb72158f958c716a81711dbf65aff8cd12f5dfa53b376ebb8b98f8628f17ef8b2ab9c0bb68412f4e347a633e2f8da1a556d96f4af7211c078079c10541c07dc3722d18dab8fa8bc4925aba5c966f805040322dfbbbe87fbfeb1961f5ccd40a91b997e54315a7eefc3a47bb0c87dc23755ce7227574996f4be7aa344fe0d17b97bc50c5838f99292
+SIG: b8f3e1f3785a2a39bb086ca465c0abf0a3e87443225ac6e966ed9b4531c54a894a9abd01ac31b85757fe75308c9594ff65f97cdd91e8d8a93cf12b9e6dbee90b
+
+TST: 923
+SK:  174e993d9b81f2af67e9ffb8ebd5da417966a9e77f66c65c767738fe8357d07c
+PK:  3bb7386f1b1cbfae553703833ebcbfe2dfff8c899a0792d7ce2322b5ba645a5f
+MSG: a401750afc4837dfe3aacc284a597145dfef02629ef87bd0938d443979df76f29fcd66a5b71ea8ab787277e3056f6ea11b08bd238979f9d3b062538c4d6040a86b6e32047aecc59c2377ad0ea4c40c79ff9fe98c958b2bf25f2fd6342432636f5f7d5bb0d2ecf18183426c73147984d95bbe162e11972ddb78a2a7c345c5c0bbbaba9cf38a2d5dd509a7df8b842874a96e64b5d64f5c41a21d208d14cea7066cf22dee0ca41aa46ab921d4ceec89ec873f77960eda60d9676cfd0dbfaec872c2ade8fba4285aacd527143ae0341d67d0078119653b5d23d46e6ef70264b1b0913870877623716d0f1a59021be74c914b432471a43a29f2b6dbeb6a223e2dbaabb820b4adbe337829e1de0c184dd0d09f9d01d42527e5d40abbdacc8ac0f1b2c5c1cb2f23876d2d1b6b43dfe482f9d45a18f5c22b15f1fe521ef57b08aec6a3033925c7454c93e6319e778ac494fb140ae5f1a31cc832ca2488651004063bcff8fd9ae9266af527f2c31f6acb8f3debd9978ef9df0108e3d50c491990c90dd8ee9d64ea4ebfd711c99d9044ec11342c5383ca39232ed97a07e4dc51db4c1fe947348dffe70a95c99db14751314801f13fa2bf42d867375a08ee9b3b799e0b15278e95e91a8968064d6dfd8f5115438ccb8b516ca0c41dbb19873c6e10a236ecc2dad522f80f01c14e2fa14a0d792b9fc486c6fb0efbdf2130f02df1497db5aba8be61ca70b29388e4eec7e0694a38c0d03c59bb6a2dc3ccd6dde1e29ee2c1b325ac72aa8e6fab9138f8b6f5d324d46af3a3542c8bd87cb04fafc54b5db827de606762a097b622799ca827bda9c1c0bb267eba8254a81c6b858a375b94bd09f39eeb88cb14b8d46e4740dc1ab42a895f86d2c57fc28b07b7f60fc4f8847b8bc8ad83a2481a28f29bca3510ff8bf1dd7581e3357164f4fe920f9de839376de064900dc7f8bcf511dc572e0f0f6a75b929797da41c52eae6fe13750ce351e8767630badf6d7d4eab90cd1904c96c048a9acb213a9e5b864615738a84f222986ac23554cf4ce54e80ab5733c065b80459921dd3d8372d0e8594d4364351bf041c146fa8d23a193eb807ece23f24ab6595e932c9ce1a759bf788914db008e87098dd81465e2610647ac38e088666f60ec5d0e2173320a40cd985f0e00dbc2b4570727483a8c25f6fc1e093bb57ccafd1ca202f2986c7c5540a7c3e10c4a6fc26d1d62c2ca5af8305ceebe42ff96e7dc548214375e8a7f9f712ba8bd875e43ca10cf9b183f0c8519512928538a478cb98259bd8b3e334bcc4635595cad3
+SIG: e607bc9a5360b31da56be1c544c2000284951d8689f4b722bc4673a0c8489b84483ed8e76e297ea046e85b37ba5630585e5375566a187afb5696661e5bfdc10e
+
+TST: 924
+SK:  e53715fec9d3b20e9c2991e54b5eb0a8cc81875569c95e22a200136002176004
+PK:  5351899b69b2116bc7f8a8814d1e5b9fc785698bebd9ab14277c3ecc01ef8b1d
+MSG: 8431cd16d5c093775e18c08252c43f95b1017eb711fcaf73e1e00c0cd6f3448744ab9b0e64335518c483ae94deb97677f818f0e81a7490615b7141b9c35f80556e6971cea28e9a32c328cc2669fca5b123cb662debab2b98157764668070e18edf761ae196bd4b244fea7b74984516be2c00739e76e6c4b621cb3983765a20d84778d5a4350b168f6a0f712a9820a85a636faf92c789c428cfd2962ed207c3ac8899c258cac1adb5159f764ba37229c5cbf783fc9aa4d1ea46ecc85fe0961485d4fc5cb21df0012ac9b955373b1422e51afa1c550988862c86133b760aa630fc0acee8989117d1dd96e3e6287b69287c590bdca9cbc8eecef281ee6d1c8d88822bfea5fa0f530f23278093c7c85a0d44c3a77404ee79f1c8368cd7321bf148fda4dcf2eb07e4630ea422587586371780514536b894c524e6b83d5a76a15c83e95ab314e07b34b98cd99e0770b4eb9b3f3f505bae8a06f7f950258d790748107195eb4f6b84840f8c0590727396ed14e3f53239476c4d2a7269b2e1f972fbff33e4724426745ec886a32916295e70d468d06c7dbb5ff9a354e1ac903bb45ca526f08b49a65e82297d8dd3fb25aa428f64345bca9740d9078dac9e1138c921bdd74881673d49d0cd2006811723de287c6c9583e456a01ab1a34dfa1eaa963b71e8bc7fa8a98cad4f941e4b37b60eef923b3294882350b38ea4eac0e9232e93c532db5d7eec8ecfae65e080473078777ddfdd11508a6e59f0ebaa3f60441f82a71a73c84bca06a371ff5c9f77213a2db795d4a8897823d88fd92ae3e057e8bbd80c990af8386bdf26f12d973c8c5ff9ed6f7b2d8e6183cf6e68f3bb898f59a93ec4de3bea605a5d8b15dfab713f3585c48dc9a5768242b33101438030e7044880d17c2ee84f89d26a1f7b1986193f9663c587d50ca9ddf6186a5176afef1adb2481b79254b78d3b34c69790eb28b90b1461170c3d73818376cdf371af0a0feaf14fdf7016ed6e7f08c0c14b52705c86d4f0003b5e45f974c06416ccb5ca3e9d529aa9d415c25a446fa2d69e82f4994e57e922c17c1c342dd7281e410052d9e4aa1b309b7d470d458c663e17ff2500d0bb8e46a9c4367e091caf87ddfc062aae08a65cb9e0eaa71c99459c5e7cb112a2ee98a5e4cbee0dc520f87c3022da6549be1ee70a0a73ad8499c97dd06aa14c9fd8628a92ca6db487322db9598ada1fce28f4b9fc1d3cc39dcf2ed1df3d862d87f55cc1016fb9e73e7cc897b970d5ff35acfeb05c1c89192808aeebfb2cd17cb1c94fab059898fedc2fbd44ccef
+SIG: 3d0adce77a4e046fcb9b49ad5e6c6809c8ac336c733404e5d3f015c9225c3df46ef21ea34cffb3af69974f8b7eab2d23fcd5a1e1753a4023deb3818629a98a0b
+
+TST: 925
+SK:  abfd697bfbc5b6ff2bdff3bce1d777e05fbe3ec8b95ce693d623931209313d4f
+PK:  a709321a0210cb80ab58bf955ecdeb8aaf9ee4c375f959c53089d437488c082d
+MSG: 896b7ab8413ffe439a2f4487ec49d64e31c74f50ac83f55da61a7003aa716c2a9df6b438e62f53d8f0192f3736324760d7e8c44ac0baca3ae2a6fb93f13d96886799fd2c4551b0ab36f1730855551265a5a3c3c21d9516a237f5dbc1c8e72999b782c5ca41a4f6e9308e64afdee0bf479e546b89c51bc5e4f71e57fb24ce437a8b81b91dc798b5ab36f29afd5b48e81c176ae5edf95371ba3246fb439405bd10eed3678e3ec62307a3b3dc1badba051f16774b85088188c2a9e320a1618d5f26ce94ee2b933c305f6d9584958eea3156c3d1e0ef39a186275ee62c40f3c1acd15d8be6e074351f5349ce3df69517505f45fa06a815c69ca18f450f42b5cf4ebd99268445e0f68104a7deeb0a115b817b99e1a73e0fa9d87db71f8ec94f8708c9bc2e622b963365ebcfb97cfe7332630070e9654eaa60361a45d402dc0ab297665242667fbd9940f6cd33195246a8c2869af759a862d4b641db144d5732366b20636c4027787f558027d76fcbf8432eb93e6d14567df8dbf211daeb5655db10acddd05eca06accee9fda8d3b70ca1e6dc587fa4b78f63cd663ff0243870570f4dcbaa3fb626b4e113bde47d5c9db2b4ba6ec6dbf918ac056949ef3cfcb115561615771a035a43d33ba2651dbeb46348261ce3c4c9f246d23f94dbc2d0c19b921e24c77da5992f1b4bdf2edea499f5411168ac0c12e96f3b15d2e12ac8d7b3ed8d1e07c4267a25d3a3c353a4208b7406278aab9e700f7b206f48e6ea7cc97e554f15c9be349dd91514dbe8d889f2dcbbfa182c9faf5807a69b2e97fa771a6f231a4c7b31d117b8ed0e630cdf13e082bb4f63c3f9acb3553204ccd76e1835c46eec3d43c561bbf17c92214a6db1212b6003cf2cc26c7ae675fcd053b947e722f9e85762ce8a16e4654ec6342fc646e5cab472797eabf658ba4afd142fc8fc4c8f98f23c24dc99847ae8cef0879e1ab3bb8097e4c3529add2d8e8e2c2069210f50ace1ae32a6c8e6384a2bf7d79c66c746149c84ad75a3a176e45e136d94695aed4bfd08b426ea8c4b9379f3742550e1cf5ac84c18174d680e92af2c1874ac1c13d28232de193768e561947cbd6b79e9b99da65cfb74ffb32f7d3d2025c60763dc07f55539b4d253de1e6c25823a6258c7a9ced1501dce2786898a3e05c9bff8fc5b2125d0f471088a134b4873c8d55c0445f6ca396b3d7b4bc2bf5c4d2240da418293af6a3ed853dedd3bf668d937b35aa0c2acbf23766f9f3e96828475ab086496617a6e81d653589b2fe50b7ba8f0cf1e5a44d8d62f08377abfc26297
+SIG: 8c36b5a111c5a8119f2d9db57ebb592dae86ad4bf678c1492e26f3c10fbe03f105cae0dc68b55259b9b5989289db33d95d2ee6b756c760f9d3aa0e68a189de02
+
+TST: 926
+SK:  dcfad59fc6b697109e727ff66a5fe93a6a226f631a64e5797ad8d8c8b6358734
+PK:  e79f4f511372e355e7e9e0e8b5346fdbcd2df1fc5c3a1890d27fa1fa928d27a6
+MSG: 7d92ddd8133c61c610c1308c23aeaf993884a4e67f7b94bb886dad509869a932ec4a27d410d2c29ca7aeae6f9280cf6c4b067ec751e5e8c39ff444d422ceabae145d42f047453dd402d1797405033409e72cc19f793d5d268fb3fd2c11ea2cb0d70436e18f9e88a01515dc865f6a1eb23690328fd75de26321a38f12197a97201b1d8452944fbc541cb68c77d49515db5326f2b1d0763eda06d250ce2a5e0bbd7d1676d7d41fb3abe88bdbe372f96bf7bb526d6b65a2515e83a577045b5479b38b852fe4ab011cbf21c085ef5f0a7c1bed76572b0f860228067a899f895ae7f6256eb6514087f9d6f5c35596c1f480c73113546cb9cc30f56ab074a9ff28acab7e42650a961da325ac5b6594b81c93250ae7d39267a19c97625407edda0404cbe5a36e959fc820b27ef5cad796c11eaff1c0e2f9d4b3c6491502195de03659b364e4e87b2b2d733ec25e6f9b63d5f69179e0d27bd4aecc8f12a507a91baa48d99b3a426cecebaef37d7361106a8490644309f6eb4d2596443b6b0118b945acecc6443ea61fcd155b54325bc2c31be0250f9482e13fd8eb44e2aed76be812af5453cb7f8632458fc8a02a2f45480d79b06c7dda38b4695d08b5a430504f1ae2275b05c91e799d4470f38abe77736dfa895c197ea4b63c2df18efeb14184837b8ddf48909520d91045b9d9655c225a83173960b4d7cd0d8bae30237557f869708be138ad5246c866c6c059dc597abfd4943237376896736b97b7e0289ef9bbd29477745cb60f46202f1de984f509b1808833f58018cde8c26bef4c005bdca385b05735110ca02e562b50eddff6fde9fbb8d030cedf7031bbeb32b12b242be49fde0160c1fbde99b03c062a1a47062345c92e0b604d080facce9243481529c70597dfd64382cb540691b59b71b094332baf0bbb125b63a446bb97491c0464328cabd7627c46f392f3b124822f2013c6e16d3ca87cc5becf56b0fc6eb2bf9923b3012ba2b61250a633a4d2ee391256c520957382aff970c5d22385c3344c6d4b4561571c96329bf75615297516b9f2ceb9f997a39523aa0f58b488772d82fc0d78c5dd52ecfa6bfac63a76e148088b36f24a88e68385496ddadf3023f72d87c2efa26e877d32f1da97cdb42c8f15718988e428cd02f4d09543bd0bd5b2f409963d0fa373531f78b592bd137eeaea0b4e7f918208e1d59008a8af5058f5d923c4f32df19990f10dd3f0eb206293b2b3443f4a5d2dcc5f7d3bbaf6af43fe45f5dbbe53ecf4bf1b4a13e2d46ef80298d4f01c402e210fcb9ff2084ec03e42008d
+SIG: 052ff79540737456c6a42c41c97d6bf517b8cf289bc78b503dee6a30ef5168b38f75beaca1e14d971f8773e3941bd6df5cb9778dea125a4c4fe0116b70ee840b
+
+TST: 927
+SK:  696dc481f619a9498563c83d0d0e55565c14a07845fe4a66aba2247b113ff8ef
+PK:  c9d737abc4a9e73c149eadc195a837899f2cd5019373c30ecaf62e5f8e14b645
+MSG: 2d4b3ad0cc99f983e41f9b48c4a818eff75fcfb93a1229ec2740ed19c107d621df78058de7c2dd7251f5ff454340865f6c86da65831f6672db231726fdfe4b9ee315d93c7244a920df37054c82449d310f892932ddbad94cc9bb39ac8937cc76c96521d3fdc028ba23410b29023e8138fd3f524319884ee5dad0d234c8df661f8824be477e21699f6369b15ff3ffefc151aa555b3c3d76adb45f25672d380d472b3148dabdef4245b68e828562f25cc5b81d9bbb241bca9d1934ea353f95f7dbf3646433e81a354e1e2056b81c15aa1fa8ed7a9d1af99238cd5a5ae9e841c48dc348ae1de7c41aca23328236bc38b47f47c736b257a3078d57d574b647a7fc8c4d01bc50302150d5032bfacb04bb0fd155d94d9206667720e180a645af462459e3326d460da3c48e7572678e1919268d3e4740d62a26f7c8559c1c439b4b0b0c5942a620cfdb93cc68aa15520ff2864269d7a0c155780adc6c188e0b565fb9594319e6f51d15caf6b280e7158f25799407f3ba0dd1ceea64b9326d2cfdef017e1f172f4dde0f7e4613501af01ee0ac30095f48b59590902b1aecfe093413918d835adf962ecf18580d16f9fd4f6fa1098af1d8a2bc24dc86f71d0a61ff150010867d086987b51dd030f50ab6e374b8e01184b3e2b214ab1c7fdfaedbc545e38c3cd2f6982979541fe0ff88bed67506da95727af1a2038f3240ae5bfd30ee09210e00fdcf2a064d5db4614946bda972c670081a6ee6a10b63f673c83c915ca5573e0ed687b0067c400792a9bcc3344e0e43f5df63fed5efa85e9aaf85e4d7a2c53a6c92828e07fe63e2d23f1bdf97d84adc36e9fc95faadf03e06d65a19c5e285effd0ea0cfa839d55a0a0dbf6da28785c77f5c04bfd59974ef3793cdc398df7a1bbc9cfcfc3a51ffa9a20d60c47b245dafa3e44623cd711d7762c50a67d650c7e8c4fd3bebc0c498d2152ab9827c700c7b2861565749b5864fec95b7f6b1994e78d8f85d069cc11f85bed9712f7a9f060b0bf67532e88eb9df3eb4a8d2fbbaa85eda926d81c49fb86e73731b7ed2a1905078513f7ca0fdcc3b1d576e6a60124c44618df1890e169794956cb1ec501ba2049970c8e74cc180064c184468be4f089a3ae2263c855863b62c28313ddf9ca85bf66b08a264155ad7c328238dfe614a07ede9155a09ccaff92292249341baedcbe0e6466e2c76045e46dad2fc899a1782e00998e79a83abfae9b706f707f58e730203e1d2cca028c922beb6d157fa7a98132a921a3da21f2f769bb6c1f5f19e9e85a13b781af141039d514ee107
+SIG: ded5d991935cd1f9390f1e85929ca16dabfc83e65e43272eb1751671aa31930c728555341430ce7c80485de58006427129a4d34fd681d52d840a16bafa153002
+
+TST: 928
+SK:  f3f8d62fee3af375669630cbf063bfa930189af136cd7591e24d578d7366bf61
+PK:  4714c604aa95e1828a28367ba78760b5896431683ee996cff96871773291953c
+MSG: e1dd1ffd737ac6dc24b3b9ce3b79e835bf698e931303d809cea1782dc3af63a0d5e67392823d1439e7b6e337b01c8b215434c2782b3be7443cb5c881e5fb6cf3bb244128b4da6a6f42b2bb2cd75129d56418854348c339dcd912b45557a915e9fd7f37916236510cb6c331c140b87d225311600b8d132ac47473839c720f9ff0f9c1dcaa85815a9d27b9758cd91dc5d3e53326fcdfb2730e52be3103957ac89149a4c3004cb6038c0d80fa72ac630d333be5ad4adb585aeb71aef1cdfd57b915fac4f1af78e7a597f8d1ba06672b19c0b65808a8a071ff8409034379589f3d41302d2d39b3318e8c0090fa36cb958857ff5b211c9666e27bc895ab9d006abaf5950a03ff17ea982178a446dda2466f5a40b8f895509e4f4d4a6a2739997fbd4968f89436cee3d8edb8a6da9bd3d55b066490e8339c78935b77883f95b932fa5e6bb7df303be30fa567249fffb473a1e464322d7c103fe8224c7ec57bd39bcd030b96787aebcd20e9ad651cfa2bf04ba70a1cf648e0a5449567202a937a45becbb6fcded30cf9b5c748f882b5dc2a4d65be69fd7d9c381e83d0dc2a34b6dee91220ba906e512fcd63368e2ce733e466b4b82b84fb0c717dc8945caf6d46ac1c2f6418f7729ef4c35e402422d64b1c3ebd1b32a30fc4c5eece7d4408ff679ff01a1c7b03ca517be52e6ae7650f7bad38901e348a5593bc998f7cf2ea97729cb004f561b3b58fe59809a41fd4b3b76660906ad9eda23bf925437ef452b16f540b3b80a35a7093c2734eefe6fa97d881d79ef5b767d9889f118477b73f58a4c0cb15e0ac8101120571ca32ce871f308ad9057a80c828154fb1bc2b201d0cd1006e022d444dc93f1bcf224db74a5b373e153e851854948b6da147b73287cf17d1fb72b4827611103609cab2a1779e9793b9a70820fc6f3828a64c9eac35ef7aa7b17609d8eff8a9e52e4ebcd86b1e14fd140bea47c6b8ddc41e8cd271eb92287cbd0610512242f76a1ef3eac1e4bbbc1adae50034a7a2647e08b2fd20aa93a93cb2ffdebf2e461eccefbbd1fe894ce70adf790173bae96f5a55a1887e9ae09fced1d4306c291c6b19ecac4707e9ef713ea18a7562c6678326228992077a4669734966108000b4144f45a0c3a2863a4c6a3c07632cb93eb197d294884d9ca3dd4b21f39db707f63a7f9a570f7f0feb99b2ca7da7df92a177abcfe86ec661d30bcdcf1522bdb1fe11673258df7e46ef4d326665093156553f28b3563fe7192f72f5f9b3903d79fea04e2c488b465b4978d69f26e05a59d5ed4ef4cab232acfd564fc6
+SIG: 8d6f7ceeb9308b4a303879fc6cfa5ca8e05dfc3defc2b2cd2910dd4b17c94eaee845abe65fd715df05b0128e4316e2334799c6e8fa747ebc8a040c74f5a1480c
+
+TST: 929
+SK:  865a432ecce7e78c42709fc1e531df5e3959132b2b6f318fd1c34521f9a26e3b
+PK:  c7a8caf8930b622a501337f92840ed96611a322080fde5e49f0a2f6e33b88283
+MSG: b231b6d2ecde49f513b0df25aafc3e5da45b6a9958d60f5464ca593c03005ecf361ef1696bb6e55d6538e34b38f324c21cea5cc81a0073278bb92727eff81af561802dcef33bec10ad6594e22d9c4418af3988a43ed087b9954bf8d6283e4beae8c096de6606751cbed685846c6630b9528ff364a7c48464113472c9860b3371963c911495a9c628a3e3e47ab0991f10dd1dd33161525262d63bab648819d57d1269e114825c5434e6b2845f42795d4fb083ad79401f2a0761c634a545aec7cdb13b5be449f1d829326378ed1f493fe8c8e9b068cc1dbcf165550b8132c319dac487b87bb22a54cdf60aac71516182a4e69ba083f6e86d1a4f05083a77619ef239f702396d7e46968cc04a3b34df3265ecf16157abe15c642cd7427096d8d40db002d196cab1be304bcf322d9d1a2451b6c11eeaf3e8e3d929f480b6b77804fe84496ca757e04337914ce94475d7990c7457c8e606f8bc207d2d48119c80a6b4a9e07b229226570dcd994989fecc694c6c2fb5975c9a6a9b74e8159c27dd3677dfd5cb651f1e32adfafd810b6e5d5efbace31ae6d9b12191e89398da063f138b7584c58e77e7f9fdd7fb9ef5d68ae49c6ccad28d18bc6009d4187ed1420224a5658aadf135b5a953f2dc3c8bfcaf669ed5da38d0144fd9665e6f0677d3fc8804e21cc25fd5e01a3f3fa83e571eb2f882a7659ce5d864d8bb54072b0986a854f1a7f2d2720df857e6d4219630841b1ccdcfc6726b91bfc17e18c3e3480c23a2c05e4bfeddd4db9ef42388f234fd3e4f3dad666026e2780612374161316afc7665f9411b6c5aa78933b18021c012b084f3244760a4ea1bcf31cc9f5c4044a9bcc75a986707f38f45ac1c7fa139ee95a6d8f16c3c1e12764c4b0b1194c0fc5f7eeff9a848c4050b0e651684719d438aad56019164fae4f48882205ece0b99736791084a753ba7d56e88fceea533566c3a2ca48dd6efc49b27dbf14f2616ced652e13833ab9028ada454431c89b3cb7441fdb8f23e12b60a1a104a2a8cf4a64e878aa26f54e8881a4b151a16a96de8b9807e729396ebe3e3d394f808bd74b7312fe6b84b1312af8a1e4133599d07bdf33db21e016b5c196c1ba3115708f581bb82f4b57a6ca1a529e64d193042c1dc5faa0a03abf53849e1bdefbab64b1cb60fe10a3fc1823a234c45f3b0dce66a46739c01aead12de6f0313c7be71405f3fdc4a507a9d84e8686f6fc92635db0f7856c7373a618a7252c129a7760e2029543d726228c21d00ad4ac52e5b1a6e31200917f15af515859e08f2a79ace67991ed69044
+SIG: 32bb7520e2639c6cca19a2b9836b08f8b083ca33369ddf5f9a877d4c7a9eb05f9c3dc34ed4cfa4b283e51922b094066ce9ffa4d9df621910ca37b0b37fbabb0e
+
+TST: 930
+SK:  2be1f98ce6553c915b6a0933ec0de347b370e29ca294e8005541239f63b430d0
+PK:  7a6f4469c30a63f560f98734fc1906ebd1371ed80125fa3e4c86b43f262cabbc
+MSG: 6268201f932a7cd3f879ae6ab83855a2f50291de784d7d9e9adaa1b9afed6f5aea20240e59fe93e5a7088c95ec8e15745fb8fdeb91df0151c7b4605067561ea08dbf00c4ffe1fd0acf103656a7b54fad0f25ab16b4bda347179ed1cadb7b98be0895e050dcbc379d1fd553e99795928b67a752f8d2ec1b9d66bf6ac997e744dc327f242230f92e79ae312745a5ab6ddec1998fb63dc4f6b05f147222d4b65ace9017dc1bcd675e495f9eabb5f602133f6c72e053e9f4ae30d872d78bf71feba37acc595055c3bea53a05ef0c7f212dcf4e0af838ea2928f4cdc9fdc837da25f26966b2456abea66a5dfb8faa8fa091f7331d5436e98a8d6323cc9e9a91d5a02a49511714849b47454baf99c5f850a08d3d98410e939a9e89b15053825f3e9aee71447416140782e1bf3b0d8b4ff62e77a4a03f710a8ab76cf63592c05c440c8f064770099163c12270f3d5ec9a6bc9715bfffec769611d21fa003c3cc8356c975d37b62b88aabb8597daca196c9648a31d15bb0b86cf070ee01e511ef373b4a44c6a00160a797f2e820b716f5ca64464e4189a00fee978d35bf204f71db1f501f9b6e5dfc821a8af5dbfefd353ad3681f9bc3c22c67cb211b430b6a55f3e73da7c3a07ceb7d2fe254b10c2703ab2e2294dd0d3152dc7b21aab87b150f737a947463fb204175de8543236fbb0da5c7d48c57f61744de6f984aa8e61b970c62d0eeb849da7e89a61222d432079cbcf5f8a2ba930301683c0785c26fdf85da3020874604599ac6c847ec2608658b5788c7b8d3a3744fd5442e24c8eeccd420756bdd8b8a77cfd80589605dced9afda2bdb630a0cb612f739ce617d54ede6ccf36aa31e7e373d8a0fb1b7c9906f76b5f9de8c26891de006eb797ead4a86f7016f34bcde92f94ac3e920ba58d6dff772078d802a94f56cb26bf794fd90ca0ad4f2e7acdc5929bc7364997ded98ca69c573991bb9ab85f235b63e76f77e0ab45e78912389869af21e74e66f7c456b827e670beb0f0726688bb1f9036d38da07d69ea3666f76bd605d82e2dd6387ece6e824a569700f01b195d1a9bdcb0f96ab5c54e06c2119b406bc4888480660418bb4288ea2fda96631b0e1f60ac861d6ccc4c844b647a7d7403bc2d15bafe4af677e856fe0d2b5f663be4e480b38f6b766adcd3d05298ef1398d04d1523a68b91dd31cf5dc4b73decbfd7213f981b207e1f6ef225d7948a1aa17d8d57a112f1d4468d2d28f7ec2e54b74a692c5958022e82031a41b315090ed4d5bd7bd0b451476338f739a7d7031af2d36caa09ffdbb7c396507c75
+SIG: 8e659a3f535a589a5fd2d217cbcb8b777e5af20b234432f7dac29f810a2b4737c5cab10b59dfd0144f3090f5f9e0e667f0e21a9f573fe13b1c28eccbb531a205
+
+TST: 931
+SK:  10bbe6e761a75c935b517f0936fecb9ec6fc215e58130800ea18d1ff442a4f13
+PK:  8643ddf8aa8d9c8a78b6eb699fd20a57f6f18636b06ce69dacdca1267acb3954
+MSG: e8108c6de4133733dc199a73392e226f712c36a24fa91d6fb09f92df218deb2d2830a668fd694b4809d0253507231247c7f258b4d65c56bb69345ef6aa97e7c59e8153775a5a3cf109c4bca9815569da6932e82183425b42d7483c9dbfcbd8eb38c84729571e8ec93982c317716759598c4f6a1b7f8da7306a7815721caf02e70246712314f766be9cb177cd2fa3bda22cd676c5d2e86e8d798fd34f543c9be3129651f273f484f0b9467b140955cd2981ff2603c0bdbb436ac0955a116c5e5fc30425e1fe78f6410f6ef757f604668854bae79bfe22e1a85ce5ee5d6434b4610120ea7e5d3d137ce207514f8534ad9bf392b7dc5355514b59f835466c8eb56f44eddc5bad20cf0b480b2e822a6f46fd95f30f183c7bb3143e4e6100e2dbc9f2bf0d43073e0fe65f01bcce6a1ae401c12541be3ae68cdeac2a4ac71f1663b5fdfc2e50f0e077fb3a0a8b8eeead627c1c3e79dd7361046f7e57c17436c32dc4432f050028cc7aa4408c2d29d1d7998fdcdda32bb32f704dc263db9b8e06c57630870f8bb6ec661fde1b7da94d53b047701a4588478c1c662346741aeac4c25338556a3d848de5b2a23ecea61b776bd0e8037efb8501eff239c7facca6c8367ed7c8adce919fef1a155ae0d5478a98002c95a16fbf4c0ed016ea5d3866fe1de454832a4e9565976b60b3dd2eaf7fee612f2bc040d93975435eebd12f06eb09ecea2c66768308f58c77ac51ed7bd21636fc9cc3fd14870bd06bdf128a81b14792e608c47ea2d535ca7aa21eb8a8a56d76991663a8190a95057d33671e73c7cbce5a98d31ef0d73bd0b163787b7fdcd2ddfc72960f2be320846d4b29080d7aeb5b7ea645a2ad5a59c012bf7b9515d859e1c1472ef8a4d3c95e711af97ae4618efbab3dffe88c9f6af4a09b0e73387e251b77d7bff5214f791862db6988411e2ae2c75bf28d28602a637c26f49c18d309d2fc58a126667ad3c2ec160c99ba40fbdac17e7e4c21a5d507859762eba09c4160df66f5feefe6715a28c5296cf43e5e771f31fce5133be97cab57301b4c9df9cd9a4acf1c33fac946fa1596fa65c8f3658be47a473a62c52181eca183e4246cd624d8783dcce5fdcc1fea173f8071f7074f55897de9bfe84a6c4fdf802d5026b8145e6c8c8950afc5b40fd0356fc55ee17e1f853a4c2fcc34a1369b87d28dc2fd2010f19903aff8e46de04938f4948245d5b425d074acdf2bd80bfc3735cc34a22590f194af9313eef4ab5fde61f1f9b58578638fcb4f2850b2fce6e03db4d0a834848163c4b27e129f5cc74f67f008a2712d1d
+SIG: f0f357410373313b7c6252d6d96600360c23752d431ca8075bcfb772d49cd609b65c9cd838d634d8d9b95d1ee30edecc13e3ca997b2437303f8a33a1ffc83306
+
+TST: 932
+SK:  186dcc7efc5ed7e61ae53dc42093bae8f15dd99f0f033326c576ff756950d06d
+PK:  c8d141acb642aa9bfbd543277c2dca8aa9888eeff04543b3789b21f26aeb0f71
+MSG: 974364d6c838842ccc4e749e6afd537170dcd8cc50d66654d105482339cabdf74e32935ee219272ea1684fb93c1fab42b5631839243591bd07d3be949b0dd15e3196df196ba752ad1121ac7112d566944e153a4e0619b3a232241f020be0719f6bec918b26828eb1670ecfc73c66844ea3e404c6a2fc01beb403c9d6ca551ad8a6e71f46647fa6053f0314f8124d8d2bc12cc8fa8db95f2b735375201b816a9cf40f83ee4b8671618032de229ce76271d03d2672a1ae4a288c85dcd27fb8452a8132e9ff29e1e89bf11b1c835192c04b13be14f3cde5d37ce96f1dc2a9ccda0c4d737bca1fa220d21bf360b90515bbd226bb2a6c8d5f2ab018d4084e24ee333ce4e39bcb6b46e7aeb4db9b6c65b244d982823a770f9c62a0bde2cbb7ec36840d455187faff4e488a5c608ebdb7db84d87dad3867e3b0d04b64715e16560a62f1ee03df6183fd5e37555da1972fca062d12bb8420e082dacb8debb9c1438541d0da2464ef7ec52263fb9b9a4c469c83323e4819dfdf4fa0a770c3a709254e05314830e87fbb6736c72d9dabe01a310e91ebbfae767a1fcb62f64fa3ba8d53400d6469ad1ccb811fb9e115f14127b13e8364aa2fe80bbc886a10df1b9cc4ae4601f5461af091f526d272da9b203857a4447eabdef439830496a5759c21de65ba3a3c8b8e939c461332a924852c205c7711f3a68a2367a945def4fbe5f81c60cbb7e394a2a49be9ec2aaeb1f330575979446ad9d0d54abd436f2860f0423426f4bbc26b3b9f650d69b10072d747a39e478f455eaa12c7c6e12bfc4536a3594344bd02b620e3e2b4e0d534089dd7b04fa634804567586c62be0391c7bdb0a9fbc1ef3b33211edbf8ef58c2b7a49d06667959d7e5d44671ee7357a10ba0cb1a445ae5d709ce255e92de715975af94b89d4a29c71f9d88c85b6cd11d8b335bf8f2c658e6dd7c3f6c80ad4d0e5a6c87dba7b5b8a8a47e72f4d1d3c743631df9adfcfa45cee0498d5a44a9f75c83b75b2a3c230ff0767d3888f941ee1b6624dd0e12d06ed1ab8bb135ffd379e9de3788be541aadb2d6a7cc601316f21eb9aaa922f56a8e3526c9bd1177fefc2fbe3e430b628eebd6661e3ba2d631c6a8422c241ecd969972412f74da6b1243bf0fbee8a84d52e40aee3f1e4fc831402c62f3576b22e8e3c3dc4e160bc3b6b9d2ce005853812eafc0a4e25ba712279b00ba3f9130ff36e3ef1971dde7508b2792fe64d475688fc6f3313aadb785302e6b7f9a84f2dbc2f3cf060ee08b463736f836dbb262d329684c208492d17d811221be02b65ee28e11b54692
+SIG: 8945069787c1c676a84a703cae1e0bacaeffd33e91bec3603e1f13fb170e31e6d7049eda2bf627180f456c3f7aabfcd36c49a8c04f8ae6929ec5ada07b657208
+
+TST: 933
+SK:  0705b336c89ca35ffdde0af0f906eacf623c56c3f76738168e76fcd5882df79e
+PK:  eaaaf2a15f44b634cef15a638b80207f61099a0796f5d43f3e9d048e6ae796c1
+MSG: 616fe15fccb3310f9ec7456447dadaf8e0a5fb269be169b0c3ea2cfdaaa55d37937fe75b78324ac278a65047e0ae4f327e97effcb7bed91d09da720b0a101be9e96d0ba85b1ff49d8d1df362d3454f0db6825596101c97e5dacad07ec492d30f2d0cb7e7de4e744bb6a6100b754da847411d09aace8d5d410758b83087db4b5e6297979a21fb65af390952c4f936260e72d7c78327b94aa6cd617278b0ce9e1bd3fbed93b69bc64985dde0e2c4357b502f055ee7b0a0388474dae02d6c1a731f87785d753aeb0d9cfdf85002df566fc2507de7ba6fd035bee17a2e808b4a7588c583375c82407a40ae9eebdf94df2fb8cabf17606c439ea70459b212aae4a3f530ecadc5e88e2548fa643c7ddf5063b2e10673e59d07fe906892b67eb58f9388a56b370452e9977755fc04dfbc77da6c05beddebf0365256b52c9aef8a82173b8c89fbd98cea36a8b896fe66d37ca79bec7fbfe958fe89f6765085b335dc770343e230caddfa2833daa662fe8208dd885a6fdf72e36ecf22bbbbcbe79d370650236940bc2e6d4ac74fe4d554c9bc232f07d2af6220d157bd2da6a6612a081b4c9904a2869b137ee3a0856f12b2eb8762db94ed0ba136f23e7fb4bd1fcdee10dd84e2cd3b0a49148ac74db466dbeef81e6a8ce0861102de9b1a3e1dcf5c6b0308a82e3ac7c2283c7cc2f34ffa145b9f74b79904b32b79e960b814aade63a0df0167dcd24ed90a8da7b934c772932f5a478fe2a72f945a13096ec37ce764b581eb89e5f6b2bd7eb88b85a89587774d458c58cd879457973d648ef771c5f1deb27a0cc5b29246ac2fa12d18ddc6b9f9ac9cf146c3f22b1e4499adeefbcd2249740e13a224e7b6b3ef15605e7e74e68d7b72642409b90c4ec161eb24c9b40ff9c7e6e5da98322aca52c46a8ddc190f1cab157c4c7619601a6b33df6a50da661bc75360dff69750d3457409cc0241c3e8c4b3e506d426af52b70231cd6c91260cc431e4ccfd496ca14ceaae1cda78721e16339d52682b6951f966c7da5c6e10d919ae66a9f52dec10867538d3df6d593a32db695a8d7745703516ea56f8c1c8f0ef53bdeb7f53c2d944f511940ccb90624922ac599f4619c3046207d605f6ff94de788d25342229dc8af92b5fdf0dd71df2b446cdf1d9a20524339ee1c31826287ef72781a7a35289f85a15ba57c7fd5d885bd0553ab40805f517e8f1b1b3c4fc6771e6f224bc031124b9c9aeb19c5a96bf1488e1e66c6e88809230c83a74155554a219ec379ae54a9fe79dbede3d576042a635d197f4d818c778755b8b45e513deac88f60425
+SIG: d4a9bae8ecc472c376bab805c2ce0c1c2ed5fc773715468cb1a4934564dacecf438b1dd2ac1b5c5e336a1e20701d5dcf3c8ee3ad223b139fa90a1b552e1b7707
+
+TST: 934
+SK:  95174a0915684cdbb619b055495b00f19282cffc3b05019e6ab709a4a1742bab
+PK:  aa8c872d7e10b67f7ff24172c3637e80825a0a71ee0c48863a2acdcbe8da459a
+MSG: 5e1a7400456cad4f9ba86643bc7cbf3b3568dcb522b37055e8c39d3c80f2284238e5727fd7513cc8b31c57ae7b4050aa819fc2360930eb0dd677a5b2c729feb2da3ad79ae7fccdddb6c08446261ec9bbe59c64e99abbc86d3c4835f00fefe527433a501a3b6d572cf5e12a88010b46a472b9bd8691a407c365f9f71634b4d97edfdff06314c0c1b4eb93c7607f1d6fa354659322c284073f42602518c54fdf26ea2c27c80a6dfa20568391ab357282c06b23bedc1df1264b611c1e9cf18aebe249fd8617c6e3ee98c53c0f6f2175c57ef8e206bd3cf105627a9892eb689920213aaeb63d87663dbfa53f0fb281626948296b2dbcdde1c51af862eecf1cfe8a46a2c4b28cfe7130330ad173f87127aacaff43c0bddea48b0038976e662c04b6b04ad03de12462c2765db535049520cc114afdb6c92549b0546a9027d449755beb8d4c17e6a2a475f9676a337b4e866d96325e389a52c16c51e18e0d8103340c8417b2c57a55d042ff5e5fc65df423e0092b0ea88b96a907c95121c547a68061f27bcfb58ce6c07728d4846bdcbf0c625410edf8dea8cb4c9d0bbeefcde19273365f48d75aec07d1c22ccd23068a97c3fe752e87a30118fe2dfd5218b6b125154e0ea386cf239e3137f8ca6d8b746b6a67d508cf8c1ab63e5715e6721eda5c2bc393a493dbd2f9a1fa926b9a59e45a180aeeb02599a8cdd686f889b4852723cb6dbfb5014cab5f658a309a472239360eeaf64fc8203a3c708970e15cbcf136255d96446c39a927031d267d69ecd51d7af6e91fb4aef9d78c3335e9071133cfb8e2129990c64637c7adf1daef2dc26c1163399f3fe1e792338092ef6f8dfaf25730dd2fe8d978f6f770f52b68238176564cee5fbb9850b3b3a04d948460417826eb2eb24fcc5fe35334bb9521e87bc4dbde2ac9e1c98949dc2d29ad279e3884b905268ebd0808bf418257e75e262b4d01b024a6e9aa7bd501dba94ff506394b4b0ae6081ea73030c43a6a91766e80f9f42c0b68b98419ad4eee4e9a728adefbd79e831f70f41e62b43f0bf42b3b2cd53b5589117664bcebc409a7645b1eedda482f6b6895a657ba789b89e502d6998751d6303ded5fa156ee7c7eafe54626d1032c4d7dff977f1dcc86af89b1e646a4afc2427ed02c0af5d32890f95f13f98c1a5b1d9fbb781a9a89b2d790c1465c2d1520926fdf28c17d9ba1587ad761f065d339bdbe38f4133f45bb5978742642f90c065ee4892573f6059f8b4ce2c13e73b891cd05f23731ed9a07e2b8ffdc963b06a510209c329980949f40d8073a013ef843dfcc4a3394
+SIG: 780f40c20fea3b11c9422a43b9a6f79611e7f1f59d1488c15a5fd2d32c07dadc391c38953edf0de48be52da2af335c47b8d2e44ab9d3dfb76ba538b066495208
+
+TST: 935
+SK:  5a84af28a5dfbb3233a12f0837f6e8654e7b0de16b02ab3cd17864431e274667
+PK:  80d4ba789f8a4b2047adafa5ed26cd8c546733292e8bf693cfd17e284efc6871
+MSG: 8aacd1b8a39bf08fd5c918446be576e6a3f27f36111607f27b56a91214e763f9a87fb1d1844898961797644460bff5488c103af605e8740e46588fb93e443c3bb23b92c09870a557653a1f22c218ccbc2f073a272d17a84223ef143f4c7ca258460b798169673da107d71d5356ce9f7559a9b038399951f575c77e5b9d0529578ecaa2e2089266fc526c5d409fbd46bb86841cb554f5bd3c99713b043e404653a7d01344d4db831a217282c4b336405653b85d27a46b259c855cdd85ad6f7aedd835ff5500cc8baf0fb2f0180910c64672b8a8d49d984a78293cf5779c910c3acbbca455a85466e535044f3480262c090fbf4e0b0db4d1ef8759daafdd8d05907482461ff910c437195d5c7fed9d82cb94e7e4ec24da053e47f62b488eb7b244655c7dbb20ed607eed4531449e0780e61cfd574086ffc5dc524283775c44f7547cdab04a51eee4e1b7b65a57573a92484a35900a909f81e415029d22ca937a3acd9e61f8c0e686b2d2ad0377af8ee166e4a20a82aff451e151103e0a1767b271fa9c2b1dd120f805853b3b8a560fc8b9376283b51124324a284a0e9ac49df69f524c8e042df82efbcd16881ec131a15210df73de02943447f22a2ea1dc8bf968298ee97f3ad546d78bc660897e08d2a28b2ba68b54b954f1476451c69207e5dd248ae47ef35694990e6f058bc0017b7495105cc8739066afb11e1f26601942546ae849ff2f56730f1326bbeea640ee178fa247adffefc046494fc7ffc0777d5dbe8a55daee61406fe3c7088d43d9e14da21ca52fd8c160091c8f99a67dad65c64fea9d18b1537d061f5dce879e0bc42648d2eaa02d972185753cb2f6225d8d03bb07f944b10cf4ea22275c3d70848020f30c823b76143acf545999a2cc4b5898d94b4a25efbe5a60331cc009fec0a25bc98947b1b7139e22d23280ff8854a1ec76221b1bf3d108328c8ac463c65263a2d7ca7433482931a1d8fc144bbe9bef678c92e1c2d10921b6ad43a75c53bc075854ed2d99d825f30a5e10d517438e4d4f7113429f1edb387d6bd7aad29274f8d2dc889b7efbeb58686f8d669ceaef92c75ed5307f0c03f5900181ce573c8fa28675205fb1057f626aa230d03e2eaa8cffcde20081475d80b245a1ca6045ba204ab00069079c637fc3fb3e80ca0462e7a4cdd9283ff9008530364816792fdf3b9a4e4dc8379228edcbb154bef387d37760d79afbb736260a1db10138361f24b826dbcd5f0fc9e7830d26d80c52a792189276bce34760fb77be1312ac8cf97d92cbf3d0778028db5e8eae89e0b9bc8778aeb1278f0471cb
+SIG: a0b84ca5af7646e6f62a6935379473fa6e4c27695851fcbdae2917b2dc68d796e278d70cd67fcedf6ca629b881f7c4f2aa2559b20d670611766bd65aa4fef204
+
+TST: 936
+SK:  793ac88d7d3b6fa7f47deec31f68ddccb701820f1b13ddc652f7c6a85b6052a5
+PK:  91b6227acdd183da62c51965c635358b204d683ee06443cbd40e71c1f76ad102
+MSG: ec50afad8ade7405e2c6f5c6247bbbccfb2c17166f7884feae10d90f5d83c4b6f0bf76de2f7897ba1194d6d3449ddb80ae74eb8ed68f049b35c6f21916db4dfc2724dc3af7ad8dd5c44f60d2f49fadd7004da1593093942cae5208bf54cf903bee646905fce2eb2e370d0dca48d820adeab16a3b675e5a4a8e267e34ff96f3122b18de0cad9292ab63d26e5f310fa2168c2966bdb63b0de08626767b379de4633b9f3eda7917281dad661e9f772b844a79e800fd842702446e4aa731757107f3fd6547bf4075963d5fd5f58e80853fc42751dca078a9fa8d5bb3d9a34abcab0293d6ceaec48967a1e6224398cad0f605a3be8e6758ea8f29209d8e4c4ca1893baad91e379ba3b17330c12a5b6f219b384a8ab978bf1b37c3731a1b474b24b5d67d4cec28aac6510b11f2cf21bc16963d51f5538727718fc4e2e5172e3c0cdabc277f0d7037c34ca68f73288848b926bde0cf47abfa66600916946f07651c280a2086b14d52570cc8a4b74358b59c302b9d00e1b498f3bc33ee4ecf2bce2c65ed7e8ba74d35b751d3c99f40861968c2b7f3a5be348c57d93b40ffd051edd7caca6ee6bca721dcba8db8d0064f54d36ec5e8d62a71fd1c90f14924f41c163f007afc6fbbfe8645fa47c3c980246d1b92274385953c5341cd64c34ae9717cc2c37f58359c0a9991c23fe637de6cdf0862f7d0329fe758aa892ad4583b9df2f3337d5be570ba654998ed292f11f01772382a04342fdd99e69e0d97c43f10ac9b96f140a6f83c4729e7a900471f2b1df2401bc5c680422b13b0c8007d63681f66a0595a1c5d3acde5b779426e736bc100c5e6f52608dc391e3ef9b1bb6af13d249b7d32ce0680c368f54d5fe039cfe10130251e4db14c79c8d044060465822990d88093cd736532852e447889db89cc60052996a32a64365c0726051c119eda901de576b334fc7049482392e2620b0a3a13fab1d36fc0a5f23db147fd857b26a698048f8b811e23d722e2e9027ed4124b48dc5e578a7aeb19a1b4f948ee5b46f65b979646e2be074714118baa4bfc15b089a0e06627da46e4bb06aa3c7c5dd648e03c9c2dec3facd95626562f3000883230d2b0a1f8a7478cb77f939a5f188f458d1037b90176664d86ea850b8af5087f86605a77e025ef6c7e6a2a59f006cba189fad933f42c532708109bc1af814819595ffcb95fbf5b7e93a71197e477ee7c04b851c1c36622cdd8e6c860d9ab2cac56d2dc98fa69124f2bb2a6471e1c73b661f071f5d86de7d1deafa4edcdc7bf1f705c56300affd058b9697791419e5fb2a5b7f78ce3401ff550
+SIG: a84f552bf44322a6db245ca006d1cf780c61680fe7429a8947c35f21bc4b44228ba30aea0c744b866459d3b8acad453b06ace247ba69528c6b3bc4b20e75630e
+
+TST: 937
+SK:  89de7442d74ba9385969c9651a88fe28e040d593907dac1a3987418bdfdbad89
+PK:  fd3ba9fad320eba45d07b84a497be17d3fc7dd9999c968883cd6ac13b0669b17
+MSG: 9d5272f0b784882b94c76dfb9d460ca495025e0aec5d52ccfffece9f8173c10558266c498525891a97bf3878e33c3de2fc2e52550b431562cbe4a3d011ecc9e77ec36ad38341358c88321c03d08bb426a7d5854171c027ec48d57819a91afd02a618ccbc25e68e5309d047b156e35705373ada2eb831321a203e1bd8f0efecc09618647b41dff22b39d02235f871532f6085e9cc52ec009b33eebcdc267d7767c90c927e154f72f3f48a34956319b293c8a8b3e34efc5f62f2b4e8019b50a08f5ccf95bc831baf40811d87e5edbd2fd5365b26a431ae95800ff381cd62ca40e1866d950dce14f030918abac68e7916ddb95adc1971287874d07eb0edef64296652c48044b0c5521a8d270d53d74ec63b890f3363f9207f6652ae8e7835c3820ad6d9e3633f4bfd5379a44f29d65f3609fe355817dca5518dfe3bd769320a031902e9cf6669c24f88b01eb36995bdb8dbed6ee0c9b7f32295c61ba8905e5598f3c9e1c8bf7264f98293faea17747f88440c31818c433ea3d23c01f4f7e9c3dd3d5f32ec9eacd71a09e3a997381f1cbffdf4b5ba4979deb7b09841afa3b03d1c9311097b862cae11707cbd3a4ae6c8a26a306a687c414a4ea1e812f115f60f70bda7f8fbe7bc2d50cc550bba291d5ec523229a08ed568b5cee18fe6f46782c17cd828801639215bc5e9be4555c9a18009767a6c5c74a8229d2ffaa399d8e64324e884223d5070f735a75d85ff6c94a9fbc2b3651386de5a23cce95c87881c79399ae71f090737e2187fe904aab1d92d6186795c9b46c62a5914f3630fdcbac3bd4b0da4ec3136a1fb2ba40322d7cc4085e167009cf7450fc6a286c2f7951d51aae23b8f33020efb5e3245ba6a3543a2bdec447d51ae00b5e1678b76093cf216b9507c963ebfc024ccd6ef6c78c4572273beaaf55076dc44a224b58615705791965307cefd48672c081bccfbc1d15b062b38b4fba9b9bec956cd14444ee437e7960cc601eddc02f1a76b68574d5f8843150c0b9009934a2bfaf605770c136ba29f3dc7e29597a2480db23e2b2677ec6c51bd301f2b5a39dfda7b477bedd1cdaed10e29d2954629b9876f8ee54e4047369d534cab54aea441dc947eb3f59382b218360572f2659583153c0e2b912cf30c815b26f05853dd30551eecf64b858a441bb8c6db8a9fde77a32a7b46af66f8cb9f35ee0fafb0bd42d9e65b2a9058241a31b8ca1115434237670aab4eff36010ed0371f46595da1bdd579bbb67aadb68e77ad3a38c8f26d2af5a7103ba5f22b42cc12a8c3ce5c921c91cfc0e63df9027d26229b1047cbc18f6b0
+SIG: bab57284d20ee54cc7f9708d717706d8faf6e46332b0691d6f213a8db801155b4e338c1361b592be758501b1821793ae5227cc3ba8df8adfc6ed9acab54cc401
+
+TST: 938
+SK:  2622bd9bbef7ff4a87629ea0153dc4d608c31fa5847988ff500d880681f11372
+PK:  199758a9c3d0ee3eebcbbda3e1ef5455ff46d736bb4ef0c06a739f9ac5848395
+MSG: 891e82122547d61e83b0abaf27c7303f0522a2ec4af44ef0ac196a9978b1c623ef1fa72baf70910a5c51c4f78e0fe9fe37e2439c4795916cfa22ab471a2557cc7ba6b66956063ddeb39c50f14f06348fa66b6064dcffca5043967f05254d577abf22ae8c90000ce2e6a1a8b2e3a6b3abc563ebffb20445f0911cc42a987f8456efba4130e68f01fcdf7bf771fc1d35371a0d75dd5f90002c90b6cbade40d5b23fdb49abacb7219ae27561aa2a879da88df34a8c581f0c67198ffc608fe9195b5555c8ae934c830aae2885bea87487448e11b4f2f172e4d5cfe4fd113f9d2016c24a734512bb918f575e754139718e3d20e790abb942cba3ec8b2db590796dc435f139fc64ddc85a22494ef2bfa1f5c0f1875ea58e84eb374ecf8cec6468b6b09d1e74f1541ed454a2807d3f4053566b0e4e2c6aeced10dc007e9df416f267fcb3fe17b8bace03f0743e0e6d4a48ce76edff60c0e3a308456995413c1076ff37ecf2381a0d4e9e4a913a258d983b9696b5c45af37c8684070e400b8f865a504043f45d78b9713f335aa416a46166410735fb5d82210458d5a08a104d4002ab61188f9df457dd7ed5937ca5077606b418bbc8684a1d525bfa551087640b1d177ca6d4f6471b39b2ce43afbf8285ecd687e438f4425df568ab86fa2316349a1102b4143d71ef4e24f5c530c77afb0100788636440e740675a6174c5f05710b253a411173f9e82ce6e22f4095e7714b8737e147aa0f23191578ffd93823ce4bf91c1d110982a5da0e4b81bd25b9b9c2142a7671ee937c90fd0715ec9afa44d86046898b42f753589d2268d2aaaa985cc90e0f9e827a3923e7716346f4f8931c72821b3eb645daa7452c8afc898d7975545c12da1bdb209045cb00f4bfd5383df01f003680b973440f1a39c9d820959ef6f85bd33639065aefdc8bcfecbd9b9554049738af29f1294639d3915d632995e8faf713ef2ee3c298b5596fa10c99f946ddb32340695df1c194594eaf3778d73c8ba6040c04eb3a4ff8677936b88e0c5f0441480d107d7ac2202b3b694e57ccca6d825e2a07e812ed29b2c20d5c605471579e3edffc223f242c59391db41e98d5f3d6c5b1e32ac8237fcfd1020543a4041e03d92ad3e2ec552914707c77cd01f3e48011444283f0968fa4deeee55c456ed1f877ade04ac8e8d2cb6c85820b4929b25bf31e925435d6bcc50d3e2e9b85102e970d7895c25ade52161a3b6bf501ab01961cb63ed990aeb93eda3828bf04ca52853c7b6b8e9e49e349d69b53be07485f542b7cdd06b527d41dd119c70b564f1a93aec62ae74e6e8f855
+SIG: 4378966b7831def4aecb4989bcaf9cae99461cb9b59d19518cc1ec7b8351bcd1f723aac5f061b38363574ff96ba10e196b1b0531e1183036a425e69c4598040c
+
+TST: 939
+SK:  aeb13ccb90c8cbef90d553da3f6901b3d75c13011f024974daf79a1789c8c632
+PK:  5faafeb595f16d338f1c72a9f3e498f38bab69a81b37d2d092b7bf7e505d820d
+MSG: 861a1018d6bdc4805a5c4df87efaa462c68b4bf4065c684c2af131c6377388baee58c6c8f8842362ec6e3bce07c8af55885e82db87a15227800dd33afc5e5fd15701e95f53501b1a6ff83c64e8517149bf3ff011b094a09c673d0fc4a39ee55e69f071177b8aa364e1e256064cf70279cc76695ae49dafcd80ca0a14e1691db946422ec75ab4f7865915a69bd48d89b12adf487d4db9be87cddca211aa88e9bbe849da213989eb0844592ad63e281b2e4afe6a8836006609926c0f787e84f2a95b46b66f0e4555c9483ce2176fc63f7cc9f4f2a22db055aae2e68b30a0da5feb80c2a60ea10dbf67fbbcdbe0be33f2e9c13c469e7768f2ff5960a55eb482ec11d47e154b7c42a5fb756c8ad539b33d125a4a65192c6c9bd576238ca72a73cd179e8cf5cd048ed330213823abbafc3682b2b7f68c5bc46fd09a8cb2a3fd099573ee2e6f28c82e271bb5ef934b0b0c381cfaaec666d717106a874af30aa74125eae9acc2f1f24118cb4e683a731e37e5e464a1ea3d2a53cc0dcad4c17cea9a43e2365f3ae3dd89eb39977420045550745fc267fc7dcc5602e914972a4da6ebeb687f68a0cd7d8b4fdd73722106a8e436b93e5b58f5982acecdecfdb382fe98538261426ba64052557643ce9fec71ea43cf5b6cbadeb4953193ff3ed1a1f922a9af2ec6f338e7fb0affe3d13c33e395873e4a7a7fb044981e05a67197b996b199b43011119363e561d5b8a51784fdff58ab80ed4c49e93f0cf41924f9835efb09f64463b65517b67b15dc3f28ad9a9b2d29468de2c63e62004b6a3fd0c5c2e2aaa6cfa15e4faafa1e2c713e98d3fd25cab9e5170359c8365152b474276ed0037cdf771828e2fb7ccec4895f21adcc5b6887c86e51ad05f255f6e9dad2c41f56b98b7bbbf9fcb6ba8cadfd38ad8c62f92dd87740fa1e1bd170c00b2049c5130fe733f16b1f2c7f00b2ef97b3a95458c53f199d465336d5ff5977806e1afde3eaa246d85cabf7e123481e23929976ed19c40e29ff33d80e7deab19271decd5ee06172b0b0a139bd62a2e7c83a8a65601d0a05d61af9c6032df58001d473e20dd6c6afd78ddbd7cd178e9c271e0572f85982823ce6c402930cf80f5e0c7cda85122a76d1ce021b1e3de2556d1b45ac7b01b59cada25291d638a52a5e7dbcddf96bb1774ab0b077e4b3da5a958fe11dee4a02e69b918ddbfa1c5b3b7dca9f8784bb6b0b9d5a7fee74bb03747f61c2b2f1b492452d3b560b48d39d8721e983752556d44da6b028d9aef8bff9aa379c8e2b0a636d748860abd8e64fc8e96520a34a27f767aa97a8f77b6095218ead
+SIG: 0611b19a7472a443e87e54d7c6647faab1b79a83fd4371c92b975400fd628acfc32577ccbbaf03d88f893c88f2cac784c722a08f387abc319a702c868479650b
+
+TST: 940
+SK:  73872b14762f68dae4fc10dfd6f42d3f9622bf2afe6b34a95649aa387424ee6c
+PK:  dfab2ce1ab9981aa7cbf3207350007fa6ce6ca60a2ed7b590f3c2f62922d8f61
+MSG: 433d71781ceab2b47d826e67d39f9b80d2ffd725f8c5aeb40cbe4f9b5f48ef93521ccec604360b9647323190bfef75ac931562d27f4a4e31f46e57bc99fa5158c82e12b737e45c5de9f7dd7c8622d4a7eaadf7202fb49d819c9ad24f8807313c5f37dc20453bdf05c9bf1a3c2117c93e7f3cc8a2542098e8fc1c642fa47b05543657b85f480bc86ec42800bb1422359c7c3e8ff4be598bd54f1dc586acae45a4740622b962742bc86e17cfa63e775354e7707e5079589e8d108b1f11dace0575cb9a6d26b59fce981465d9bc344ea6945a95b862796384fa8170560857457beff95a9b5ac3d6ad282d44929a303026b4bbedd60e2ef055a31f52d7ce8df2ca5d1851c5b167db0809259bb812569074105c734c85d6231273755f3a8b56dc508db5c23dacb7a06167bda51bc01350f016cd41b21e8cc5bc93343a9bb6ea4738c5c84b78fa963c410e433dc598196c22e5b791e12a4b343f7cd47bbb0eb0782bdb1a4e466846a030528eeb89056f73257193adaabc1b229862034878c3258a532548762e29ecc001abd989649da5e144cf35d48699f23bc46c5b34e04a53e72724b2b0b878982575d688e23cbe3a34067f4971e555972ec2908ae5f03e8831ec67755be95687ce6372939e1e2fb6951ec9ecf4bf7d1535431e259f29ad431222b54b65aa7d07cfb5df162a87c4d03481eb441f221d7f58627a14164e7f4c2e3a1d507e899d5358e00829b08cf3aecb8a75b2a31c3185a580e12b13f0642869fffb056723e961aaf6fefe67b4a7c4c93db3fe1f61adcc765569a99c09a3c824ed4a98babeae43efb1f351ba130e22aa97811986be923cc4180a7c4b78bcc140cec15574654aa6d65a06b97ecfa5f3a9355f96e4eeaa7689217b663fba4dab0d99b19c8d8dbf47a157e5d5969a35ef84dff9562edd434e73aee7d0d892dda72a362a22a7e9fa8634a57eebd1a907485ca8921bdc19ee9ee588f395687d3fc8f8c25f2e9576ca60313fbb2c265a99f2cdd5575b1dd530604e9ad6695c9fb35994a8b87d5c8570549a4d329b9fe087069ab7eb0d714a94e19261f86e448f2da9b1cb0c0dbe41d44c3a824783d1bdbd7326051aeb10adab805c5c59d0e83b1c11a2fdd35e444a499ed15dafd83862775f6cdfc67595818407be55ecbf7bf86c73069aace577626a8563536f605042cf7caaf6fc8e3b545b77414df8d9f649b99ee42541da38c3aae627207845b8f414a8074d70868a5c0b07b070c3c653be04076b83cad7b0305d9500aa44455cb860dcc76400af93c3d2efb42ae056f1428b65f122e1c7b9584d814d50ac72efdb
+SIG: 8525c346ca3a6a6c5f65c41778599377659870cb6df9a4a0e55b40c35beba55c8e009e5600b6447dc7402ba27749297e8f9528691856f72d2ad761ed1bc15309
+
+TST: 941
+SK:  67cf27155287be6bfab66215e017c3466322f21e6eb140be4f1bdecf55abfdc1
+PK:  d070aab295a8af935727c3be442b251db9e774d2f44b3c2424c52fc89656e169
+MSG: 0ff05297031c892774cb2c01e8ca60ddd0ceacc0b8d591a891e33b19e1be9e363bc6420d6f529f04840b3b08853c835a03e036978b04a4f9ec6be4aef331956190996dea272619f1686d33bef03dbc085a923a0f115b78f653feeb60bb9e45f34fb8be5a4cbb648c7d29956f0d0e96bdd3c8d0649720624cbc2079e84fd6d010241124098459f12af2991d3828770f50b104ea6e5f51fdad30a9b8079d2159e46d64af91d07c10ed19814df2afe660d7d8f2403534e92c62e1ea6d688203bca3d97c2afda83b255520ffe92a33625772513b1fe34fafe32b6a9b8cf994df7e634e686591e5f0073ababc64a89210ba53a4991c11557e0334e6c6a5036c642a318f2295117139085fb34075647006758e32bc00ad109fe803f7ee9f5ec2af4d25c3070abc51cf4d78e13a7ce283d4fb4eb41d3e8ce90238500ae0ceda320ec5922efa10b903748e1e853a3729d24c105439df2f7000123db9b2c01533bbf0d028ebb2fc00dce38ad06328ee9ecd849a6efc3ae884ef6933cfebed055bb2968a0b0676b5729216178c7519ef0788593fc0dcff50d7e0b1ebb3cf49bbd1bfa5c30ea7b88c36e1a1593aef0bb3f9e2091c8589f7414beed8df466a2ed87b2cb5f35f1d31246ceb968609253615d78043517379ee6974a669cb48da6ac2f96d700b7e44a435cfefec402a1e3110e76981924f2601c01dc03546fd4f511649302f0633dfbd25651c5a599c90954489c76a65ec05a7e4cc74616ce25601cc37b804e1f0bcc8651023b12e13568441e8b8ef4c305fcdad3d2b13fa080324b2fd6b61998cf864b658bc7fefcc48a5a7681d7c866c342c7f5d6cf10881522cc710257d25a4c1e352d270e902082ab9541d5900ceffa0914b16b55e0dd3786e98d41720875a148eb4abdb0153856679fb98c0ec485e5f458d635b7861a2b3a8ba5ec2c1444d353980200e5e071808854a268cc76c605c94f37329c36187a41fddf92aabdb4996a0e10b315526afeac80eb2fa32af786a34316b36111ee9352108144d70f7d1723b32f4dbaa82201353411d657713e55e35df78580b1bc08680f0159fa116faf463566aafe8aea69857e72e44ac809ac43f5c45939d85a1a5f4a370a18996c8514a46f34371ef9e5fb204422c934a1d293d101b8c16f99cc073ea366a13a45c437d620d132b74409cbf8b9c075b4163f726aa67e509a24874fc1b1fb6fb7c7355159c02aa13e64badf150356b1841b321f8041e13ed77e8461cfbb8e828488bf517a5d29ff82e7367480a8edddeb5350e7a83423bd0b1c55f7bb424ca04c205723cd5405671e733f391600a
+SIG: c934a3a1aaab78d9269d1e9d13392f72c637bc5de54f04691efc29d473b475025d8d8fe3c523d2d29c41c5f3dec6ca38ce6d68d7ff09b6135ba24d0d32cc1502
+
+TST: 942
+SK:  18c21c0d0de13d4c64497ef0260d66cfd34216981a1b49391ae5cb0e41436e9f
+PK:  f7d4dd1e059c36f6d121c0affeb21f0c572b45992f84948b09aafbcd86bb535c
+MSG: 68abca7c166afe063e477b80e37db224e1a235de8fcdeb7f427af67e001247cc5e057182fd9b6db8babaa658cf3b3fe4b0763bf88d67311b1190be834018cf57a332922413764620ace05445ee019a06dff98b238979ad6d30901befa3c64f6bd8c6eb092c2e62841388fd8c4e8419e2778984896737ed90a2cdb21996aef7c21638d6cbe680322d08996597a9e303f6f5f47940f8c5ba5f5f76383e7e18064a3d2dff5fdf95e90c5eb30f4d8d459ee1d506a8cd29cdc69b6754963b84d67494b35305d10d12b9487417b2ce28adcb10b65cc931fb3381ae02e7af79a02bf99e258a56361090e0b71222b3ac60bf2fb7ba832d034f5b6bc6fa663ae741f76d97c1ac32bcb7411507d518d2f6054b578328c5f67f758ac01bfe6f4d35900f50a5dcd30d2f9261b6bbec4c1d1fc18d2a7e70c4d36c21faf8cf94a587c3a0d1a9cde7831ae626775468ddcd40a8ba18f42b34188de5741e1be8307b1084586515ec015e4e371d29443a40b0c069c641d8cee5e4611862987c3e356b1293b0518b4a4c8ea97fc5a4db1f0129abee72fb8092ea35c2dab67573850207b8e82718999ad99c4c839eac14636bd5e4d8436a270dd90b8e321302e52a92d891ff1891542ae2caa0d66e0f661eae37b25b08bb2e0eeec4838009778cd525984380983b2baadd7102a1e356734e41d76183829ea9ab8244c336597ca2d67988f281438467e453f562c67b22d0a4dd9fcb46a5f80d299db5f01f59160a19d74c644fa5a940e32c9d8d983bab7efb0d7c7da4e3fda1cd0d18a4558eb9fe46408aab5085912bf2f46ab63a9354f9027c93691223ffaab8463bac4c4bc3b11abc46ba68717c91780d3f30470dbdd88b3780a194c8a40a2c0a81a4d56dec2d8962c34d2ab73369028e1bfeaa6bb58241ff4f898f80ad3bb1c691b8647f2c6983954c1c77957458eebf1c5055c31693abced05384735a4f741968bd6ac31565cfee71c884c1e29e9e7ae0f7ecd04d463b1dc389c36037e81458dcec61d0764032dd589b92afda2fc9028f41ab53cca2d04ec6a9565955cbcf1a3463989c7139bb902a5921e8b2c99c48e13711f0bcc399259516c81ae942a679d4ba33979eb12fcd2860602e4724b1330f1cd257b5b2891daee8ef4c92fc3bfdb34e532d5870f3805986ac97b503fd85873548e30950000f8a70be51fa757603501f2d30e852efeac4826862aed7f6d20c9a8c8dbe362dfee41893f27e6fd5e91d0e7e3d4fd8155f44fd8ef17af14a848d44a87631aeee751462b2a54087068daeab3ea3289ece6212b3b52ce7a8886df2a727b72a570c2fb9c50341
+SIG: c9c099e21d095afadd4e71c9abf6b7083324776225b587b60a0e6092ecb3d33cff39c67d34776ae99dda754a3c2b3f781135a38c78ed6455aaf0ae0c313b6205
+
+TST: 943
+SK:  db9aaee198cd26a52b1181fa3fd92abe425e666d890bf969467dd2ce280ed4a7
+PK:  3c897cafe2b499ecb2e1dd01ea55f3fc88f68c25b64a636b31a1fd1c78f37f3f
+MSG: 47fb621561f8b7eecec6033f2bcb6f43ac68c958dfd2656f52a0c29b4acd44f4304c6bf77eeaa0c5f6d3b22db19699c3dcdede698abde623ec4b2b90910c80ac3af39c550b6dd409e63d77706655a9199cb5c0258f5ba38285ffdc64b8a8f373d1fb29ba87f84ddf5f34d8f140bbc17b3961682df5d0a8f9102e379a9998139dfe40ab8ce753bf5626108237771a7d8e109e9e0afe9b66d0420942e163a4f3c03f71813ee078bd090ac3d0772e2622c259e682552c75b08dd055a4a5eb5e609440bcd3f3a6feb876fd16921520c6cb6884710d2e15cdad6daaeed95962dda21c6788f784917917982e1ccbb5fdd9bdc1769db6b6db57ca354e01a1339d8e77e9dbbb5812fbab6a14c54085c0659599f150e22472470f1e5e672c425f375f9e0d6e8d52fa17b7a8d7a4d7ca3e12f4db53836aed2bebd74589baca8ce9100291bfb7e456db7f2f0a84dc0a7488851366a9a5fea0e3efc74b9cdd4bd97b65abf361393ce1703d8571805ee68a13d3654f03dcecfb77a53430d09496ad73ec01759957e51046aa7396f592338650117ac7b4dd3573eb53d9c9f9dfa62e2369c77af9c0d42f61bae74b287ddfa27b7f1c1be9883a044691d56dc13734ad4ee3a32a9f40e328c500d0fed8ea0510e938f2758004022bcaa6902bda1014b8ae3365272829ed94faba63cb14a36cf81390eca83fc1c627172013261b3993779aa076a5c5d81d90d27062e1a6d90b5cf1005c701917b7adac180cb75bbce0f27f2f180e2cb90140c14cc6009d2d41aab1db9418f91d4cf394002cd70ac9dc11ce865347fa3f56f87c149e2b17d2c72b663a58e3187bb19b9bac2d11483ba12f770ac04dc46d388518fa54dc152e9a9dfbff14f14c61cb375897e30c53e6de42d5e1401dae1b22baaa0e8a41c6af9d0e0b13a91a23d9b7d5552047029a3521946c7120d3d258b3aefcf754d1959487a1fe7743ac7e1cc89e368b197809c3a27317e0ec48d546db1e21eb629a29bc6247cdd4a1371437563edd12faea2c5cb77eededbfc58008fad1f65af35843fa274c734e3fbbaa9cc50d683748b75a485f94d630b032a5f1067d1deb30e9d2218c935c981d01c0c547fd68413136edf4c0c770286e823442e1c513651929213c121c1de700989141ab4af3b3fe7404b4d2a38c530bafb498e64953ce1c0fb7d340e21135bf8afdd8dd65b1b18cf1c8fb9f402b2670400b86ddafb184cc51d5fda273b80c26521f912f3583b4ae301dae151cb55c75703aadef032415227d53e395db6c150a1ee839ad26bae552e1ab736214dc04b0f3c41b7cfbd049681bc84c3d16530768
+SIG: b2e3d9c5d0ff329996bc89d26fb3ac126bded313cbf8df86718638c199e057273d09eb163c6c181fd8bce51f72d4d9d2e84abbe08330773b9fcc2166f140d60e
+
+TST: 944
+SK:  a804c33b4d38cb3ce31cf3bac1049e0d4ec63a1a0b7b59fd8a36ee37541656aa
+PK:  6072256d6574a293bd7c221c551c32cf2f7715e19e433a49d9b8b0490e56ef62
+MSG: dbfe307f2aae9e07ec7c4b682106d2c9367b0c4aaa58ae804e0a3904754e6cf8fee73cf9e2d45d0289e5078293dfc469d46ea67026c5aa692d2f2c9fb4ec57cdab4c043ff9ae6185f27a704454e5f53950aabd25c9910474d45af8836862723e0e6a27823d82bcbb68a96052422a1819512e3b43408cf48957ad6ae235b7233df18284749153dfa57de35074a30edfab8a56df28ab2e2940306c221aa55490cc664e14683f30ee615e2d93fdf971f596663465843b3add6392ba3390311ef8dc59f251445d669e10a0061991e113561923aa215244463d8264199ac588924e231e8419d8685f338e599b5f40bf9bd1aece772535bbbcb8f6881c2e800491ab3b57b44b8ae43aeb5c4ae5e7edeb228fedc9f6b9cadea176e134936ded60af1c228734fb00570f2374bbbfa1bb170785805d6b6c701e820952eae45b8c2366113a1dfb2e35852af419b754f9cf7a081c3dde6c8053bf1ce0c85339d5699c422476fc21f26ce75d2a7fed09fc0f4175789847d876c51aa4e0bf7ce842b8308dc7a28c8239520714dc233136e09f557c7ef3e0f83bad63cb28ac616d3928f3837dce1dd58acb8ddbc72e822deee45f00776acc88e00cd3a9db486d92d535a57a0fdc4f903b62e517221c308cba2e30ffe7b91937a99417721f56fe6df44840e9e41136929c0ca3dc28ddf2379e4dcfde83723e2d4c9e23299c056afb31d3e70d085d0a312c5cd570b699dea8717458531348c96f6eb52d7ee61d5660f65e909a14ce1033dc853f2f25d09cf4e40d07eff72e15a390564a2be3c042d89a68660a97ffacec4967a4b618712d7060756520c29ee8d9220ad8615c4fcf3969bd3b2e0947e1f0be7e2d80e0a61480c3166db5582218bb0a8be9848efd41b6ce0cd795c486abb67210beb60cd078b46aeb7f4f485031902bcd7131e00b7035aa2d43fee063f7f30bd570da1dbb65c0ca92a4812632e432778553e35e856caa8218221fd6316ab0869173b38409bcefe6d2db9210f9024173b66dbb92677cbc71c8a1cd583fa6f354d3c93fa8b16c71374f25a00c332f85a8befd540388fb50db9f5d96e4e4e698833ce3d63c10b8eec70a243b9015db459431b62f5668bba60f0704f6bdfe9546ea475cef2ebccba4b7680848e82beff5854e49f65bb773a4922e90f9b8afc7cf818730588ed5aa7b399826aadd54372fcb761458b64de66857f4adacd4c32900cb77136a535d7bbbb554597aecf39ff698b45e6a218df1d2abe615eb8d9e1824c0becce90767899ebfd2c730144b32c74604c0e53e2505bb15d28007a87b9931d6eec0a6cb5b0f96d3194b2423
+SIG: b1b44a142a7c4c3d0bf4661edac5b767005726c14a2769b7c214fb58737ec2e4bc51c3a195d2ba1b74a54eff4c33a90f41ccdefa9e9365fde8dd859fd3978c0a
+
+TST: 945
+SK:  f820e6f24a8418b6acda165f29a360f767cdedde8f64d768b95fc2a5f3f404e7
+PK:  79c4b263b2e58f678628d4ea82b175aca230b9a20285c828f94e1ffd63d75b23
+MSG: ab6bd45bb06dfb9069118ff998f3bd393ea8e944979e89e049f2505cd8931b93086b7e9d8ee764e9b447ea4ea12138bb45275a21a19843f75dc5421d61ffd861838e5833825d67162f3259c26447be51dc1802ef5a04ba73b783935706abb42c513b65f2bbc44f83da1061242f2d5e5198f38c10717a86a3a197e7cd9034f636114499037277acb4722c06a91cb2f65e21eb8d22d36ad73b4265f7a7947e00e722bda67043cd1281bcd87e763fc97b54c8f86836cdbf08c9a1f700f4eaed9ea59a6fc1bc0df8c9ec1fc2977cad60f978abc0c8381aa9fb060e3f99378a51b2d9afbef358d55162a38922ebb87d2a3e0f0f4000b1c39b1502e95945e8ac9f4a3ea7c9ddb581a5ec06c00ba87a737084b384faba09c84871ddd67dc1bebb2f7fbd94a5597d019fe629e5bf12bea2e33ca84c680dc5a3989bbf3af9eeece8ab8fc861e3b8bfc1e67e2aee326b37fb9b51cfa0b5f5fc160069b450b704e0fab7fb6c5ab3c40b8f0b3d0930b9112d64b9dacab4dd875f29d8c58c5d2053ad9148ffde22d90bc0d50f5deca68d3ea25c5b4c7688871c0c77dbceeacbd0a4229f4970ec87b34499e278303c06694c30ac68524d11b172794b481273a5dac46122d2472095a563a435d185d5e91da726e74592999cdac688a33f38f7c035588f625dc6ac73d0047ab3d6d12f1ae33d8b62d6d6c6cacff0bdd894b57e318912ac0cf4a534762b2f6d263c935804423ed868cf8cfbb8be8f6d8a714a268a390edc2dd509d2dc96851d1bd43249bd0f69b0c4cb2ff4080d1fd5622bc238dda6e930025d8a2b12b972f9eba17421d4cea642f40ad9ea8547ae59498c3ad1b9a0c34ed8c01aae3bd21ac17743b577f9515cfbdde2704dc57e80f125323d55100b9f697927d431dfe73631b58e52aa6aeb0478bf459552438689fbeb9c60d87aae09954362cd02a2b0b479efd38f17821af39b21926ee02f7d972ad0f54ea6572cc3ebd020b1ee26882533bd19114323815f672ec8c90568730a58e4e1e35f6821219a32b8a6c52ced6f9573d9f3beb28513ba62fb201f7fd41bb10ca34bb1c70f2fd7bb9299a7c5f7f2e0fa1d1af0e9aef5ede7c16950e860ecd61f1842a1a22c9831c0c0d4eda840b088a54520c9b18c76eba9bebcd591381c180d7f86a0e58add92b9b0c8076a7cdcab60dea4c1afb18c8b94b1b392ccfb4dae2711e7d12d2bc7c7825f63992ec3247163c283b1075e32245f69cf47240aef0db43efae86fc1fd3bb99cf5b789f5bcba9504657d9e622a4aa16f01d4d844413124447d6d1a4423e7b55db7e6a31a319f4bacae430a33a9bdd4ef3680
+SIG: f9fd72f321ca2133bf8585908d9ca7b8e336227e3ffb3749a1fbe8c9b1e5d50ef01f9db5f0d2a7c7c1399b97c9044e1bc1adc32b8bea46dad7b8102646960303
+
+TST: 946
+SK:  0a056be039fd55dada441d037361273f206e000a74a05c51c0cbb62743f1f340
+PK:  73140217a493a17866fff5154832273df79d5811543c222a39d056b8c970dbfa
+MSG: a5ab147684e4d4a7bcb5a96fb39818e23f56c2d8a744e9123d62083930ab1d0bb532e68714fcec7e6c41134b6b19ddd867fe635c9ed65393ee39c5e8fab456cb5b32797883f3cd9a0902b9796348ee66c691fb4f2bb14764410657c74ab364567879b6fa0a6f4dafd930d9234cd7834fb9d0eedfbb5a394bf0846ec6969c2ef7ce39e3853895ff5b4da31e54341b4272e4a26049189ff28241ceeffb7d2e1faf4f779fa65cac0f5783c60ae77de30ad4465fdb390d42571eff4a63136349937d6caeefcdae229e2f28cea8abf3ffae3c3eccd90670a4212a2bee1ca6a5b54f094fc3231058f5cb9eceb9993be47027d51c18deca41cddaf4e8bc56a99fd270355ff45971950e3437a198ccc3254168dfc1574080802ee101a617fb604e868f8fa8fb30daeb43074de11f2483d916de5643b7cac23d9340508a3fd621ecd25004356a53554ad3ad7d5d25817ad7c9a610008c67ac16ba4211c42f5dadf86c2c3aed825cf2a9b523bfc03dd7de400c67807e139ea5dbce4ee1f7d318889b01a9f44803c322ac3b61e20e6312d0a03bf9927fa33f04ed7e207b16f26502c2983a3a961f224461fe9b64923b1d09189476ae8d001d0ecaae4df60db35f448bb612f9655a5fb144df11d83aa6936886c304949e59aa46df65c22ce7bf289b3c77c25d896be6d51dee10748261688c8b071c856f9962c66775ddf16083dae06587e32a6361199d72097e383ad7439491b5a563a3e6d58da3d5abb1de84890a36b421ce03d484dfd60039638d46edfb60659e3a25ac6e9a935ad6dad50f927bcc2ff99f9924a5b7995dc23c8f301ccc7769f71c18260904a3dcfb817d2d805cb1f196be8b6ecf352bc296bc3f76ea91353f8cf35bcd2b57eb5942773d6834ac50eeadc7e66461d1da098ccec75ff7205215f52459d97620f9f0289e93911db39b21df818fdf0bed45509244633df01cdddb4b75972fa7ea6f73281cbdbbd1bcb00c3bc1b1728eeae0bba172b131f5d30890a341e6b72f7e89dd4b6db3e79b6927586cf2c8ac38dd14f374d7f5bba9f4353def10ddc94d3d1118c5699e38b6b504918e589efe3f7e973fb40e2ebd057de1385e39d699a8f683b962fae4f3902881f1afbed7c783823558c36d68c6875d166fa243eb2ae14f7e6315a6d2ab4e79ea8e16e69d30edc708f1e7af7adafedcd3168898b331878178c4ba8833d20b3cac9d32b8888cc6783206397470a2e7cc4c9809ff79ceac9dc24ca1438c919c8a415e82f0902b4d9cf4ccd576968d5bee81c5f19c7d57b9bada8eab4756ea270dd26129e6122ee2d615242bc7fabff4f8312e686c8f
+SIG: fab8e5d93d7d46c65ee117c5375e73c9705f8754177fdd46efed4737c28768cc4b95a9c84c529b4b916b28dabd8741183144bcdb483df98af89d8240cf094604
+
+TST: 947
+SK:  220524860cb89ab295bd884f988a57911868693d6b105a80b230f21e57805a7d
+PK:  4ab32bc1566a7677e799734dc84181fbb654b813379180f1dd35aef2d324c12c
+MSG: 024a54ac5e0163b3a4fdd02f5936888ae2f9b74a6414b53c6381173b095a4ddacfc3a69f19167d0f1ae0c120bba7e9fcb7ccfc796d89ea46ef8058866ef6da7d01a6a142ea69d720c4f805ac5405a8012c3c2a8263b5372d59bf7f4099299013d26259dfd5193ece56179777be51b86bd1ce5f1fc9156f2b3a32c09d86bc6132de576102e2f03c716db5366ccbe742aee3552ac3b39d0ec7d4e4e9626bf8ece031d678d3480905c0e338fb7cc026e3e79cf2c2781ac2a5a40df4284e235a0389e928fc63557dc6f199fcec5f361ea24759fa7c5f71978c0ba245e4b03ae435941c86c81a51430c2dc9927e3b0f4ec4eba7c2745b493987154d7da85b67de21c598407fb2a760804ad05bfdfa45a613224b22a08588ccea3cbdf47a198bebf8cfed8649d6d5f3fa501376bdfba4003dac2237dcace5315b7fefb879a89a85bce6da526fc360cbb4fd554ef013f33b7384cd2b22a88577f3a2d366422aae46417ba916e1646e24404a88b5d53ff1aed2a47baf81fcb4286397991394b2ecc39667ac46c2bdb6d023b33db013457c4005d839015d8851f028ac334fb24bbad2902a4d63ae68e0eca7eaea1e856529647baf1412213754ed50af3f436e9bafc1601639b39d3e52a93a898fb6019fd5ed6e7dfc050e7ce5f3d35ceb5067021c0fbdc708d3f26bd60568d1ed2b612b696235d5333318f9a6c987235a7a07f8c6a9354fb8e734763065afcd4d937764a4f037cc7e7e2b93217f1641684fa81b7ff7986a28b38e95b332e74649e83d0ded795c57f24cf276e0143901bafef0f1693fe7cf10904fb0d880d72e44716a7069daaae742cf0ff3ed92f5f7d1e10e049d8df043631ed0ed4c4ac4022d8403cb0421b454cbfb6f48a30e9ee1609ad7b68211977acb33b9c1a1be735814c58f66db5f0b8ac773b1d58d4e6bc45dfd48a294bbd25e92671f56f302f29b50d80431c8f2ea33996257b208e057ea7672cc2d1cd4204b85b2ab509027131359aeb42e3eccdbaecfe2cd3e5a3313266e761194ff69cae9e37e51cc0a54f086dde13cb33118e34fe33c74d735582752d68d21c79e5c3aaea94ba107cb7ee8a70a3f9a01e9808c0aeba6665315b45625840a033a6e2a875495057942ed9bb2ce6e4ee60bed47cd9d584bc24524397a109498ee2a973aad6a29b70a1cfbfe9aa5c7cb9f35f0fa00227f43988d07619b6fb2f6d3bee28e10ee705347015a922e2e88d34fb0ce515b08df3a1b634ff9ec15d0594182c86ebb0db783612a7d19e4b22e822d566245aed72e694c3d101bfa4ca879862e5f99c23a5d66083ce06d87f399aa7888ab83b8664472
+SIG: db1cc0c5db773ec51689be28842fa6791a7d75e29c228ae9593a580e0875b1670f09b03442929a18f1e9414ea34315ff09d91d922ee47f10f71da4ab13b7d901
+
+TST: 948
+SK:  4ef60f0691d737e64d437bfd3398330e55e3c094cf41fc557b0fe0b643909ab8
+PK:  306ab146e5c8cd630f9b48bf8b685db0b6b553ef69686853b6b531960118548c
+MSG: 0a188ac26f3c5d89f3d588374fac5ecf9a467e2165b31d0b0f23501bd22e62bf3555ffba94631de74a6a3c3cf63b03ac1bbb37d233eca5993b0970a0220de8d6c41a970307309a52da0576dc334d806447aa09d0b245eacd0b42c4e19fa3d6fbdc229430eb3c7558af5331c6e7fcc2e552ce35d579073b548dc115bbd27e5a33ce1c47fc8461e391b6d767953487cc52ee673bc4be96569c8557369ebb6e02f79238108c3b5856ee381a79ff464c8f6009fd47e67b4c80201e11e61ab8f59ba5d07b15ace3fb374c64b6b4c345e2b00e9151ab8e1c5c98568bc58dd0812aaa3beee165e7eae58fbde63077203c4fd6e16068d76e3d3a13f1cdd73288bd5e4da44eb119a04c4d32efa2f13e7426a2f41c5623c9b066b1303639b8fcea0d8774cc08045f7e346365ff31d3b1ed99e97bca5f25c92b2843ac585d02193a2fd39466f73aaa989b1fa05b9a157fd0277c5e745d258e027803a524ad94309425c3f4dec31c0efc547752f4c7194cbb272f849a52169c6a078d20ede1432016528477b58c2bdf6063f9447e33837ccb437d8d6b95cf4c44be70c8193ad980a105f3db6f9930bab4678c776342faf170edf74248d3b1ca96f731b9d026d8f0f7c34ed372c1cde176f55f558675cc3180c23902f4ba9508d1c91c3c9e688730327f3f7b637a8fee54373759fcb17c9217ea44ce43691a8f6463640a4a5e151e6254c4ef12623b49394da7cc79452693817d6baea9a0a75876948b1f8d3b717f9ec36753f53263710383b98262ae6354ff2a2283220ad42c5cb2cbbdf12c879513710b16be856f3b1355b36f4b80c017c21be85e96053da050c40312100abb640b873d88fb6ee0d19e9e61b04c970bd1f060dd311bbb9a6e35b985fdca17caee8cd5db637acd90cb8e823255c056018fef5920db640d2201c5eddbd8a9c9474da8def7e1325b3cc436c74f815db1e42b421faab626a4378c2d84261bf649a53b321f598c44bbd3002b06cf7f1fdef84ab35f73ed7dc65096cb1dc0cc0e34c561c8a15cf5279abbed9b16ff24a9744e3f5e649cc9d8884f891c3fb78902031ffe0e0121c72080ad10c247b7c93a9ebb2d84d4f877750d7b3416393d03045226bb7994eea58e272dc18c46b382d1f97b23765fda7a8ce21fc6b98d723ffccd99ac4655cc5d10105a2a5b7c8cfbfb90e27a9a809e41ae640063286405a9be83ac5d2907a45f163c7764b09f99a55593220d6901292b9b5803a0fe71b0e4441cbfef841c33cebc98364d666e5a9f5e7e69a1508e4380ed361345b7248a4c1c1ce08769bc7152ddb332fba176200f5abbae3812f406da72dde5db
+SIG: cbf7cf22081c5f235dba35630fb3f0408fceccefeb28b99d74dbd98c902c7d99ba9ca7fab3747c504cc219f4dd101081f58ce616e29280e362539fe49f34d705
+
+TST: 949
+SK:  197e15dce4c47d734dbce4688a7ad5fe41ebf2aa29a2bddb2bee628429c1bc02
+PK:  30fac323048b0c781a9f63c1ee69f2b9e75a2706d249512a2739607f26db138f
+MSG: fd971d48946b51ffed7b62c5d099c1e56b1358b92235e1010e3f23844ddb73bcee8d2e1c9977353bc96a221c05602931fa16ccc2ab6d0f01c846c2920e99de026dc2897f3d5f3cee174ce751d4a805ee1959a3c69cfd42d7c9afd31fa9b1cf05786d8f9042a4f9f81cf7ac9c1c39b36f1ee95b98cf7ee3f43e2c343733d1d82cc08b2cdeb78d982034085ff4dc6536cd154a790c85c8613ec4e5e1dc377d38a745d938cfb15c8b8aa86121835f2e25e9e6d0de68025d810c3dc9df991dadad39dc6981fdbac1ff9b7a791c3960d8564366e5aa39a9e9c7cbf1d3f0f820d1b90108751ac764dabe05c51c18529da1b0349614668424ab4e936440c4a2513be528539372eee78754589dbe7994faa1f6229124f839950ed0923f4323315ac963bbe4c8e177dac516e7342238f1cdf140befc8acdca3d002b16c1398d868600304c7e9853b23a51b17d9fd06156e1d1d08a28460909fa209ccccc4cecbdb1a46348089115318681a95ae580ab6766041384651cc4e6145103923bdf4a32a93d93eed318791f20805f7ea84b743ee11ead9e4ca03da76ddd249fd4475fc1a353c70a83389bfac52098db066d1029c4effbed864ebe7f107e0103b3a8f3fd1d6ab4360b99e8b140c5ea133e923c392b8e4063aa6e522638f61d7a71c9225897d9f8a1e16cfcc801e7d54104eb10e61a5ae63c5c85a5b29392ab3ab8e5c039f100d0f4600c610e0209436ef2ece4d0bdb0bab437b2db5f3708fddf96660f6fb1a90d6048d395afafa760ccaf15deaa0effeb26ec17681d172c1330f78e78a8736b285f615f15d4f2c313d25f30aee9d1db39f535fcdd0ebc8e71b89ce6b3fcb567cd0fa288f48ed3a759bb2ed200fdc23091502fd9ca651ce5e3422a98335a81d74a65cc1500e9070abb609c1c1f68fc2ca94cdd550f99bcb2d092416b9bd388410b8fe748fb8c9a5ab8615f2ed968f85dcb2727726984beada7a18afdb0c72aa65de7abb7a86f11169a6eadf1c21d614e52c0c8f019747d341a05d85e37bf58d8327e9939c2387c2744edf838563cb37f0b16e8a06fc628a97230506fa4183954dc74815f3be2eb2aff4a13c065f743b7d85de804eb28efe570ed5ecc71aba97f9763b436173247f38e0cf6297209b65128465a382664ced8011fcc3d0e563f155bc63c94dde73c7b17247b8c3a4e8034ebd4364635185ce9c7081dbdbe8545f79d01aa532a0dc52cb790a31fc2ff41acebad27cce9244554db652fa287bae7decbcc8ce9e01d1a88ab412b6c6578203b42dec982b7f3b82314db2cc7c5c3dc1d3d8b17144da7fe60e7a8725fd0a97c610607cf413c72
+SIG: 2c3c8cd299c9060b65999b03a6579bc50ef1fe0d851f23be9cb58f8fb8c672ee086a539ead949e087df091122d26faaad206a5c52fcd58b514d7a935be017908
+
+TST: 950
+SK:  08b5fd4e419d2370c0fcd6c3b92f8db3afd42268f533085d9fce32b522824e34
+PK:  cd0da699379e4f9425e84b9757300a51a163f358734cc37a91ff0ea488d29779
+MSG: 3ceeeea30fa401563df36b198b9b59698c10e100a2f30e6f78fe62b92ecac989e8aa09ec760e89cac0a16bde3cac73622a8627efedfa4ec09b873f7e1000e76982910ca0aa4afb1ff5a8448b76f7b0d2a2d52a7f40dedefc68d60ce6622ca080d6698ea6c3bd7210b3b648f53252291494b35a55ff40fa1a631a57c510011a46bfb9e271bae1e78ce6c6ea60c55ba0cce36059bfb01e394556987f744b72aebbdb4b1bdbb3bbaaee1b8b2f3174506a793f0a511b2b569049b30a2e0841424184a48eca9e2d83783ac5b61eb947cbd8bab7ad38b0c68427d8f94ae285190dbb6e0c6d580a25142394be948158d8da83b4f34a8d258b97075632b3c28bfae3105ed1872e356e43aed59397b9110bbf9d8ca2a044d5271e6cc361e14e69a932517683ec81818f02cfa0295e5661cea3e586afc0db41ba95553ee75b200b0f9790111d3757a739e563557aff9b70ca14e87b795437ba91a95dd07ea69a11359f36ca03298e0bfa4f912f64a2924ad901975a2a960ba1be89921b1f5485496b7ea5da6d8a6937ac105bf3760e4876990a0f5c5a634f74cb57df7c172c8a415372e6d903298717499616f8971c68bbece92ea878a18e23f327c3649b6a852ef23b7b3e603cdf80452dbf1be2fb77e814d2525496bb31fb6e4ed2533248b39d5fbe2390a9b6fccaba997e8b49b59836e3e09529ea5e4113eee451c9c6bb26741d0e4c586f53d604c6ea0c0e60db02e5109f3734f51cdd8985afeb3ecaff65e059e312cd50fa349ff28bdc9b70b7f532dbab1df43b03167c1d2e3fa6ee8c9b174a0b2cf8aa9ffa406bf5bd7288780c9c4a6b697949b48638d42079c8c66e14d9b572a210a093eaf1d2f7a703b5cd20adc4f9927a6ea8ea78faa61bc62b3c5cbd3a53252566d043ba556590d9a763be7fea4b20e1e9cfbebfae15439b334dc539b17dada2e434e9c83225b1e8f6beb7d556b47d7f69f7eb7df5ede2eebd84e250b7c9468c21fdc0170ea8df662d6180581f657fe76cef1858b6b02f7325c7219643fba2f7e9963a33322d6504ab91bf10a978fa07b47d5db0be000dcd002bddaf676b77259c9f60ad0b11671cd5777c1e80b13f82eb0fb6a180b5666293a43240862fbfa3978d95311971afab9e1cc8ab14a876b6572ac8a4b7e0b40aaf6b52a1cf4c1ebc6c1c487df5a3cbc4005a0ee329cabc286db10f17d0f1782e07d3324f0c73efbd3c2fb52b71f98ad95db95062d91425e73467bc1e4e9bf552e8a24429d97db1d66dd4d995e5f8d24e9c910b2eb1758ef75525c3d65a3f430a027348820ce3053b6f3af4ec96d0493731c818c6b1a70c250ac686a4fc
+SIG: 42a13756b75c6722485fa3f694041b39b7d7c5fd40ebc06a52e0ff34ce14d8d40fa82a9508b568537d26d0dd7c0a31be710da80aab35196a039b60641db1e101
+
+TST: 951
+SK:  1e85c9e451b7acf801d16bc8268eb42ae85c72c68e9f90927aa0f3b50befd229
+PK:  a69d057f4b743811e07ac74561c225be0381c7d5849e6018793701a8cb6c99b5
+MSG: 189ea9c8d9ed14b0de82b44cbdd58757a27c68383fba597761f9e862e08de15b1e44c3db1badbde76980ee39e699629f6fcfef32d36b3393da2ca5a81f959c8b0f1b801b5fa4c47ca39591e612a2435c5bafd77a5c7ab74359210906f47533b1879e2a5af5864d961c8146e25dac772555e042a887261419ab8c9f6f625625481da5b93526a131f37b534a0050a8a462b33f20a7e94b891530b19bf654ee9534c9a8361d03635d8d27d46be7bf84781ad0d42d1e7c4854a49ba1ba458262fe5ea19021b935a6949492d70b605e151989ef2641b2bf81ec4b92020fc7074c2a63229d51a944186a28895e8ea95292c2f872bb21a3149399e23ccd8e2fc4f17a46b59c282c51b58d00266a5c16b1ce350d5485e8d8016dd0a50a5984cc948154cd5ce7cda0ee0ab1d7251bdc70a1785b8e9103917f4b917ab2b494f3483389a2f9237541849ed3bd565cffac9e756db56ef5e23495bc771e88bffa8707ceea5c09becadd059ab889d1df7e887b71a9e6c238378fbe0c3630386616363f207b16c3270d39acded511529992f4e598789121d316135810636baade8a28edc66bbf5ede3f404a70b47d35988be706b4eaa03023a39093d583cd4cd8bf4c74341a028c19d60da31b6a7a034c081a2b030feb3cd2f03d0faabffb58e3fc36c006cfb92947a7de5ba87476c1b051e18283c03e9c6e5a5c3c2777d9a0757372379664e82f8485824fedb70a4bc4e356edd1b5ce0fb6e41de0171621b84fafa00189afa8a6a900b14c70758f7aa4fb82400e0d18ab3cd7e48acfd489cab0e72e719f79a07d066c531a891c55291f2245dbbee44e52b1dfc8727aae387ab9e71994a3854e1add73d9a7965c775521c2f540842276dd309e2f6a341e7f0f37f22bb6627b6e9cb25ba24c6c4f4eb9f5e7622d88da1984e29c5da001039c44042b59351406a41336dd772d497d3fc8aac41172eb5aa6417fe422ec7c150b96b0454ee331247cb1538aeff3eca2d50e53d6d13170a76a0049ea0c05904a6390ed14ce7491e97f754c5222dac4b6118ba381f552e73ea8491e3b7ac949569b569cf2d29a80410e065b5cc4a466bb04eb7a15f596792e8490ba7002ec361571af5d8f57675c956449470a2f9955407367e409a232899553120a277db863e9a82ddabae87b789145ba898df3c28b96fbe3014cd085c6e60ee8831701036d99c5425d58e8bcc9fd9271d46aec1eb955130102eaaab44e0770c30b2b127efb0e5f8a3f7a0ca34ec9984a46011bc26bfde0c0819bb54706b565638b7542dc4b8bf8098dc01f161b3b129618b59aded33cb59ce9189a6762dbae5b0d34b71c8dbf
+SIG: 6c36da9ad6c456343ce642aca454923a52a2844ce5ee58947c8df7bab2ebe467823c5633e530b167d71c47ad9549df05943f99421e17475c4d4f08dedf6f3205
+
+TST: 952
+SK:  51cf868f820eeda0dbd10180f777e6065c93a483c58a778b67e7d842302fb767
+PK:  ab088f502fbcf2150e4846b34d2c8097ff013c02a8b97cfcf2b95a1c72df3e24
+MSG: 7c2d8ee82d9abf8aa9c724c75b90990473f131763fe93b30cb04723588621da2a327928b22649fa062cdeabd77761538b2709b8fb7a2006e503509134c929c3011e1d728a57a4e175198075e214253f3f30e01b6e04eabd4de06789558e698b186efe34b32129568b3e8d0d7ea3ff00b3f25a42236893aa8a41b674a0ab5f41e7b28cf5a7cb765e18ead6de6a353a7824a3c49786038d6f4937f3264d6ccf0c0a2465bb693e52b3d1e6eb9ae4cb65d09cff54842e85362857a59f7198a688a3df38513cdd61e21dfd859142c8344a3b8b2a7c7db170f39f87ca3ff8ed427962b2b1a14d122fa2d5aea2a6640117dd258fa0fc54ac6e940bc16d211ec9adf914ab16578f521f655d2127e79e871bf7fa7544719d58ed847850cb27b99eb8f29b16cdcc28b15c1259ab4d589705a406688f605a2ebf58051c43a77c4e01fd6f749d32db4e89f263c2c16de181f0e6bdd0a6a64ffe6f1829444096d9f3e2b67e4bb006650b5929d1f82eb11bbed24e8f1018a7384605a3cf29ab598337939c76a3be861e483c5805ec3cee45e3424847a08558dcc99499fb9382acae56cdc87fbd5b26ff94c86f2e108794383501c8b33366850a76a0dfc0a7cd789a03f01a3e9d9e9ae39fd7245dc29299d24f3b4b167caccd223a99b6b20a3b673dc5f7466d0b2f815098a497ccaf80420168eddbf4da57b8666e9d33c48eb304b4cfcf457cd7659543f6d1e661890f562b43b8b6d1c4dcc077b60bfa533ffab928dbfd955dc5116d770950b690e2106ad52d42c31c22b8848894332b5c699e5c331fb381e5812e7526fdf4b8aa2daaa2ca2cfb9c92111b61cbc3d1eef6c8c6737f05588f04467db8330843acc98dc1a16fbd9d9d94bd8bfde26c3f71dee72b50910c36b240f802a61ca16372f6ffaadb2be4e853c5ed69a3d1f6c7b2de513c53a3fdd0a676f83d09d5c51176047d9200716bf22bae45fe01b3e0c2c51c16e46ad0637f79f9b4d83867704feda9f227831dea263399ca2771a4e78b4df8ac0de6a941eab370b1fdb47daf6642aaeaa63170fa9b3d1e1628f7c4e7cf0ea8b8a8e518cbacef9ade84df032484847ffb61bbd07e8727cc4c25da577b264519b4999fa7c0bc323d4f3f9739f780b9b2c23c77855ee5f6dcc401544d6b64b2770158fdc6c12f4d89beb044e0e85ac7a68d42917b1345114b9a672d1231b2c6c0f969f203531e71bbb4005b103a7dc3a58b5b824a7e01b6eb9f496dfa64d64d8c6777f53aa58d5da046d726f55454c88b6d7d4ab0d2198a89709f118a6b32460b9ebceff3fddc605da77ef3d1ba30fecf07be2f5313f4ee635af5e9561d877e99c
+SIG: e15342a11caf892895e466228863d083b0692f010610748c23df2f11d29475bafce927cafe7f07efb8c347ed5663e73bea89531cedc0c348e79b6e58a7574907
+
+TST: 953
+SK:  543d5f1d4a6e1029b1914138fb1f4659e69456557207406688a2035cbbb2a68a
+PK:  3c83790c3b4553deae4f843b501d26f6167093ee54e279759ffad8cbc061e720
+MSG: fe0057f062fc871324b8bd5d427e9a5276231bd309907e5881d7ae53b1f370c2a43302a16510b46064a30736bac90951f1d9881af62c701483ebb9272ad77212eeb5fcbc7ec228d969f8902732113b98e3bf82dfeadd0de5e765d2870b12d1f9b5a28297c9fdd1495cf87789196a7d644eecd93587dbf20c28eb09da286603c582d2129a657db2d17add3558dde029ce27b88352de3f95aba17e1ed1913722db08a795dfbb70d62a8802724cb0f535f848d052aa3dde9166963a8041fccc4e60bfb11de2bf286eb602a4af842f4d1a340d78bbbcb2857f0c308f44bb101e7bc8b741d506094e27bbafa72428ef666ea6ea16f799b4ee58278f045974d86dc72cf5260d96f9c09b2f1181e1a4500f9283dc677f384ff64e51e89f76582020326c388c08a0fd00de73d5d49c06c0c684191a264fff726d872dc3ae496c7b478cfc61b51714192f76463e3d0aab410ea115e8befedb997ddd169921b3207ea66c1f59450b7623129fd1e2dd3da8f5206391171338ea0ec8ef3c59ed8afc69f3865c29a0723a9bbe95a742681ef9857e81abc80c92d2a718a804f5304fef3c63d799a6ef8782a7db46681d0de3506446982267b2152b0c321869e23cce8c4ebebeaf4aa1ebe9283b692605260ff621b03c10822aa5f6d03bdef49c462a68d471e849e164e3874f6e9f6cb3b5f293eb38ae5245a159ec4261a9bf6b5f7b7615fd339ea12733113ce767f883ae6675417fc770b50bd60e6f20addb29c1f7506233e32a7ebfadabff98cfd09b2b3bbd3eae0069548b9d8987af46ca98eb095bacbd874724ba10f3633aa08ab6ec26494ddf6854309b55d43bdbd29a7556f12dfb23cd0db4eb3937a65c4aed96e87b346555f9fc6897943a0faee65ccf394bd89b381beece25d1ba68f8fe32c23b3354f5be7e3ea3c0dec0f7ec2dd83f92b73058892b638d4c3b7242bb8f55bf087ba45a190a698bae675e0cd5e8446f2b21aeb63d2caea0f679a837e79357308d9f0b8af31f9d08008c39ee8d347528713c8850017a7f4ab98a35c7531940fa7621e67203ee782db3a2faa30f3aa850a5ff7aaed84c00ffd214f2c9261735fac3259d50e03c2652505279d91251927de5e56a8b9064ccf9f45dcbef46e1189ced2bc79e6ff652e69097ace5568bb2d5bef3ce21a25b3f79ee275ea34e621380566d704cd93f24dd9020932cc05218c23b5b22fffa7e99ee7fe457876a5e3364c9a8e8b049cfa20969774f506d1996cbe6ef5a37793ecdb04cfdeaed7dcf79ab278474dd770822d4b36fc68e4b2dd661ef99de01de6eec57fa573ede10fbbd5ac6fd6cd8bb4eee509dbb4610374401
+SIG: 55201194026fd6448b1d52f83ed20ac284e7e77fa92d5295d33825cea3aca47ec7aaca2fc08679f9acfcedb376fda4619be3272c7445e8705c306141cde16c0f
+
+TST: 954
+SK:  f8d257fdfcf99796f8ce4d8aade3b225a53c26feecef395b9561d9d587f5a33c
+PK:  f66bd4877df78aec04ca7e77732899de06777e698629f29969f8fa9c2f47ab9e
+MSG: 233e1ef901abcb69fb486085d8db0233ff78f37b136f0afe24f7dac1944c3678e74fed58a1ad54835b7dbcb46fff6c3524312273300b6d878a93e0608a4abaca4e3194722bb9e23d17194d8667b84f2db038c24efb8f53409cf5594fddb8bcd61f74cf0726b51c651ce01eb66a59b455f7d8a7d60d3927e0c6c54b138e01925371d2d9d962aa982f5e6085280cc05f356993911fd2039dfc342117970291381d82027db36c799100057d9352b2cd879d9c82af734b7fa297d21149c978aa5e125b20372a9b2e0ed357337efaea1391f3b9ef11e3e5135bb70bdbe32a9bdb7c3c42d5d57cc8dab6811628a01089495cb8a4a76a48296cd8dfafc005ad49d70bb19faca2084a1b6f5e48d23c03fbcf6f106db770f07c33e8e7f4757da904a44dd0e738f3d5733a329375ced74f3c42bfcdbb910100455d6aa7d2e3e3aaa58a829630d376b0b466dc85aac48fe269946a7bc72d91eb37ded2f4a77c684be01093fd12de9d9d83199ccc50959a48d6e9a41427566092f04a0f95ca52372e0762b966ce6232055a4fd757c61b8bad83baef91a3c2772fb32ead8f591ac1e02bbf90a7f6c39079b86fb814cc242e980f0b8b1a2cecb8e6d4e8a5211bf8babf38e829ab9883608bd6d59ea5e836a9b4a4fbeded1bea2ffe977e8cf3615ca4a50fea1f05f1fe53c8eac500323e1f52a806831539957988d79acc7b54f7d02b480c469fd69540fea4bdd68cbdc68cf9c7872fd792591b01e9d9902d8a614f4c21823f23508ffd49ff218bea922ec141eff60da177ccad7d7b9d444f3b03458115f116cc6e37625c39cbadf09362f31d33f4c13c33b6292007f2cafd194f62c643e7a25571564febad7d33e364b633d008b090d7a091358bc69c567b9522b5c1cd01218d38529aebb03d9c2a5eb2285a7176f98c28036f21e19e92b406e94895fa281b35228fbf76e73e1758af1b434a4df98e8cc556b9d83f6b0b7ff52c680f65efe4e00c59b46ce593bf98899805d02b9165b7429849e73953770ae393e4f1f97cb90cd6159cc93952ae8a4d3d56a9a95df7cfabacd4d030d736ea454dfa4b4aed1bcd885d2fbea5ffa2cf2927c137c86be4fe016412628fe7a0a0f02b6b6a9a2168932b943ff8b28dd587e77287790aaaa69a98506c764e6f5ba6338c09f382e1b987d99f14a3e1958cb62ae6705a577f9ffc67306401128741a8d0af03c0aaaf6af06bd88ee4b0af6703e0ea60b0409ace24572fb386e07e9c22c9686bdc66d4fcf3c7461d3833a4c3013243607d4d158217187326df51725a6bc5116e990bef8a5a9579600207206bfc3a6dcf0746ef756fd939e187f668750716c0
+SIG: 9235d44807869816e28e42c81c801ffb121de826c0d33dcc4a4e1c932d5228b639bb294e16090a93d1f6904a7004222fda0a55446d9901c72340007bb45ae103
+
+TST: 955
+SK:  8da9f54da0b6a5a38985b88b71339dc7384cfd5a60bee159c394c22363bc7edd
+PK:  1ac1a8edeb217ae9b3a3de530d24d83e11fb6538cc709b52994fa9c3f1faddc8
+MSG: bd53baba6657d8db8becae6eabffa52b015a5a05fdd2e070647de96f9ca4dd219fe0da608fa0447f46d17c9a358244cd5408596582ccd3cdd0151d6f0923e63d166837845f273fca7af6c89d8d5246175c2167fbb9c2ebf6a7595491f97a9713b02bdf413e209ab22db7dd2b37fc49436918ccebe5746bc64ddd6dce19ec4558c40e0896e21909280cba06d16b72f31d987685d071db8155e99ebcc6c821d92683fdcee08668a5ed58f839d9edafb9f1459d48de8e1bb6f7ce84da0be411c8f7be1b9a24bc5d0fe3a96b02350750a5cb250b49555a487672bdff3c3f784e3fb63c1c97ba6ae43a10e196f188dcc635e214e29df509e5608a5367aa2800c1a96ad936a9e2a579b8592ec13a359336a62788c3ec55c0ffd6a7d49ecb7c682efa308199f708d79d0e8856366d269fab24eb1a075c96c881cab89708ced279230d3f1f3ee173672283eb8d8a824038f648ac437275d75a0e15f71ce56a8aeb771f07a7f32afc9d612a13bd83b7f93990d38fc3f4f4ab8aa9430c65736eb64b16806e995c1ce9dcf4c5544e7b3d01541c5721bb4be4cf0ae382a0c1b169d8e418defd559442acea14b00d705bcfa78be0756a8f377cbf183bf25906874115d8ce4c3ba874102938a4ea16036d91a42c5f8f188655cacb00c88e3a68508816e5e1c31d27180bbba9518a9630726d7d047dd8d2c0401219e14e6badfc9b95b77a6ace9bea71d1b47c218903a115ad029e7f2039ea23cfd1fa6a44d089fcacb678153d674c0e081764995595cb6894895f08e25b984e3a694c92fc7cbe0ffc4697230bcb0ca408c2d7085c11badeb3e6c0e75e6c498db1bec1ed2a3e2445c32b1913a89500f69e7f23f41d62e5c189f39a056cb9fc68a452023a333f75220cb9b94484acac6bbc671f59ffa072b71a1896a1b306e9dc558da0ec20f373e4c355e0c5eccbbf1350c8c07914892c454defcefb717be34d087aeb244a86ff49a6c470afb36b40fe8b71c505a4ff7af2984c65284938ec0e405231521f4810147dc4e373fdab6647b86f79827502fd087e27f310d6b312363113842155c57a32ba03b6cff965530bd795fc292e241c9b6ca085140032efe746f37d57e958421184b8a4c1a6a1e37d45e077319833068ddcb89d38c75beba1a6e8e4052888ec18162dd6ff0c59a2fd0b47f3119195680ffccddf5f76b35f022aa66bd1ac56f1ae333e9b9d046f0b79a892ecc4f8d2f31e17536c4c62a9b5e063dd2dce37d3d0acb42023eb2f2ea329d3876c2386a02276fff9d308abbadb7274301a6962ecaeeb20bef5e36afffc387ca8e185e562b865b49204c17b2a70119b061c29c0fe9004
+SIG: f6dcc2d27baf16c4f4817f87499157d3ac1f84ed398a5e8b0d50f42edd7385cf06337a0236109970b79ca09d7c9831c876a802799421c2abd07587f5eb66160f
+
+TST: 956
+SK:  7a2efd390124d3fbefc54a577106e74b2d1f5dd504c050d0d359e53c0f5c872b
+PK:  efc303d922e88f70f38c1a2b920684ef663034a1b23ab9d69b6ce8ed8706f7f7
+MSG: 238fbe9fb35c725c6c1f329248094bc7da1b273edc7699a7e3452b5788d87867defc40a00590e87580d2c0275df5abcce0e1aaa18290bf93b44e5ad9d760dd21f1aaca383178f9fff9130f73187ba9d31ea3604a1cdf3911e14377a0ce8b44189adaa7aac23b6cdc7a425b7ea745508455704f9ad7a8952718c398b421b6e09cb78cb52a1814ee2e9639ec68d361f0a32041d6e7425b4bb33c70196e2400eb812db8506c9f3245bd988fbc891be20cb0691559fc916b57ff96c9b14489e0993cb739a39da246d01a6ebd07583581f250bf480bc44b2c3391542d595e4d399490195f8445df638f34698f1a96ed27b3533e3eb67e8f865865fa9555ed34df11157641a00e6d60cf623fec1a92b87a15d765185fd9055acb38d75c99db4fce7b0e39fdc3f851daf65c7a33f464816931839fefe8e58d9ab742b861873fd229189e59cd4ce8239fc9543f539d2d296114266ea8c6fd152ac6b342e5d1a557ab35cac51e2d1212ee317c4d26716829e25746df17d2a622c243f3ecbb65f57ab0f4270e3d0668a962502245b94c06df0c5e39e353aa842ea080cf502708b1dda2d001824de458d37762af2cdfd5a6d3f35e08a18e14aa7a642c51e4047e637517846df646d07336fb172434e0883e2b77d8ed1c52c9cc636a56a19e57a5f161b92d1dcbfa496f344ae6d4dfdc9569ade457a49091362e5a0cdd81b3753243fdac30a2d27ea026a5e601441ecd5537a7201bdcb7fd58b240d0229fdd9babf112b5694812250e768d7c0ce6ca565ad06ab8f78a5c9950eef538726f576c4bd2e0755c7f983929372a5fe11c73f9e1fa453ab54b5817aad3596756127d84e3119453e8825bb8460d851f1f7e4a2838a2be786b233504a691db0fa22a5f41fe3fd3c9b538b04f409e091809486b28ad0deda7b38a42cefc48de7d8679c03bf877238511820d0770cc8d7b4172377823a0b99149abb8918bfb66d5abfcd10060b05cb4f239dd4281d93483504b731eaf5add515f1f3c3b52b4e3bdaf976a17b3c9ec61bfc8e77116715804532cf2dbf20b7ba5ead85afb952beec2fccff85ff5072ba4ed6b5438ab1520c6ef4b0b26f12e84aedd65ce5c7bbe6acb6772f593a6b4f81ddd9d502746505047c812a0067afceb8dc9bff30d4087f8d5a375eca605a0622784d8fea278cd1a5241ad4b3f1b914f74f73bc36ee7cc82d96efda63a3b6799730f20656c12356c79069b2be6f9b77be101983118823ea66e7c2098fbc72fc9c039dfe30f2daba13c3bdefb8a780beb5cb1b6c286a6b3ef48fd15c66c045ba29f0970413b988d0ea004ab84c93919f04f9bf8caf58c4eb478f358ef8b68
+SIG: c28b34804805d81f7aef784970670edaa417232bcc67da9b51e9c3d74fc4991bde97a06bd53fa00bb440fd5616cd0de6e9b0d19f2f68bfaf9d4c5172c4e5200a
+
+TST: 957
+SK:  ef3648cbe73402ab450cd6ec37e545d0cd2c999ecc1fa381a45c660e18533032
+PK:  52a1a45273872676582cc767339926414cd5d03d980cf629dda2d1a205e9830a
+MSG: 6a93378f880cf0ffdb8e07d683cc352e2a1033c450baa0e8c4e16205fd0c02743b0ea064971d911e494713e6d94a02172ed014d506592ec6c70a9c97855246bf3d26f3cf74f493c1b697a0c414160c341412830985430806a0cb3c8475e7e5a973686c24d5ef1be7d0065096feb52eab260b5c488af09270de6decd33fea8589dd1021baf41e3f255fb8fa1916ebd8531eeb2f886bb3b3b04f9af6b276c35923f10d3a0af1e3f58b0d15aed165045f206f3f430abdff09449097e4b26d00a8f9f1e8f7a19f38588124c328ec43a9cfb43d3b2c6bdf6a3c1a102e0e333de1ac214a6df76dab44ba76bf035273b7ff6238ec82483b2d2d9d54291a72270f88933b786cac051d990b3cf740845fed3a67867d7c7c05674e7cb02ca5b7acdfba3852803a3d56c4d5c13bb1d7723467741eac1f2a7acd3a95f3a51610a486fc53a9851628c557d36d8a4cd37aae9c4174dbbdb6bd885cf40b382b8ded24a4522a278fef76c45319067e55286e7b08c603486e38a0acf47edef848ecbe942eceadb8636c833feb882a51a4595e24f607ca3c9da1b2404ce5c747e06264174d64504331709bef30055a5d695e09537c8f8c1e5a3a5db06599e319dfdb28729665273bf868955ea56427f08bacd777f179b302f3f68d04f3f3883d344955b655ddc6d5282b6d4df1d83630210e699178e11f722e9e5cda672892ae9b23e8169cbb548093b83e643eb499d937d28f3811597b6484102f0c8eb8c8888cdac229aebf89086a6495ac551f3bbdf2d1c9a93ed1d3a861eecd9eb839949bfbe6a4f6e6486ededab5229d532b58976d67512f9f71ae79b4145ca2fa497a165f110717666ca3340bbda8df1f82b8c054cf7654c35690168f96277d41c1c236b68198173c6e2b0a208ef83c02a43e473d90686ace75b5bd321b3f54281327a673cad4d4ad3040d48cf493ea231b3fec06f39932d7f70a38428df8fee4370532ae5fb112059f0a1d4fbe11b5a23bb87635429ed33ad1f6148014cbc160d93ca2592053a6e95378d6cd3f50db52be928e4092fe5d2b7095a9566864adfda59fd5f2fb6254bd5917b70fa14699665a37297c983c1bb9efe1c67b413dd1a8530cbf227297a8bbf93a8a02454e8e461ac212b846a70d5d56d6c3a6e65a03be0580219bddec88d4038911fd9574563f33e0f9e6044688d3dd48fac703869aa09d96efee7d6c68071d9922d5e8ed8dc40f1b798f1c580f7859cb84f1e14b5e74ddea16ad5cbeea4c48fbcffd29531accc0633938e3bcb2212676b61ef901e9c831a41774d8317ef35af76990bd24931fde6d407e22e763cf6a5790b23761908eee609637a2c11059
+SIG: f670792942ec414428475638853c42728e86ba12bbe85948b39134cf6e2bd12813e0d83e51e657c90107ad93a4788aa38313fa962f6767a8f7805bde65ca420d
+
+TST: 958
+SK:  2c8ee7fa9ba28ce7049676087b1163b241118d34cdf534aebe8ba59282a62ac2
+PK:  244c24f5ecb2dd1d1463512221325d73c81ee4d8adb8e01e23345caf9ca5353b
+MSG: 07669a8964f06380d2d4982cb6349de550b38cbc35db2ce572de887f663055736faac7ec07c32df60ee2598422bf37e7cf319ab3c9055608ca0c49757d7688e2013b8244f35404f45ac219497fe924de93a58d0f721aed7825f63b2667077c161eb4dd8bf7ddbdbbc19a9eae5978978d5aeb33a06dde18e612e05bdbcae0161aa2389038026429960dda3aa17e967d10773ca49735d8ecd7409be165c09bb0b509691d591c185c93cdeeae95352316544680523821458caccf528ac0454e4cddc6df0d1ea5f1f5cc1eeee05e19a2ad0b6a49736ed8552336fcfcadbd931b0b8e963be05c8e7037388552512b6823583e4a14384cef5029232d3e0bafe466351b4bb3f567545ab41fa46bffafa877a12b38a27abd64f77fbb4db466ff7f706504141d3add0d7372f16fe3d8c69f6299d93966d624a3070eadb8b49f29fab4844c7528a2a40b66987060695caa66b86718c51049acf4cfad3853edb492e368cbd073968ecaa4a1ee6046b5e826e901f4a808c0427c026fe2f7b2e1968667b53a7d36d702f2ff82c642d34919f8e9aaafe462a3d4f92692deac752be348f54cf089dd9cd051846b04b71931e19e89d125864bfa8948ace0eff33c45110569a0df3753f4c58d8002b5bc38102ec2ecf695fafa8916da9002387e44f96dabf8a982c53c9badbc37bde437f146f77d8f7baf12873196b0c36193af55f542d9968aed8069ab9fbcd6814ec472799ad09c730d41eddeca3b6269d31ab523b59547077376345b05f2ae69b4ee728c863d1bc04e9b7d3d0fcceb359cbd0858597af2d6063e253fae2c3f25034c33ed59edd2782868298681caf564db8d19366f34eae85ba73c1e2389b0dd78a9d2caa0f23c9ad5f6cd9f2c4ad5d58946adb718cb83da58e2fcbb6025bef4660a83e0af55e2030802932f2a896a096079b754c99f7b6423b45a86472e6723ef8896c4324c73d34ad58a4c01b38a97c73be5aa7f74a2fa4d0795af6dbfcd6d4eb442a7e204db4ecb1f8a226bdfa21b6eb171c9e59f1a192e23a76c352b04d8a80233985b77a29c020119ce651c7f4183d0e9c19fe18aa1020c25e4589dee34b901bdaf9ff9450c91af3c1db670b477e0ac2107696c9ec0d31d82647b68ea19499fe34a8e2e7b378dc7e75424e8c45645b0c2818e9f885a1c58415bba1c3f2a77549bdc4680dbcd1650c75d0f452a6b208591df0fa6e181da2abfab444621d5f77c2cd79556467246447a89f0aaacad660c9a925ebafbad43c478a3c850a27e01019d88a5b1dc81b5d2e9f740a028ccb72c1acf897ea5ad89e0f9448888d5b15ce6e42977f7a729155a284d118758ac65f3fbb98deb65
+SIG: ca0bb6c12356555f6e1d8f5c8aa7b5e80cd280e8b1b9ba2ec9550f622f482c3a9ad3be03a4c9dfc10d0112b0189de94bffafd7034114e0e0d42c23f32dc81807
+
+TST: 959
+SK:  ddd8e9ff855679896a1397b427db8543abe8bb5dd122e3e302ccfce5fdc63e12
+PK:  5a9a312e892a10b98d0dcdd28db3481c3c28add5ad0b194616da4a3df7660109
+MSG: 5e8feec509350d2ee7955b6f3e278278a4cb48ae72b46589e478be59747df5394a169f19e10db53202a6a52320b63a9a2b723fd31aa2db6d58c57332da3178bcf966c53abda35f12daef9edcf399e4a8c5f83d36f44a17d79846bfc96ce690194c219a29892f0367a7ab3844837879e3818db8d70c4e3fba4d28073464df2085951038fea43281b6b606dc8846b30b0763f2ca82bd5021f9117035a77bcd1075477c5f43214334d4d4cedd18f738d676c7b51a185ffa8d04101186a4952bbd8722f53990b60637041e114aeb8ce7111131d4db3fb4d35d995ad8d6650c0c4ccdce9dcc39db188a68785562740626b3ae3e023f40772ded876a45cbef74a058fd78c1a1ff2c2451e111ac1b4b7ee4c81cd76310d4d298fb3c49f5e6401908a630fa85db7471804fe990847f0f759472f593dcf02e113e15e564d30d5984692da55b0b7f2219c4ac1626511acf194dc7026eb9d367a4a2f1dfb515cb2c08da4fe595c85811120cba2ae7b66e67c91fb8fbcb9d99f13e50fd67464d90c8dcf6935523cf6d13fdd10635b9232b7a61dcec9a2b921061410df1de6a45167fb9f6f109dcc08891f203b274a3b68271b3f35e74f94bdced0c5ff8637173a176e7dacc81f2cdc4fb0d52d1dfa7f27b552fd8d87a1c55d6947fd92ed3253f9594db7df17a7fc6a75ecf4faa4d1e21b676b3727d77fbd43fa7be76bfb58fc309e5675f0a859cc47f37b1bf455932d824e86378de7a7e8c40ced22090044dbbf91c70e528eacdef3785ba3c69a3735af6709cd76aab28a6aca6e844974b10b3fb7b0986007a727c2c8fc95b25f31f146b36acd4c537074920aff247de0f179c13ca57790a6a71d62e23321ccc75b7f3b0afa0d03527c9114a7d4e30c1ace6d7712013dee66699af9c561c44ae6198ed39104e6061ae2c45a9a3c74b5d0fbc4a33e8dfe2a8acc9511ef7e6567133f9fe3554284a75a059a649dd24ec04a57730c6d2e9bf114ea58a8994abdb0c1943241572c79ead043ad1c8caaf5c9da53dd05522febc403354d62fe3ff93882df75fb29458d22e6996c35b69faaef2e0c4163886cb3c3d0f60e150d363d6db59fefc626b1bbb1e052a62414c4b7856d72093432b08f821bc784a5a6b0bc2649c2daa508658980d802291e734abaff06afbf2795e4e354d5221dc4f52cc96d6b8cf1808b1a8208db7daa80ab710c56a8b0e9cb8081dee93f5f015f07664463a3dccff7c8ad19923a97e39045bcc4dce0a73d49c56d5e937bd11e61823401c066206e313e60b47537e34704d7d3515559bb9d0532d028e28a57a879fd617cc61f7f776bd6a008cd4f812378ed37f394bb97e6e756da819
+SIG: df849b7bd29745f8becdddf6c9baf094d7a98cc9338c344eca17fde075fda8d1543299f625982317db7b3c773b64f7d1f28692ac453b81d7ec7b7ec3417ace04
+
+TST: 960
+SK:  a886f4d3f34e320ec6d5f4caa863f81477df772eff97e64a37a05f4211d190a8
+PK:  e9bc96c81e878110268b55def7ea4007a4ef9f54d383d5fb0f6d4343e1010f38
+MSG: 8b831b877bc3a99f613c89cda698b3759d643822b5a88faf3822ecb2ce98f671d7554321b24b74b4e30a663f7a5570ae917f479bda29894b1a8c028c9d193e4e7ac11916dd8e9c3f0ec0ef80bd27fdfeee80c170c78140b24c15271415acf75c26956a4d4bf99d40e861e9078320d097e1259e5ec17b583a95e52430dd8c008ed8c7dd1de1becdd1e6bfec4bf3347a22dd249f3ac307a2945e9137fa4a8c26c8021077239cb324816a8dad32b01ee34a08903098cb9c4245291b903c9627074095249e782813477032ba32ef041a07486eb4478c57b9d532269a4a47cb5e974df7e01096fbe4f1ccd4e663663487974c62cdd94d77716c8479d79f6b6a7d9c155988cf3902fb697424963ec4ec34ff2a35d742c4455a593bacffc4d9699ba7626c76cb1a616253751887f6ffe2be208c713df1ab636d722ea06c1c03a57f2cec0803866cca3335c28bf41c7def81acb38858dc10e59467208624967e2e22d9e5661bb945f9e0517687dc80f9b8fdecc8a97600b6c219a3b23a90b6d18aaace2c78400ff38c8c05967f544b6a606c71ac199eafd07eb5848df1657efb233fbabae63a05638191a0af7484a1bae1581375672c571e264f604225173a54a38dd62ae7130d05dd291ad12354de86a6e113e83f6d668516157b7967020dc6517d8cf42dd7b1a897fe1b4e04553ce26e299980aa5f7ce0179bf4954f01c2a23654e5e9731e1447347fa43aa8b2cbd6d4b2df93fa54af71e5028a6da8c71ef3c50c0de24dcaee785678e92aafabeb233b011f45c1064965085d2547050f21c652aa533afe918aa0f9bdaa2607b873ccd3dbd1d3a8cc62172ceb43b921ef6b25c06b0992e4df2b91e371b0ef2b3947388daec8ec6f7e3867d1f61072af590154fa619a07f87e02bddc7406314270af1c15e8ee88b39c01be602e4f0b52d9a0724e71eddd7fa9134169c5faab915979eea9362d0f1f9160268162dd38db02fcfb41350aa08e1e1409b2288db1fe4a0e586b5910f4de894bf9974f6a4983013a190e7a736d14ec54c3644a3ee958a5bdfbcb6297aba43af6c72746bb135410507d8fdde73a2a48b746f918bef9ed92c5be62dd5523fe14b16d6384ca46ef59b2185fe933383a2c7a9bf02da9d0fd8b0c7d7bde6b439f9960155e345d685d4dc3c71404d656811923aa3c47d4b09a0baef0a12e75b6439ba8135db15865874222cd7aa428f5ca5ce5140e22ff92697f37fc70b5b4c94d3314e6aa16b2146bca4fc94157951fc49245da53f6c43d1bebd894e31a1349884d711b55dbe778ffa727165cf7cb676435866c2d2cb839745ca40166a2f7cfc77a842468b51a8e76575fc9ddfb5f
+SIG: abf283db1f80c54c583b499dbe20aa04248c1dce121f3911677813ac3e011fd159ad0bf76b1aa7cc7b14d7b550848688252acc7fece90487240c3d399dd34308
+
+TST: 961
+SK:  497e3ebd9e4caa81c5a8973d52f1d23f60c134ca53f62a853a0ac043e51cb517
+PK:  71c0ca7cfa05cafabb143d84ae41de83846f42c77caa7a91a2e348397d07d52f
+MSG: e132f9d67b1729389b828a9fae05a67aa57f0ef7e7d4d1ba244dec8704db969565d1cab809e48fc0abf950bcd4a37d97aeace6da546d4914cb5b86d6ab181d831870c309bca616468f2a34d3dfafcdbb7580b0c5d9ff98e2c54ec803be0d3fda1d4b8c0d7709c89e680b008bf9b8d903b5e934b019705fe0b0c8cfbc3c0967843b0a1fa1b3f162776ebe96b740edd64ad7c35b3fd1a085c99d16f5416782de17358587470dd13b5194f20f23232b2f702f10aafcaa59c7066f24c4c471e42fa86c6b9c5c3e1e8f8365f4dd75acb32fffc053c9af41c6fd2efac30ecf6a2dd0085de9b1d8cdc50b1660a866df7767198bd9c87370615d2bca99f77b84d98d7b24c9c20fd7768fd0380d6b37360340d13598047820dced88a8d42d572937b6efa16921a1b2b2d0eb931673070838e611e6c023290d86fe902f14ac3acd029e3397feb97b17166245ab407a766d2e0904424d33cd3d6e2e62a52c65df7cf004d1415c0b430c1127623dab272a2c2e2b43e02b481be928e89954272832be098b502b8b5643c67482f5de4403032581f08afb0aea48868582607bb39198c1bf13a869b63258a75890b69445ffd34564023e47f8b1884a5e49b7d9425f28d5153013fe3755c6cb114db180e60b3dc4adb36a21428128005a772fb57189345565bbd1759813523bad62855e7928eef5880d3bfff1d0ec65c24592335cda47cfcc5b5fa652b47263225224846a209a3dd7766661fca4ccca59c456fc9cc3e1cf804255aa5f397bab199804336bde29e55c6c377d583f082ce64723739e4f024606f906c110d0a5b610e5fed96dab5f08f4cb3cfc40a35557e1a740b8c7c01f7d3279dd9c4e8764c90bc14f4161db5a37f0989b7bd8035f8bea394ea1d6002ce9c34f1e9c52c6a15d15bc5b25c6c15ab00dfd6a5b1bc917af0b1b05fd10d061b3683d75b5f9effb22ae72085be4f6797b58cb0cab561844121f98bfd9583e0bccb70fad76980a7a73b23c70b3fd02f7757c11a3c21d19e05650ffb82b9e0df8a6735d480156f47949d445851baeaa5ee23814a41b25234fb92cc0df1980d023d51b5cf4c31185c118e3ee3c0c0a46e0a2be6f1d3ae452cbb66f0fd91971342da7b1b996589d94096781552195c433caf19c37f9f14fa0ae15ae0b02b939e402034ff81885939d944e604f474f21524389390fdada06e30d69068c8848cf0a951eab25c4912562944f402468187a23239d33632f29123d49b7de13083398dba97dede12f7959b95247a08fc8e4b5399d1c035c0894cc75ae981c2dd4935413bbeb6853fe04655c77d158c1237b3e0deca5636d69e0dbc5acaf72b60c10bb98ccdd60098a03
+SIG: 12740839b3c9f1ba879896dff6d725e84e0443ef96c349eff94dc4833143e5b419804da9db118a9592b1b1ca48af18f75bef1ca468a1a5c74c7ac813bb2cf306
+
+TST: 962
+SK:  85b4d764169128626fd9c782ad6116229edd77631c2bc9b8ee54b36542c149eb
+PK:  6a09897e629bb43704debb6715c9dea5d892b634306440997c3c9e94be8ab547
+MSG: b2a0493d471c3391f7add1e2cf0bfb32ab05dbcb14f6e4f5f3463aa8d99552f433022046d2f8eb763c0171fcb1e74a049ffeb4b8f0100b8210fce856b2e1a8e739d2f93673ef8f8f40498b3081fa1fd785198c6d370e162d41abe83186f2329783408b9b880d00f81d53100b42d27a261f20cdeed19cc58cb8631281d80db1925310e235e44966309b879bdfc232221433bae5cae46690cb527b6779e11f1bd2a56b59c56ed4d94fdf7aa89dfa9bf20dbfa6a4398b98384517e1dd5d2cd9ce524a47362ef32ac792742a129c9e06130876ab5ad5518eabc5e80b022d8fa13e50d55ded589533e6ea32242c1b3fd7e65f80dee720b6d87dcff3e3df04c802d2e914a87a3629c90bb69e0a6f8bbb5ee505f143c9977375adb065c3e3d391f905fa3c336c9da41e4a2320bcf460976fc7eb1fb6c6a3c395dbd1d28a1b09cdb9ae9f9aaee4d9c566a2ac40add870479faf54ad1b7697710b4eb6f7320244b59757d1eac3d922b7a730b1acf0de9a45d4ac879d21fc616ef3965d74345ed70779eb683280cee25bf3739beb6b4cdfa25d202da13a4a673040d97048658b9205479505d0bee4880a73997c70825a6ec5fd9f952e65fa02225445fc3bdf4adea3d4d22551cbaceb3874798d6a33a6663fe3757081d6243dfd7cd2eebf60a3899fa1f8f6c956a3b183f89b9e7d2ca36448584d53aa8b44e65ad3e527f78723fa6f59224298df31d5e8ada567c8d1b11f3b1314755331c1732dc54a12a4356edda47e3c130b325282a354bfe15c3000d207822931794187e0973ab8ef87bf89c354a035a81f45911223563bfd99f90a75e53d010d8929f4f85a5a5a4f9fcc1c78f0a2fc466f5f1c6522cf62a7be37880796e9b3ca0911ecca3f22c3b24d5d9daa6888f89a8f71a15859359cea468ef238ecf646192783a257addade9047e13edd8bcc1fd4177cb20f88d11998d9c7262d648c2bf66fb227b9b3a9ed46962d2257a420f64bead9e28657b521db2e22165287791f3a1bec4c7822a6cabde5ec770188cb74498a4f08e5a3a7639d240ae3f4fd0353c0dda8ae410b9fa7f43feed13e9f13e6c9410a1d24cdfc2c8e64a15a12f75545b0a575713523d4dfa1a47427a8851ba9acccad78b4ef6a185f5c3b001190dd8f37088a000accf448be8d49371d9da2e1cb5ffe07d41a5c22e94660ac37135ac858cb1769cb66e8269fd53358ecacf5dd92c7eb6186b4d4d6130a732dc10bbb2be32f9b1d6951014a635c12d22f0dc5bd5c2a3f96aec62e7777947eaa022812caced33a5bef9ff8835f880367a37b0b76d2dde396c614e1a4721e000c00f161935b14a738a1b70f6ea54255b7951869646212
+SIG: 4a79c442a4c39c62892617ef8e80b40911c4b9d3ff0a5673b57bdb8454ad736769df27c78a4bf7ad566040e747278b11eb65cf9ec7eba866120a3654f4716e00
+
+TST: 963
+SK:  33d477602f296305a6719ea694c044e90d233c2dea85c46abe1920e88c317849
+PK:  ff6feea028ec346dd49107bb713fddbb282ebcd034e2eafc7cdb1c5adf926390
+MSG: cfea07a779f1537e498123c676290573efcc5db70245d93dea5c05726f8713d002ae66c1c9690747ca9230b1629d3662ab73d66b949879164b21a35f40cf3799041908ed6f9229ecb390c5f22234e1c5f26b3ab5ba59e78c64969871b428b78516777555af4e89c6fbc193a94695226c6d329991a11bd580d18956089b58a0e42ca35f6c6d2609ade0d0b619d48925c68cd9d2250dff27cf2f0d44448709b679f35bbdce0f496b0a16ca67eaceec258b1aec91775a3a2ee801b1c9a226a6b001926a057a06306727eedae8c577531df04ac09b5b49bcdeabdeb8ac4e8e82cf1e7af835fc611ca7a684b83526042415b1d6652e8634311e194627eae78d011e6f40f645794e36895a23e1bd84883a393ecfe5a248026aea86447059f7a429368f21c89e0145207978b913c80a22d7caf2673f7c76f6c26cf884412e17d0c255430f502bce74e3a310d17f6f4d485da280ed5b5eea6c49ba748d764814b9e3daf6fcc218c2740ca77018f71344519da82ada31e001924fc77679e3e9ff9fab67dd09a61924c821a1fd999f74dfa3f819adb31d15e5ed8aaa52c1bd7cca266711a74dd62104ef3c2bf737fce6942b348a33c3dfd6d92a724b6d5878421aeb230a533fe21c8b2fd3da596a6180a45c986d7ece4cdc8ad681ead69064bbddfc20f3c52125f83395bed1557f67182b9fe99138af3c356c5e652978dd238b761c742f8158e2314b964208330978b0620a13a16d761d52f06e466a4094b65cd6f26854aed6f9a8c2a884a0d0bf4ee587eeb8b602487239a7e58172c809983a8db1c1fc7ce8c48bc8a6fb812d6aa9e83a3ab4ddf7a8d40d3fe00ea16e04062b8aceb9c99eefa41f4f87447828126d0d9c9f8605e8467c5e4d671d5c6d9fa70d747098d941211223b9bcf261938d6704a32d22c61e30f3570a1f5d0998b4791080882aa5623167b63a23f340f0e7c6f9a830a75b74631fa5b57afdb1e6bc22699bb03156675d598353a5d1b55897e4c11061dd145f23e8537c632f75c10df05b25547238574017fe7b64b8e99869157fee35f7ad7e63e99593302929503a96768023b4125ad749dff4b992ee5c2b4f3ada4889e4ae62ec15d2db5969d730db307547f638c3185032b12f75fbb317e47df7b9292ae9e76a2c0a06fcad108cdd235f6e38d967b6379511ff6965c22f2c6680a12b0304eb2b296c99a76c2729d98e0a7824b67f3fe842d6f6ab273e894845b32dc6ddfc7a220f76bd965c69858183c8f357395fc57dc829defaacb5603a757868d5e562f9781ee39e0e94688ad3545b32dd7366b6b047e8d1d3d565997b236e7f7596c5f8d7c1c11bcf4a244620cbd21d559a7c9b3f
+SIG: caa2879895d4f620b9eb5fed22b4562eeb1ad63822968f76ad91076b166c05ee20864d98bbbc6e79dd0362cacf7a21b4cfc230d6355d43120cfffb948b8f6c0e
+
+TST: 964
+SK:  7074568611a66dfca8307cae608bb26995844df435e5300e5b4d7291cc22907f
+PK:  ddabddd15eaf83115ddd065d7e220b1efc262a61c52e914347442bde6d002506
+MSG: 6c137423eac790b8e8e418b290e0579c7b86b14aed818de8ce53cea3f340a1a95391f984968f2b4229282a8161c09ab149cdacd66970b4013f52e5e68ea8c9db685b2c53073500e5b35e29ea0ba1f4d159a558d361b06516836cf7b9ea501fa0506b985f036a82d9e084489d3bfed34093e2d6d9edf55785ed35a90ce56c761686cc3ea1a2c76ada5ec8c145d818b047cc516eec5d2d6a93a55592d892e3d5cd10c250c04b049b38fc7ec0f39aba15824007336c2b0f7f81d64d5ca3e29d6fda4c23d9ba65d9fe3cb4e03913697287b46a0b1fccd2624e397ae95c5254bcd88d2c7c8f70fdc8173f64c1de32281ab4184693b48a349e6782bc8992b43c7de7cb9d33929bf95306c2af7e938d8486b386f9fd3f0f7161e0e6862d4f9281446865a1c9be2460efbc20151b06e79d014617d0300e671d48767458596625b76dffc558aa9b40612196ec827e1c6fff518fb7ad4bf8c46fcb278885aa491b77a28995cfb9d79640aad174c6df43938e3f1385205c54595b33dede50143746a1705e7e0b69af4a26c3b76515051892b15ca6e48c3d91fbc75e8fe4a0fe8ed2c26c1073beb70ea38d0927029278406755ae6e11da378653649515e0085b5ea7db3249208e33a6c8b6ae8cd80c9bd6b983e73e9b91dbec091fae995f8032427edec02cad9055eb8b7dbcfa80d4f64f5727a152f11c47e52d753a57b6e5fddf774cea4da910026819c41e32b4f199727e23c54ab5d70142b854a27b04e64cf44af2a8995e1200bd117c7a1674edef59bc53f73adaf638e0773b85b56334aff6e11743e3a3d3614aa8a375b3781ec814cc08e71efa7818519cb24af82c331dfd6ac78ec17fd7174b61021e8cf901a2aaa6adbc902a916b2a2f4f79e551501fbf01df6b8518504c1e94646938bed1a8509c2a38fb6a798a7858f409b0f2fb9b3f4817e568c52d9abfe2168cc3650fc43e0f9975fe29e33aed1a7bf30d8631150790650a3cb78c368f1aea9ac60c5eeb969a45f84aa37366a83977190f41ae421e0c46fda3fa01b926fcef8224fda36df4f8a87701fe79fe0628ef0cc02df2bd783207c7db87119a0369fe16eeb38fdc9fb35d9e195fe14f8c1038208ab97700af79f2e2e05496830207c7da8dbe8e9bb73bc471a43f1be650fa92819aeb5dc7eed7eed8171270d219257d19610b89d2d62d3f5b648e139eedf1ff74be01a5ef1d95f812922601ee92515157c4ecadfa3eef9f2a677c003ca4ab9b2c45472ce55e18f40a21fe1b0d45b50b50c52a0b1a5d7c37d8ebc15e020584d9edd7b56505f82078e0f899389135014c86d1e2ed49f9cd319076943553a312ae05ab333526e136714f09a402b3c8
+SIG: 7f653134c0b90f44a489f0b05fc40707ad9f1398f340b447a3c9861f511c9f1568803b7684a04a898c45154dd486bd50758998e126439378b3f59ff367492a0a
+
+TST: 965
+SK:  7d7ca8e8d3b84344a5e4dea08b338d8faa5ffc119ce566ef656f0f4584775b21
+PK:  0bde34b746d2c5490853064d48c6b4c1cbbc3ee7beff5e8f684c120f315d7e4e
+MSG: 0b727075345d619f5cdc7fc4c43cdc19105811d95d069f81c0a62fe1e1178cf1c35db05e2de87d11ae1a6f53ef38b39bf4ed8fbf56ef017a1d3c15b64fe4b2610bf69bd19ac7afd46a2b87b488b6c78ad456811c1dd6bd4a6b5da698739fd1a14ceb9f27f124b69f6bd16de5537aad80681c5633580394da3b84e9b7a55ebab8522d2d6bf1aa4e7b159cbf4e20b50bfe9c711aa047119f1dad8749260b87639e9c141def62026a990373dcfd99f77b0f5ea6adfd8f594b9ce41064a5ed307bf2d8d17370498ad7f45f9c4dd26c420f450f53623bb6d7f3f46a149d8f135bc2913310fb8f9043d099278bbeba39179fa367b01673e1c953effd2caea7311c47c0372744095b1c8f90eef5f1929db1996cd584f615d56fae3aecac3ee88bd0b296f449cc2713c52da695248faa8e389b05a0bcac69dce9719723194f433b0297eb0859019f141a207ce8ccb59882caa6e18f0b43bdddb90a0a85ffd577d6394a1d80489410f92afb85ba506aa9f3f427445d21224b9cb046c05f1bacd7b749fb7b1024d092e4ee4b30a46edf718470c99491c68f4879d62bfce7046d8138cbb9e7212999a4498b455fc90ac283e935de04df6fc999e4434be11063d6e4ee9e096a87bc716d2c819916c37a4e6298c49945366ec3f500720b06dc99d3d8ac303e6c264e28a7c2d419ec622a97a711544fb1f4735b11f8bb1d7e2c816a156287b4cc0c65aaa280b837737f0a84e36de2df2fc3a50df980918fb9e5834b42ac0e0c7278d7fe8db4dbdeca0141d5fef5dc6151f87b8634c241a8fa0a82717899773ae89f537890b9155a7a05bce47866ec2028a47898d485823a2e992319680eb699b0dd5358f546fc537c73d3a4b223a0941518b6d1e66b27676c1b1fc76a08320524a72e297fce17aa80d8ea7b388a55168e7dadb836e9dee707ed25c0ee4db25bee3c485b39649204efaf2820b2736368fc773ce090c385378002c471b094795cb266d39eb7580d701be4c8916f6b38bfe25fdf36d6c4adafa9ae9864c57bb737b49506ed38d62de60cc0599ec6bb1acf24b1d37d60efdeb7d942c53603a2f0476e9512c938b28d495a6f26a907c396b841aedd8e14ac447b495df1f676daccd5a740c042f5772b7db17f4f1a3a1c8e7c488370e736b51e690fd2ddcb5aa61957a7c7975acb2dcb915d074d744279ea1c4169f868873ac5c20890162c1df9656419975a43d3198e18c309a1eb7c1d87873fb15c6da47f548a01f69bdab9c39ef00d418a6f619dd73d7db45cbb6ad225a2de787ba777bc73d28fc304f10009f4022c2cf84de008d70fcdc8ba7f107c369859e9c90ca8a393b553f26605ffd7230c921490700f
+SIG: d0c3e248a8cb2ddc7e9f21c9c5b009f70ea29da6897cd92c260f047ed68aa1c8b9657f9d826e88f4a512c5003be6406880741263ae7ce6860efe73ad54d48204
+
+TST: 966
+SK:  d21fdd7b10e54a8b6be95a0224ad70664dd92112e2683a4fd279c407db3871bb
+PK:  f89c272e7d1cc93d69f694dec9cce05ac247734504829c56997413c8958b9330
+MSG: b8644adbef9c7cab9120acedc8e75c433d036ffae0f955be6a488f1f427a68a8902d026e63dd6c9bf9d97de786b31dd4f4c9a4f8a622f1ffc84da6967ca77433c398f4d3f1c4434989b7ac9d0f3b1be0c8b352824f4e7a083f342ec1be1da8fb755242a654880ef298f05979ff026ddcc044860e6757a29cfaa222a3597e38f1779962a41a4c8ce6a65b878199b4d80f4a0390cac19c226eea4b6036e57ad830ecfc00693e2613d3edf465fc8c4fa293fd8cfc36dc8e37bcebabec0349ebd884e1b28bce824e0d55b6d015383801668b34f5ba723d2ac0a264fab2c728608f162de01179259be2ccb0815002fded8e0d78b02807313e910eb3a7337c534e846f9ee155426e4aef643661b0edb44596fddcd0b3e814c137817a422baa40c9053d0386c6ecdb589052594742677c48dcfc8cd4a93667ed4d87646001eda079e8b99d52ba21c5ec5669fedf6f40447a7ff8901db0ef1847d3cacf0198a2f3bd7bcf2dd811a097fc5e5188b03fdf54e517637a14501000d0d35516caf0699402b48f8d8cc3afb17a56132d08237035a0c95490bfe5d7b7fb40178f281e4d872e47a0e955ce9736f3c333a6adf50ad31994eb9f45327facc8c5d113fad4713fe7f198010d42046bbfe68b0daa79dcb8755929be92f9caa150dfbde3fc9e392b2b701c3021c240e4679de41124b1888e5db5a83d05ceaf49eb440dc45026d450bc984b8d6f02850ecb570eee0a3819b12bc26367b5b98e1b141c9b0a9690ea4a3700dad12395f975d11cd77f96368831f21f4e968cc5ba9ef82474038bc7aa26122d218b743041506aebbd1f987959fd160d6eb7d58d4f576f8c0ca8af868e39b5ea87203937e0308acbeae91e10607e44e8ab495bc01dd573fbadc94479ff92082c7bb7513479c70f0407769025d34d72140c25d821f034a39851a93c623b71c9400e942639f28bbd032e1d8d3c059f7c2cd31d7476462d2776035d07880202dbfe9e07d154622d7ac6175a5afa79fed4dcc13712620c41994e11d924308fb2ff3a1eda44c761bc736f345122f02a40ae6f7dbd03d9fe96ee3d7a3b4a5eefbfcc56dc42ef27bd8085176038b9ebae63aa75035275ec34e4185739d636246770acccc6dc620e2fc9156fa9483e0d9cae0e8c463948a3d97ae8dda5966c88f07093292cce22bbda062baafa7fe84d0ba2d2dd295b23458bcaeb2ef742a2ed1c834483cd709385afeadcbc0a9c6a4f387babf7e3dc36c810db209beb66c8666404c661dfe9d32c4c08afc6f3b1257d6484a755f5ac701eb13f87763fee330ffa0422cd80a92038c6f45292bdee5f89e94c7a652197fc1906b48258372449b1081c6b97134c43c89ee2
+SIG: 6d69e83b3e7ed55a85f9fc9d2519da0b0a1eb4daaee991a6651f5c89190c0de72373cd989d46be1367f9daf1b92fed3b52bba54a1e4cca5bc8726ed07f302501
+
+TST: 967
+SK:  d336fd8408196d22fb698eb25b7654fda46f5de4c9b4d04950c398b59a44290a
+PK:  f3cd96347cea63e500a4c92c3bf215662dd0400784dbf8b595dd3d395f90cc12
+MSG: fb49c19bc4444c28eb2625f31d996d5e36c57fa6fdd772e67b7199cec67eda5451712df7a69dbbd56e7c398796b2001def651c4b9c05ee31d95679535c812a37d31ddb3073199cd704ff7ca2981f7b9c927a7f7d776fb6f609f727e6ea709ce7f43a60793504169a8905d9b23109f0d867966aa3e300c7e11ddedb9cc117b904f62927e48e4d73fe1a6ceccc4ceb08e64ab55f25c98216cec937608ad793146998f14c2985e6c2910df7b1388f9dd863f1e4d7d1621479b8512cdb34e673eb02a48934e39c2d18d70f966d676a2bd75db543d25c5dcdc3ef3b8bc8201848c30961e915d968bdc31946b0d18ede7cb0166dbe1ffeff9439c9c3404af6016c73edeb253d93f562a1a6cdd57898a9b3422587d5f56af3d06b3f6c25751f44460fb3299656dc11227ef4837aabddee400fa53f69e5ced053c76dcecdf0adc9ef80f4b330542ff1fa2df0b8d43cd1c311b1b9955c632c8e5f0491931c04de434df8f7a394e5fef016db2eb7c87b2ac7a4a73043bd7f98ad0a4d453abfb0be8be4cb145742aa56aa5ef2dff12230a510e3b7f82f7847700eeea5905b0289696c4c142bf34bcf81a962d75b8d091055733779335b7fd47a20d17c948ab732947832674371e22e711134f5c919792357f79bf70c4470787528434fc0b4ca093ee92543420d1ca81124f5585317e250821a4f3d8ce0f919de9fbf0127087e676903f6cb39025bcc73a0762954b72e66a6be9b96c97b6f6030bf5ca0bc2727a9a179cf9d9405f3fe18f3492389079a5b65bcb13a0d5ef41c2cd97e702cee4a2feb1e6702bd4c63fe0a4ae994c4287a837bc3f64c2d898857cdb32acd4bd133676e51f77bc7110e3ce52d9204fd2691a6d37078f68e7bcef30fc9c483985822b661119238e40f9cfdcabef2d7b16b059ab24adc05003712bbb128096e37f91bc4c5c81508be27fa0b84940be36bced2e65cd36b39fbdc5ea68614159228ca65c5d8407baf663b528e7d87734c7bc77dc8431a1dd6873cfddfc3e757d9ad1fedd3c798f1fe60e715ee48a6bcbb13b616a89a38e336489d3d6ccb726914112a1bc5d977c9b2a3fac107ad094b038ab75468263c34bda817c056e07a6c56697cb64a0b1f966f6de0bb1c0a71c8a5fe133ba2036d24daccad3fa03b39cd27f832752751055a8155913d040f51dae78d71946ca04d83c7c894c280aaec285543e5fd5e327accca9abef156a13b9571446bd8007ff92dbc0fbaf23a9441b53c1cd740c34c282929101ad2ea8b85d70052991b774e92ff75cc85113e0900b51b863e1f2adaab2dbcf46af479ea248ec2889afbfe737408393a2b1b3301f65c1fac8b676795ab5bf447f05e0daf6776
+SIG: af7e2df7529fd18d1b21b8fd4c0681505918e2511434fe4e4954e743c1cfa45e4109d36c3eecf2e25d209b9b5d25f7cbc380296d647752e30d3bea3b929b0903
+
+TST: 968
+SK:  6573227841f6f92831146c44c0e480cdf544bb876552cc5f9d42f15bdcc044b8
+PK:  192257a54ce5d04c19439fdc9ede18ec856e29870e24d3731fe2224799949b7e
+MSG: 6e7c6b122ab36bd135f69e2b85e7fccefb072c12cf088a3229d876eff532389f0577116f7af29f1195e3828839381380467178b229c5a18d7c4943ec970dd18bce723bd0ca91ffa95563546a324fe0b9bf6c0455d4276039e8d291fc7276aa55a1cd3ea05282654a7f9700adcbc78077c5dd0fc86eced48f4a60ccb76bfb8b4562bac22a02d19e4489394ab9719fc144f5db2ef039b37f3b51d1d657a0cf835d71f1a4af01eb9fd885c604a624cbe910bfde093ad3f0cbfd9a48307329d44234bd01191d56e522d72b54e1fe4733da3aec6827eab3554898e03e577b4e7b9dd3f308e616808d0294499f2886295e54c360199ca83a83ff46195ea3c484a66838d51acbe9611eee036ae281c6793cbd451f9271fb5d25ea7c1899ab5d43ed8b9d067bc56d8d4a15f1dab8d8d95d1b17af64cb18c1147551147addcbdd53fbccd9026f855547131bee95071639f649f2d035a25a3e42e38e22bbf038106ce8bc4ad6768ab92cd57afacd04ee55cf0714b768952dac240b1e9b2835ecf7b0d6c407c82524a923b9f54d1b8f12564a872144efad3f3a7d2397cd1217dc5a9c96e43b2960a8425e97e07a02b0dac90f346b91a346a23ed2bb7fe6919c22dff03f62da7dba176e8ddb22f3f3a668891d3f4e69548d0ac4e71e6d28ed5a67ab5ac611d460b67a201f4f56a5003ca7a7d1cd1db6c10075b09227cb8c5dc1666f8be710b4b7bc2b95ae60da4f64179a50d2f88744361591671d36b7296315f6996439ad79821da8e772dfbf55a90d5d52ef7d76b35ffebd42e3525f4530c54a0f23b4d07c5f5974470e89404d176eeff9ef2333619691c59b7aadd42c296b1d0d328d9a3bd59a54bba93a0c1f1d62418c2190c38174b6abea02db66e818320ec4b8bac1c12f18f30dade27e63c58f9e7caf4bf69b265a2f9d91800861acf479e65ec17e680577e058cb16c109bcf9b2909fce3361a2c2685c10be8540a1222db5ecf0cc4d53a4214b7bf6248adc3a861e34841a3779c46046c5364f1ea91a78c9700d462ecfaae36ba760c1bd6a237c961edf4022cedefe5e937bbed7051ae61b96d08b0487ce0568ff0d32740bbd49ad0db86e09102ab21a915616e9dfddc81ebfb36c903e07a40cd2dd119ff4a50b93fc6fdfc0f36e59e0148fcff3fe8e2cd6d30a9e4b8f015567d118b6274e1ed75b22e44ca9d9dbfc160742cfac581e1a0bf5ff3326bc5f7896b9ca05a811d55e97c834d37a6495cc26cf442bd2d90129895e9cc0ed01e2155293f47a07ab5880c6ca29ed44d9ccbcaada7f3eb60402181488654e04911578b1aa9cdd4b86b0dd2450df3a43081e4110ab58de763924d3c89152e99293e638f9acd8d7
+SIG: 538eace493de53384b1e985bb907c094f8168430dab14d37791be6e78ff3f5a306ec70dcac86d993a4c1f75850786d795f022b79be6a547769e41569c5a9a30a
+
+TST: 969
+SK:  a63c1f54b2ca058fed2ee2504b983ff33d570a9baba583c086cefe19f43ec49d
+PK:  329b866bca4194297fc1ad5a0eba0df956699c74ab7da5fa5462bd0661471020
+MSG: 791b86fd587713478f9234ff30cefc123cd7c3eb125fa74e4c6db64e7844f7c85b1686e71ed08d1a6a04e0ebbdff4ab160c976c8ab9b505f6a7eb0a18427e999a8828df10684f8c75b6a6b0a64c0afa4bb22bed1cb9325359cac3b8c508d98bcb0ebcd748dc132f1d6a360a4450d1292a1fefc4e57e4107a223f421e7d14a384b85c18844d0b9eed2ecb81bb74e8a12652d98505795a013116a7076ccb5493d6a711f7637e97a780e74da1b39b15cc7bbde2e6c4d0d3e8300597c836e80bcb8d8081d974e02432eac88368211d3aaae89a14417108e1ff6737083849c625b40d631f6c8357220c7f37380b3b2cc5d0e2df6b4d1196579dbc57b6c9ea0d41f4fa0e556f943c9448ef42fc78df5996648ce2f3de04d8a663f967f3d933d4f65357ab29ba5b6405fb162972578ddbb2367bed143c854c1088de921d79f5a92a854837eb7702e1ba925c6eac23d134ba1bafc5d46de2a1942c7f366f701b0afabb75cb1d808e1a1e4e3ae5de88e8e9989757458bddd8a806c110cc3a733d1d4ac58a405c4d81134fbc24ccde7d5afe420f9f1785f0a5020fafbb2261222508aa0528b7b48b567200958425efcb42934a880b133444bb109f2a954cfa35a2d17cb05ee3f16d06b321a15f91339abeda243ad6c0919fac51e907e053fdeed1cf03003734137793941b8adf9ab6af819c245d6d56f16964c8a75b0756a8cb0ca8c12ac6e6b3942eebec2f868835f81b109db498a4ca2e021fa765608d23d803dedc9e51453fc1d2a6a38a4aab257c0fe7d67d32a541e014b60e1013a92c1b3ad9e6f11be293b246f9a0c6440b0b54fee75fed2fb75cc91ecb32738c495831586a11242d87dcb4883edf6757a50b18843759b98dd0cef4a3fe10d76370ecda8c83fab87eee2656c5f261c340ea91a560d0e2c64289267f0036ba35944800a5a0aef3f1df839a724e181d79b8a3c16f65ae27953c4aae8ccd30ff5acc4b31e4765c68fb38319f10acf89247b5a39b3b08a191754a24aca9596a1f8a70b6e4f03a2004a9086ff6ed07652a926e1e2df7bdccd5bec16e5c4e968364a09abf9ded93df5fca0bcca5c812976e5cfb3c3493fc175d1d92ee8d1c98fb3382b3ab90c5c0e4bdf6a3ac94767b68d47e6b9c244265e3b1ab0623a8f0100273f2c607de89612c72d39be4c0b4d77a3c61368df40b3608652989d1e19c0aaf0e3c253e562c6409fe6448929b33753de162e6de5bd466a5114fc0e5f57102755e29544f03b28d4f78de9a024dd4c4e8c3c2d44115a7ae15edb4f558aa7dba6426e7e372c54f7940bd7714467f8c3a1add3c640189c31660d8cc01d3c5382e42abc104c723f948a804ca853047b6b87b5b6ef4
+SIG: 283359be41290a51e6a7c5d5725ca4ea0a68f14aca14b0f02566dee21f490da3c7e95f7ab739bc35a7f4f232e971aa157657a633eba0e72dc97af32cdb928702
+
+TST: 970
+SK:  5b67a6d7c650dd92ddd036ce7a305bc959a497c5e515a68493035cb3850ee03d
+PK:  4c6fc1640505fb46669f93048f8ef557099f3fd92a53064b163363a31b7f00aa
+MSG: 62ccde31772c57e4853aaf2a8181fdb53fb82790ea6501bfc8f5d4ae8dbd52de42ce2e8961ac1731f4bc085fb561ef09a2442970b6297901aeaa2ee555b7d5e3951c7c351239ddee95ff54f924da95cae7b15ba6a9a1337b8ce4921ed913cd791c1c6941080e548f3c36e845acbfd8d8ce35e2fdc2a2ad6c7e2461bfcbf1aabc55cf0fae428885be5e86533308c9756805219abd7ffc1657b6f4632920a0c10e0e363319d900fcd61e7ddbcd6e762a7db92480c363b2c0640c6bf32d690dd829d8405fa66e4783ebe1cbde9547954a90baad9f774e94549abbff2c1f5caec2bfd28e415d36429d58518c3e17e8699e1989d47b8d627ef9ab4d1e7d120b372c2141304f7fabd0265b8be41f5467f4de9e65c125ee1f27a289c4f7c9a1fbf25bfc2f8d308e7ff52191cb7644c6af204522f2ac87b5f40525fd43d308c8dbc6a861d25db23ee276678a1b6e8e91283be02470482ed6cc9f6e396351d11b1c7e22329c091fe7d368f60653f93b0f6a3f712c20f9d2d8a9a0819872f0c71d7b1c0bc1683a152b484bc21cf556093ab4c0ac16d322ff0bf452e5581e1e7241673884023c7d6e17e2de8059f60e4c18e13bd55fcfee623fd0469c0d0911611d099a257020f2f31bf5078e6e65a135d5bf407620236d6cc759310fa728ff8bb5ec56abbe1a3cd15153f892d958d30d162d01ee665f5b562781d8dcf8428059e5fd225ad78a99ea760fe5d9ee8219c95acb18d05622e10a9b6c67f6d4f6ed11635c5e2e0f85dd5d3cbda65aa423d594a80b40427bc321e0eef9afd2bc8746ab7399ff6d0e1287b661ddc4062d072018f4c10e86cfaed72d9e686ed09d5255d360e3eea2c29b9eaea05fc78c8cdb8c9d4afc7adc6d4aa067b7abfb0a4e940a77580ec206456cb9e9f95f6d565d536e535a167ede8e20ec36081e2fc55aefaf24d227fffe5e6cb03093f443b4c51655d91ca6f275959d1a802adeab44701b31e8b0fd0222c499966c72d1020ad9370e2802be04c9933f6b774f6e8c69fc0bfd315939a127b4e06d0f6f5ede671ce11612126b5187b53329b0a9cb7da3b1ccd67b8c07bab99a662df8ce851f502fc4e1ed1632b6ba555544018f7527e362efc7e3b2ba6f75a1254f428b3b7e0bea69549e7f9c736275550080aee3af5914e3a34be656c77f6b29420e5433f3dff3811f3528208e9d850aa3c29b0f778a2427d5fde30732dfe50443a9c1ad55c72a08ab26ffaf8efb90bcafd3726b00c005c8c0f0dbf2a1353086721e446545b813441194a755fd26b963afd977278d1b10f09001c7ed975403c15cbe7f992ab07b8470c939f866f420f77db779af839700329e0777a6116365d76c36d09d860472a5
+SIG: 0f073c9a586f6f5e08389a2a5e1808e270f0edb6af104496f93757623fea53133a731c445ac23578cd56a3883c08958668631fedf1446ce34f857f90822ba80a
+
+TST: 971
+SK:  2631c8c34d2948ddd5996b4149cefd238ea7452ec22e246124dfa279ccc27db8
+PK:  c3906786ffb8a7c27c44c2447f9dde7d666dfe588cfc54f2d25040512a371bc1
+MSG: 6f9bdce1443f2856d4a2f22782835012b7818a0e020dbcc22a821658305f134234d14cea636100ed896c2a8fb0e87048ec6f8b31484f78eb171045add72c85710ec9f9b5d43623417b5653be86e7fbf8b4ff91110a808cb41acf66d436e89a737faea4eff3544960f114b833b0b4ebc2c14070b0bfb7b0057eebb842bd1c1ed458ad3428f8f72a1d1db3c4cb4797a399d47a1e6db74dcb2ee24ae81585cf66ef6d9bd223f0f54bc8c1cec1bb4460bef4ffd32ee805c3ca5ee976ff9c14559f8d756662a2bc19e4c5985406a07305c9950d866c9a79a3e5f6c5969753a170e0fc4cc09c6d87a12b44cdf3be1623159e90cab7a8a3e6f01f268595b021b1ef7d00769477270d5584c912e22a367438277f59df20c5620dd5beaa9bb60bee47f4af527d892957b2d12b678b5279a3f83264654c0a0f8d21e709668f30fb6e68f047d0d9a7c2ae9a28f7cb9dbf18f63fc1661f07d310e540c77631f5bdac5824685d7c9aba0fe1d09407a9662ef18eb3e28fd1e8bc892657bc38243a2e6453bdaeabb2791fc5489521295457ad04180ca871f6318792bd15fd1800ce59dd3ecc7e0b72979267d8183e804fdd45daad84fc4cafeb561ea8d6a74a7cde722d96253ab3e75f0adde02a61fd5e1f59cb1f5f1b2e052643589a9e4be4dd6ee64538cb0b109a113f30a58b3565624043662abe17f60e31e89c36c995e00ae07f56a9118a31aec24ad544bc965811218df827c1730bb904bb79b68613f6c994679b6990d775b5cb32db97194bd81019bea41f3a7eef501bf8491b0ea859388452e3ecbe16aa7d5691510a6606c493e4c293961bf40b4cd300d9d22ea1a7724c078b8bab1fd16504e989b136d9251ac9f1ed94a5e9acbd9c04f8058afe03049aed8ba29fa2e8fb44f8e8c04e8727f399e735e6c1496a91a9b2cd2ab02d43b285e9d7610293b6749df1044b30e2da99a564429a23e68c96fce92b08a00b7b742ba97a62ee58776d7dd565a490071d4b19dc648e03329cc5c825d387eba49e2eff6c4341865c464f13f1beb1827a7f268cc15a982480bf084fe3652c1b0e0b4ad26255859abf1c8a7f9b3bef098a9407fdea0a539eb008fdd749fa0186cc0169d9d9e68fe5e54cac32ce57b5c84c2d805eca39c2dbbdd2e02f7d228826712ff4a61411ca0aeb6f01a1f80ef29eeb071a43222d9497184bd85d9e44b166be97cfd2a732af4a233463d3ab543a7a3c7aec555656568840f4dfea217f6553aa98af324c12b2c3214ee76eec700670af68c8c1f36946efd7ff0933e5453f128e9715fdb3344ac10c4bb7ec8f10ddf5db71f1cf0efe40f75e5b6334ef8cf8429b3291e6e4ce379c178affcbc61030eb896d744d
+SIG: 0adc6fa40ffb81f6ef4e4187554917775cf465e7b5e857f2e1e7f400977106d2377ebc76abb1db924c64867e3c6fe38c0b4fcb1d0f9468e8fb235029a81ce604
+
+TST: 972
+SK:  39769a66f0ca1290fda14375b35c663f6a4b2ab3607179abd99063e2efa2c6a8
+PK:  f9fd4c191f38f12190d3285e20c6cee54cfd6ff315300a4efdc8a90e80af4083
+MSG: ff4d8987e3fa36012b7586736b793d659754698cd12b65e5ba9d758cac1649288d20224377283ea5425dec10ab9917d18cd13d1bdf4a769f37044c84faa2a449c689e004c14e005c49da4106ff75ce1303361c6e3e34ccfee75ee9c31cbd06a4bcdbb42fd649be4dfcd664006d6a5f61077c04a6a81db36be86ba42c2951f051aeda64acea496cb924982b9f7d234ac9723fef98a8e12755e326a52fbe35851f411eeb867606d45b513f54526391c554635c180b8fd0ee451afc96e4efd360b61e6baf03dd6d19ba515c31ec1cdd3affffdb27354e3e6b56e9e1a1a1b7d4b57d9d7689bb2fea6c8d3f9ce0df2d9ee919c4230a1f20b85dfefe1ea3d7f77db470e4022429ef609b0ff44946440acb44cd13445bcfa3f20503c26c2fb663c89065fb9334a603eb9ab7152e62629233c44cb00e77716d9b72c84fd1b340634ff1cea347501576100ecb0fd1bb76ae0dff1c2b0948eb71ee2cc31e79d3015d72dbee224a980e0f95a69f793da83a2daa56efe57b2f8ceaac9e55f443ca9e732b48c75fac21c36fa77273c3f34835ffd83c96f00ac6e86cffed08153646c1cea223da9ca360cab97e03b2b6c8fba7c195a39ae52eb2ee864300ae56a10f547f99a3169872249f97774b1798935536f2f5f011ce57613a94fcb7e7286a6d49c10fd929d7671cbb8cf17dfcad4b2485c3d8fd79128721e55d84808763c2afa9c55e3b0cd7bf2f0a66b5e467bec5ee89ad570b60f188b3f7b4a511ff859312ded078d8d0091134fd49bc792d2d7d60b304941c7f23206f99e863b1e2d8c9ecffd2ff0a3a3c754985615a9a92edcead00fe0e05493b198d1f7c90088446bba46038a71f32653b5912b24f43137748b75aec2c15fe4bf5a6f86b8a6cdd9c7447f2ebb0f43b01ca1523e0d496240006ad7ffffafe0df5754b342caff3555d72a27d0b92ca1667665cec43bfb583077a9c1741fa492ce3dc2c7529cded81b8281a3f375948b8a7ced096b2facc25e39029e221b66a53d3979e1f405fd88afc06ec6e4309dc85e69d6ef2b4b49266164a9d9d1c31ee3921127b13381bfb740dd38dc1c7315921f9c2fe58b61b631a7d9fde2dd8a4be3ded0490ae3b8376791955c1c4b4fed00b9f4c38ab7350fc2e37a3150c18162b1faf0337894bc23e74f595e4be33466deab35458be97b4f7565897f06852f71c60fef9101d726b72e0102a97b2ca5211e3806834b0ac1a7df87c2a078df263ef8ba457dc891b7f2e627811ab622b9946f8c6b731f24078d17b06b200c3447f8032aa3e7a243ee422dda2e652fd75713afbce8a59ef8536653a48dcf42a70e7621f9b2802409be1c1a61f32e36789a5c5055e1a8268e9dc438c2e1527
+SIG: 1442dea2807e031159ec6a412d8e07bb3e299308090f218fa7c10a9c5068ef9b64ef11ca9fb92be1d0216b99318ff0f03cb871cd7dd63a38ae1702313e5b250c
+
+TST: 973
+SK:  0c808b066f0c8e8dbb1c23d6c2cedd0be866d8425f241a9285700ea54536cf6d
+PK:  44ee72900450c56ab21f2686d29525d0663e0bdd87725beac5d68baceb69f1d2
+MSG: c945714100581f4e24da11fc0f6c6d0210433f9777525124c55ee072d85d798b705f9d31c8f977db6edfb7a65c78ad2d7d31d6b7b5be40ff1178d303b6839bb0c63210c1d338c103afa0d453eca1bca277d930778ad50802272f03dbe2184fc31ef8ea6abe216997199f7c1b337737968907272aa51bd49c07389c95468cef4fd99ae78ca4542a2bbc0e8aa95214ad1cfff9d5085a434394473b84b74be9bf2f0202ad1ee4616604ca1dd75f4a195342ebbf8fc59f3f79616554dc7bfdd556be437221c10bfad39e119e06045be5fed683d3534fb6cfed33891c96f9c330f28b684f8fbad47c01418eab6ceecc2ed777f4c218a27ac22582392315c53aa7309ec54c6175236e4424dc978465ab628d9544b0be84103eb56f1bafe5e5eaed04c98bfe2e8a2418c6c52a61eace85236b66c7b3b8707ed55641dd9d5da97c99c11cbeb9aa2db147820dc724800a9d80f505fa5af20921cad2435683bb4fc60bddd475f863e2f5950d236399d8d75b404b394a546737f93a62408700b3ab3c1e922b1a859a2915c2d35368815cd45b85b2ac083121ff000f050dcdf415e5275a5c42dae3b15400f3ddaf9339f20a1261a88cd90205639763211152df414a9a6a6218f56b35a2de9e8482449f6da77c9e3d4af0493015a726217f82ac58954fe3e2e34440356b112e06a6f671fb5a6ef4619a6ea7b4e04db3757fb664c396b341ca89001dc1604b51fa9153f9130c1020ff88909287823ab3915ccc85c4e35df6c2f8e6f902be82ba21297fd3835aff5ce02f3c07dc093fcb1aba26e06dfe6f02df79291aaca069ecab9381404c9c3ea1ad409adf292a91e3a582d5a7b68ffbe10a0305248e0967e6df372f281bd192e139979c9866ca8fe1e10e0616dc2d4f85e119e0cb4bfe8cc31d9f5c018b65408524000a3016a23d9914d57e955576e2660b0e0d96c8495a12c3d73122d200b0f0e5ebd446562b08f47934ab499a96991dcf99c96a62880739845d29820150553eae9be0bb41d53d3af01d9867bb4732c90bf6e137316e3b1edcc209a8a09fb062a6ef05f37e57f2c5d1d0cabaf07a8ed7d41455407b096754180aa96d3d96591945dd7a1040a2de60d8e1c054f7854652b732e7a8f5b6474c3baa1840fbe81b1e6b54e201ef0bc8d0f213d7cec1d824d22209ac72525a64b903e773b83f1b68f640279f15053d21ec15ce2ff75922176b7584a16bf1a1f0d636b7942a3d61862f6fd1309972d3141eb769314ca975d020bf02bfddf17d14b60eb786bf9f55989fe473320d4429677e301c682633f813ff26c0a3da92f6d0680616105b0425af338c2ea6153bdd5216fae2afe461e9249c05e32f76ad7c429d92534b686dd1
+SIG: 38c682cedefb13e46b11f7b5f800cc8120d45a83cd8d8dec10c577bb0153d509ba4fdf400998788b706007ce162b96945c7140beee74e19d0743afa4ecfd250a
+
+TST: 974
+SK:  049dac3c977d9df503496b43d76e5540e315001ad57f15ea9f0870cad2d4f9e9
+PK:  fc6f4b7eb39a711680f966d468a61abb13a9b6449bb99fda3d12ce1b506d1b4b
+MSG: 7f31e346f68da73716aacb16eea19bb24142dc283e7263ffc3f704a22ae5275a0ef95f0669bae5a54c7feb84bc74873cca0f335d6cff3d8b4a20056c64f5e882cbbbd2ac74207676467e5466ddd56aedf56e097c7f59d945915eb0ebd0c3c83d48888d3e9ede51ad2dd8a0ee1eab4cf87ffa78635afc4d6ef3e87dda3b65565c2985a4ad0acfdfb81cb0e61c67826a6ea0bed4c08aa1a541de60458704ac21ca12f1c8118bb3092c35a40c921e684564562c2c1049dcdc2b8d6a97e3567d356bffb5692a41d89ddda0ec3552152a27577f1cce57d00986dca77edf5e2518158200adf690affb31aaf2b574836839440999f15791cea85342ac94a96c7af7a19e494310ae26675f43c35258e85b6840b99c6b09cfa58d19f1e43a77e397b08c0db1830bca67b39ecd8752da611e0832c6cae7bb8ce74a82e7e7330be5062ed05aa5c84457b007fb5ccdc20a55d54d8e0409c8bd83883d2e029dff26ea5db275dce099e418659a0400f13be9ffdc14e7d645a94677ca846970b7e6ac527fa009a359454b3c49364905189fb49c9bacb650c03cd82875894e3546ba03c32e336fc6516a87676c50d5b80b3054273b157c5d767514e54574b8a101985a8e967e95da8f929800260e08148beee2d7781e9e85d463a94ffefdbb75c28fa8898015680999429cee798b3fd2d96737868a263fba9fb6f4aad56a15c6412ff85e7d3752102daaf25e745fa5f6f174a231fcce8624dd70856f9babcc209144ff6864648dea0d6884566a4c39147805be084e4740bc509309bcb142964bb0cfcf6726a0e04bbf32ae6834732bda0384cea8f4a4849bba0d18646c1c34471896b5bef149f8cab9ec83722b0fb209efe8a04c4a235dc8ddb20acd92765afbf3058740ea70b9c10d9c5aef8606298fe4151593b21f797d92ae9f1e0881b0d271b0d5b10c6ed83c349ec2473fbf2ff780dcd076d8cf0aeafa71fe2b8c5128015f8fbbcfecd5281cd5eacb6fe9ac6eaa6e47d667b9ad4b7e411e6cb7463d567607afbfd0418c4eb06afe847f5e40b499443828d5a273a4a87e46def21a919d73863af0054a099e3adc5450b8e32f51ea52c599a4a2a35351788af7cb71e5c44bcb8df54a601e6ec2c1828b48c4b1ae4463106f10efa5caf3091abf99aaba5252f484d3bbc62bfa6b2a806d23c6331a62fc46bc627679e73ec82dcc08f79143f4b71ecf357ea2f0d74e6d3058e606043f6e8fed704282c16b1f988ffa365cfae9a3cf792e0c5baad70ca7e25776018b5e7f0e9544e1d73f3e5d1e416a5e50fbed296dc1bf4b29a3fbe32efbd7e99c83015d27f535adecf175fc36c1ea4f4423b36dcdc054ba993278e85ac3622d435f5237ba61b49a
+SIG: 7532d1a61a981f303d7c2454354f99540cd484cde9ab337d6f7b51f179220f7fa2073476b41c71529f9836db6b1d0f5a482bbb4c68366176ed14d4d8eefade0d
+
+TST: 975
+SK:  f07d61b5ca1c2700cb50f900c26b7c28f6c6940808c7bafff74fca4b11f425d4
+PK:  eb243dfacc2dc6435776d554eced8bf92390604b35557cda51fd203eddb493fa
+MSG: c1c67843d69a0e62e7bf71f90206a3d5595ca3c482aaa767e931b0d6c2f4752ab86991f03583bb138e9f72fab58fd602a4b6b29602cf891408af5a1bfd3398c0178c441461e3f49bc81d64c0d97f5ded692c75d4d64dac5d80d63bd4dc5210c1d9350b142ba6e768f150807ab8a86cacdb59d84ddf660be56203c014fba1e0dc16fa6d32694e14b128edd1f6c6ab445a3ad34174fa9e4b01f25b1d5e6eb76983b4295ce4914d3ae48c704a30e554fc1f868b6272eff06da24bfe17e4e0f0fa46bb08ffb907cb61bebe52df311a64cb578b30fd627df11221ae4003a0b0c68e3c6f95a21c8500d41b2c589cc46a139cacff57dcf00759f52e9ca3dabdb1788ab6b38a5048f58e08e05c394f9d3c72113d452b7084c519f86c1689ffdbae506ed8450522cbe43de27aa3bfdd92a91b71e52a3cbf77c1bd2893eabd407a57fe5e146873bfb2043f4a6147df083e54a2208d1925813fa404e4c47406e7728643ebfb0b10142f909ef856fd3a916bc0851543b82a55f8cd529bd21d9e2909d6d7e77bdcea4673e545ff4a67fa37d65f1f63f11d5d0d55974a30abe188335db5dcbd356658f9b77682d96dabb258ea95951a0559aea4064d5ea1680501dcb4228f2c956f81d2101144af74c716bc8bf4296dc3b831725cc17d3bfd9066a29953b2ecd75059435b49a25ac525b4fbab1779022dfb6de525149dcd902ac8a7e21f344f5f0101480692d61608952c71413e30037945e206c5eeadfc3edc4bae0d796ca0c5f56d6ffb3f0969df9df8a794f5dc83a3b2f5c3ab36bb901bcc31551c550c63fa41d6a8d57bdb9b5c65bc610c3a989752ab28a015e7c2f6b2fbf199a76b9750c0d3d592119c8b4022fa45bade2fbb41432679b52acb4608a95c34aa40bffec10bc98f4729dfccb650b2a052dfb068959e648a92d5aa4dd2d17dde67cdf2e6377af0d4ae379607389d7e3596441b9f4222cff6af73b3300270ce54800bd934a9109a02563adc56ae46584451cdaf4a77538157e5870f4ae12dbc81870f5db41a2cb55e00db3d2231628f1727c3acb99ed3acd8b67156a8005a4cc8f3d3555b79a03773a931f14eebce40b9fe46ede5da0881fb220717e418e8b5a0fe5e477e7285c554e859e16441672b489934a3a9eeb88d78fcc5c1db2d1fbdde392773f6c939972ee8fa3189f4e9872b4abdc83b379c0c10e818dcff75c83d6870729284ced41f2ff55a87c960e63d1211f08071293f6ac63f9bdef38fd5919ca90b3f5e25a6c0c664c4ecf831c64e2d4c6e798a98a3a0f7be7a2463eadaa6a2a348f9a494717123cc0a28c0a5eae3f5b585f2cb8cb260c2c503e41578573cd9b7cba1408dca9d860ae4f8c3d3f322a45b58a2c4
+SIG: c19b532b8248563932639701bf15bc015faebb17bb98d871616e1048d64ca5f955f558f63b5353a1576fa1acaef39bcbc9021756df5d1ab3bc741accf9059b04
+
+TST: 976
+SK:  50864a75aa0c69b59350077c204b20757f2b8b6855c37ed721b49f2ac917d6b2
+PK:  cff3ebd5ea0c8b5531d9211e2219e4cfe5ded991d8ec424df54cf53c8376f9bd
+MSG: b365f476ac92e76012a7ffd8782af15a3f5ee147f603a367adf2f9724613e8765b037ac0eb1f673736e11363e352ed5ae9eb5a67125ed818900342ae93371c433b91f6021d4be2a052b0da43b3682e7f740ae801d0541057858eb0c9c28d98f03b45e128aaa342c6b602776792aa81241cad06f1338fa0c71757180f588c8301d91c27679b5021cd75d7f6171ee9f8d56e4377679812f6ec5ed46538caed500c1d15f5fc86eaf9ed9cf9a0606b22614faf676462134e3db3582332b483dfa54ca29a5eb0d6bae3380e19d060113453f32bbab7e118627b40bcabf1711bcfeab8957de339436c7088bb883101539a09d3bef088fc1f840764036ffbb33decd12aac57fd26f84823e19553d4d67e000e9436ca323de099bc1ce75ebf5ddccb448cd7a2e4bbd6b32e3f2024f96cc5c7152b8be8ed0bd8e436d324d1ce1dd3cfcc452a28c73a95af8482aa772ae53d5be1292e39d1716b43758fe563c8aa3b74bba5c02d04778d91e3d43dcc72bb7c7b043c05c8745b705ee75b5a4ec7b95b654359fb5e853338219851d40a8afbb4f91ecbb41eb81534196cc0cc9d3eb714396caf045b231722d4486503640419988480a7815808be974287372cfc489965aac5b8095c637581eb910f9055cd1c0a0a3b0b33aca90f7c5b8e6ef683abf0ce53aeba51bec4fc7b427a2347360fca8636d3f1469284f269a9abf0cb1a244a15d6b40465e75cf89092474a8beda033391dd311c499519a08c4f034e71918d7cad41845327c89e7b1e94afb0723782ce5c553ef36791bba63de17d746491894012cebd87b1837a821ef5c624bbc84cc5035f5e70cd9f21b42219a2dce30e0e65c250d0d194d2b52486b03ee66332981a5225174db17e5a8bb4a10ed9c8a445c41442f3bcdb6b4f49e4e1dc87661a7b6e41f35f55dd67bd4cbc6ff58bfbffaffd2c382fcad0cae8f0df9af6acf0940007618a54aee31d932cbd8e8b41ca03821c428a0ef8e58d2435eecd503c54da9c1628f3c749b770519f53bf2d57ed712d075d37337b77a2b10a72d2d590c20d5cec2cacc6c3a8dc113e2d16ef2d1b390ed96e4036acd304e0c7cef9d431f88218aa1f83828dda636b94aa761c7317ecf116cbfc611e5ba6d94c50e994693023bdf2d248ed603f85be73a0008b75adef951dccfa30e42e9f5bb05023ade797506cbf90bb6dce43cf3a1c3141a5cc5fd9a4f3cc557b90e18049b3c130f461e4f32299fa1d1cf9c7f2ea2053565e8160a341cddf99acddd491697fa705124abdab42a5e8fcf048dd9f179384ec92a469aeb11e8bc62b69dbcfcec6681754757e4c5d0fdd9b9cfda49af09b83a5a4a10aed9a4cf7ddfa289209d475ab3318cd4b965e007dce1
+SIG: 177455a71694f12b762fd17e08bdf010a7fc91d19141d7ae2399bd241a998a6a50a9722ac1232c59e4e2aaa828078b2b92f4a54cdf0efebba2c16dbeaf072203
+
+TST: 977
+SK:  e55f220fff8079148b254189bb294174f8e2c575e57f39d4bac8165c5e56e769
+PK:  7fd507d03fe1d6e3f911f059597b0e292ea096f5bc851852916bf1217cafdc6c
+MSG: 1e2ce8bf0ea7875df285b1dbd34bbe67307f2e8ac8bc142c3ba314c1642c65a2d62eb2c783f916283ca4ec3e536d3eeb65cfdcc0549ac4f6a45f539ac5df79a6d5768219739d0c9a0cdbb31242296c3312b7ed560043f536cd1de9a9c2b289641a1c2d84f9a68b7c03b8b8567e5dc7138c2cb967c628aa25b2eab434d4490b23507409717cde94da59dc1dc25c7be42a8aa02edcf4d995368e6ba0ee1f953600db98d22de0f8d257020e0a406ee1669bd527b9fe1c611f9be5a3d7528e8b6151670a8663d2ed1a58d3e369bb722a6302d7c172a19bdaf357eedb02279156e3b9034431a7d68a39528eb4023587573eb88f30f94e833e8a23b9d0ac7b5ca87824596bbb0a3d0ca1b16a6878fdf7e2cea34a6ffb95a9ff4e888a97593735b868da75d8707bbfdb1d93eb86a51e2d215f1dd9dcf78388729a3eb0f066ddc941e950c92127198bce63a54868d997029572ffa6f6fea1d3a69164c9996953dc8b6f9dad0635c9b081f55f983340f0814bf5470803090e7997f7ab796c2b15adaf4021d67cffaf6e1ef62867503945c21a329664e08a95a41582300da9bed208444ce6aa12b3f867795c6ee4c4c9257018627361293bd527821a29a339b404a2da4bd9944f877040798bb54abd2d76cbb18df4297f4ce3337f64d20580aa64bdecac376a6a4ff74d0144b2fe74cef82d50a5e6bdd799e55ff69662bac537adcb6881228cb63704500c143a4f4d1db28d4556bee604a399ffd206546597dee92252547f6c657f36841a87d565f6552716c25a21151477bee9ef961855fb1af2da8068f28ce9ff70d5252c7a63a2e14ded6b8977b1d7691a77ed2e57d22ff2e1fc4cdbceb5e805858d903896ea6707e48b345f60e2818b2fcec4dba48caea9efa38279fb83d5b0f46a45e42c41765d0171baacd8d6dda7991314b34e15fd36127c467d1de01c01a3a78a8c1b103bee17a7a0b7ac5576fdc226dd2459773146cf38261417ca19135dbda9bdbe54cd17aa7ddd38fdcac2aba396b365ceae98919f6c5177fc583f5bee3f48704914306aa19ee90e3fd0de5591c669ff35ab16fef38dee187bae1e5aaa566df10544b7d6d4eb00da7ebeb4ecdcc4d8e32b49cbbdc6e66640bdb0f72e05918a05c35d9bff7e0e88f241d7c6c8cb2fedccdf65560af0e7833efe34af790db63189022cfd71fc8acf88860127bd4fbf026bcbe360e33a8995e636d03bb86dfd0198ada959342d8e9c9ed93e23297da98d66a0d4fc965162733bc86541b95a6c9097cb55a973c6fac194e8f8a164274c479c510e62d8a035eb751181b502afb614d8c4467b5445c268dc3dd0abbd577004c0bc47b15fcb801b79359757b5ea89cf8cf77fc6d160e6cd73c4
+SIG: c1023a7068743ec4668f495eb7bd4db58129c11e58299ea87d6facd302bf296a98e298fdb48eddf9c44e79ae8641f734503bb83dc0b31f610df1d1e9d619a705
+
+TST: 978
+SK:  d5e3a40671bd45f08842ddc78abe57de3b9ce5646b730d2e59fecf5a7df80f40
+PK:  416c37ae1ad15b632b0ea43932c17637282cd91d5979552e5eebb99a419d5c97
+MSG: 09fe6ffa8bf0942a64921357659dbc6e4f8b63ca3b9ea475ea39d7925290a148d87bb155741dfa28ae1beadc1f3e1ab76737eb5d5ddaded0bb382d7e11ea81a5e7801612696260ba3bd09c80b623f636380aa0208fee0aff70812d5307b27183832343debaa3605ddad17ddd70d611400ddd10d638aa3d6c68a28cf0e97c1dedf6ccd9c731a84ff0405a3a22dcba00ab44d5b21844f14d1374ac0cb1e58df4a90c412563cfe69d882d350f6aafbfa64fa2f9ff826032326780aecf9305d8217c179dbb63c151541232eb65979265d876c4bc4305c02f40bc1d05dbaf7dcf4f7dd9232c17ee0f7a0555f504ba3774548488933e7571eb3f71c4cbb20cc4e4a7322f35ac0e79a59155798dd0f5b3c11319b7d8f3ea79ee3acc68bdb9f37c7d4c8f9caba1ebf8eb7f43b462aefd38e8c0d4c63979cf6631dec31ab5ced3937ef5b2362cb09c71dd096657700fd96bda555e22712f71aec11ae5e91b24bd1649498b8d9f867fb6c41e076080f740d074c2a25572d34e666b6367bf7cbb3dd42a2382dc1973961268605396810a456ac081bbfd3a54b44881fcfc45b4245ee72465b487d07f2ef3f74add71cdfdd16e92fe257d334645b0a9bc7d072613fb9c0cdea9db4c72bc87109e102d7cbaf366ecd67fbe3ded32747307a7aeef61735ad3aa5ce95deecc16a16eb2a0bcc7adc0a11d888032260e7c7ec9e54f5a2531702a7e5dfb87c36ce313a3147588aef962c72fa966d241637c388b83ddec9343bb86343e920b12ce1cc915c83b31e99862690674ea4935a48809d4d279054137546392ad9f08e7b8de61ae73e81e483d3c63b5ae734e18e7a22feed1233d0ca63355f3a48a33067e1a0e1971f36aa929fe0613c21c4aeff9418429c3b072a5984959287a5e5c40be02bd22b9a79c7f3f5359d2bbe493f556dacbb0cb4c293c7d941265e777392d148d68c07a13c8dec8e5d1e1c7f041e8983edddaa4649dac1572a39ae4c6480ca550e2e4462dcc849c1bab781d28a3552b2d98e02e1518e6555340fb76d68db58916d556a7b81563aba81d9a57ae50f04cf5686021847d79b6bb3da8017a60b1c3beefd48d2b3cd39c6f53c08bcc967d93069f562bb36e0c4f4ca6bccc5e57d35903cd800a61785a93770e377f4fe8e9f4b66680984968f9649e105e7a119d97636f3a05caeab1d7ea0bc81334b42d5cc080830ec24d369cf8673a490d59eb4cb08181da39a46d966e23fed8d38a5fabc7e843bcfb015a4474bfd46d4a43ff4a51a9567661e2696db87c3758d3b54ce7846d1391d7f46526ef30844d49320018d749b5d4dfd30d380c6e573fc414d8fefc5d710470756bec00d88ac4afc925d1ede37eaee6004a23ea0ef8b60e48
+SIG: 63de6a981142365a3e592631c8277237809739d1c98f5a1cb2cccd34067d1ca5dc8f2fc63b8ae1a689dcaa291ba6b69b1a6795c579a5db6dccee73f6a420ac0a
+
+TST: 979
+SK:  4ed7048aa1284dbbcc248938b40c35742193597addafdde06413b8d4ccfbe137
+PK:  bf841fe444add1f7c3eacdfd0784b4e855d2405f4021cd9d8266071c32c8a273
+MSG: dcff9587d6046c1132be07df26df6382ff92cfc8eb5345c51dd50dd188ee769f10a4de5e8883d116967bea97d3b32bc8aebb9f013d6df952f251c1a312346e72cee135a1bfd76bf3080a35c838b44d755f263d210310fa8d28c4ca52f08cac5b83a8a3b1dfc46d9b752d9fc73649d00bb9ee992650639c225deac1f39b9e803689d19e6d9f8ef4f51f1d11601facf410db648bcc82bf648769a7dd59c6e8a237db239d3f661d7852c426d394a90509526a859b476459dedbe6d89936c0f3989995511d4a576e542cce5e0dd7eeefeb0326d33f25c22ab6e7690633f4c9ed2aadf1d24f94862123a464042cea193a2f0479d39bcd1bbd1c7a0ca7e6258ed3732372f54e0ed5e3f1e2e4d4a04c510bee08d1c6d570cfd63abf14b4eef0b96f39ca29e43c52f2ca3dfd460f66e30235b159aaef2cc156012969fd3d159978d6caa0a94522291f7989d8af10831996137b68d97fc17f6a9bc2845ef3dd47cbc386e8977a8654363412dac3ac51c63817b7c051878dcf458ab3630dd7aef68d270f8da7880a467b3304f5baedfba9173e7efd007c412d17209c56d23968e340b8a0edb41b7e2a4088bec01b532df89b5215813131107b7b474f03c2e47d4317f11c4f5160904304997e76a121a9560235208d79b2dab4f7e196793202c0902ce9c4bfc10b8fe397e35ca0256454662ae878efb0a0a606fac0a952c9f6baaeb2d45b258c617559c0ed2528a88b49aa44ee43035b0d793aad3953c1a5a3463866bc815b1ffce2ff2b65e0fd47dbc15f4e7a06bfabc290fc62090bf7d94853f77c0444a9b90efe77d1ceb4bd39e203bc884011624e6846e2a371058daba63c23f86c42c3e31eaa4bd7d7a42af2d524896e31baa3e20763f85dcfd52775f28072d89f0bd4fae30d0b137ee37ab063ba06fe9d4ec62abb2fea0f81b8cbeefc030080b8026a58fd1867f66be1154e65bfea7dcec55fe32d51fb0b4a8a5a8a044263943d6ac8011c6e6701beec3a88655840c4892d450d312b7652d2514769f23bfd6e7046467df29a287ff3c4c9d0e64e6d9e4edee1b935d07681d47004352886e847b0c6d5762fd45a81a53cce9476c887221aea6c0c82bbf3b297932e5b11e538a3245d63d7b7b091dfa1d7b9a0e2db6698a4c5e9fe931662d7c6ec6d9d5b92bc7e041555df4df0ca11cabc485f9c556138a71745f03b9783bb200b72d233697e8bcf6b4117ee6763d792d7422264852f4f30f8d1890e2ea08098040f7f288e4abe90b63cab2c14373060840ef827ecc846cd560e90a20b8305f463c36ea03884a5df4c25f1ba9ea125952dc091b97516de1d287c0e2bf529775ba6d2f8ede03cb42c1e400ec804a9df08e46f44b5066346e3f7c7a1a8
+SIG: 106a9deb2327f338ccb71bcc94e2fe3d2e973ce6dd8fa7baca808b4111813e3bc3b4d88efa6a00c4710bbfe53196f9ab3a150b1654b908feacf9c13df2d63802
+
+TST: 980
+SK:  c7eca83e948576bd9f278fd7b82800a41d92da9b72d5a1ccdbbc65581052568b
+PK:  076b8352dca8031e853c8d9099c2ef579337cc7b2b4c75d1a063ea3ec725b7fd
+MSG: 8d8cefd673855ccd8eb8534c312d338005bb05f5b9507d58859e1e953b0a4d913be759d8edfa92898c6e70a53f81954fc344b4ad6246b0109481ba6f73ae6331abf2df108eb2e85ceb087c1f6fcfc9de2c1f139ba1771b72680302d811ccd0ccd4e0c7feb0132eb20b334e5aabe5f6119fd8947d9e8852e1eb1b74107e174100e3e6df0c3a68130ca6309402594bb50c1c8e2774f13214496a7b1f348385eabfbccbac165a5a2e7d9dea5ffd58b0bd88b49cb331ecb7f4e9d6bae9791ad788e6ab8926c1cc1615deaf4cc400c77a316197bca1904995e1365d1b9702648376116930f6f91166e6148629e75be2d06895f6a8d15d5a94ca69b712f33bcf95be0c1be6902bb78b8a230d7a8560c4d84e2389552a81571aa665c19c2e93b0d43e8c2cbd9e885d7052518b77c47e841d119dc28b65a7504f664271f06c7ff393f825b1e5930d02b9c70035e292411c4aedf66047006970e349dfca7fb41c10fd537e35252e109e3336d7a82a14de5d5540c6fc6571d5774f39b7c403e7b8875ec215877efc6cc8ea48b186b46821ea5ef2ba8bacd40d797e6add06413283145b60462b3503c5b881d79a592955d18afa08969e31457f5b27daec010338ed867f300878fd87ce321880b860a0c64284ca2dc15f5e5310e10e6a73a7ea650ea9d373694da4dd429ae7412ef9b29c83b3b068c74769f431ce0615f9ff4f82baac47b4bce90449ec41c2a2d573d92b92e05631486165bc710ef5840f80dae9f9dd5cffd4ebf5d10746510c5fcbfe62cb9703c0b154c86f10816672497670a3b0150bb4e1b03b3bd544c12a90c3edccd7900ebb5b31c91117cc8281a3c4ed04998e99aed41bb41fce9990a406485b14dbe3bc1a5fcf7719507990da3b0b3c68ad40d8950c0d49ced1019319a3f36aff6caf75d7f9a0933dd3abdd7692a1562f0613fe4a278d5ce4c8dafbb55b2ec2af2b24e8396f587b170c9ca6547508facde73490dfb01eb6657e3f4f272304b70bf047a43a2b58e5568bc52b2c8d4c03219a5a8bd3dc0643185913c0af7411f81b77be2a9bfd5cb26977113d2658a97192b41cf6c7011b0ff6a11cbff3505546322f0bef6097e46b36492b016a4562e092b67c3fccc7780ea274d96d595849f7e2a56d79edcb32d784049fc1324a5beefc24193a66e1cac4a13a811b909583cc910cf08d4b104dbdb8a6f2b21fbc1db1175a1a2356a63d3eea9dbb8537d2c68627543df0d1f8fd8d57a18b0dbd69b920cb9b286e3c07ae44ae2e1beec01cee6ba988b5d1afb99790b1dd910655c43d7f2a3ed3754ba46516d278705559f5741622a9abb5c8f23fa976a9d146948ade6ba6608a35e4e0d330e82e96a2be6c78ad0cd4d8704e57cea146
+SIG: 86996a1b8e495d425277e97cc0830549349bc2b6f3dcda60f3b7d3501b8b50b5b458cda58b436e23c02cd4a22b234813aa9bcc3c61f983c0b7efeca0f1bec20d
+
+TST: 981
+SK:  7b469df9c8f78489ab47cc70a88503f1b8f3d929c33feab1c503f0969a3ac37b
+PK:  a814c7e373d0113b90624a8ab2bca5cf53bf528e39fc3d367de154b94bb22f1d
+MSG: 1c0fd7450e29675c93091638c2ac933ca997766e380ec33a92b8a7e1a1ed9821c75fccb5c5f3760e76d0e8810311ddc624ea8742131c1c4308f4178e04d04960693d846c1f51d8773b6deb3443d874b9e2de3b77785185518b2e9ee736c63a39c8212ca8669e161d131b1ab2264fdd72dc5628b11c06f2af9f0789047bdd4ebb5d55899f74dc4e12e7975363f63a8da76b5585c16bb6d55b05fade8713d19cad1a211640262691aac9b437a9ecf89a9246ecdba1ff0bea78494cee15296216ea6bb882479d2437c9494ac7fa4f3015d1d3149d5564d7c11a7e7b614f7d3e9d454f0a05b040a1e06fe7837c2a9da2794d918bffa9e61a0c3f089f6c9f7eeac586e34bf94470d913da41371cacdfc7ee8bd1135655566924eadf096ac030a65902c103b172d12e88f053fc56ee73f31870817083afa802f7668b815ee790f7d40b437a2e6db2f0fb26836b4b2331eba55539614c0fe17240242dd3af7383bcff7d3f47d6544b08720c0a52441f7411935dd4a952d38651a80005fa3eb0eaecc735d290e8bd5e31b740140e136b2c002523d8eb2a0ab5bd687002b3b926f75eb690d1da73ad235892f3b23a756b605a437c00e0621304e810f99e314c4d63e322d9b69815f382ffa1ec6280fc0e641c8a6f6f7f61985bd3567e0f440de9f7621715dacd07428c0090154d59ce6db40169c658ac5bf44b67671fe19e4b5b38aad2d3d4e190a550aad4188352f7981a6d88062502df86791350392d41cefacb24e37bc700cb029190c3b1821477e117d5a462fb3e79133b1073598966f52b63256dbf326ace14db0c80058cf00d689a0a58111af1692744bf791bcbb427a372246e9501a85cd520c61a1e59ee180e8c97192f60fa5d3ab05df8d8551c1ac6ca0a9a012ffeceb3c1f521411edb6509bc278a651e129e96b0adc7aed707221caeac229884413daa10595d22d1db7082125f4f969500a1d48dacdae80f4029c163dcd79ddc6468fcda1637b87ddcf2a3d9b4d299a0e5394df90ed03b62137ba67b9fea8ae1f0d22f91c63a24b5934f74c265c43f1b923db980adfcee8313da520176730ef9736b27e6ba32d17ea69dcac6f4a016edfe2db5a5bb3b64932f7011f1c453bbe88bbac8c7035f93fe39b581fcaa7aaf082fbed004fd1fd5a4e2d9c19716604b19ce199e2169a7be518d5fadd2ac31b95478082ac91306008de4ec0ef4c9f9d6f96d2f66d62fafc2194082808af0d67b9fba0d189b055f061ccac24b27610bfbd5a2232dd6f3c890a9b1266471b322e9e1bf97757bef72abcee93b051fc923cfd4e723be3e17143f38eebb900b5bbcf7304732b9c0a1c5fc9509a693580ae73a4cdfc5fbf20ce81ebc835c6c909d831141b194f6
+SIG: 18faf82d08e1068e9f983d812f05fdb6929d2723db1f77c45a74bb09cff27773b54ce8f43b3015419112e725ea7acda4b23b8120e7b0cf420153e5b03dd06109
+
+TST: 982
+SK:  dfecde7a56a18c1f19d80a19a4f1daddd0bcecb01eecad6dfca0f957a914ed7a
+PK:  afbaa6e73e85b02b25a4b587ecb8c4dfb79aa9202761efa8d1df2cd0aa6316c4
+MSG: ae6e8ff65ccde6f26484950826b43623058a5efe020bb19b7d8b4e25768b692734fe07c913b9e88126becbf14a0fd0205b39fcc2aec373f8c184c6a9bbbb84449a7ca3b920ada08801dfc66ff19aeb92f2555399a430277ae22d23754eaace3c73846797536dd71a56f4b5842c0f410d1989acac5d805d26572c0f3a64dd2071662212d52fe99e59d966047777f9030fa4fd2ee74b7a7c9f7c34a6dc7e03593a13d64ce62453ee3ca30d84672839f19f1c15d0c45d2755bb394acf4dcb7f7f0711ac40ea46612ea37a7607ad32e818265fab1933f5094e2d03bcfaa5f61667f3b37f00c4c58d9b41b9af3900482b0ffb4fa4376aa040009dec2f4525799cb005f39d74cb2d8dce8c20c2c3f5409703af156cfba28a9d916439cb29f83d2429ce6223519e75e15c7c7fa215119e073fa7974db14f7a01093faa94ad52ab1eadce1a89366ca13adb89066438a2beb73034170aa42d9c2ddb97c14a17c3094376d2a3ffd8095fc4053d91d16e06d27693a1310f01a75111cfeda892c3972a133a09addaa8f74145f88681b6d277964bfe38551a2c619fa3cae394acb29c9410b45e101b1740e8b2aa6febc3a45dadb9d9589d597e57cd947b684cc355246ce6c326dd98cf92b6eea3ba5ab03700622636324dc1222cd748fa07bfd39a1e069809e567141a613e2e8be9dd398ab6beaafd85ff3628ee2aa32d0a57bbacf956190b5c4242eb5b8587d2fdcb0741b9416a05f5fecb1fb2d64788dce783c1f63e60641fce5e1d2b18a9500cd6a1fd335cc1db46ef04752b2d22072e6dfcfcfa569bb25e457afeb63a4fbedc293ad9d1aba4e394aa1097e12b0fc90c89f76df0d6441fa99808b60be07dfcc7f9010bbf9033556d5ee2d448937b783493920f681e4da708671097e199481b8ef0e0150d7c2851df44c545122f9b0e5ba2eeff2d988d56d9bbb55d9896111151a436af065e0cad178a2c9fa8f6974ecdf09adf013300cffedaf4b8791b467ba7933ada5d632db44ed6dcf2aa648917be6337d2e2d206856d08f9ee7b5e2f14ddc6d3ac429215a87923ad32d5dcfee3686316ddd1b27bb193a5fc05c893a939a5b98987366c829e392f485ea15e22cd8f857a134afa98f37215576ddc5aab4f2d10caaf050059a335f24bcdcbac819f66db07aabdfb76271d17bce22cba463a80aa892d0d8e055f948df7f6e6c300daeffd3a236dddcf238fe10666a57c6e3ae7e3673d35578f8b8ea69d3c08e0140afd3ee030b22a372160f908a378f8101b5f5969fea310eed37a00d97302d5c2dbe8cc600075dccd33ad63d265aaf60e241ce311bed7dd5e2745241ae02ae532d15c18886e818138751afc51850e506c6d31a8eef451adfd4b3d266b415a7e
+SIG: b4fde55b916cf60068f19b25351c1410dcf66bfc40f96d1ba2368bc2b9115aaa5b2d1cf0e3dfca02ac902a943e2489a5681bbafed39c6e33211a9cb2ff6e5409
+
+TST: 983
+SK:  07828c580ebf9e1d825a59c3bf35f072ae123355bdcc249eec7f2fc5755e29b5
+PK:  58e5ed85100bbd9b2221afc9c93184330ad59e1385606244bf003b8d2018501b
+MSG: 0edad5cae6ed9843e91c50d934cf55dd658f3d252039cd6c75be4f6b866fb75f35c8f98f1721d7e6d9d98a22e0b4934dcc129261bf6723b2fa7a995e35c4bd79c5816a321607d9dcce39fefa1d55de4e7617548ec385c3de01e366bf50c457a555e932070e2a5a0197b79efbe7006f0cec78b60ebb8fa8781d8eb7326edc30e62d3297a1e0a1117108c46ee5dbefc6594289335e780d55a084f552da3f36d3c4c6178ba74d4decefc5a3b8c47c16f534bdb60895d3d54cd2bb266b399e4d4fb48d7a8cde17f42412560737d3c06e29df524d0cbd3093efca1c8fedcaa124abb27abdac6a29e0e8246abd6f5f531950037f76323aa56cc3fefa603041d55f1929e277e72cda1f96541d2af3e90c0f0e28be196d8f6921f3cd57a7926b860aa1bc403576892a96b93190ae383f631b72802658b2e8451d52a2f45db4f8bc3b0e4e50b6d603a5bdd30c234200ad7debb963f58a4fa20330b3696449445aa371824842fbf326d901dfe3be045452a3740dd160e72733f6e2733525a29a865f6f50d53bf7191c599c876f5c9ca1e3fad7960648e0d471f7d5c01c673f42d659bc3d98dbf07d8febfb995d17f9a02cd6c39f2ddcd0f1d222b9e11f2dd7d3c7518224bb6bfb8b7c58fe8ac105405903a1b9da7516715b7afc38a555e6bbcdbad46e34e576fea34ce35734ed20af5d88eeb1047a2660648bbb113ad9db8c53edb6ed9871a1e44c9ed2df5656fb2b2806ecf03b1eca9eab50a6eaab55b933b2dd1f21d450de9d5cb2232f07a392081b0b4b885d54789e2f75bf2c4cdad878989b1d6dabd9ed23c7c5b0356a7d9e7335290d7c85b966e80184bd07998602886d7076193565c81cccda4cc7d33c85d905b1beb6e8e7418e8acaedf0d9a32a7d29d07cf44d3119d4e7896820b77de64b655e4f148800434af7bdb2a56b25eb94ea39f2169596bb2b11761f082baec08885f4a0eb6c95767135a7f7cd72e743d2dff144dd8bafb1b318006e5876f8e2cb44aa588f906266ac67119c17f5de114e72e42a1fb39944321a111fa795ff7017f2fb8caf482f55d77a80855428ded7ec20acecca83f8d1eb137b588ccb745c105f2b2ca41c3a9f49d3c6e9d7c648b003b9707c906462edad617a8cfbf9bcc6c5fb6fa984325d6582e28f62005383f338df5b38fa9d19c22a2a7ea1d68a92d1d93b7fb0b8f33bc8760f28aeb1439a8b07f3da58ddb155b498cb09c75a5596838a65013e24d5640d0842a7699322cf3ffcb5703f414ffd168860bad3e308b2b5bf3cdf7f363bf9aaf4b3bc424c146c6f5421430f9f476aa34a0c6ee80131fc4d4d970723a2186ae3625e286d17dddc435ccb00831678aba584a62dbff002bead6e11e23c54d33cf3a4b231a908
+SIG: bb09360439a82dee5c7d85779e54c13f88e06d38f4b94960fe17a1ebcaa3ee2f330c649154bbc875a4076cf0bbf7eebf7b8d08d5aa4be7413881245fc2d2b601
+
+TST: 984
+SK:  f08ee8daa73e1feb61a88e062dfb1003c8578a0d53bd3bc9e589efb92f68be14
+PK:  76692ce8d116eccb897077edcaafdd3eb44ea1a486b90e49e97f966901015502
+MSG: 64de90044d0e76bc02fcffcb75263667b3bd733b40bfb26c6c52fdb4b0782278cabae41e2129ea4017e94de86087964f66d86207987467a1688f9fab3ffb2f1d0063bf626c941367c12e319ab7ca3020c9b3a7215a19303e2d0e8988791de0d8e1632daa38c7f3e7f6e48ce122143d1e2cb661ba77c69e6a710911644bc110ff58bb00b5290820ce30970e7fde189e140e5c70c783eed53f0e2ac7ecae4f27db81d15b8646faa9c5a3ae2b7f47cd580d7707b002499b4cfeb8c591afdf1cc62af2595c184abcf0b2623a1bae60af7026b28d0540b41526e3020f81b894eb3fe31b72b21a3260dae3210c4ce4fd69e2e5ea0c8632a583262a12b3a8b16c9c1206ad73023037cf30653cb80aa7df8314b0f5bc6e9d5fa00b009d5552d83b7970b5bc4b9984f69d1cca9ce4cb74ddd2d879d37312a0e159d7a6afb77ac585e6b459c551304e1eebfbcab43a10b505924e03ea332f5d020a55c7aa683c541dcf7790a240af079baba94096b46060fd7afe9056ca99e688df280a9be8c8c73e6e6fb052a33eb3328a7f602542fe280c890e3ccaf22c7f34f87b5e5ba784b472b1e1a99347a9e0d240858d1277a5c6b349383fe4fd55cf92e69faad326b8d6db46233026221ee6d0a1c4246533c4a0e5bd172eb8936a9c0d30066538e3eb4ad5cb9877fd861b482b30150a06104161647e01d004d997403ee06726cb97e2e25f18c668eee4c5bf72529803189ee6a7aec238d5906ea5ae10722c9a61a78aea52af33eaac75406b1a60befbaad48476d9ff887fd283eb1655bcc07cf753331436db5b3b13032ff9c3d696380e9f5abf50d3556fda0df0b53897a737ac7a3b87c2a832b0c7273ea9fc54a767f1a812bf0164bf7521630b81b9dd930d92ee2ca28e3203b77bc082ceb37d55edbcb71df0b79236789a25d418cbb95544e2cef33bbdeb27a3f7909c1f498f47135ae9033adf250ad4f6575361e4cfcc9bcf4b90c3ad47a3442297a223cca843d7205ed08a9b87160a6d01b46a7d1c844e8d1f18f618682bfb22955f395b2a5790a51a696499d9e71a501f3fa546de9b10ae47bcee42ba7f869fb9ce4ed7c6453326c034cf05d9f1e3c200701ba752dabbd868521c3d8f80672d42f6cf4564f08cd7b390e6d49dd90090afdb84486ffcaa4e84d88682744dc0a878faa7cd440a8b276710902081f4dc84174619a66ea3a371f95505400d99fa999017710c8e2714be60949d461310f7d43a0dc123516d77d362213f9f75a5a1c393affc49ea151d46a81ffad239f28c07f65f59ea077d9a4d9c752de49b9ef36be60d112d795f588b00ef6e7730dea65e1016da0dd462370e0ba5c660001e457c08b436da2903b62906932084728c81671cbfb079bb29
+SIG: 66dfa4c1575beff2f5a230b28c58c3eea0736df379d75559bc9d37a9579d121c05c373e8484c9747ef4477e80c4b2cb4ddf16ae9fdfa08a07547d107dcea1203
+
+TST: 985
+SK:  272d64de50b1312bee23d7f4cea508a8fccf3e9b324e97b1c8e72502f61fbf45
+PK:  33498c3b712ab9c01ec76b2efe2b83add1e1f2b5eb78f21692323451820cbe10
+MSG: d6260d7eec5d436208e7e737655e0971814270194405e36e39f8f17b649fbc16c0f3d7f2bef5ebc02bb1c4df48e8470a3eae8a3ccaf640abcc094aa91150ff1a8cf1169693ebf5ac0034b9b919ecf17db791dfe5fedc90918b23e54e9004a1ae771c213ed7ed7334434e5bc02c0dda2bd1a876fb824a197bc99613b1409e7052310b0820da71446929ae7cfd3afba042de54578a5bfd94c1544391a3d9acbd5663ef65c6920d78516dec1cd55f6eb7290ba0aaf9a171658200b24a47a071b96fea03c6ca7ed0d6fe675dd63761833d75bc5e58a958582db02a60c6ce0a63f42ba837ae77c17a32705fd9cafa587b555dd4619851079794e24eb44608835a6f4824920d577a270396c9573bc7d82fe2aa0465956613a2c508cf2432337a365e6c984cba917f0cf842af122dc89dea958d418cae44a6e4ed263a415ff994a5ffb2ff13913df214bbfe90a34b247e71ab73f7ff004c23acfd90c767611aa55814c66964168e568ba75bf34903597cdcac78c24bb9f14f5c86a51f364f9ab41e464aee64fa50a1c159cbd850832c504ab42a584a96d5aee082d82c1edda19338160b8dcfa3419b3af64d9cfb104f98f9d35e5394e23228e275c87db50ca867540b880c7af29fbf534294581c22240bcd4d7d2c20ffc36733ada27653d3ae1a8c2203eac626e2e9bb4b52ce523e5adb3b2c10dcf78c2a1e626a16ebfa1bdb8c161493a5aaa2d84bfaa0f2027ffe4e9eaeb332ebda7cbbb677769d78517adf72f823a7f844165a079878d258fd95225c21177837e69c19685a051ca92b120b7d86d78595471ffc42a5e6e6431be7b64f8076458bacd6c72903cc34fc63a40cf3df00eff9d6ee9a8f39d25ead81a8128888b0a1ac0e5e3ad927712c14146adf828770ff958709eb19288e77bb70734881e9e016cd29e7d0899341ff6b297ac796bbde486ec35949f6a32b2ca647385915ecba3b9f0225087145c18d6559d3a31d6f22fc49f8a6315f1d32abeeb7cf2c2c776ea7350fd5ebc0e0f265baccc2697a7c8ca40c135f6cfcb0b58a61431960ffa9065709a961a633d570b73fb4491de52ad0d7b204b6e997b037ede3f7eca820a7cdb2c69ac29148be3523508ae7e4c3d1a717f55a821d14c3b64f08ca9ae49613b115773ef618d321c908bd2156717a434e5089a5948c045c8da8a4bd86ed5fabc6b13466e6deda583207d2ada2b2ab9cb1543df7a3734dfbc6fc428106d4844724a13df42faab18ca89db20ac9bc27b85394667c5a2779ca63ed7ac2b7c0d4122391ee4602d61ea0381764fb72dcc224e65eae2bc4506b0f09e23205d0bb21c77d8287c165e0b42c551579778acb7258a2479d7cf25b902e8d0da429bde36b4590dae96f525481ac8378
+SIG: 33814c6ef375ab963769b2de4a25e7020fcd97f78f8fc93455c4b1c2bd45d4b01e192900e3122265fc552cd5c5f00e931e3a183cca5ba0802dafdebb79ebeb03
+
+TST: 986
+SK:  0c9fe559ad1ed3ba164daceacb023567b2430320b6715de732a03c59c7303130
+PK:  e70fc466fb2acd74e099c36e2c22fa51290bdde96df9c31b6dfbfdc2e2c14a40
+MSG: 26ebc648cf8c7965ec6ebe965d9c792bed90655ad440183c6d70ea6467bb8e6f04ec843f333156917bf4c51d0ed0f28b7cd31bc12cf840686b82b0c2c350bbdac805333725d6b69c2ab7f34ee593fa1cccedf3f0642a688fcc1cd98b0987d01f713a2fa6416c961921de0cc2c9ec7a555855e7fcd4c7ddaa14fd91ecb04224e1761b7d6b35f4aa5618a500ca00d1ca2451b5d368afde3a407e783135f39019a5b984e82ac279c05e48c295ebd1563821a0743c52246b5d2b2034e3aeb6ce7c5cf919e74a9c7bbc9e25da30430eb16ecf3837eb38a0f559792a729890ba8310260f8aeb9b5af00eb633c12dee022628ba418d75cf18de2f2e65e49b1a69684d6127ef481ca861ecbce3be86497e65df4c5fcd0817c9716b59f2a263d5e9eb606839f85c5a365837b0fbe2c4274d66cb2c65ed365fabf58f15be52b51cb60118ca4f730d447359f7ef346b750217d47b2e79c86c0c62816a0c7c18a2ce2b688e0cce0d752321e79b423857dac59f8fbeb09411e71669ef9a2643f2e99f387ac183e0b0ac72c59a0c3c18c0de8b010878074acc1a2b39f9df99d9f8f8b52fefe4943c525fd4d06ad878e46608abf27a54bc5006f647db724851db7c4578ae66583dc4bb518ef028890347e8fce0927d7d9af3ab5d0d2d202a4026aa2ea7487962676a603298e7d2e7b90921ee1b52806d71a764e03e25ddd6848f61d46fad3d008e10ee5cd5a3390f9d158a4437ef615fc90ac5bf3a9d682e12c3398ac77680d22cd1a6a56ec3b25cede867edd383159c6164d63e9cd1c956ac7235fffae936166ccd35898e29c9b4ca4e2925da323b6fbf67cfd596c88a1a35a8359851ddcba8f6134a9faa244dcb47e691276ee625cc20adcec21cbe77a3acb9ba72f0c9d3da7e9cd5be3b95990ba54a9f31af171f95aeead3331cb188a5b2c6f539acb48b98b3f7341f60251cb60429ccd9cf32f009205f2753fbbb26aa53174342ad184dab6870c0fb52930119d9f97d8489a60076aadb2e96054ac7cb7f84e13c75bbf9e4d924d2272afef0871915e243ce66fc2a8888513535b10bb4079c806bd949281e28283523d0d210b31ef62a95dcae0cd25290c7edf2c24b432822debe347f1cae945f5728c71b5403ef14e72c3d8342e198b362ee20f809e46aca015f35477ff89ac4b37e6615856f7ea251fbfe13f9065259b0946aaef24943270a854de889780033d63dda5447998a3ed7e506aeb51ea37b681ac3076797acdbfcc27883630adb72260a46af0a60d53f6654566e20d6088cd48e23b28d81f0eed205b92aafd96164d6d3ca3fc8b171804ee9fce7abaed2ea4ddf9cb2b3ae73a70ed63de45e14101428d0a7a226db39ab6cd04374080e6983f018ce93da4c89ac
+SIG: 6cd8aed97d9c62d5fdae597d061c0c2bc37e42df06b8327a468f92b3f438a1e6b6b1ef2be78549a289fd3fc1a6299e5a33d5396cb4fac1e8e9982f0cb3d20d07
+
+TST: 987
+SK:  15d75ad8e4afb12634cc8e600f1a4267ef9584f4c4ac44fffe4b9fcb885c9d2a
+PK:  09d126f017e0169774e8c37ab379263a8075746127c2d11ecb0e4cb454709ff1
+MSG: d1cea2b7e9afc1f0fab890d2700a5ae41e15e7d34d3bf19d0f34d9f9f0ab9812dc7c2a8dc44c8ee7f3788761ecd988ee72c736b62a7cac3cc9b738e938df7787377eb9ffd120d4ff58cf1c0675633f7e83c4b115548f14d2f70c6d482211443a8499599558c14277980fa42a78427907f73a41f5f6693b2f75fe5e7a6ff0a6c3a4e2ed1d0d968d5cc9d6f13d41c3d291396ae7e434e664b2ff243e7f6d88010210078c39b5a576caf409bb4711b3eefc486b67b7ffeae0cbac6a0fbdf5343fb2ae4e057edc8c9d2ed31eae9ec83d2bedd219eb989b2d4419618c2d3ce4490e35fbcad432b0124795f9c5cbdc1eb0c3072b4aa801d26fbcc7b07b8257f5fe47acd9bc587b5657cf07ca545bb568c9e4e73cddf6254e22f78ab2f8064519f8abfd16fcfa90f87687db0c4209be2c6c79a5521f44189678d932c54585700a2437702e56aab588a17cb2cc94c00e87570ef3ac5133d753038aa46510a260c1fe80479bc02eed9a8d1de99354ac2648b48b96ab1b80cca6cae1877f37d70428bb50850e0308db0b423087bf7dde279e096766f2ab3ab2385b0464a5bed7bbd8d457e935e200aaaa8d951570e053076db18a6a62f72b319579884a0826ba2b436371dd218b01a0c5e58d0cd5ff9825e4466fe966df05cc31c803e5212183ddf29cef7fb91648a4f8ee19fd5f8dbd8a56be7abf33659a9224a1e27a1024effdfb88e8806148d0d1780906af1ebe3e5f14363190d88cc6e5089444f125d063155dcf86ca9263f2f5f183c26974fe000b9342d24c781e2058287cb6f3f1e3270c22b7707b8323a5cc8db81aa906bb59d696cb97cc74e359595ffb8373cad3710ea09ea9744c20e9a12e05be5a95f085ac561678d7da432e4c7cb53e1271df5cd5a339d2d7520f1c1848d15071d8c69846b23c5d2432c73890f2eded37c3d2964a4b5b55225888e892f526d1cac31eac356f361c2bf336c462d60c82e82b616f2a519c2f67bf01290369be9b55e9f5c8cec4f2e1b2ab302506c903dc3e7b9c978141dc904b01b1c23d25004399bf8b73d69cd539c79af5e9a0a511eca221078a1ff7b0f604aea84246c3cb32db9381be121767e097bea517bfcd82dfe921379840efb4b6f02a48ecdaf12d2cd38930d4473adf97cd71dc4ea10382f4f5d1dd7562cd4bf5115932f6c4700aa8fe8deca9d5e7277902b8f886529765db2486074b23a19fd4b04356bfa6226c82baf69a087d9ca18823f8e3e68308e16b804c363df5b6307e76240db1ed841b612d65548ddfbe8367da60772c6aff554dc85d041948345e567da9333151858fdf6993273925bfdc7181b5f646d063a8c8f310569b0ed093bd9dff04febf0b41c6dc55169a14a3c862e5416f1e582fdee8fe87dc
+SIG: a8f2f4b9e2072ca9fade37fdd62d8d0242fd4daa09fd856e75f4e343c7260ea677f753a627aed08cb96c444e29bdb5b5385d43843bbe79a3dda36e1e1101c50f
+
+TST: 988
+SK:  bf3c0cbbbe20be2acfafb27a3611b48921a728ab17334b8afdee8305178f613b
+PK:  4500a03c3a3fc78ac79d0c6e03dfc27cfc3616a42ed2c8c187886d4e6e0c27fd
+MSG: 8f30ba2f792e9a97f6eafe29f976a48028cb8857b5c798bc2b6168c46444c0ce696070374c5e6a40c3d18a5dc7669fc41db9a81cff759b8ca0159871c3442e8c7512698fa447b5783ee01d1b611449abad237162922b02d1aec5de1d666f17da1613106301d30586d116e2ac09007dd71e8123ede4c5a6a9ac077fe3d93909da628e865870a4e25cb35591675a0690bec4af0281714fe6661bd5c00a27d79f959fb4d4fb1636a6a3575f4f01470663899d737472b096be4db723715367a41a3a4c13f742d908f4d921cfdd156e75868261ba9c10d85874ca2d6c0c9e7295e5662bd916a363c7a796ead617c4251e6794da06c3d08f2fdc3886944a7509e6409c906b593113b4b1f9850132960d9f3a4eeb7386fa592f6193beab8e0ff0f28908a0d548db87bae978b05abbca9b3e96d8795b88077f620f2124e31590eb099e94e0e6e3cd620ae6290f3e2d01467e5bef4fabdef79d9ab9239e753ec4fa0bb110ff1d393fca02243502d7e987991eb76d08f8be7eb2b1ee00c3b68bbf72a623baa15be896b3215ebe8a82313109fc629b0cce6491f813c24970e4ffe6869e40b46b4ed22986d0042155276c230de4c05d678552f2e851cacf5a472157dbb1a99a2b42ff4037f0dc6380672921c909206e80050e61a6b3056b17e3ae835009b20419a3b9846d374892e719f1b35bc1257da93ccc6d8f8fcaa8e609a8d204df108be7193467e7f105935282c3fe6670a5329442ea3edda2376a03a1cfe8723a909c064d30fe9bb0212c33afe2bea30c9143c001da01c7ed504559b97fe2cea09beb9db51900dc136705921e20297845ba72a97aa7c953814571be3f08cef968045a5ac34004f67fbfa54e996b311bd8dc527d89e1d4f53453a6713720101c45a60ee3a05c2ee66f134b5af40e4b70ef37ba3f0afdefc039f342c28af9198251381a1079a5dd035a8c28976c6b7f4db09ea383a3a87f0f851fd331aea7fa4bfcd95631d652fa2f50f1c23ff2bc137a0604e3d9f39ccb965145bca48b06dc8a817547b625effa796d000c3774bad198db1241be7a2c0dc4a4641b9a8cb9cb8c8c3887576f5272c33aaffe45615f51a96fae76cf5125bc69ad0a4038790799b5c2624421a6433dbab39cccb0b1787b5bce289594489d17edb5f9310374807d36c6e6734726bb33004ecae8bb691dcd387601f4ea911b4b90ebff756d7d8d9eb422cbb9aaf7f4772e0a5436430685e57b697454e82eeadce4aba062b77682cf219be1fd9b00f1cb1135a1021349539a4b93ae213f193d2932738ef72920499b7be2a81c9baaed17c54641a5974d27223241e3c6a095226bd237e0591e002b3af0565df3e976420f9764a09ae8bfa2795f8fad7fc687bd2de23d1488f449d8
+SIG: 8f8703bcf4c0329417339eb026f2b72d314d922e9accb5d8bb7eec87e07e6138551672a6132cb4f875508ed3299567b4a74134d2bdf0d857f980861d18be7e01
+
+TST: 989
+SK:  287fafd21374572f57810047d0d98cb1ff3d0120faa4886132245732c1a6ab78
+PK:  e8252063f5ad7e95bd05c502a8bc4a17556360869b9de0a3b858938e11117619
+MSG: b3c443e4e5899c16d39e81b4f8074042a904a735074b2795d9ac06b1379ef7618d2a534b6bef81569e60719267bf29cd9d16acc9a174d8026b14b127d0d2d8b4583998895ad7ef72fedc53b8f08a2250100e1f1f0aab48bc7074643488e6b670e1b0727c385a34ff65a0d7e83ba86083b873dff0559209b14b2ac42bf7c572d0c5917ac42e4ae4dae1dd4235795276a076132cfe3e0c350b26580fbb3af81777b93ad95cb7ff17c2d980ce0d492f6d40fa90ba3fcaa21bb68735ee1ef208495ebf7b02276ffa1efc081658bb44cd2761ef5e3e1ca60ec8b5d816d4abacd0bcc80268d8f4df8b3a52049db0157e2b6e81acd6f3f28947c07627955cdac9eaa1de17d4b9daa361fb49782664d7d6d2ca5cec6d14893c3e80b6d16daacffcc0b75937e8bef6f9e112a87f4b035f9036070a2ccc55c2aad939df674f7e4e12685e016ea0e4902aaaafaffe38ddb2f90d9cf78537f61391696ff0330ae8f79a1c1ed5d52b4ee2a62d90fb82d9a48393fa33810b40d0455902d574ff052003e0160c0f47b5e580a078bceef06073dda8b2d1f104a595e90bb6a48eddd865f1cae4f178fe22e75f2f6124a9da0682447112b3db5be8c42472b241e944fd2370c2dc2715c05a41bdbc890c41c65fb08c2f593174391ac880f3cb67d1b74ff802ef962afef7b9f3ea326f9527e7fba698187924b64ccdd0866248c76ee64c79069be0a057b10ae190f38ff5aba844e39331cf1db13c900906bee0d7e7546ef52324e37c590675f139f58f573a494f4ae82c4ec81066a68e2d92900191c47d3062f0f9aaed191137cda9b83cd130e8262960e6244f8f6ef39f15a4fed13cb669edc19f5ce162ceb8d242b9addbfba8772ce74985a5f3720d590a920e1dca75a879b1aa459f7462fff2e95072761b209254fe38c54d833a8e2cb8fc40c598f3c7f7d6c5705715d0308dc30eaa84676d209d7b7b31344756e69a9a4cb4e4a251817a3786fea6728dd60822336b45ae5d47c704b45c4cad38c1e01ab93d141692d55d12fdb9740f1d181582f1c48ce5434860d930f0e7e70edcffb85560a53dba95d57b31e8924137bc2c19e34bb9c9866877174280e80c23978d57795864a7374aef383f3bf6375359bf63564740098461a6c76e8f238913288769a1cb1c95b22c32a9ebb3eceb048ee324cf0d7e85a389b04dedbbcbeef298d0527816085c0c83efaa298546e8390bd1bfe465ec1bafae69ee5218e72caedb9b649cf73eec454a2b484965179672debcf9441363995a8a907de17dc0684f2aea579a2fb4484195db4115ca32e970526dc00a5cacaf588711dbd469ce80bd297c4f41d6fa28a597c6372c0d214960b54598cd8bc849ebdca36d6225b20dec0d031169cebb36eadc3a
+SIG: 6201e30591d36b7b226e36fdf56434c47cd3051837af31313a9917fd02dded2b5bbb4bbc368b3bd15d062045f105b6e7341b15150d36f90087591d839901b801
+
+TST: 990
+SK:  9ad049100851d0f79b711225c98847795acfc3601c14b8a9778d6270cd4c05ed
+PK:  e7cacf4f3714543c27a3e9ed833baf3bde4c09563bef59e763fab71fb5e4ff56
+MSG: c284bdd8f8275b49ac808c39045e50e1ed50c8a1afd011afe5db3dda620be8aec37f45605762e225d04111f21b49fcefca3f3d5f813b2020a52c49f95c4ad61ca214618ade7eed6cd8d314dc4c6355955277d457462f03b9fba2e225b1b537cd4b5237505c90d43205e1715c3963ccfbec379e6c1705e08034a31afce646727e78a20eed88aeb0dcdabc5c86e86979e63a5c26c3e2177973b6983cebfeda9f31479361b661763aa7261c0939cad48b71908ea90768bb6c9583d8eaeb9e0338515aca1242626dc6be04ecc4429e4cbb4ff336096192f7501ec471b596a99d4c027582cc69e204b6fbcddf59f5bf7462ddcd5989121fd10f11a0675b6c4e4f6520d27d7c61431ba7d174f57395a0bf72d38c1142736ded6b91e4811c0e8541a6c0d996c5a17dc97db388f721d2357d3c6af5c86b1d5e476ea0ac0b1c11d4387f769039bdf538a0216edd0045ee6dd89eef82a425a83faa1b12807038ca19ebec002e8b3c15344c61cfd1e5f0e3b0273deb37278cf197d8a83b13d992308a51373eb38114c9e45b438780277d1e32f3972962a3e14a8d08db9f09aec3dd32a5b99423e61f5e79944ab57a36f6ec07cc3204f9165ee021ada93e6fecb7ec456aa0288c378a75afd6e9dad6c6f88e959a2cf28bfe56d2e61b2adaecf0d86dd8928bceda26b0540246b7337f5cdcec11fb0c1a59d631fcca19408f9522b68a39f86ef970b883a0f0bd6b7b1415ec9aa043b52e19bac176d67b79e2a5dca8bfd29102ac608e473e9f982c3ec8932d8aa8cd565284491de52f516b9ebfb7dbe1299511ae732c2ad1ee4992b077faffc65f488f1ba215da6979600971196d0ff3a08ad9f00e829c1de1afca10ca476be664aad261889b0eb7aeb6ed8637618900acf481e2d224ec64a6e6cf4fa4df731b7a4feeff2580c99b6d75b4dcd0976965cb2b0b5635227842d08a7d907aaebc2fded8009811dcdd73354921753bc5dec017689335f56d0fb7ae213b41792b1f4eb14a24535977a305b19eb9838dc6b51528b98a39bda06010717a208c347aa158eecdfd9a0472d3b8d920f969e12b65919bda38b461949850cc9cc18d8e3baa8c886d93cd096a209d543ca3375fc4e7d65103cb6424beab44e8bc4a5b62c29a01bcf44dcc61e7675c025dec0724200194bde74d72c02e94a946a752f3608457fd91f292715771487d26cad4e5cf6ef7c6f71627a4daf8a4c9b891c1ee8f04aeaa99fe0c8b4e833b7609066b6132a968890e2695da22b2d857c8c0ad9187c96069e476e27e4632c447ee76714a31d1e5149ecb337ee132f3552da33ab2d6fa9d7e93f68a77cbf191cb06bc22f3470af6d7581e3accbeca0b6feb08a14b9a80c1ef59374ccdc0523c3684504c0104bba22c10
+SIG: fec0af34cbc5cffc56e96dd5ed5968e52cbd4269844fc30e3ab0d3472b5d180c8d1b7690518f41f14438e7f3a83d5e8976cb9a26151fc4149a3298d7e42c0503
+
+TST: 991
+SK:  de54e13f9e2cc754546c99b33b3d72f4d1f7715038a9659f33636577bb526adb
+PK:  36338db3326b005e5c61ff782be2eab166d4eb7234a98ea1cd855e1ad535e94c
+MSG: dc4041ad61423a12a0411318a6e62a5ef64a19abe2d9852297be2d4a35eb8670ca36c521531b3038acdaeea2ea01a0b6187862a4e1a89d4b81c5318ed4d67131bc38f841a142a2f6f316dff076939dc0eb81b230fea9881f8f0ff7ed0b293f69b289fe770881fb3710808e8e59e64e190c1e379b9dd348b02c2347d7e20696790b62776a2e825bed6917037cb635c92fbc76b4c5851027e7f13852ee7e7c52573a9030b79f22b60d5869efe680c01664929fe9a06fa333052be1d6af3a0b482c332e18051e78b333839d6cb93d93ebfb277e4268fbeeeeba1e8f96a5c9e328c4267212cac251215bfaa78fd88a87417a80602dcd8828e80400da304e989862d13201082de3530925e0edc2c130a9a419071b31088da6f6ff4056301c129fc2135233628d16d8bf160f6ce86d83cd4e29ae0c73843d70b53056c5af3f3dc561271cb5aff393f0803ade072d9ceb745b6187b28d24696767d5c21f4d4ac58d5bb66c5cadfefb1626ef93f714c782b6ef3ccf4b44ee75f0bb757a25d9b46a9d931a03727d496a22810c634f5c1ae60cbdf2f1ea29b54607cff50d9f8e03a0a4513cf68dfb619773411b6180959a8aac30b2eee4ad327915f60ae52b90e04a9bcef8dc67e71ea10aca553db9895cd8008457d76f02ceb53500211109e89603f304d880aaf02861fe37c9534a9d672d83713cd326c9ab81c353764ca5ad5ac0e7f1ff880fb48acd9cbb949064e21183bc38fb1d90cfe619a8b8fbf5321889bb15c02a53e4d367fc668877b662281c4a2af678f86e691daa8afdcac1b820189fe5c2508ce36edd9c6f8f51575071839439a003352c1573e12768dd6debdf1ed4f94ac79df1ab6a0bc25079c0935477d9149988ec3b8793efcda859acc392ab3fa99493d7ae0a6575b695a1ce076532860287dd498967c46f7add49494c02e744c40280195782e2424476165e72cee23642e51cec432191116aec59b59fcf0a3683b95f760760a20bd67454d8de647c0f9ffc4f90f6e45ac93d802f338299ef280d3bb7a4a89db8c59a12526f2783024c8ade9002f00e3d529b78dcdd4903daf5767a2bed75145396efb69790712de6a5901e6d8c15280182388285021d0e70929215d9f2b799bb92f2ca56f48e8cbba2f19b085845126567cfafa603c2946ea1e7d274554a38bf7d86511f3e474f9fa5cb11105fb52fc68177f3385fe1397be584a70089dc741b4b0095bf7eb2993b418df87b14a1f97926e868df6e568beca2215f2dd7ce8a3c9ee849cb41346c684f7ffef0a792edf433ca99ef34c73f9272a7eb97587c8fce4a5136444737138d53eadf3a84f501bb10456e8e4a4047082c9e1435f576526c2164714d70b3d0a6e9c08a53e323840f4dcfe8f2d19f0be2c88e
+SIG: 37aca8f248394a9e04d06a7da84a7defa39de4da2bcb18d5f64cc34db08651af4abb19fa2a92a7dda56ec9930b81aebd23990511f684c6d15ba595f7d4a2740e
+
+TST: 992
+SK:  8504fbcaaba67683f815499282b6ebd497a81a9156f53e025c2d3ecee0db6559
+PK:  e62da86493a0caf52921d5602fbdc3dd3a8436941f6be240b31509681238746d
+MSG: 6c63edbd40a03874ecaef81602cd6850c09f4915b7aaf418258c568364538e8392a8c379838b0c95345bf64c3dbc175853fb641f350f0b53a05a8ec290288c0326d435ff776f8683a273333f9bb2802184ecc53b06b28c2c402a54bf134c1a23299749a6ce2b51a7ba22232148797e993ff258286e947778a8742d3f36cc7842976043fc23da8a97ecb9715fc05fb0f23fa7321ddc1932861631604eba2ef25d8b756ce4733656bfd1e14708923ac7c60a79846136d741973ba5514189720bc0f7774b7bd3574595bde2515031b25b62654b161035778070ace14971df1fe0be4ea1ef55cf8747d3716c1ce707b1a7c8520e6deb334eb186338fc93000768eb2be40c6e0dc3f5df831b32c3a2c33e28898d6762a1522d3d48daee56a0269bddf6cfc9d73f8d178aeccbffef7ce164f98afea224a9b60ede46a95fadc9fc5d94d209c166d9b8de253381ea2248862946b9cf534947455c24458cf56683a0ec47a2c65075c694c7c3d6adf9ae5e8ad31ac769f83aa26e312c5b01a9a09404b15b814baa7666b3e03f06a8d6348ab8ccb9b60a4a4faf86f7135df039d955c07bd92e7b8e327ee6c1b40196a28b4446aa5a9b2b9773ab76e3ce21180f09d6c08d277c6771d67e22d84540fa43b38f634cfc46e5b8c33f15a568a77e4914aad9ab8c9f7fea47f7677c01880b3e85d2d0e3fbd6dc6e99e437ddc736f92b5a2ff2927e0b442142f0897d0b8a19ac203633df413feaf8ef50a5f767bedaf20f1c13f3b89d1e8b7bd18d591f9de116ee34f9824e4ead1ae9da2e8caaef88b29516aa942de77a7467b6fb26a666f30648c715a2ee9f946743b543a4428e0dfd06178e7e93ec6f26e003e058bec14a4aa2e3b8de11295a764cab30b313fcc5743b2fb89962ddc5cdc6aa0d2e4a306e77af76a05a598923f628a85df1cc73ad3bc01c4b979bd7cb296590a88b0a41b445d50a08423e4ed80f1763c716b6c457d845dfaa68d12b0d03c55fde8ae6b2b92bc6322943dbe54c706bc8e5fcee70654b26f3bfd877f5f5339ac182d5417bd4c0735d825bf70e85eab8216edda632ae7e22b3e53d078a8b20b5a7e2385337cf92b3c16b023563e11cb5043b704d37eb5ed9e85fcdc95cf7a6eade40803175a008ef653ac6136f16129abae1137c5823400748a81256254d317cfc939e26ea0cef9f6548db42890c48beb0479103ba089e514118038b1b90943d716f7a8d4cda5983a674b83a002d8ac9c65734a28b77b760c8e3803f8781ea9199f797ce729e06bfffe8c29b20bc85227c09cc05219ff2ba38e18051083732f83cbfccc310756450b261d5be183d9fb44ec18529f2cc9848c40119c607676bc4d9015fd4bd2fc918dc8031ec19a05ff362c184043be7fe066019ac5
+SIG: c0ea074bf9addee2e3350a969e7c569e3aea1a4188ee5af34cb73f388298653d299b5dbd94163fba209e8f7dc2e2634d3a52a02810a88c6152945bc16bbdfb0c
+
+TST: 993
+SK:  eac0f06c2c14f37d434bc99897225dd2e3f1ed74aa7442c550339df77d0b7b32
+PK:  43e62055db6e1349c94d89029187882020cbcf9d75e03eb656fa0a15b19002d7
+MSG: 27b7fd0e71adf194cf5407b6771793060de0fca7ca0ae64835c43187408a704f533d5ea0c83a654387ba7db16ed58ec837226df57c1fe6382c5919e92213f6f18cbb5735d178a476af35d390b7cd2556217c530f3a1f8ab2339c1a5e8d969387efd39414b56bb784dfd5eb89b859e1f403a238eca2a941e6db56ac456b73450698d1455ec1e9b39a1e907d6bc7e6cff424a28eed579af16310115b67f5fcf7f8346b3fa0260c6da2e27755aca570babb3d303cc832460c963bfdd5c1ffb2fc19921929dda2a717fbcbeb2b8525761bd660ce4a0f7685285d7fad6115ab09f8e63f5f773914494e20be1b512d1114cce3f0f68c7d94f54857694f22af4c698d782ce837b0c1722bb7313bb2c41f6d3dd1a02877fb4296d8662a9e8625984dc1fd1a9510eba9d643ac58a886a045cd0e53c056a833f968b35d01320e9cc0b435d3f6bfad26f9eb5754d38ddf6d5c4bf615a7644a23f9826bcc976092d82d81d547000de0081b7a40a93fbddac13f7d99708ccdeeb9405cd634ca0748cad2c1d8f164f5d77a4f364ae488bedcf1f20eb954bc8a278af81432417856a900f8f152921afbe17914229a513bd71ab7e661cde129af93e25094c56118ed1f22db644428b474651fe36be82fa3695c41fc8699667e053743b0a41155c31f1e2679c6e8cb9c9d1f5f4b40a320a9fd9f47da9b94211ba601b22a115210d9f559c4496f01732458f49ac34eb386636c8b6c68c7bbc0078ab6f398a624b8bafb1c622958562d231dffd4db096196bb87479e42ea22acbdcde8deb10e311632f02fca14787fd3140569b9428991543ec6e834e10b149f23c74bb99ac7b3799a2096d22e387a712b6f9011ea34c5be4c468581ac62ce662063252e066a9a3b15c9570d065dc1619929f06bc75a3179468bc8a16e3ddc4fe185ceba0a92a546b8675fc1ade56307150c7e4c844f6aa5f1edbfb54ac632ca2b259c32a33ee2867856c3390a6740364cb0dfb976e53d0cc6c42a106a1c26918c8a6a033b2aa3c7f2e4392e79f8eca5b336bac5061d7698a3bfe7c2c292892554030de6ce7c0d06eefc54906f81e0097fcff27d14b9b7994a7970e1a5f5c6b6405dca22033dff0eae138ad899f6ee68120b8f22744b0269a9a8989b6f7e08affae77bca2168ade24058ae68a7f800e02e7c38391baf565dd40b55fa3ab3c247b9ceb4d967471775e663d6a1c6c7e17350bbd6b9a3eb1e484ac2e7a7a5c84f5083e5ace8730de89c47e8dcf8341e40ba345dbd66bae0f7f076a705b1bb7f470e3edfb2b78e4d6359413d18d33280b454a0dbb881d8606726fa9bea272475e79fea6a54cb4c0619541b4e77c170c8616874b954beb8d105b86bd1917e25cfba9267187ee2038b3f0078f4c318b587cf44
+SIG: 45f2803afeb0fc44d3aa965b12659bf502e47295706184b2a1c6f16d050613f596a2001394e00e2a44c46cf6505d5cf5b8ab8412f07eda951a15005e338f3c0e
+
+TST: 994
+SK:  e608d5de9797907db6d98e0345d5caf2ad33e0eddebf18b81d61e8373ecfb499
+PK:  60e0c16ada586e3646912a5f2bb318fbc3d50b57d36fabb637696f9d8d4dc761
+MSG: e610fa7d8385c09c78989ed5ef7a230547f013cb7e8ddf31749ffc31cee10ab3efaca3f14ea194510f0985a818ef8b040e10c3a5114de1ac080f14c3d65d3c244f9242f75492cabae800fcfc9bc275ea1f27728c920c258fe7aa73948060299cb87835792edcc072150b73cefeb0d51562e53b46810e27a4d7f6abd32e959f7d731dde01d94bc41ed835efcd42c922437037a87dd366ffad2eecab6abaeb4fcf07392b3ab40cfaefeaa4266bc537671693c9093dabe8a0538cafd12c639a04bd2ba80ce0f29adbfc66bd4637ca0543a53b0e371d0e2e470d31ba360642a45ab4cfe3e790f587f6c5a5583fd15b18997838a200921c1c399c0b16278b7dd6d3aaab6f325b16afdf761a1bbf867de2bdd48615f15b526770ed20d79f0f30714beeeda58f52a3cc0c5a618315e522b9ebe7cd99b65ed532a62e0f0df72764d6ec6d6d1ba40ef40e05426360795d6dd85bb39f7321d3fb06275de096aae4a2fa2293f31b33f4ad4d7c251ac13e8e15c2bfb1f98f4962c54b6ce033b08aa626f2905d463f55b71cbdadecdb3e0b365dae07b170301983aeb83b1e9f2f28cf65419fd6b0a1a9c26cb54b5949f4bc01a98681844b43034c372a453d38f0473d0ddc709d9f49c8753a75b856c7e9775517df574a09a3953bde5daedf8e4a8da9d773a215120e269fa1861133cd4ceaeb91d5cca2606325458e50cb966d14055b22447eb65dc10118da0831df28c3b4ee8b11f0732f1521bb9482b11f5a86b22f18e83dd1d967d3944285e5d63a5a989817ab2418bc7ed891a373846747a12b527c2f44ee0197b946c67e67fa4aa1c29f3379d46fe07d3aab83da17f9d76bedd38436a055e34ca1d3af5a8754d38c17b9ba4e6419cbab515f431a2595954e428c2670fae3bed62b4596179cb59e21108708d071bcf9c621c6dff03d3cdc9202029454013b9d133847f26544811c0169770fdc6fe5638bfd7a720d8b38f7e30a7e6879060b5f28c8ab17b00200713207e8637bff4844d842d9ca788391340198a3fe0172dfa74de1e55adefbc2e9bc7e885476d1b9c055813408a47528434355bf03fdd4e27d8b3461b0fb66ab3e15a879a184457e9ed9ea6c51b663b31edc8c4a3cd454f69d9ce518d1b87888ee3d9dd5416e43e114ac05721352dffc2ca88597377bbc414009b0c2fd369be5ba35a6dce3478b6c11b33c0a33918b6ee5ac4cd4c2f1ca6bd190a000a838da38f53077560335596d1358937793963810a79a21b8d46140e768898dcda88a0faf8ddd0d633847aaea0e030be6455b41e3ede1e2873730eb8481acaa7a519cf9195847a86afa57f9071d44f4af4ca0d343c90c0d22d946146585f00ef3aef57f0f9e55e818c0128ae255dbc3116cf0fe02166d54859decbfdccc
+SIG: 0d8f095e42a2730a3c7bedf42d5c83398b5c0ee9c77c5a61d982291396a9182a0802a37f324bc4fb5d4aa4ed60444b66144bacbc865105d7690f140650691d03
+
+TST: 995
+SK:  0e86872c78620f10cb6dfc463d2c2872c4da660748c9cda01ab1456958afba7f
+PK:  de4989989269cabd8f4f409cf1a4d974038b275502273557f312d5553fab93c3
+MSG: a900f3e9c643a5649b076fb69c3b2ac084d52ccbafcdca5a9db1daa70500de9933d23d153f74954e1bd5f57b899fe8a4b134c195412b49833b6e5095a6554eaa6d844b11f1584c85055b87f41c999669046c71aeb5c0453fd6a3c437f815f068987c3868cc07aa2af65819046c307bafb7530de84f7130aea78ef005d5fff52f8deaf1d5e9c326d3217fc55b94f628aa104f6a24a395e62d1b62bd9c0d82436319c5d73e5765435f3ba856a4734fd60ae617f7f0c3ba5722a73366c88a6dfeca85c444639f441f2c55fdc464ecb299eee36d8eae063bb94bb2439da04fa5ebc5092338a5035e480f0834aeee8d711f28c46dc960de1be9df307c18c5c178b26296dc567f15bf60863a36710867e92fd51048865674c2af0c53b2e7a248ae5bd09a49aa030618495f82480c420ae106889bec006278b92272075709fec95487cfb10061e6722b93eebfc0bc587bf7ba5f6692b074f55a98d5c302760b1bf1d09f7e8668479ca6f01eeda2fdaf584ac2058fbf7cf3100d06b8091bfeab51c0c0b1d4ee3a8257f69b1617604fce953bb5f7f271c6a1880ea1b3f66267e2439f34580628917877c66ec0fed76e44e8bb2b91a8806df4baca6cc92889b8805070c9a617f807157530751cc17c47b09eeba94d22b4e547c370ce7a496fcaa3412affffb8c9b4de89b9f121aaec5f544b0c725ec5ee9d4b3476adc9d050edb0fdbaf02ca9e38af15f515015a267292ec9aa5444ed1decd9cd9e1ead6487a0ccef995b1c600a036935838660acab276d8b0e5b07d9f36353214bf80f941ac88cf40a08af917926234112eccdaa162dc99de3e25baff65bb01e49898986332bdc2d705d5aea40f9bc4fbb2806894496038da236e9dc29600c9cedeac3b616cc56d89ec2fa67389666c6c4fe233b639105023e101b874a6330fe573f80ace55d037cc612e6dfd5a6e686f9a83054fc46e15bb6da453d810cf138a178bf039d1e181614ff40cbe6bb3b473663752ea8025ff7f739ee4b67110f968089b2473cd044d48b009d0677f791f54e2df6afdc3acb9e99dd6958a450c0e1b6dd5e97a2cc46298b4f48ac6adaf013d75b2c42072d2ee13f733687ee83c3f70c4fdd9720fd1798c662fef3ba012bedd445c4729f2130484fe77ac1b4c4ddeb81faf60f76e3bd7d21a9a6c57a69a9cd9cc203fc63b59ee84b8915b3c18a5954e227c86ebbb7d4c4c1a08d0c5e467c68a06970751ef584bdd611e1dd1b48900ab354b99cec6e1df3bd4146ea0755350dc11c3a3f600d470a74f475e4feedaf0865276fa8a97713471d0ca9955c713588339dee79656e567e6ab1dbf9830703817ae620929a0684a5caf20fef81a8ee897be7e505ade6496b9aef0272bd8f350860233b338c2e36d3138db69538
+SIG: 2037e97741c3e6409c66fc6782aab389c5d778097ac778999e8576e49ef4f6a0c7730bd9e093dd3c0ae7ec76203380da657147d33a8d9dd65ed00cf76224d601
+
+TST: 996
+SK:  520354d85a87d7c22ca6f784714410ec98bf6a65f803ef9379bdc804359b2349
+PK:  d8511ceac2fd661acbffb01ba2741cad889934de6392961bdec6fa46123b7f0f
+MSG: a1d4ad486ebb7c1a0acb8f117013e8e4746789c6244a56c9edfbf1ef37ac1309aaf51c9375fc12cacd6897a4479545f2bf390ab7c0c0e5c592f5506e9938378a11b636bf857029b968547aa506c4a0829a15fd3995fead4f860fd7c623c63e8695436eae55816414778347092f5f4d422bb1b5e5a06966241efec14f1e4fca06639114718c30ebcadd4c6d8abe7fe93b25d17173533954188b1ab03fcb7792cb635ce36e9bdbdde7a561c5f66920d910cb269c8c1c3f593265090072c48932e692a9c738c704897489a715c2b394d5a86f7036a4cac5dcb5b85cfa162156e0bc6bfe02fb4c38608cfb23c92b8b6a3cb46e487d60e0dc97aa2e33e3dada925e4e6612cc5af125e5aca45817a2fd6c3ff10b18938b44bd4dd20d7fccf7f26b40a66f48aaffc9a541e6d37138fc55469868e2d10365eff37fac360fab3dc55437ac2d8fea7474405fb3630f7963d2d45958f909d14830286ff152aa752f510ce980bd5754e3fa32c69924dd95d5c152a737a8fadcfd0a4560e0b114f8e8aaa618d438b9877111da1740ef817c441939ecec799ba16b1b171ca9b649b7d78fa052d1497a507688bede4900abc53a9648da5917035ceffe0da21c25c09b06d6185bdda2d778f7ede6153e3eaff495c9796d4d166d2d2ea418e4a4aa6e678faf0696e752a09e02eaade763070e088e9964919ff4aa4c82f8629a3d5c797c2a64594d206835da0bfa43ccd9ddfcdb6aac4d486e03c84122375939a5270bc1519e0707e51c3f46f1e5c566b33a245fa0c202838472363de9f0edde2e791d82293095f750bff545e6c34739dcc54db0a36ae2e2aa39b07cb4f6a9646240d2d31488f67815b29545d220be929e3339f8281a937e05a8c5c3887e06048ea7b18a48f8d91b1e3af5cab5ceda0ebd71bf54edec203d37165e4c9f9f80461cd29fcd99ddea439693941b5d53ff94379cf642571dd559a11f8f383d943f2255cf715800af776b1045bf19a9c9bb095155dfb646b65f4a280f2a97ef927ddabe24a2f971a8170dd42a089276825cb9148c015aae1e9dadf22c10e7548c59bf6b868b20e86c83a9e7343aec2754ee6225f9fdceaf8e51c40e955bda49c35ded38fa8bcc1e6c8fc9c2412e9104c5c2368b1f9923e010fa2ede911d42b139f4007e3426922ffb6158eca97b47cfc997853512bb9d4ca2f017c2c263dc199f3bf1eb4f1508ef828b0e00db21002736a7f22ec91298194583139ad75f58e21b518daa49a4076c6375faa60891a69e52a656699d8034a7ab7fcbe42175491441fe61b1783e837857522215a5fac5590bed2e9d206606096d3be8ee92873bfc30cab15ce9f9910d01a117f89926cc3afa8d104f799ff38098de28b8ff0f038725c2903b24c1429cea4925249d8781
+SIG: 754e60d3f6f4ab4f5d0ddbb001532009166388487f780b76f60bd0bc9fefabfaab6be2ae7869573a64796ef2846e85e5cdae52db1044fefa796bacf48b968b0d
+
+TST: 997
+SK:  061bcf1aa6fd989897b322e591ccef5454ef4a5adb1a4800f32611cff2b5bc78
+PK:  73c80b734bfc9417d576890c20166da5c7fabd613f75474f7649732e00295be2
+MSG: d63bb9208c1f4c7d43326cf35fa5d83933151804ab891d49b0bdaf429e4c39a321428e0d90aa00318b97e08c7024c912cf388879f3cf974bb253a1e7a4c8eec193bf4c14af6fb9794df0d497850edb04d574c97ed76c702139968401b40eb54394ef4cfaa7e5d3cd943af12192538ddee593c2a24a267afa1371fd77feee2071f4369fbef87976e7ebd81d1e5b31d6e09e02d830357d36bff8596703e4146d0827bec9c0f87b26f31195c96c93b6d8c46767ec1bc6de39f0008a41ff875da050a3f865ab92cbf29c38a280f3bf69f68e92b5f430cdee3501981d0b3d189096e0aeacd64c33102421348812158bb61e51ae936592b2f8f1b910949ef3723258a9b44e4e1bdadf1ae2cfc18e37d2ed0dd1734404b8baa5f393cd56069ecebf7edd7c06cf6c8aa3e8e12fbf946d7b32d8453b6fbb6535526c8fb8fc1d5815560bb31b995df2adbd836add929a56fdd93a1747d93a40c05e129eb6f8583c2921cc9dbdda4225e176db386a02ec40af1032c9b62e95147025f4ac8dd58433b64ac073150c69b9c4154dcbb00344f308113cd9199ccfb5075801c705b8fc43b7c8bc167365e46293d06c4f4835c64ee5d5383f6890ca35a80af917748162df2518ab1468f153629899406cde66ce07fa7d2993dabe0c60089c91892488f3bcaaec408a0cd08c9aa98e0937e02c41ad52d241a99833e3b83f7d3f1b078c31d45c34fa0175abbd0f322b8fd2dc83491da292ad00762e3e577b9eee0aae08729070ac25e33bc94525bc0d2ab59704efec5c0148421a47928d34b1e45ce721ee6447fb082ac400b3e6846d204f7f9db6f0a32b2a69738b3ee9ddbb0dbd7e0f041d7ea53a5d647fb50b39ae24d78c8b07cfc4e052711f0d4639e721d5c36f31b588866712b757108a40cc7abbb9913083303aae05a0f1af0ec6878441a25cf8729aba42a3a94ce9b73888a0f5c9e40c9fc45410f0681fa7f90898562ccb4bbc55f0ab1fe9c70ea66026dda8d7090f7b38edb5aec1557b1166987cd41a7059cdee609b74d8fe06b7059b7724bff53007f7e110462f06ad14d07ee1b4d69ac823bcf576d2fa9e2e8ed7f3198040d471296063137c981adbf364cb20f0a1ad2054472f7cee2527f99809615d2e4b734b06f35deecbd62619663dde81d6e23528b0c97132af0a23bad63d9c08142a26e2743f8618ecfe723b19ffdd0b19abd9a3f4fe210b1e71acdfe38abebe23f7fdef66381cbc75f307e5577235b02e4cd9cfaa15030868ed1453da58f783b7352b04656844c042441efe6a3b4f8fec8f7de80744540c4fc7a107f4e1bfcbd99da25b9746095ddf0125d56da7e7f8603f04d359a088b4c044f936ccb7d8f89ed53cc991a3497ca952094ff3c33046f2609d07b29b633981369cb2f0eecd
+SIG: 5adaa94330a0353712a34dbe973b7518f9a2c713f8aad100251b086ae8de26f6d2b6ccf0528cc5dedca318df19cc7e45deae281e1324b96e32fef45aaf60b10c
+
+TST: 998
+SK:  2e19cd442f22a4a99dffc55e7bf625f89d1344b563f6785313a7eee973b4aa36
+PK:  ee3da76a8fcf403a2958d4551da0a72b2e738522b2e6b20fba6aa26b32307357
+MSG: 1bfc5c6aa6a5354fbb861469796348ac6319124da3f10d20d50bbdc7159d41b5abb136c7996a773797122b525e8e2dca1954f6391707301d90f2101b46c7b086efa15877cadcd05812db34b996cb4f531abcd1e98db08a5cf1368e8f4b1109142e9562bd0085ffae5e660f59c930793ebdb6e80b0a2f4f3f59bf9d395c48d26e0a72a60f9d1ff87fd2d7a3f5383aa902adededebc6cd1befd038336162749d91a957ca2e3dd47091c5593113da87c3d66a02c80a6eddb535c48ca1f34a97fd1c95ebc2e570fc8fafe6e5d6546d1f3a9ba8daac334cf47bf117e1280d0ebdf14b0fcdbb43b8d248cc6b61320fdb0449ed5f5de8bab121af0d8554956e6a12016b42677b44367892c3b20afcc2cb9cfb5b100a95b51e8b07da9f51415f4cd7781a313765e20db27f2343e0f719ecea9af026956f3387e9ea7ed0a293759b4a262202807b41309fb80f50185db6a5f8bdca178841bec06addc7610df76017b514bc4142f26a36bf5bacecb012fa41710dd849bef7a7e451432836fe9b3265fd5b59ee40b04dad85cf48f891465a842cd4500a1024eefdf0f554f0ca17ec9f7b715256a9b9dbe27966386d8ac37d3c515896de0f7cdf7cf5b320ff7a8ef6b34ba820aba9066dd253c5b7763777f94b2d6ad8c710221e1137535dff8a1b7565ec81bd8ddeb502e3d58ff8f1fe6e86b8dc15a3aaec688bbbecd4688281db0f818de0f7261ba9cc58c8bc0d02e06632efe7287ad7a84331a824d9287344efaaa74f1fc576d0269430f856a8565265b9d6ef71fe134d2510ab06b60bf3c153b57ecfd2e6342403fe678b5886b6b734b7d3690662b6c8c6f6e250e5af6a8183166ddcd0a17f0cddc8636ef1a68498be50b6599539d46b4cea97130e08f94ca53e884644eda75d23cd2c038a5f17b591e21369378cd3fb5762d1a7c3e66a11ae6e91cbae616ad055e39dc41e154f4fced7b2696d9dc67380bb8eef474e9aa83cec47fafafb941d626564b2075bcc0856da8d6e1b0b8f18baf7513bbd14e491ed517968c4f7241af25098ee8df130b7a34d59736d7836d323fe3f43f508cdcb755895f59a00c804ed164cc33992f3aee962ae9e990b74272eb987b12d90b27314d57400e737d1343e970985c4271060876abcd7049e7c9fe244ff3ef98560995b7482d31bc7c09d9969f7cd41f4e4e252750dc16ccdb29b985314a0b6e749c95f9bd2838d5ac49ee031fd079bec3028dd9dd07db6fa622ad621b3b1e127e8fca37bd146e3cf703e911701b7a16c2d30369c94648ecc03df10d7dd5c0558fa9593425d948727d6860c3a14f811245106616d2a5fa981c6b7f47ec9def65412d132acc6919da4e88597aa9190ca614b218066a0f7b16997ee747c5a09785e50d0a891d95937863d613ceff7
+SIG: 28326b5b978e0dbdab5dde703785a667a7ef439d81ea47e066b089d116c25a34bb633f260d55f45bdf6bcda74803d7624b1927cec18eb1992260beefc399d90e
+
+TST: 999
+SK:  82109099d1eafeed5a85206046491b34d06dcde33f080960287b10fb23ff9f78
+PK:  081cfdf2d758654c41c447e1e6273810f8a738a733afc42294a2b1bbb769efce
+MSG: 84f47dd794977a6c1505ac8c05680c5615a2d5b057e39b04f85e3f9ff04960e0e016685a86eebcecf6fbce5fddcdac1a474c8a0d502c40e10f948646fdac6c81f1ffbb177a2a4963b67825903cde65b5dbe0d8941d546cffa2bf8a8ca8d6c6408530a6290f5d0882f1a1672dbf978e10c5c8af5e0a6239f0655ee7fd9e66963077a0e847137397d1f06999dc6f8a945c6003ea4ea7fd58378acb44ed5780eaa367796beea37ddc236999d012d6a716d7915649cc28e58875647e9f5ac0553c0f544df56469c67081d5e30395f3e960e6a52f0833192c548cd57c926b82db48c361bde70333a370083eaaa068dc2ae452d21ef1331aed190bd3e1289a104cf667834377cf7b5a29774807c3f1ea9e7b28831d0f6c4294785867b137b65028c14f932a1ba8e6f9f59624fe0c396843ea19e46fba09142cf9d42497312f360244032f1e00f38dd0de29f963b5ccc1ef12b2cc6204b994af1f3baf196d9e21e8fa4f097320c64404d0b7d5ab38560ca0655364b0b09cd6dc0f0e05b8c9110364f1424a9672b7efdf7e1f378e234550566dbe13b01578b04153e9c37b553e32a4441bc97e2953bec2e41455510f9802ef948dcbf13faddd722ede573627b258d55e83c0895b22919e4be5ce8d819ce6ad843b2dd09df64004c826c1dde7ce6480a271a858a1db169e1494d4469032bcc1ccd89653198b7c073f76a26a2999b5648cbadc1574c78ead8eece83b91e129c437f9eeec04c807459002e66dcca9bfc2caed9e6c0ba23d2355def75665749430ee92c532a695479fec929174f440ecb61a5ae8b2b7e958920558268978f7fb4da1b38b12014f5d61b0fdd7f6136ba4281b41a3a3cd188052b698765b6f05e41e78373ea830469787a37510993d12f93e96c72d72f4461984f691a41c7d3397ddd5a1b39237d1308864d415fc6c22b63f376cedde37f5252b51ec72e5155f3bdb4fcd5412498bd2e0c1f9850b3a85d1dfd25167a3cd771e8e4c9d868c95a7175e3775f6cef17e4e36497ce9e45532bd7f44b2776e40f91a07ca4fa1b95dbe81cf8f49e46b6c82a6ee4347918a7643b0d9a38857212c693eadacfd37a5f1d91558f5454dcdd05935f290e62d7e65006cd549f6553ce741df44d39644001eb479ca69568ad1f23bba099a41a47294db938731c530af1ceb9217d29bc2705613c1a1fe9c208d0b01ba6f4d9b4c7ba8f021df91ea2d578ce083123e83ba4b9c50407f6666fbe61158b0d1b9577772e3eaff8fb429d0f6d2e384126130f21b449fb1dc170db45af505bd3182678a9b5f9fdff65f0413b672c4786340fcf2522ea7f3d8ade8a059529649dbda9ce51ff05a2a2a3d66d2166bf2c9c6772ba0ef4105e68c055e0213d42c1ee123b3c1217843e6ec575d754df3c90a75
+SIG: b3987f324bc7e776c0f287fa13ad28741695e2e7bce8d143e29fad5d00994758e225fb802100d23fd6ccafee8e0a95bc479be8c23a11319745765b7cd47e7006
+
+TST: 1000
+SK:  65fcbd626d002111334baad4e6a8006e47a1f91397bee6dd6cd7da5a0e0248a4
+PK:  20409a146b42c96beab0b42ea7f2c25193119d0df44dc2bf14d11a32fd733615
+MSG: e4c0947fc8ca78fa8863f4d044499d036e2e7ef8c17e838f2fac02675b7b5381e5f9abceafd0d8886a929d9d9b49fcb73861b29d1518ac5f83f7f8fc26bd1cebc22d873a9a08231406fb032e4866e5f55c7c0441c519041bb2cc73f9226dd5d07eceb660d6c967db23365574bee8fc10222928767713571a71c93a85278d42299a70599ca99326cc86f6d98daac000fdfa710562f481faa020c72a76e2067d154c235a7a4f29708cc544533bd799ed6363eb3b56aa4a6d0e379bbf07600595c23ab1f3f9f1708e0070261bbbf4bfeaf6d6ced4d7ff722c9cc52d9133ea68d495dc9489c3edf6830231351f65cb5272f5396e2c4a1a5c88661a101892249e23d6ce9fdb6a9abf74272c2f59c3d8fd8743cce461126ca0a8b832b4b218336b1ae14da677ba7f1b2cc5ca3c7158f727a9e1b8fdd9edf5c2187fcb83db862ad0c6b39216de3116919556465100ade0a42bd6ba10d95418b69a3e005e9f104589ea5948b2b51bc7b1a9a0749da8f013781bc05c805bb51e187761ac24c76414f668eb45fb0a5024dfe5a5ca06f0403a02e3b2fef7a2c4bcfb1d075d310d5197e659cd14023faec20e045cabcb86b221a1d4827113ff3267a64debe9939004cabac85e5c7461e7e82a975acfae0b6c516a1c605374cfea7d819044efd6d74654424fd5c90ff2574fcd8e007740d975861d0df5259fe43e43639e36e52895439ba2c27c1e889c93094104fe914921bd6f25d3985ab1f22ca557b0e49afc7375243c521c6d5fafe0381ccea828e88e647fd90976b3fbec19fe9adb113c6404bd352bfc000446d21005b5f950ae07e51c768ca3ff6177b2eac50f10dd2e64610fa8ab5788faeee29d129009d7fe46aa3da6b9d86c73065eb5161fbdbdfac5777c4e75452e6e16ae9fd66bb7d9aaa426bcb7a6915f0ff44a1f8ec71394e9352fdf20e02fafe1e0cefe50744c3194956f928f82533755373838dcc1296a891adf641c7382d69b4f5a43d4af7772a4a1ee879292d7a4f32ac35ee121c6c34ca5f98487a941fcb1e65b44d4456127eedb2fcc1c3f48eff9300981e52ac38b496ab8bbce144a85eb9c07638b31fdaa781744bce17e8d93dcdc60afeda488807617f88d6aa54422fd347ddaddeff37a563dbf19974b2a23be300fbfa6c7fc41f84c6905415269f195990b5b4de12668c71c87b504f41124bf94436f333045631518152c5162a2475c40efb6cbdaaf9af428fed325b3a7d94c17520fd89e00ddf08b22adf661f0acd723b3969dc6434ea6f92ef58e8dfae5b0cc2885ba987ea1d16c39b34ef65023009d6345e48e3691a41f02a77b7fe133ea9de7565f157a2078ae988bbb266d22d5fa91a7b263e98ad2dc0731fe5a29025a0cb436864a5a60db257f1e76b5c608f25cdecc87eae6
+SIG: bc78e16ba674e0a7dba57a19094f9733c55d74b9d15f8a44d1bbc0a023f70155de2977111a417eefa8cb30ec12abc8384228167c70982a8206b1ffb72174af01
+
+TST: 1001
+SK:  b500768a2823915c4a6848d35f6487d43bd766d2ce0945f8a3ccdb8d82a3892b
+PK:  b8cea215a0124eed27005725d897781ea064dcefb21422c8bd2402c56a10571c
+MSG: 0a9fda8b8cfca7a5b05d78116fcee19ab803c1c6010ce11daa8e93a66d12c12e474eb91c2640d97a813d9a830d268868eb2e3770425f10c75840468e669dc7f61d3be2de88ae0e542bc809679113957a14da4eaff549bfde637d7cafdc6aa83994837397f86e4fde86d402fa9aef7f65549a214373e560e6d7a1c2769e0c7d5a0171e7cc00dff36e0429798b53aa621624bda74d6df0bffffbd8fd7bef1a64f36c000782f6ed031af5c2a74a18963598c9ba062392de9602036794b7b5e68c25c93fe7cfad47a7c5b979d476cd513a12bf0307cb1631740042a9fbf3eb0be5170620dafd5f16ed89342c2625d783e74ee0d784bf051943740c88b0bef7bc85e1a6a4a517d492fb737e776699590c93224cd4d9245d4e9371a367c0712f87490f9247c49add9313f277a4d9f26b75aae4ded6a3def85f83fc995910405548af670ed8aaa30524ab829ccb56a5005b58bce868c9e8074f07dd7f3818f299e4e086bed9eab902cf11b398d531b8632e7d523a8f877695f46ccf9ce24e62cab2c7cd0aaee17db52676a4b5058e9c1d7c47bffcb641b0ea2b0944f39a75665a7ef29b7f02a878db823883bdacfb0fbe5dfe5a9bed9fdac7e4142e3eb50d5e840bd0ac0becf4fa97e1fc4827c397a52465d916889954b3701b0fac61159b23092f4685f4788bad35d00da2679ecc54921f1a8647101657ab49477420567aed67c8605930444b5d07927c17eff1f8570cf2af29e719f85ca7849b895549f13dfeca68bbef71e3ce8b6cedd2ff68d32b02caf5951a0b3e6b0bae6a96c02058191f305e090711c46daddcd5aeee769c3a105e9a827bbd195d329231c26238479a9bb0071afb160ef955e874d7a420c56785f44ae0a18c52d8280c5998cf3888feaf89898134bc8d411fc9f6c5768ea7a249729413739e532b643937152cdfb8d2ff87fd48084dd8aeebeaf0f7b10d87b6e4423228c9fc8dc5e3852aa8b8acc545d18f25c55d73da1bb82e3eb376f9ef05b274d7ecb1845d65ca0cd2629f038a2d664d7a69781c84e98de2c209c46efc51162172856649469e673308dcc145eaf783f5cb5b4be7d9fd58ee0974c981a38fea8e31267abfa410e69e46482f5134f3da1ffe381bd69d8d0b78ea909b4af9396dcaff89960a049eda6946616fc27ccf9a9e5ba1a0135764f37719da4d28078185d04d72419c2c70f290d97e1f82b879f71b9e19d504d364cd3ba22cf905250fd37d58e5fe40209f6072a06d8b5ba70196230577877ec46153167a7c7aea270fa1098aba9e3a74acb36a11b09bd07a3b88ea654e268365625b589b2206c710d960f42ea419b7e4e3da4759fcbca50e4bf4cc55cf88f70b3180c805a7045086afa04c6be23223ecae5f82c146d54311d1807c2e4a53f9e0a4482b4e1e
+SIG: e3db47a11e10e788925d14b1e28b54c9fcf9b6acc1df8c14f683a5672fd504dd4a475a3393b3ef8bceac2361dbba3530af25c246c3ec4c05899b517f6cd34f0a
+
+TST: 1002
+SK:  9eb5c9ef13535f808109f4a43cfad5684f80daf02eed5410ac0b0a09a6082d69
+PK:  367eea1ecb4e5eecdf7e471b90bb34f9b7982c8cd66d42555c240b41cd8739db
+MSG: 2d7cb05e61dbae26258e3861c639ef0e1d17fc711a00f335ba3c027137e00708d708c1ff457ff2c65112f7dcd7d02f24d56f072158ea1c71832550a58366fd9197296bbe61aa4d00de18a453ef9174fa81968305c41c3455f42d447a9234f06e13bf8bcaa1babb11695fafdc08f7a584b2ea1f61e9389260ce7335a07de72c8911a58a313f1088dcdf5c8d4c456cba2dcb4f2d156b4943b95bd493ea4fe1a82d4e3ea02aa02972400b5ee17842832d59979fc179f843c44b03eb3c302416d0cdaf11c4ca8a66ccbb6997395edf6fca2ea004cf3486971004a42042af8ece005b94461d86dcde212a2eb1be3b914c783e48ac1ad46cacd73e1eb448368322d2678efcb2abff52093db0f259dce5c1e19a512820f235d6aeaf0e1a723c2c650cff1ee3b6b4f4cc989c0b7d6de3cd7e6daa39bb690710df00a7194c17201f0e81be64b6739e1c1e8176b7e12a353427c067c19314db642e5c76266b640eb1cc0c73f84fc0227e5a96060d814071cde2fed944767b7466f9001dfc223685429bc4e5e48f5c13a63a4e0d826133ad920d11772145ad6e13c93897398a8a401f93dbd103005c7dae44387f3e80b793607d05d2d8bc0d0351a3a452b8ce759c1ad48df7b9ba9e4a17df61fdabb9b577b5cec3e9461fbb5e128155a3c9c89f8f6bebb7322a16678e8ecb98953d958310db1b063448c349f36e168fac484cb3c0d4cb2c251bd92ef8e9262b44093d7e650a7d3bed3791fa88100fee6ef0d5e23d1e9a8099cc0335202a4f106c24777e98f81d26efba15c9ad1541e0adbf1d1d76076b0dfd7b7d6c8b82f9c093468cd196672dc5478e91ce701cdd7b68b353c97111f0429760635762f8683ae970564bceba9120517642e8b3a2baaa85c25b54a943766184904c72d929634ec5f0c28473415f12538906c678fca4e682db4879758492537e7850b9bfef3eb9053b43920d810e55be966aec68c9dd3b62ccf57e8178cb5ef6d16d172a56dd924f00f2d3b5e93aaa92b29fb8336d73e29e59d1c47ea6230cda1d5b03bba5dfdb331feb19443f123d2a03ff4f10eca166c2998588f1e584ed194dd6f73c8aca846631904d9fe4a98b367823e46edba2885129879e9277e150f029b8fa7bd11eab9ce1336777c80b56b3a1f0811adbca0f5b4025a5503c8196661aee90006e9c85bbfa4c5a0e902885c8ce51212ee67f0fe0b6afbc8bad453727543b3c68b890ddaba269d25fc1643f54835136a1a25ba18d916cedd6a47fc07adf6fc69fa508949dc10d9dc5e0261b52f3657170384eccd9c80541354b1ce0f6fb5ed3e8d54af0b5bf0a92835125c7d9bc4f092ff380e5e896fbf302552b14d5b61a224d86e301c7a66a66e4e4329aac0a66b156772374dc1c7168d5b561652f8f4387e4f289b6366a
+SIG: 429ce1fe846d250849eca7d456f8c59f8675b1f4c13f2be41688dfb8ca2a3b24ae29d5b6bf471157bcb6e2ec9d4a26b038e6ec28584cc23f2a03556dbb37e900
+
+TST: 1003
+SK:  ef0948e13281f3cf352cbfaf8d89d117768552d5a1548ecbaf37412e97670fac
+PK:  58c2457f5a5e3cfbf47119a87f2aff1918f1e67ae6fa9171d3f41eee07a86872
+MSG: 7ec47f2f1fe3b70a6d1d82c7cd924b4bf9b2029fc12c52a6e1cc06cf5abfc0a442e7cf145c1542b9b135049665711035e3c29a91d4fdaed6127057a812c22cd75ad1879be1d2c6110e79e987524e4e8f27f16eda90cbd4733f111825b516d1067f81eca5e6948576d5bfedb3277c1abc1e60f374d0701b32ccfd6a5e9c8d1659aaf3d0818613613b7e288d845e9aaaba2e3e9b411d501dffe856fd313e9fcc9e7430b9983f20ab4ebf4eb616bd63e2c57743658995ed0a149ae620a395613719b3ed7ced4588d5915d70a2f0c687680ec34fe3e9f72392e189e13a4749d5ca9fac651b92c084c4066fdf98a869223e4e0c9bec5812b5c1900e6e60d3a188d48a74dfd415b5cad2e91ff76df75089d20a755f260756c8f1382a29f7b93726e731071cd477458c6f2022dfad7d4fc7ab2380541864f6b58774f9ae8e5f077c1a8da073c39853eb2fd477220b45a3d92263dc7e14d3bb2b36fca466c7ef8a247538725f2fce5c7221bc751cde1394604f5931d733360ccd47ce087712958180ad84fae713b543f05eef6abc0661433121ed3b4506a1465025316fb8f9d64535cc4538acd4064dd576b0740e1beb13bceaf155543dc89097ca5ca1cffa0ad65a10bcb759354eab8a42de734af909c2feba380d66409f325d5f17af9ca7f8cb4134fd6a2b6a528d9e60d9612b8e8b4062f8e0fad1e7eeb9cbfef6e9738ec7973e1cb2ba2327deca4ea46568f31e12f730e247c1d07029fd4422b298ff2398023b4120a3a425ffb652880c19ea69f3639e0f6df4f00876cc4528e267e81d5943199d0feb6cb4e1baf404bb6f8b39b12dbce9fdc35dc158066e9975ae5bd3b55f2a41a791baf3e8351ec604944790a22c933c80b1590ba197a4706f7f5128682edcd74dd78d435e787c2b76a57b3f4e7d7be2efd26da5f9a829119b01508b7072c7699ce52bb578cc5b1b93661b5172fb84daf1ba364d2cbd80e2c99bca9caea873cc0a1629eac384e9b206842a6e6183387591b4aa34a95fd89b49d8d15d91e21940e17dcaf1eff8a0a47a0d7a95daead82aa3df8204a0cd206924ae510fec8a9c4e8d85d466fdb4dd365dc99336b22ce0b956b5ee0017f29d25ee66fbdcecb0d996ffb97c8defde40a9ff9993193ca8f1685067c19c526e0efed236f8edb8def6c2a03e21952c8612d624e6886a311ffb9e2f15da44abe180d26a14b15f63561e097a730ecabb792c7c235fdd360f571f27ef68677a7d63beb4975982cb199a560f816ee12989445f7f75b83eb278d62825947d84099af2a6ff2eadbbf589b5eb2f72ed114c73151153ae0022bc9564d15c2d5cdbbaabbef638f03095f53eebac9683409ad3060cfb7c7037b9b0befe069c92a02be953388e9ea45d36ddf4f5a8389432ccf504c50808b07f69
+SIG: cc12f69db63a678ec477a605a505c57dc2b810ef85e3e34519cb25c51063aa66355d3f1e2974695866edf6f17171ce37842fbab5075fc895d18ed743c546080c
+
+TST: 1004
+SK:  903f3b5399892e29ccfafbafbd7cc4533c154a625682406c89bf894c889e43f4
+PK:  8fa5ff5b6b26bd67df864046429df124b523005dd89444275c8ab7ebddb6f4db
+MSG: a2c11b5fb884a822fae64da8dcb4452cfd7a04ca6d7a5abc8d8271e93f93449e1feb8e02975f496b9034400d3599ab97aa3997dad1c9ffab5b9f8df4aaa5b840d90d862fff7ff0cf73a60c66150009e01c937bd1af6807b5ba2ef612ee13d6def40bb09c46811a2d4e468e038b323055f9dfbd01829ae2f1a535ef0295ca1ed176e46de996cc87bace45356233211835b6f4757c99bd527e766a5f0b127c8cff8e6d66f8bab86d0000452cd7f67be557788513ec0709b537b007b42016e7a89683469bd8ff8d21eb10c14917d47f2dc4f826324f7c01b24f8dcff04aa6d85095d9ab154ba5c3bd919c9d728dbdc990d19ceb237b452907bdbe21f9f08cddae5be479276709b8ae73f8974c4b113841ad535d6ff6223eea47d185c8e8a65fdee2c2d45800c17cb556eafd676647d9968e55ca9c59232b9770ad10f955fcb5858edf0b7483adc1817c0f8d02240482caa76f43c6d2e96a4ff9591cd7b878ea619ea56d1b588631e7633c5ecb2ba6998398cb06e3cf75aeb3e08dab19632d454ff7dc0e2a41f09737e8ee823d1b9e24dda84a2ce0313cb9fce31cb663c55c05645e63401756e8ad38f5174c02a663d815ad64422ff7727d4fda16e48d4bf8f6602e7260da62330e6878c34764e129afbd552208f6bed4f7cee9b671f488388815d74b4951b8682ce76cfe31e938c470b8f7a45fd63a9691f426a75c58ed3dbce3ae8fd9d10a8352e47cc1b12c9192ac8626d1b384b77a18b986e71a998646c137992b67c4817e346345faf50a2659fdc5cad5c719648efee3847c0ff6bd7095c28b4c5195967c90cf84e1ef68a1ada01f6274ede363fb82e0b549a870245d608cae8234f6d84abeb61b718466093620d85c584ab01eeda091ee8aff1cf67a4675679a1f4003e66aaf43871b88ecda6a16dc5acb05395f2da9df70d3bdb61438e1c3d40981e034627d026ee1d2e79f65cbb8189fcbb3cc8b5c2e7e796b5d2889411d5641fb869c7b0a589c43254f8c5438aaf5ac423832f018d79a51b96f242e2de0c851cc5fc2b206bca4b5be836125aca144bbc38c8c638be0d3bbe025a1be8b3d03d5929baa649c3544a32a915e926a38791b134a971bc52d1b6ca625efb7c2f3bb47ab51d43c8e374d16cda882204b71cafe9093cb6078ef2bdfad59edeaf36d0c1a4dc425b9e718c45185225a9c3084b782bfe163492f8e8482ec9aa073f6901ff3d1117ce917e19122fa67650d858f8f82b37669723c226d721697e7ae3359f5a6b02424ee8794cbeaa641edbbf753b103a5fe158be0ba60d8a212d42f8c5c2af254bf1b9c80df6f1cf09d70793cae1abb4627b1780f1bce7f617ee50f6bd4b083b2fc7cd844afb72380d5cb6b255bf47ea71cad6c6c4df021f81b548f432c18ac366c6aecd03b6c8ce2
+SIG: 495a8f991941c629bd641a67471ab860bfd39b72f23355f7270909d5307c77b1b94bae3ed19450780e9085305f31b1e1683facf0d1fc8840aec77df67aeab302
+
+TST: 1005
+SK:  ee81e0fb052e23ad759de6aa9838de98e36d4820dc0e1b7b3ef1141ab9de3340
+PK:  98f3c9880794de64fa269bdf336095e0e01b1a3b375f965b93700bbdf4b96869
+MSG: 28d99e9518b88283c220e76de205d7b6162359b1dfec1fbaab98ec0ef1df8da40b6b7a775e9728450aeb2351fe5c16afda3aec0d71049da4cb7d4c63713a2410abb022f81611cc064587c8047d4383c00c3c562e9ceea35775095391b5f3dda0e373c4a77ff618a28ef68787ebfc3ebcccc5d1ce32ddf43bfce57203da76a8664b3c616a8869282db0b72811b5fd5a2a03a4ff66724b0489ea2e1073d781c3f189115d79ba20a46d1dfaf5b1a5847b2a2e31b2808737569e60b57231e6a99af26f58afeb15770810474812fe4afacf884506b8c314bc6751bb42b4bd6e87d2e5de70fec5f0014c4257b13472a3b0111a7a8cf83b1dc0cf962022cd44468a3ab1f0016b70cafb1d0246acd7053937c9ac40207cf13b50dd15e2a2e15f50a05bca2f28e770262371dacee02e25b2a59658ed90c0600fa265b7de3d44f8ef0721bf39ec4d4eca5888527b778067b1d659c00514c8d7056273a294cbafe45090d069bbd09f92f461e648f3e682882c71576e974debb0cb7e0e8316406660150dabb58e76246614a291c12ce9e0346c02774d4d09cecc23696712fee250c0bb5df7a2a4c43a5563331bcbbf84be3f2eeb0654532e85ec597b53b32f3954ccaf0cd426def91ec4b208416948af27de04d832705897a04c5e24a2e88b20040fd4eca3089fdb918a92e35c4d31da26850b9dd34118c74449a855ff4bc9fff0d1447839654b00417999fa4eb89102133cd320409153584957c10489db4b7244c95907988e83dc821271dc1ab643d6992d0fd820492ae642e24d19a179fa75d9363b321662606fd94a47fdb2e68d3f30c04673f809de0144945ea4d4183d48f175079eed50323c6b192e020e162a3503aa582fb08b403624a23e357eeda08d904386f358c36c64d314c77cd9d4d23d581ee53d81ff97ada019cfcf04eb9dcc1de9b74c3db6b811578bd4f219c5ca48ef4c826b09e6c96d031f65dd48b6e73d0c100586b21df0293a03d2ed7e5009ad025340c21d09060691f5cd8af2ab12f9b860ee87815e1a9f400c2a6f634ea8f9b3425a08d10b3c815367388f4d1be356318ecf9035d0ee975affa859caac28ebccd0599bb2f6f3523661bd178fc9e4cac378bb9dd4716bb06923fd2bbd56c959c42b95d50193f8bf299fcca3b2eea94ec5f98583924c080416e28b54fe57658458b055ce4de8a75fc82715cae91d375cf69281378051bb61fdd7bb0068f63efa6d6e83d8fd4257af80970f4a9e6924b2de0ad966dffe6fa4a113b0e772f1768785b3b42049f76c48ad80f2c67fb0f91a5fc4107912520d8d683c062c3a222bcda7e710bacd478ee88367b6a059a452fd26f114a5acbd6979ba019f7da68ac04a193026bc1c27e4837b1de29cce090e3380d5051a586409e628e3145665bb1d84ecd8
+SIG: f0d873be15cf454c7434deab71de25cfe99e81a48d2dce6a35d1633714df0f8b4029e0582511efc4d06892f672850246bcf070c46fadc2faab44dc435045de00
+
+TST: 1006
+SK:  69d01d829113081cbf5d0c6ef77b21775c8d9b680000056f03c75a7d0a0587d2
+PK:  ee8469dd61cf5de400da7d7a479a4418e6772e69ff5330ce5ca77859fe271755
+MSG: 0b9e110f29d19816a17b2c75478f13cee953811a1983014cb7eb0f75526912044c3ea6829780e657f817c5597d4661080d9034c9778722418f2c3aeecaef6b690c5bd3b593701086988e4340aec34e0172758eb24087d03a8f76e7cbca53aaafc4d2155c7532ab54be48872653066fa1fdd54acfe9daaeca356c290e6be63355b6d9fc52eb5e4fccbbc6083507132de485bfae9f42e19712232b716402c23fea74efa69d73c8c2e3a8662b8b65b0fd007741013e1f6e3cfe4345d5c830682fe60021d708e10a9e9f4052ff7a6abf28acb1d6b5fb038eed3f72513c355bbfd5c2274fa85fc4f446974b2d1bc036507a1eb5fcf55dbd44210e538274de808b900bf1c0fcc0241270db8dbdcd88349d67224f087e5f07f699b0bae68b2ebc9a4e27c70d3ac7d996fa7d4dabd568378e3f93905b1c89c652d384c16c2bcb1c9844c38f71bb13e0c6a2ea95b612e390c5f86d248ea531f2ec6f639a402dfaccf37217005344030745d1f1e520cc195dafdd7f295f377b8d614716703836219bb7b09fea7aae9ac33e42dcab65cc6142fcd8ce15e97717fdb33e9538c44f6cd9c1c65db62751f552f870f10142c96f9df1855abb39e42706a563ab154511fdce687c9576f9edc3b4ba55346ce66802fffef4b1b5e12015ce8b57de5458caa0daf341968128584288c2f27cbfb76eab286bac5f66aad0049e0ca60a9014e17901c4130e83ceaeb4c2713e971a235eff995a813ae4ea64a583ffdefdac82ac76eaf4d47c4ac8250fcbafd6b88faeb48015f5b42b5334a50b31d4502ea491da90dce93c08fd56f5c58eedb379166a23762be5e4adeaa6f4ae1c24e0cac4ddca0383458560cdc48b8cd1f42a3ba2f6ffb6077909fcb294ad1ef4a44c22ec4b3987ddbeef325b98ced56815ea7d5fccf5afdfe98e0e6d920f7ada2eb5c91624c76cbba2993a9c7a55021d127a667b39e235df4f81dee7dd142898778dbd92135b70b3acf59f6c29a2c9d4a7006ef11a918b3a2906264a15d6b529308cbc89f85601fc1ea1314d67f7566cf109165c7f92de1a18d70debe024349db3560a6e527e2ac3e06789468704e6b8f1871f16bae9827392b418f1086cc497086ced14b1249d6d8794f23bb8779d418648f2155656a6fda7440c56284d9b2188fa7d1736bccc9cff0be5b1e1f551ff8137ff5966ed9d0f7f01c3dff298e9102ffbd324bfca5ffe0968e66f9d82f487d303934f27f78b28378eb72c38272962a5f735d7392e5d333fd86de167269c17a165b92d31a4880a41e136f718960a919b3d7c4e74cbd73c73f921be513f739affb2e41f80426bb8cfb4564b98fc4de53255ce3f98b4d22ae6fce9190b55bf2c93861c1dcac101b5e16cf09991c5defa33f8d51056d934bb4b477b6520d4c7ae22ea7fb3109de7f4
+SIG: 408cefcf01417e2dc6a8a18284e411657f039250c31278db2819f9eaea4293fbf6831a2801fc1ea6871657b841e173f451b0d575a9379e35857e8c7297fa1404
+
+TST: 1007
+SK:  4b8ed29731f104795e97dee7c8b401a02afaa9a795e613353d2b95001765027a
+PK:  f22298210b09fd617fc8b35074ca1801e6075dc92a8f50344b80e85405a038f5
+MSG: cbb5f13a0ef2837b805d3b785109f9f2e0d0a017bfe7692d91ec23ddab7817330bef247fd91ab2c77dd4412519cbd38475ce0cb39b1480092bc738d4152b8a6d55248e3b9f32cdcd15ec5d059ec3c8847554ee47005394974d8eb23592d17f5a396e3c19f8e898370679fef5318c4dd299c6217d6abcc9b61a5b2d0cfef695d170ca20a83d6fd3c666c8fd1c10ad970e2fa6af10ff0ed0cbfe752246d03f3a3c6032dbb319bcfdac4dafc50bc3e6bf595f491dec388b3441b8cee0df91f55cc7807d07f8f541ed7322ffc39d18f89560e4123aec1d77969cf1877786f4cf94b1770b1090655e8c72eecea4572e46f580f963966db2a1085eeabc57bf4a84724b9c8599a433abf58bca804091d3d5e6e5048ec27bf8129b670cc2c88d9cac471859f469b918f3f6d70f7d6663501ffbefef026d79ea70927ccf6075ee5105423321e11aee9ad16f987efbdd00b62aff698e521adf9203b15e9f0f3ad07dcad9ddccaae9b490247f12c311dee6b73b8f9124fdce1299b47fb1914cee7e3a07814e312c3ce56927672c51b3185980cde57f3a759b50bcfc4cb0753b954d97135deb2a0532e98b66f39a7c08cf4d548539e2eb9f422f6649658893a7c3c25a4fc901f8c398b8c72733911a0072ed6bd2f4189389ae10a814f648d71f69c37e8295784428183b93c8013b964a9fef86b48f489316bc222e96b3bd15ff149b96820329551c15e0d095d1569b1e2131c78751565c3041f29785395b97151317f62e3582e407b1649e60d03a8599120a302a4695fa862b4120f94d22ecae72398d2094d108ad2dbc1b959735902142aa5fe6e7996559f6f601448aea02f356f8dcdd144340eb3619f9865bf7672aea326c4e93c99f0ed1f9ed866be15d3af2675f6dd6e296602ca373a815b0be46bc2a3fbba06b8805c731fe08007daa06050961b24d14693a72898ccfb8b8fedc60a4eef8ff79b6dd7592591833b576ef48294e5e0485942e57c119602eddf88b1faea517f2fc2e3d14d246a52cbd71a108c66b6cc4f2d45804a282ecedb1b0ad3dc3b4880ab2ff78b8ddde48f7466c14fed349e95b5053abf1bf0991126031d97547d143c2ae164928b61c0708af8ca3e4f55154d13d75e97db4ba3e69d36e9b37082368c2f721bd3f95126a1e004eb2a1bf268343ae21d2995044a2cadd67ffac9e1538175b3cc44db5d26f1d5cc89ca0e1c1ee8537a8a91d324c2e02e18b9fb9730d6dda55f72d843389693ebfcba7fbe1a0bcffb9aa284f4ae66f44a8b89302983b22736d0c72d6a044e4291624243a4e0ce65d5e5346d67fed3760ddb0c510b50ff3eef0a18a267de730476dd82dff7072cba0984825a004dd4bcd8c37fdaf1f683d1d9380e135a95d24b89fad0be941c548251bec90ccae015bc0567da84b371e50
+SIG: 2345886686eb39b5199caaa9615bc6b4896f076e8bd736c0038a6517f9c2b167e759f37372268a697e9b78605f2ed94725f6905a7900153fc9e8beed31ffae05
+
+TST: 1008
+SK:  080d7f76182ee6bcea894b1e0060558b3b125a3499df3973b8dd6693408ee469
+PK:  4124713d7c2df50f93055730d1b281daec3028cf2c1e4858d128707a23d6deb0
+MSG: ab0a6de2351b9a8498f68272d9a0a7a057365d34efa0fd34cc3bf862e49cdc302b2bd5a30d601a130ec4032f541ae6cb7ba97f84183d2d2581287ca701d7d7a9aba110ce58b946ac0824305df7929f3dd7fc9c8732238637e2b181d6e116c7f66e3226aae3ced1610262da1a0a4aa50a1b9443ec828329e4734d28fc25ab9c1de9b8987e5dc0c8131916c5f18928704a71e80622b1492bf2fec5d4b6dbe415c8af2ce3ef109b34dd5e64d56846f085935a4a5d1073497fb3fb8fb77e8f5d5e3fd00c30652e3c5cde40a335d14e5425ffba942885ed17bd36df506924237e75be84da821950b91424fd9f16c1b2c783e90f8cc2ccc7980ce915c7696b06a586730259e6d14588582bab9d2a39f69e98e7f2ae9bc0c2610d7e0457f26a5d66543be1d65b79c4b7c0d8ee73d0c2b67bf50d8082f006f96d119505873193dfdbd432bb1c9ee0d03ee54cf95d20e91f7f3a069b6256f42159cdc1e600a9a1c2f5a8e467d5c2a9dff8730e6be826fb2a1e6448bfc4fcaaaacdaa7662351faadc91f7caa7737dc82ec3d4b21936bca1bd7ce373ad66264af13241167549318cdd78e563827f85eab20e0b42bc554a712c0051a5010dc2f2c7db85acf6549f9d102c903c1be5a05292c30f21ab1b2b8abcbbf104723c63f0ebc554fbee42020ccb14f443478df77c6aa44db9a57f8fd44d97ea099e4774823ebe123fcf5016a66e837b2f65c1845e681ee2a7059fb1290cd0a933129855cc83c87e0b3bb61e44134addd3637850246cdcdaa29f15c41a3d4dd2c1d760062124333124cf091435fdce711f52316368999befa4c80a39b3750e4e386289e4e2855e97b619b0a25799912408b7d58a4dd9819571e901430f6d555529dd630a1867459b8022d0e0add6ab4f12f60baac75979bbff7f6258d28d6760b1ff243c39e4bbd6cf9bea572a9c082d05adcfd4ccf9fa026f2c904b6e782ed709df7748a307cd2dc3a0fc4123df580cbf49e05ceeabc9f39e57b7f300905d8b310091fb953f3def36deb3e8bf372f5916b51597df024ce85cc4c36eabdc580b5cf152994648f1d7f35fed5cd10f6e2949161a3359b3034d450ea6f61cdf1d5af76d40102b60294f4e49078249026d62fe35fdf224928b0c49ba2b5339ebb192c5ab7f05cdb946e37d671a4a5ef2a5827220b4438cbda05736292806648f5bdd52420fa76b84a6addb1263eb0c500e81566d718d5066026da097054a86631016ddfb706a5677d502ef84aa73b5863bc40fdc42cb7321ac5f00e2928fed7b0418596db4b6151dd6bc6e818f0253552bf13741e69680e966c92c293e13c90f7c9999bd1ec6afe3b4affb47340c89859829feb599db3a8c3d33fc8d45fa5381078ae9f75d85c1496f5fb5addf4e4009b764bcc9118e9275dc7219f281d0d1ef7158
+SIG: 185fb1b6d86dc4444810cf5ec6fef0abdafa2a6fccb45d11cfb54ba16a6843f280d380471002ae0d71508556c78ed5415e42338c161f2b621e74cba4f6a1d402
+
+TST: 1009
+SK:  49846ada7ae684971dd91710799090b37fe5ad561d72a35f2efb405f196ab0ec
+PK:  4d370a8194a3045b09b3bdafa27fb9acd59943a54ae14cbaaa2200eb0f3da71b
+MSG: ab398d94f928b1d42102a3e513ccd1cb10899011039410a8888bba26df1a0372bdba0ce8d854af51e9330a8daa93c10580906a8ac72d294aeb9566fe1c78ba8471c06c4a8a75113b34893f6276ed813292053b956a465d847d2ece86e2da8a9f0fe3db52a5aac746ef96485ef81f1362b5a42eaaee1fbb0646704471a21bf76367beaa07812b3d32adcdedded7539e3a501b83c05b19a49b520ededc9a78a5fc2d5012f1d4e381844e792ed90b0f57bce375c75a658b2c78c6ff7d9efcd4bfa35c4768cbb195e4823d9bbd835a374fa04ca1eaae9c566d8fd5aa7ca5efe0dfc317fffa409ef1022f1c3b376a935af557083e95287b07a98ac6c1b7bd8bb26b60fa7c4bc91973b201b29922b4b9d03dd6882a0bd3b7d9e5b81ee74c36bec665e4343c8c9ad336da3850c9b2697fe1cce29c378622a33c248f448c88f48df0260143b2a342f1ddee74d3b97ca3e1166b156993dad30c49d810d74048bc6d467652004d7edb65c6dac3a2c5d300b97ee3a10a9e14b69f3cad675972962e1f8ed97547adedc47d1cf3471ef3b22fdbf78e34f31a3bb7669c41bd9292c380bce9a42d84bc27ac928b8bfc3c63d20ccdb478df7ddf421fb1cd905ffc4c04786fd9aef06b8938ab8ef522217b2c04515f61a1c312ea83253f8458c0918fcfe874e6e7fb11275db2a2ec79a2d868303233c1b697952a3bfd3ad0a6f6cdd5e72cc9409f7410a40d5b4536dd46eb1611ae86703671b3a0515a0377bea15654ba0a0d1e4e9602632842f2acd4ef993236e993f2650d59923f24e2cd30932d8bf8aeec644472ba46a07881496c92a0135c675aeb0ce6181088db8f156cfe7435cac6c97da637db4a89f51331da13731e741fccc0355542ce11efa69d0538d3ef127aa68745ed3085d29da90dc583701b6b3a70a3ef3e16a924b33203b92396c4b945f127a7888fa05015c0603007566729237cc0782b30c020d9959547feec9f4d676460bfe0c5c19ceabaee0682db8be69135181ec0fdd9f7a66d50bdc379e4a2c598178f9593946aca6405b177fcade0f86421583ed67eba187222a1e44495b3ae544fdca28e2c14485eab0471aaa803c29a9d8a48926764fca1df51407ad33ec17e941e6e2617237a84309873dc71365587bde4274b5dc327ccb1e1e9c857e042ccca8d8552ba288c978cfa0af99d67cd034060628e23525dbca207679ce29690878448553cd38675bce07bf97b9317dc44468b768b158b0c111d63a572235655c40e16597ca059f40c3d8ac5bd61a487c15313846a704a7811b8bc0cee61e34762b6c1b7cea1c46e6087e9a36f89918a258b3fa77620be10c184c3fc39739024e98278fd65b82cad83699f3ad8c6eccbec8b7b1bd7914d3f6c3d02bf40283b1c1f1e98e308beaebbf894b8f5e91bbbc62535f923
+SIG: a5c809d1ca4cfbb3dc70a2a3a1f267c27330420719e3606218a1471cac57cb674b9b42827c5e9a7b25c8139c13dff60bde6c2dbad3a8361197c1fb19d2cd520b
+
+TST: 1010
+SK:  83343e37ad091a85eec370701b81a58f9370a4b0423a070d60f92d8d1809844e
+PK:  50b68bf726eabca53ac6c90d4eac554703712d22105554f05bf79f9d08fcc493
+MSG: c7dadcac5d8795e174b69138912e70ff41e7a725faf385b773ed15098972b30d9b739372d975b480ccfdfc580e2e2ddf5e3c27ee791279ab95e4382b1459dd8d41ae360d4a878846692924feef390c0dbbfa35e4b82d7cbc33ee1581c52bd949385b2ee40263a57da1174bb4acad37cd8ae2a6b45f7a6d6bbef5a798ce85b9e05e7647e334ecfc776378de174c497c0f4075e625af7aed502cd1cf7f588d0d807f02e32f4300f228a50a667b5ad1fbbc17e0b3c57051ddc602f576079f6fc5889b7f2900711334420fc666f66dbaff4126336c353f1e5b564a664537f83786da5c5627745406d7b2fe3233bfd58ef464a06c95cfd0b988a76d053a644bcc159cad53a7c5dbb40eef5cd047056a3f09265b1325699c7d159d5c902440173357ffab8f7a5e389f468c333b782f80170ae90983af153f2e73bd2bef125e3d3868c2ab9ecf03aff76ecbeb18167ca2f711cd565851d7f04ee9d9b01b6d83a7605722620d28c84d6c1af42f6a769258f53c1f66da36666da5caa9bd9e8fbc169211b1aed9c2558f6aaf5b145abc721abb00720194e027035468bde3fe0b88884f4e9b26e771e6c7a0a55ea36fc50dec8cef162f9bba5b4b16105afd6e374e038d5c8587cfd7dd88290b2c9cab45a264d6540ea1416e6e4e74a12f45a2ef13cc8a36e7b0a26b902c3d96e2e2229202e25765694b943373d16e600bd786d955a4b3f1021640c39a0b6c691500281ae0d098cc7f385e18a07e62fa4a101ef5b78551fa29bd15ee0353a1a5ef9b216e8b0fa50750a34162b635a0bc5e5d7230aa19afa128aba6422d38eb77a3f0bb9dd8e4652f12070a37361c3725503c9d22e2face2ea74a7002406247dd86975f07575c9e7c6f41b53b26d5cf52c5acc2c5d98271434e9fa509c6dfbd724372aa5c13451aae393de0a186464f5d337e9f627b4f1c2909467065e89a422ec40ee1d80a133900a62f4e4f7e94eb72615e7ec2996c6c2430c3e957ceae2105a1e90eaeac0d31affa9f57926d71d972a9a2de11258cc1e728599c9fb3872491847e10c67efaef6b696a030ff0533a583bea1d04df25f7eef3a13b8e31aad133857df1b4e5ffbdee37f40f38d224c70ae04ef33b41b02e7191a86656b0d72b2cbb53c4908ca206f75734b27708154fcd8a97429cfd1f2da2429778438003f5b5b9c21d9ed23b8ad8a228eb4f65c24c1c59699a5c90aff773e5c676db362a1930ba16aba76ef8daa42b3eb2ccc45c934d23d4929a7ad9e3ef468b06a4995c80dd236a7bcf3879d8b79467f72b3384c160cc181714e92f2035e7b972a2cc5242d932525eae7c50bd263b0fa09cbd9d6f984b9cf6152d9a133c27843202d1e87fa5a6e1235d9c756bb8e68b05b98da54195223fdf0210253250633c11c5f60b5e67d7eefcaa6c2daa523137
+SIG: 9c6989cbe17e16caa253ffb1a64a106fb01782c99b1722baf1acaa42ae5b36b79b2a2cd8fc91f5ad8923817025a77825a05df8c417ec53c4a3aa1c0efd5bbe0f
+
+TST: 1011
+SK:  da013221b2f588af40e211a0f975d44f9d65028160514c396189f27c7b0666ea
+PK:  07117c6b0db5b6fda1edc4396c47c22b54ee0ce5375c3ec633c83afc53ad6ce4
+MSG: bc93ee1ec4728ac636a6248fcc4551c9d15980db8e5f54b0ef075a71970e176a3cb9182e32da7a8c2ac0cd7e595774575f9c83506a606face89512135d032ab05e39fff9c8ca6c25cd5d78ecc3ac323290c9c81626735e190eb5ae345ca7a958409f7743b0b1614916832217c57eee1b4f8e622ac052a93dd5b39d0761e40e9fbd8396f60a3bf6660c5fa99cd8139f68cbe0894e5c67e168cc74b2724e9d91d6000a0cec587a11463f72ee6ed255bd87eb30fd457596f688ca0ea73f30497238de21c93fbb1294db61e4a56089106d1cf7ce5a65ec3d12170ce7840f088a8d0e3aef17e531de478003570258e927f156e7961065afa666af38582b353cc477ba775cae45946d08db75215914da3261b62294e92afb381459c21dda4ea6ed795f79257c094dd608dc8e1b7c40cd29fea222088f65697ea88895d10acea8797360dcbacee269c606600adffdcf9c7c381d0ad6696967d9ff03e61a24906502b295e76f4d0875655b01e6ffcacc8ef01129c72a5846b60ec80017374e75d306403d9eccf26495d298120a0633835c5d1eff17c9c62476f752c89710adfa4d51617b5918173cba722540e388ffbffb966874db00404d06b0ce1139ba74143c76b8f4d33b2116e1cce175173a96fc151ea239bfc20d66fbb6f52a666c0e81cc2b80209106e2480e4111c70e7be4aabb68422f0b8c6ba15c142f82e6c7f378d7800a09eaa4da253c2fd91e1263c6b655bf70255d7e3bb4775523a0a9e7ff03797ee3ffca8a50d10f20d5e5a889ec5e334ef26cf7998b0836f656456888e137f39d3e43e2ce3c6ef540d95d9a20c42cb8ae2d9d0f25a891c363ead9cc423f9a323fe232281fb67f5be1c0784361460468a87e95dfa35d7f0ffa2211be6b5fb32d42ba6518ab6ea93780f431d3006731be4440e712974f74baea419f4022fa2502e1b2398e9386167d93eca92ca60dd7d91fe82324f682d94aa7a86ab034f8a9e952e8fc95bff4dfed6a43313abb92401b30c33c79a7ba3efdbe1628040fbaf443f3f980846fdb283dccd93fab09708b7d54861d74b1fe8f10701f211ba3d390e8a6ae407739646a79a58337a717a872009c2df6761c2425a32a0018aaf9646470cbc87c3a65c0e0effbaa528fe4783c772ab266b8f28268cf14af234b15816d1a3a491af5f297e33d5729715d512c373fef5ecc3f3954a60a2a0f64d829474119ca1a18f10578d04d638d5eeafc371a946f6ce7efbd2acce34e20441cde9a37d5a87dc619b0a727596cd12e15cd9784bb91f1399a59fc0a7a4af68b0d575d93387172973375c465df5d2d5e061a2a9b23b4915a0a8b8c1f0942094af728c8c31145fa7aaf74a21a3b032bb09c392205bf095bda986e5dd6627c1e417f650326dfe3a9c9994c6e0e01276f91f2987d2b85deda965491
+SIG: 10cb52d610e4a81d32869bffce3807e6391f782fcd538b554d09037fda72285b9662b1b1107c408178ac009f0525967388a7d85fa12359d3ce3875037dcf6a04
+
+TST: 1012
+SK:  5a868fb75ea0721f7e86c7bc106d7413c8cf4d033ce14005df23ce4c155bbd27
+PK:  6d1e29f39deda2bbfbb57cb01cb39e58808278e5196ada1c027646f20487d252
+MSG: d5aa11825b99448c80630623d8c746017cfe3de6fa8a0c6ed6627127cfc1f84d4e0a54e6a7d908d3719f1421d1d4c78b3cdd94769ab6033bce979dd90e106802eba9a03295d48f9b9a95d57ee7745402a48023bf3bddd5c6b91c773e491913a38ac3462605cf282deac75742fbd27529276e81dcce8dff9605035e8cf05df6a43db151f0415765bcbd1f1bb668ad6273b891c0dc4f3dba590ea82f8363769b9c77511947117375dc4904d48b88b68a255b28011b11048194093e98207ab1cf756ab8331f8d6f9d5be2e1190573e95e710f2a3501b53aa0825d6c12dcfb94ac80dc1082cb4ad262e6d493adceb6bc19145fbf738df76f2134fa04cbbe44ffc55ffe5f9d3e9bebd159a001aa9bf78892a16538a520823cde5d61e29a56a77ab96e49e300d9865962c7e7fb8bcf5de0b938297c3f4d6f6021e24dfdad9861652f340f421e7af2c71ed9a71587fc753b115549b2f7f7cb29690ea2b158a94cd2bc42e7063d619b939d523e3c237eb1f40810de0b44aa6937863d629edd5575e6c0475261b627473092775c84360011d57c57209c2e875a3f8963e8b241a7aa75ef30c4a718ac4dd466dc7a3e40e5874f157a849ed3a3a9d4aeb7d94df09bb55a0b2bc9f8b695c37179302367606367c5f324828ce75a944f50703a47906a8088f3a11cfe4a854e01f1741252c486337d06b1cc6c6b9b1295431ee07359357b3a78ef5075b65d7fed5eb742e5101598444b46623f89a303acc10c732449513b70dc456a79d37c48e5e726c2f558da0a1c46efbd2d920326a678b8a22f0944be4af55b6c71f453fbae400e6acc04e0e95ca200167e96ee98ea839316da93a12c2d76f11aeebeb78e65ea48f7feebbb137b2ac67eaef02a2d9e6471dd634a037d4f5d35a2f78af41a8ea5af5bc8150a99ed68a6a0ccff2b1d7965d8bc3ef9285ba6421d87c33aad8103a587be01926845bfbddbafc69c4b9252886720d418509f40f3dcf55765dccc3deed8277215e69f056ba31b8a30b50094ea8f144720760c8f8c055cf1a86964ffcbb8ee1bb2181276ea99a7b8e71067fa310ba4471e84279037bc492a55de205548e77b014504ee6664c4988cbb9ed91ff32e2259ed4cfd61a197d0dbc32c68f6549c0d29fc45f36acb26b164de97ccdc37900d93cdbcf9687ef53f1f4da1b1ae4225b884209e81ba4311520477ed4211b09240bd7b825e54739fe25d8624af04b86f6d1106d18170e5064d1a73c1fb1a27b289a948d771a2f6b8b09a635db96c6251c35a1876d369626699416c0e40298a681fdaf5255f58c2557759d8f5df148dec9dbe1ce6df041c36f83e69ccfb4aaca5cb48fa6a85c8ff66061524d8b11bd7ffaed99d0cd45c42010f21d36cc316ca860955635bffaa7d9aac572dccf3153d42ee8a2b12baa57c160bd0ad
+SIG: 38c48dba99a6524a188d5cd78a98e677dd263ef6b4df446b310b3dd89cafddb9b17a65bba8e13968bdc25b1d84b6e2436edf31aa756e3a48726d6f91c808ee0e
+
+TST: 1013
+SK:  c54bd3431f2659281d31e93b30787668bcba6e5ee47db46e50deabe3f48c9ed8
+PK:  1eba6eb3f7f24cdf80abf8a19d308c24f1e25ba15970eda7116707b0f12cf932
+MSG: 6f8cdd75e1b856bbbe9cdc25537fdf7e8236cb029acd3984492110d0c30441d42184b5fb183da9f3140378dfa7d74ccc9ef500193cc9579fffa60bd2a8ab9e09581500cf06cd35abc171d9d12c6580d9682f9f49fe36d0a3177238fa50e7eb4c27e460f5e4580a56568a19e03d95b0ff4f4a231824cd2f3442e0ba400bc11b7a989d501f5df35e4301508f72a852014bfbf4001e28095473d9659eed6067baf68f92bef312c09b19aaf7c4fba3d902b9f6cf952eb9b9a53ca8bcbd042d842e9853b672a1d009d823838bebe5637c4c07ed1b1948554b23b32de1d6c116f933b354f28bbb779fa6548c48292b612c7f551a75fbc46c02736bf99e9c8ead56f05ab0427a6ec616e3dcc7757efdb7628d4e96325fe0ae254cef5cb7a704b35a920cb3fa2a03e961daf371821be0b30f19ae4952441e08a7d22f5431390a5be8097fd5797a1a6297664da42c2008d0321060ebe3181eb795a728925808da7867293b7208f377d3a771185e6d2c1c8ce18376fe3c0c1458c7f5be34f428a0d575931074c97cbfce8ad81313ecca73a9f3db434fbad4bbbff502bf7297e17a97a8864211e6789ba192036ea59a34d84ff2a111074c3f2373b10111b5daa789560cb35490954c88ea00c410df850ad00cae2f28e719fb06716988a9bb0bfc6c989d587e5685ae883c2c2e74ddbf915c9856aae8f3288fc625bfb2fe268d74f59f8b7d8363749769169007d5e67b7d0b8c8f5a9d9f9c7b745c0a4294762cbeca42d5384961e921a7efb65da8d1e03b6745cdf308097fb13d64fd2f8c10fa9509eb2d91387f00645ca7d0483b2cd14c206b8d7ae0a3fb7c09bc6843d102adcda19f8bbd851eb683c4435ceb4b3d23d38f56d4d1114eef0fc6f24df52770d8f1f3f82f4720e892b315244ef56c36b23fcd407978524140382e11740fd46fe4299923f52b88b4a9cff4b2b4b23a2e760ad81c78ba876931d9aaa4beed40fb10a799eb30d37f754778bac85bf0631d852be7d74a6431f384a4025c1091421d67a4e9c94c1be3690c6bf81d06bdaf32feabbaf1dc263f273a0b9ed65460baefcefcf6acccda0edd23df9e05128e29d661c4b44bd92d640faa853afd8370e563b40ae0149a1428e06e3dd8e66b79da21cc753ddc476e3d76e2f36f2b6c6bc1b65087d5f86c8ac354711a8c08f3486e479d6ae943f8846332d4e5b4bb2e8257e3083df4f81dd4f0c1ee1d97182166161a18597ee0b959de1c45591abf7c51033d7c66352deeb682e777aeae2fa8d3a77f470db78ddc1b1fc82840c4065776d9bfca9d392d9288ee9132aa3e4f2d19d0d93e01b666f3647abaf225c292419c8a82eba3e11ab103846fcd4935f41241477c0f152b7965ad54bb72bc3de2e0b79d6225e8fa7a6286b5fccbb35822e80c8bfea74cb48a22d241385395c2
+SIG: df4541dff1a9797feb617f98e4b57aa7714131ee8ff545ed5082e3568efd1c399cdc56f5582991eb8785fb33864eef7f553f3e248262ed548a1a6888f92e920e
+
+TST: 1014
+SK:  ea60da0179bcaf6b218142b1119046ffe6d85a741b0d166230bc6de3304f6773
+PK:  506b2ebb49bd9b9ff66e6b7b1fab9668cb181b4fb5e4343dddd3f8a9d702031c
+MSG: 612d6ef6e4349ffae516e983e8fa7b52d9fd134282240d95143824bd4aae03234b76a8cd6d4068cf009e481c2685361c755042c4e6ab8703ecbf8f020cf5739a4c2a03c3731e9cf75aee25966153b9711515c6c39afa95f221ac3395b089c97ac9b514e17d55f796a3ecc135faaaee907aab1029647b48ac81749bab26627cf7095d74c2fcee35671c8bb46053f5151b0c2e5dabe0f2d6aa20413305020b2afd9ee3387b2c9ed0bc3fe2902af4100cec23327b0f1e4ca39ef6eaf6fdf5d5acf93fc868536d8cba401769329fbe93effc7ee6bf93a6e588bd551eaa512853952c81b245e5d229d294e41370b867808667887a6f9eba2a8d56a7a704e66b1c02f96e73895f483e44a5c566cb1af26573bfe2afce06b1fb5877e51ef3126a3f210fbf213ed65d5ca46c46ce4aa945bd8ca611e3836250f564f7ea35423982f9705fcd6bef46ae16cb0f6bc912c3f28642b8d87775b818e4e4e8061167899bd27a7e2fb8187ee9917d2d586bf9d499e8fabca83ddf58c7437eaacec4f444fb2bf745dccd8cae38944571dede2037dc41f0818a3d91e3020a7274c6674247876083d0e39746c9684061bf74ad588436ce1b763dbf4bfcf8de6e35c5a7626675c127292b21df3c16f81063322a75f3438886f1f0cebfc1a96f41384cbdd861b04f519ff6a9344d94f3d3a0aba8409dfcf18d01f2b5b455171639eea77dee706ea83dcd2b8b1fc5ec0d740761a5f05f7ec8d87ad1f292a50c8bae0ad32b03419a950d9fe3b3ecc4d8d3aa95e02b51b1831d83eadeaa44238635f9c65efe2f6744a70b9ae41ef15d97908c0533934412f79583d0e9b3d706a128e88fb51eedb65e46d8a2b38bbdd6455554967a8dc0c68bddfeae0f8f72f0b886c3c741fac4f91e5c491dbae9da4594836cf1d9fb6ee130025089aed350ef247bc9887a2050159dded1428ffd9b07b9ec2e3d4bbdc2ddb54e873b63f2475233e19133a14b6658509457008186d6225995a96726b529f44281aa24fefd1cff8f815d93a5986931662290b3ee16833c60f0afcef2cbc000623f3931909ca976a094e2b0fdb7dcf7c485e14988a36f19b66425385f5632cef65d1d3414623ae3ee816e763a5f606466622be6602114502951cf0c097c1648a72e2c43d9afa9689f2c3cfe026cdce3bd1bf9ebf777562ecd8ff1b0d775306d900443f30a843310b8de6a38ff108b723913d7899b9fbe7c3d766ef8bdfb6d8b0b52956cb1cec9936d70b487c01440a842b2fabe38e7b8851a387d358be7ef12a7e4f2b527e83090d67eb013c9c2cfd3de5a1a3f99748a41f4819d9036e500c504c988bfd24f617d6ebdcab2ddeaa61579414f360b469a33a6ded96ba1d8c140c4ffc94990d8adf78cd38780bd68663d1a0ee33f537cdf892d562e82dcd1d912cad38d65567d291406
+SIG: 27fb6b5f06528a64198a3e7d67c738840a8cff4b482b4d524b122d17d2aebcc0389be2c6e28e2cdfc484c18de425db56cdfa561c507cd970602d3a385d3aea0f
+
+TST: 1015
+SK:  b62c241878273513e0bf6f33d2104365b2ce9c5a1b786058e9c5b4d1d192f87f
+PK:  bbf6fc5198f3fba5ab007f8a632d28d1af865d290fa0a90faa9a9b5b9c13f3fb
+MSG: 26a3c26a5a189cad407cbaa3a6867ac0a26088c75f9d0fa19bd50274cec5755a497109a473284d6fc81ad4b9ec29fa7ec9764fd3099f060e36836552ff2413e3d5095fe0b1a8bfcf67ee06aa9032e7bb3249698047714d281415273c9834ad9eb665a7d97220e72d9ca73f31afa7738675ba3162efefe7479a5bc4bce2e8b7af4741d703dc9bbd60b4cf4b9087f6cf86cf53aed02bf4ca6a18f607cb52a303d78e85ad88fdfc86dcb7187727b03be227745bea744fd006525bc59a4dddab915cef40a8f30802913b7913eaf974336552e2f1456ad803dc58c9b4b18efaf7f7e357e2cd77d138d90080e296d1364a2f324d3e0d6edc20b8bdaa9d2e871f5e7b051fb6fcdb5595f21d3f8de29fb78678fa479eaa32579c784d513ac5f836d954d0d3fc0e5fc8a6eeab90202b4c4a2bec24cf63ea67c470096218cd431e883105fc9c27f9ea77c18eda69bc00a2242bd420f095c9b9a92d956ccc5a8572b057a7fe173eeb2a3166cb2089d113a816462b25805b8abaff5b0b2287c508ec2b8c34b2195c332870d3cc396017a16b9e0da6182d071d3bf363d3f1e7b7da11d711250a58afd74ed3e3158d4718bad4d274bb3444cfc318074b53beba44a2a34ff8eb726e4a1daa911051621651898b887169f62b9c0f4020483ef544f8f572fa6a6640a4cffce976cb7024f847bdc95d1d7ce653505debfc6988ed289dd47a9eb261259e3e65e45fc9d714946935cd8ea13bc6db5eaab9e8b10dae0fdd6979c2035cfb8098252f2205443b808816bf7787b7f1e78bc98a7285e733d45fc4610c20977ca3229889bb8cd2b694ce9e3fe78303af83e106422542fb7961d32eb1d2c5fbe60751674b074773ee0616e02973f6a74a3ae4664a2650915a3e10493b9e66a39fa5c89c61d44735f107d33757ae679b43a8d43a01757ae1f3279e862442e150715550ee82e49c0d4943faf13f22791f0e66f24ac50ab3c003852b21e15b2f006edc2cd6a879c476ab5b352eb1099dad4c50372400faa5498d78c6b857034c25caf7b933faf6bd7c59fa3da57397b603de9cb9d80e51f7997baa462acd537e2c4194c76c7e0be6512bce4d63660b36c7cc46631fb9671ad8c5d28e2f2ee2edce81954421b8a3d9ff6f66699f4bce88bcb8ef192c262a74ab7e191eee9101a28d4b66282b5122093d141c6496c7aba4d352e472ee7440e05af60da0cfc93e303642ba8fb8e5c568687abd63afb3ed6a32b6dae56a7e5d73debaf41d35ca36adb97a22c0adbe718bec1fa51998de9b4b96a79c5b9655b0165d5e1b9a8cc552e8c9329ede58df74c67b2ba1a842fd3e8158c1fea3a99b56a2c2a96207853d26022cec170d7e79944d2f56aab1f191bfd48d725490ca82b8d906f0680e69eeb9575774fb9d604513fbc26f5d303b6885cac0bf8efee0538f92
+SIG: c59039587b38dc141e055a93850104d629e380705b8fc918847c5e2a352da3a02fce7f7199f4ae2b1e2a59483418932e185f7e45b5050c642cecc7e781998507
+
+TST: 1016
+SK:  0f77f77a1c7e04bda8e534f4e3eff9a238cc14876b7e3eca8bede1923a336406
+PK:  1045ea9fe214583a0cdbc494932bc44afeeb080bec485cc234fddcff139cce00
+MSG: 0ecb746dbdb0161421afeb7adea7a37c2ea4408a592c9d781ed6ac6f4ee5cc65d5270e4cf27632f7c5c133d439b78d1f71aa6dd80713d90b151e19121bfa87710e84a4850a3b5b0265ba2603d0716e9b7e1122109c39c6f1027fce18798cbb4f6bc5e4d7aca4704690f5c981510871c313595798338681107f2b5794d46f6e0bde2cd064b3b1fc00ca47188bbbc1f4a0ce305cc6d8a896920eb9ebae579fd3385f8f1f35976288f4c58ffc4760f359b003c872e9a24055355ea9585e951069dca25fd0cc0b9db52aaeaf19d43f2eab4f835603ad12d2dc49b310256b94bed54896a16b69b09cb4c8ff5c23cce5593d87ade2a82ada50859e1544c18618a65c007ef424c9854a175b6e6c0e64b2c8eb8ad4d28b977d68e78169915198975394d3b9b269cab0d3261b2b56cd2cc4bddbd4f1439e0dbe2c9b3f3f7514edac5ebb4622b92a69a840a9028550b221db59ddfb001396f86392a17f08ccb194cd9e1a0081d7dd9cca2357feb8b795e517029f79c82a3be6f9a031dd1af1e79e4982bf8e76b310f9d355efcd5b1efa9f359c17cf3b510d513e8cd5786a0d3445dc59a8433a46488687b0f58b1bd6567c2af4873b51fc845e767e243005192f8f0674f281265a55d76cea322260c932cea6717adb98a2dda8c698e2e89255feb77da7648167bc1e58877feb72d1d14b0c304f07372d955675237c49f7a6dbc915e6814abae6cce4caf9f48087e9dfb282d8f340377c1e29c6731ccc2667da6695b712be0312d865111934f168d5544365ddae27abc64aefbcb322db7d97d90d957a637bd826c227e9eb180b45a431626a6fd890c0e5f4ed7e856474752f80b5aef6e73efdaa6c2c451bd74c1ef466ca3aaa2573bb52cb2b1ca96a1b574403ceae1cf05ffc53430e1e4cd5593bd1ef84bcbfe219f08160d166f2731d99b8d7a32b12991f77775a267ec08297ec512d7b72435632525c04000fb00a793f8b5f8f3747b55359df21b7e2c49f2b0b9ae082afc70a146871370b8d50086de00f9448be8902174ba2cc851fa379dd7031ca457a8869af4b6c2729dac519556b8bb4ab519ef1bb024ea8b7f01771c9aab748e57381a0192a6e398cbe6dd9f367cc7b3354f83b79bcda46b793a4ada85549c8d6bdd6168124362ff908aa1a0cb78aa330c42d5a5d481235acac3a919b969c50987266d404d15d0e706fd9007634f69e13c56ec47133884fcaddc16beeeed19e0cd917aa496367867dfcea274e1a47da774f3c9363021e7c8d6bf8f00053facc11cb68a9d6e1fc2d6d19175d6324ff7ca6c23058b8b693d8fd4e0b51dcbb113543f2fcc0452eb9d967ac0fa9b23e9e0b1da8d83a3c1fc9e9ec971f0f67fc745bb17376bc46245f528cb6e5fee11bcdda867b7f79019cf9db591858230aecb4d1e93d167cd86b42dd879a13fa0e
+SIG: b20b9c4246f0d2970138af7dc9af629b68fbc37df87afdcadcb545c1768376a09c3babc3eb1af3b7519852f75fab1c9c119c662c5877fb2f7299cab57fad3d0e
+
+TST: 1017
+SK:  c5a5053477ae31158e7469dd1504867650d46f1589067f5cd881caf25c26cb21
+PK:  70f85db9807b26fcf3e6690b91724f7ae3d20ec3604ab7d6308d9094308b2d59
+MSG: 8571ff3903486a43a6126c323e7b3a74141d1385d4bd703f19e2d1b64b50281d27168ae3e769c6dd9df7d97864fb37822f0021852e3168ab7d845a6545ed0c377d9f7c048a2b96e8dcf445779684a058c2b9c21ac68a0c341d1d6c0981456457458eb7cebf66678740777eca26e01e1c8f53b5d4756cc5f0b90f0c5db05393cd4b8e44f6810caa5a116a33577724395d413af619632a6fed14e215c2f19d105ce2bf1498e6d2ab4f650f61ba5cf6d0c73bbbde98e30429910a4e67dfbc717cb091182d597058b5d765d097e6875831b588aaeb3e7327e856b42fa983fd254ef1f918b043d1dd3d7b7e30b315386eec91e7f94d598f4beb3b27b42f4ee1fbf7afb486bdcc6081ccb867f04111044f4bbbe3c8122edeadefa9d693906e0d6e133bf6f2da6158feedbda024410f12086e7accf1c68e1557f00c14e9c7ea76a5ed1337a054ac2c949c05977e030274f6a4f2a6b30a15c570ec9433f74f47528087c9ce9a6292951c54354996fb283c0dc4cf33c001bc96875ea6e1f46f837ff18dd9545fb9934655342b12c2990b9f1c6ff4d66489d6aedce75c7cb03ac134bfd39b181dfb7f9a97ce737fe570ad5f81345939a6de5a40a33a0e44bf957503d5ca0283512e57fba8a3a6f2c390687b1b7708676e0fd03b7c188d4561c1879163eaf2b596ddd5f3c1f4dadbc139c2164892820b2fe09cbc3d19088076364510254f2b6d410329e70f2e5a945bbacd2ca89bd4b6e1f5e2e1d4f4ed2fe0113bcf32962f00d5c33b1df988402ba0dc8804c1af66ccae2670efa3134c67fc90feed8d8deedccf6a46f22940454af2bb6754cf235ddbb0001c6c741bf874bcd8d41d9dba8162581c3746d7f30e73def69415af5181c149914295122d45982f94943e20b0ffc7fe6ddf19a022e87a52133357a1e80f37f28a4c4a8a61c148dd875c1e8ecdcd840dd863e44d9bcb16b6e5af0147b34a7a9052c8d3f452013d2d354f6803f9eaf6056f3b013c616e47f398819146320a5e3dbdf16843ea29def262cc9a343672cf96bccc6e87e6a6baf0712e6ee89aa60489f17cb72ddc44bad161587d87f54d67cc0a2778497d831088315ffeee3d268c59befe884c3aa0e0ae2296bbb60eac9097cdf8dc0987ceb1742b0586dfce79ec10425b28f4e64520d712e3f46ea83be2de6a1574073bc5c7557b8e25b6411184ea283d8800232c79069421811f883c2994e7b7e2ad9f8dc489c9347724394609c98909a6c26017b50f20d50ccacbde36b76ba646a76dc6a5b0f50649c5658bbdfdd3b5cafc5479a2f48ee51542f23e9fc92132060fd635eff452111cdaf3efbdb7db9e7d4716d0d6011c29118a55d4c1a436abe24e3cbf40235b76dd1923503c5f3598124e2df55a2d1f246e90de4b71645d5175b61b0174e7e57df1285ccf8c86b8382c258079
+SIG: f5191b44bd6cc3ea281771df12549ba2be228b51eb791b9e5ed2815f862aa630b56967cdef8b6af0b9d21ab8c97a6dff681cced9f5019713d4357cb3e54c0d08
+
+TST: 1018
+SK:  05c719cae06e2bb7d87863ab3150272cb2f8c3aa2421912d87f98e7589638ce9
+PK:  90211796fed3d53b81f8feeb1bad1ffc933e5f10d3bc1b36ddf210a47923df03
+MSG: ec241918418e60522042e67339e6649499f31a6c7cf8925f1f61dde894603602ae8bb5f58809821f83344f23cd31e64ec9ffe79a986b7e29e4319a63414316bd6ee20e02a50da44012bd2d6f9f679e88ed0c8bb1e2cad55e565789883345b7546f3d54b1b362b1c650502c019d7313afbc82689b23a3a52d8f1af9f81e188dbdf203fb5300b4225bfb6773337be6750b3db88ce097343f62ee2c118574ef150cbd4c62760c3e43dcbc39218bd6d98565fa389811b1a674f617fd756733dcb567a92dbf3855b57b1f4a46d5b8974b39ac0d0e24d99d2037c04f60d9140f64b07a77d7eaa1ce8a78e844b1dcf0e37424f3f9d253a548561a0375a8d4341297bfedb7048c7935e1481418f9bba9271f9fd6026224e78e055d8a0939fa2fe1dbc0fc7b583e4cff3490e1d0f610b252e30d8497d00e4aacb375f19a4719f79ca1ea583a2f8b1406a4aa5cb55c08b6593b676eb5c34abe89392d62d23308a3348b57affbba7739cde8e1909d3425eeb20926a977d3a94a86e0ba10b386926698827e86b4fd6c6180047c87ec3b31619d05a9df34efd3d76a836962b2ef604d07af0975eb8f3dd22594323802564c929b3f65dacb572b32553d69b31a197690a9bb860b080a77cfbb3c175aafce0146a82a4d06e8c750521b726ef1cb29d021e5915e5e8462ede5395445245c9ae882eec4b1745e11791f7621d3fe702cac1525e1f7b46e1105cdd06da2afde26475dc1f78df8e2d72b0ec3ef7dd956193c996842a432696538cf123d7687211ffcd090b9381eabec879f769aac0d3564e16df794fa24728d7172fd07732eab077ed81c22084f6f781b626dac67428a9ddf3b0db0465251220d18b8bf620464c51a578decccbbaba545ed442cf12c4c66f6cb6e6901ea54aeda236ec45eef886a7ddd2c041caba3a6cee339715b6ce97e765ec3479f3d52824a8194bec2a89647e8c63ff7645ff6d05367c767bc48cc96baf05d6a415b2a5aff9bfb217948fad357b98f47dfed62ff1285eb9f468f0f29edd75adc0c8c2ff6a565edb8edfb48bea03b70c447369c52d881eea0eedb08c315cdf0bfeb979c1c0250946bb100c2866b4169b8cbd44d658f0236e1e9f3aa13bb8e8022a38ce997c94b5baf97e0ba621f7e09671ce638c2a39ee6c6e25a688019dd167675ceaec21c6b42a7c8c476d129dcc693c392a02be91b87437a08a0ebf1a7bd976ba23774766838b8d6024f5bb9b07f3c6b719b4de15b72448048ab70db3d4bea77ba359b51b1ec17dbe8010aef0244a8079ca8b9a2a797f3b1fe047c8dd5cab7fb486829239c4ef6d9a38370d488c47b7c030e49a5500c9abb39a9a5abfe72e918b76384ecaafe1627266cd14e696c09d2512e312582a8a911e7b7bfa04c21819af687f04c5e0cbe9a2ce24d4d3fd12190b253dabc12c63cabfa94
+SIG: ba6eb751371df721b7707a5b3339edb55f138640b97be6334d6cda5191a3ff6367911761882a4a007f161b748cec95b19e995f2858c257cd6169256662301102
+
+TST: 1019
+SK:  5311f3c96101cb8b7abc622bb9326b8f513c2b16d294df797f56dfd8203dda27
+PK:  230b7002f57c79ae2e6bfdb8df30db3e900756b54af3968c670ee2f32bb11e0a
+MSG: 61b15be37c4eb397d9e77e00151a28ed3e86d50a9552bb4850b621763f012e7e77bb5db8f3df7dcf769f2d1d46d8d60bae40c8ca6e25c6410b60078a93fd05902114bd91045c06192c70c42c9f41f8161ca46564ebc21a4bdd8190eba2aeb309823072ec2c0200ce6498f9d72b37b3fb466774326df37ad880d8eddb32af673e45d88eec49b1577b43b8639111c2e0b94187d2d4e0173c000f4c37be845d68810b7889ff2a049f3f9f245ec70f21def97780b611400a83c31a79d93a8e98b608fdcf2488b068fe1ae4217293a9367bb734b5bc7bd8819b377f090b4f8fdbff50799c76880d19133580e1ddfc2b9baaddbab34fc6fdc078014bd1ff739daafe5476f3f79d4dbec216fa7680ee8e84002dcb9ddbc7fc1e1c8ef4f1b2a2081b9282243da6153c1fce0905cf35f83a684c01b04557ec84f7e9a94fc2882e2ff19fea21d2ce6167861ce01df8b8d3c3e8d255610b7af2596cd5cf0016734942cc714c272c05fda9d34723626646a46130182cebcf179ec00a6a173bd8577fa845c44d19c6997944755f2b4e468563a75e9016523b87ddac3eee21bcbca08fcc29546a43cbe0d8d10a0e8ddcba172d1ded150378e18b368c7763913e4b407012fd76a872d2cb04930b8e22b308243d4cc278fdf2e1f940ae89ac891b9e0661aee553937bf350b407070a1bdfc4f7a3787ef399d2caf4ec74439c587376c77be0c3de539d3ac26089765b9be10b9038694636e262d7baa0b3a8941a2015967639f6044c67e59bc81cf2fba704ac0df48da6037405a8e8b8a7ce3c58ef38a883538b247ffe18097af095242b058bdd1e3e245eece0a71b75b97d52f20d6d51bb9766b0da0fc09c8ac2a30fb6e7b32ee06dadf46d7359cc066aa94785d8a882ff097d78a86be2d45600dd3d3060125f01c063e488d5c3efee1bca1e58516455ffcaec1b81ef433876bf09ffa51d6f5018585224579cb67b56ce1c216ec0a883e06c8e1563421ea72b0c10d4bb31e491c2ae2fe8139f249ec927d806ba08db52b1b506669047f0c116ff37ac5ba6cdb1eaaf33fdadb0705c799d35ac6d9c80da90c1438b585ffd59350a2686b1ec35166cb9b69ad0f56586aa03274d782e3f858db64adfbf04d5228a7b1c4a2048bbcdb941153a436d742c38b58b4d7d13c9f1d60e152aa2792349a3d94e7e6b1104aa1b870998c18dd7065654a85281bb6f027faad556b1f532e7a1e22d564069289587a0efc9c1585d135f31233c41f440466e71fe9012e5f9a0d74a7282ee392fb0165db79ff1d3176ed08afe1daa66cfbf4305ae16ac1792334399f71b1917ddec270acff665ea05d184c2c5cd2ccd902b22f9b7195e66a65556ca884ba6f5da04dcd4617f33dc2b44a0ea742aeb2b93f3a41df7957a026797a585ceee814b1975f523d2db5dbb9be0ca649d1d45dcfd
+SIG: 3cbbb2608870dea1efeebb3fbf681e27705c35e4ddeea86c1b342a77dc296b498419808eacbc78855611ffbc9265a74798e51827e6e5d811816d3ca21e8b9c06
+
+TST: 1020
+SK:  d290ffd93395bd5fc587d1ab511866e72b371a1735732d9d5c6a18dd465e9363
+PK:  fd4aad73b032461ca0aae871ca7016383b2be0169053fdbf6c5914fdd6dd6f92
+MSG: ebd900bc910c5ecc4d97daf7cb5ebb5491500b7ad116e30660950709d8084bb6434c5bea4a8ccc1ed5a801bebb1a117878c03747003e148ed91434832e8966241a7fff22fe1d6d8c3c3ddd7215a1efaf4b07afee1b25673a1439eaac324e895d4be839e976c03ac001254876888ccaaf3912727a60106a87be69247c9e438c31fca8d9c61bae368c83e40901a99700dff839b513ba8dc42d93ce0987a2333470a9f983313f91988659da54039e499cd1af2b8fa0ebe750e24d55c2a5bd1ade3f680092542bd1be0b9735ba393ad5697d241e8e8b28646db27d2fb5a940e8faeaf0b6c9efda88615dec891ce732930813bfbbd0bc5f8210abe843beb5e4f028f49bea34f1e5b09eac4c6662c74fba39de4a9602a9694a85c7c1375fdadfda6a1957fc5b5987a687b03995e51697a1ab5bb6cb11b663c1372fade4c0aca8fbebb4eb54ce7ce36c6904eaf6eab2f34facd8c768c8d36da2397b1a02735aea72cfaad0393410db527a8ab236d4cdabdc888fac6f182148b132614425d390ff036e54855e4203c51203c1f43e37bbf6b9bf27f5b7e7c665151465401ac32cbe9e3350535edf48a7bc3603e2232e938f9a815ac4d1deec991ef9620948441f7a2f4a46e2c400ab914c4be51dcaad8ed8239cbbe977a9f09c02698319d9fe2a8c6eb60b799f29ae7659970d2ebdff3c6cf709bbf6f4bb55b9df4f61a241dec144b5993f087e784b97be1e53608c2e817ce3d9aaf914e6b723f5b4afffd2a6b9fe9d2d73915c7ad1ffb13efcb73c56238195645203984c99aafd0235f73b3f882e073939bf786657280138db05b86fcc9460b385ef4559204ecd81e2f12f5f062aa448dccc82ea8d89466dd1be46f82c4f87bf0db2b878acbb0d9112c8db6f51d35f6d42f749856b99e550b6c454e9e8be4da175f0b5e86be66c979fd878237e57f691f0d2acd028fbffa5b0668775034db1f21ddbe7114ee3dc0b44daca64c5a03a2feeaeabeb7063bfcccc559baf27f1ccb2202fa4d1b2bf44c04b2c2f81f94e281b1a5adc850da1b9479fcabddadea56a115bb5f06cc016f141c0fcb5e83ab248eaec90158d8be647aff12e7eeb5e57dbcc293cb3b6aacb55236d4a839a0620f4762387dd1714df5c135e3d9d6824f93b7c90d3ae38c518d607120c839570413b46b8ccd7370492d8ae5c609e00cf8251e2e7df81e5b4f9c16a5a539f0afcce41bb4362e5eaa5f940a1706f4afb6b14432c81d4ba1a33d322dbf10645ab63737eadc86fe6e0976f763397fb898637595dfd36934792d779e24c2a3f0bacf53e0473c5fda9c61284e4419bdc0eef5d22f4d9bf42e8c04933bb93b53c295d7ac9395abb6dcbd742b1e1bc3b0ea4434ea21b8eca9ae682d3315a41e9c3c3371840761dc59cac45da7e3813e28788dc89de355b5aee088090a38dd39d83e5e4
+SIG: 21704d5e626dcf6a9dcdef935429eb7fb5b257eecd7bf74acb0cd30ecfcf608d0c5b633a4a8a9ba2cc82a21e03355e01d85dae7ecac8896dc15dae0485707104
+
+TST: 1021
+SK:  d7fd73d1d229a65894420e4ba734270d5a20758364de897d8555e24197453c19
+PK:  3c22772aec0a0c1559077f2cfd1f2465d4b48495c5d05f1f837c31845f34cad1
+MSG: c9225859d555bc42011af1b4f14998e6e9b0a65e2172713e968380fb6ceedda22e022c51303031d9931ccef2f7bc705c9e215c1d089d488daddaee155c939b6202ca53bfc7f6e88e1529d82fb45e02b5d05a82bbb9db5f415c58ba8bd56cffd92270b24749e56d12c99ae90c7800f54f55254ea42da5dcfbe0e1d989cd2f6897e232df04707b34af75fa7fec33e55ed56aee39c22b045bedd161083bc5514c1f81ca907b7c760317a7fd5a5a02a5d40e2e823e24ad96aef6da8ea982b5161cc39d84aa2ffd9544c11b634037ab0a1c8e36ac63019da1b2d995cb7bd3d62fe574deabccbd0d3ae7a56e5bec91e4ba3f3db8bfea88e67da62e88278a6e3b418dceea0589f25f7dd8ad19dd845089419b472efccc879c172b32ee4a4dbc2e6c2e865bb3b8ca0adcb71fdf89e1973910ef242915f33e236d2f7c8e9f1ee5b07c6e3c25360f8cb1460be87db31a291d4dee34953e75c675bf181bb7a0b7b5c1befdc86ada072a48f6ac755d499bd68d625d8514525cc3ab8f54ce15a871291778de1305d2219361aa30e332a2e069077c5c53457520379d8b90d24bd8a3a7700ff766231cb5697f9ace521a99e896da54c40793bc7c1fb1584bb1c86194d2fb7a4b802f30885e0ee8af88d6886e3a3a4d4c854649cc01abdf35319a0856cc65d092a386f8869625cd0acac087e9351790ccb4a865f651a881c3ebf109072774f940f5aa98a2a2aa3dd36647d0de83001aa7cdc031cc4a4d75dc11ce551676a2ad43a3f6a16a4bc5aee80e5364206087364eb8b2b15fb705380a072d7c8b51995943aa762e8deb4c568cdaa1411ab68f28489e1323bb6156ce2500b06e7793c510a3de29150840bfdb0b2b7b21c2bb8a7746167c929dd0adad44fed8f36e8381b342080b2a7d82a3f81ff72630cb78df91f7b65a44eff6ed64d48afed109dd7a693a1ba8c37e008fcb157e37297d32eba765a6c7193e73bd97647985b16038c74a084a8f25654cd8cd2cdd27ff17334e06adaa058264017a3b2da78e5738a27e350d882f5fae199278d4e50b8badf57c2141dfdc3cff99df5de86fec293c76cb94b6b19ba3034e460f84c280a2e6412fab5698ce890207cababca0a95b5ad533ce114bf71a404a87590d35fa7cedba43131c4ee92344839f25cbfaeb12aeebc8040893951a346bd28fdd167bd20f71a1e59fb60d55e1c567f478f027cf679a37d1d9db867e17bfdd60b347d89d322639d315bb7a2c9134f00ea03a367f305ea4d60dc9d567cf924851e469ea954ed3ea63ea8606f79f077339bfa2b51ae49baa0fb25377821d7c11ef9ad4bb4c0fe489acbab0ef000d618c7af5efd205d68599fcbdd95e28f836e0916f9ff548d0ba17da62536e74646801eeb6122ba32c41073ae04e42c6c1d5d8d22976a56226ddf4b6ac95455fb53099f20215b2ebc907
+SIG: 400c3505f1dfa80df4b26db24c027eb81977f0fb9b5aca524ad51200f4bfb133db834823314195f4edc292d5f530d08556e7809caf2339768aa38029fdbc280f
+
+TST: 1022
+SK:  fda7cb084016ba513c7c4f8f7180480bb181e95695ea68737fa34a40ecbdf3ef
+PK:  a2de3a0ef97298fd716106e2f3f54513057a40072d234c3518154c1bd12de037
+MSG: c21bb3f8e37befa367c913673101ba30d3b5c74bd8bdb09cd28640012db41120c2bcc4085de2a0f95c9215ddef8cb5fc8d8b1251b41527c67dfaa3f95ba3578391ea5a6629a733095fd0a43fdba40ffe260fff82acee2ebe980e9ececcfe7e10b2ed8c2e6b410d547a1286571df3d701174e579fcf19d3bd8086c0423f37117789f305d9670ad28c99674f52cf64211a081d0c6c3096da2c71bf5f5799a7910e6f38104a37a6557c2daef340814a1f830d593773c6cf48d83ea07294b94eb080b85d6970e28f4051d5066db10e961973a626a826aeaf8a06ec0d566b7e0c4ef60f0c5678fcbb5b2ac63f7bed06448a247b3d427b87086d33573fb2d7228c5c34ea6640eefa9564485a79638e9c97c0af84cfee7ce4a739220c8429e067143953d550668dadc84e7bed9ab070a5943390c611d75b1cb12873a37d9850661a0077bfa9ca9b8b263766c149ff0ee4b4adba25eaf7d7f501f362454256bc1269378ef3359a8ed6b960b86621fa3b613eb132122f49f2eb2ceb6832a3991e961cb0e78b742ef4d65e8de3469666fec7c5b874789571c5c99a2c02a053ff7d2fc90076bafe1f267fa81a3990f27ff14f03000af00c59286cb9bb98e204e90190ae2a50edef049ea92a1f785088f94adf6588fb43bb40fbe2324235cc7e168b80264b069f944f503692c949234d5b76bcffabe29ff9064bd7cbed9e00e5b7fdda4312eb801465f127d0ca68832a7f4ed0eaed8f559c1631cd4d34f0dc414d9fcfe849a91e25f3e0ff013a8cffa806ed8e93d08a1e5a757682ca3d26abc869c76f1c79007d559dfe67e78d8af0195808b0e771c71e64b5716fb36309c25025fae6414c28bbdbd4de597a74996c9da974920d59e6f4c2edfe110ff817fd480a5080978048865712058c5fe7b560b12b67f737ea6e2af9242cf07ad0a8a679f26430046adc3e70664cc9c0ee5abcef6d726b4e04176048b795be12851bdb74003a13204119b86864d6535ba095040a85d9781cf4f3480a304e227f787ad538e68f4bab014179e30d3fdef9eff11bcf471fa3a0bc74b5576f302d3a6b499f11f2ef326ac026c98db10e2741413f322228b3cff0f337ba2f294c78ef73f0e877878f8fc7ff6d10bce66ad6284379b80ca89327d4db0bf14e6d8f01b22ab202b716cc07e3c8866d168a5094bac5a495e73868eedc27222e6444f83bcf65acdc3ec89120bb50e8abfc28b78e6d980c775f4849a0e8cada80240bca245e39966e89a0344df8363a7dcc81b201ce9c753ad544e1124e21020d4c62deda9ed9b9d1f2fb7c54ca7ab09f383bef48cfc6848c271302a10fa687f56e00e0a7d093c927b4fdd8f1bedf6288a0e302848a8012f127a79d2d30a06ce17d94aa6f7f8a1e6eb9d0681c3774f614cc6dbcb2a813f925c6306a630572a83ec109d5f533c0584cb421d919
+SIG: 33614b7a94f75e036534d76e30147eccdd2a04e00cd4704ab6e807d6a2acc1e1d963b8eee0810d412d9d56e54556302b10730c15abf89c29a027303ea88ae701
+
+TST: 1023
+SK:  a1ac48aa5ffa3d800819d03b7f62babf291f20904c11a6400e4f45205f103e38
+PK:  0854e0340f814985fb122b78729479e3fde855c211cadeae56f0d4dc0828d5fa
+MSG: d6f124ed752021c10926972a0c26f3b1838b3c7af247c18009a231ecce964bf6698637833f607dca836f8a606c72ae3cb170174447a2cce583f6e244dbc163e215b9820de7496ffc5b7050c48f2830246678cba4dc5caa07c1458563aa2d10dcb7770ef8fede027dd7f20ddc8cc78c3a2e2e958bd18c0006cf8fb82d44e53e1da7aa80fd1006f3b2300c9b079d8a66f1e4a3f47061f9e2f45dae35dc295204b19460ca5707ab57ce215a24c10faab3fa20bccd101e7a7d70077599f3d6725707552129cad757d6514c1b28997e471f94b0fded8fbbd065dead196d2c07d3dfa7b9fb3bae7680f76621200d099eebebbea0e8957df5b5e204ca3e9e2952b8a30f0a131a6867b1381e394b1b444310f076326656cf9341678008e9525147d8d61ce93d3bf53900cab912663717e0987293833d1902d7fb047b997b86026c467d7bb17cf45796738f7a774ac126764ed4eb45124309f4586260176ba465918d48330a9cc18c4ecea0ddaf38946acc0e361dd40a7e9133ceb50e1c317ea42bd0980a72b8ba3d8a6c7693dd5602f374f2664df4ba56df01e882fca42cb4db621f476c76e1ea9fd105911a74b77952d9914a5ac0f98a900c1b2e1a56c4ea8518a9ee47c4ed14d0bd35eca560319c8ea24755d71a4e030850bc4dc60389f325804021204ccebc25fedbd32edd8d8446aa23ce56a85f779e858d36af7c073c115e341f412c660fab800fe74c50e714ee086e2fbc8d7abbf3e98fb40ca27f1f01a9aadd8cc2275c2dd3f76e4c1d81c4b792daecc9fe66044941b8b2918486dd4acb562a7b58ad8c60c21b83cf48aefa7256a1ed809e669811f484364970bc5695089919bc32d28ea752e8e318ceff467f77ae1977c5ffd79c17c2da8bc7f823dd94398683189945f8b79238a4e815b142b866acbdbcb7aea7f143fffb7cc2b4b54bbf361afda913ad6df1e49dfd6b532642e63f55d893a470d40370665cfb74efd3f59cb0ff6006174ca35f53b97c543e08af4bf5bb75ff9031610652a3f6f2a0cfe97e7a521f3d2a289114ded34772b0e49817bde1cb924ff514e2866a09e3ede0782d2c0c98e6814b8c1e778cf8306348c933adb2e472dba09db954ff49648373395a2f0181958feb1ea2834c99532873db5c88eb5289c77e90015203ef502ac8e1c48fa1a06dafa6519d52dae3c5567570dd2434e671927c66363f783156893f138a84c75664b30ae4275112736d53d4f399ddda3d23067c073f521afba1f7be585513c2cec9c8f08d2a22c3c85392cd2ae50f3928251f86b310c69a0f8c4e853ab3f3e8129b0566ef4bbbe80b8c02c8928a4de56c0d119a45bbf5af1808d488852d8a45beb0d683248a4d65de1526b3d1d2ffc1f22215b608468cbc3bd39514b397fc0db0f113dbe6fce4652e82ff895b2b4387e041d7e4e7bde4694769665e81
+SIG: c57e3c091ed24e5e84665bd9bb102db49797df9008f05557fa0d5ad7a295e5e4d2a4716b17f8c91cb12f5abfb1af027fb0411199acc5d285d842a4b65bde4902
+
+TST: 1024
+SK:  f5e5767cf153319517630f226876b86c8160cc583bc013744c6bf255f5cc0ee5
+PK:  278117fc144c72340f67d0f2316e8386ceffbf2b2428c9c51fef7c597f1d426e
+MSG: 08b8b2b733424243760fe426a4b54908632110a66c2f6591eabd3345e3e4eb98fa6e264bf09efe12ee50f8f54e9f77b1e355f6c50544e23fb1433ddf73be84d879de7c0046dc4996d9e773f4bc9efe5738829adb26c81b37c93a1b270b20329d658675fc6ea534e0810a4432826bf58c941efb65d57a338bbd2e26640f89ffbc1a858efcb8550ee3a5e1998bd177e93a7363c344fe6b199ee5d02e82d522c4feba15452f80288a821a579116ec6dad2b3b310da903401aa62100ab5d1a36553e06203b33890cc9b832f79ef80560ccb9a39ce767967ed628c6ad573cb116dbefefd75499da96bd68a8a97b928a8bbc103b6621fcde2beca1231d206be6cd9ec7aff6f6c94fcd7204ed3455c68c83f4a41da4af2b74ef5c53f1d8ac70bdcb7ed185ce81bd84359d44254d95629e9855a94a7c1958d1f8ada5d0532ed8a5aa3fb2d17ba70eb6248e594e1a2297acbbb39d502f1a8c6eb6f1ce22b3de1a1f40cc24554119a831a9aad6079cad88425de6bde1a9187ebb6092cf67bf2b13fd65f27088d78b7e883c8759d2c4f5c65adb7553878ad575f9fad878e80a0c9ba63bcbcc2732e69485bbc9c90bfbd62481d9089beccf80cfe2df16a2cf65bd92dd597b0707e0917af48bbb75fed413d238f5555a7a569d80c3414a8d0859dc65a46128bab27af87a71314f318c782b23ebfe808b82b0ce26401d2e22f04d83d1255dc51addd3b75a2b1ae0784504df543af8969be3ea7082ff7fc9888c144da2af58429ec96031dbcad3dad9af0dcbaaaf268cb8fcffead94f3c7ca495e056a9b47acdb751fb73e666c6c655ade8297297d07ad1ba5e43f1bca32301651339e22904cc8c42f58c30c04aafdb038dda0847dd988dcda6f3bfd15c4b4c4525004aa06eeff8ca61783aacec57fb3d1f92b0fe2fd1a85f6724517b65e614ad6808d6f6ee34dff7310fdc82aebfd904b01e1dc54b2927094b2db68d6f903b68401adebf5a7e08d78ff4ef5d63653a65040cf9bfd4aca7984a74d37145986780fc0b16ac451649de6188a7dbdf191f64b5fc5e2ab47b57f7f7276cd419c17a3ca8e1b939ae49e488acba6b965610b5480109c8b17b80e1b7b750dfc7598d5d5011fd2dcc5600a32ef5b52a1ecc820e308aa342721aac0943bf6686b64b2579376504ccc493d97e6aed3fb0f9cd71a43dd497f01f17c0e2cb3797aa2a2f256656168e6c496afc5fb93246f6b1116398a346f1a641f3b041e989f7914f90cc2c7fff357876e506b50d334ba77c225bc307ba537152f3f1610e4eafe595f6d9d90d11faa933a15ef1369546868a7f3a45a96768d40fd9d03412c091c6315cf4fde7cb68606937380db2eaaa707b4c4185c32eddcdd306705e4dc1ffc872eeee475a64dfac86aba41c0618983f8741c5ef68d3a101e8a3b8cac60c905c15fc910840b94c00a0b9d0
+SIG: 0aab4c900501b3e24d7cdf4663326a3a87df5e4843b2cbdb67cbf6e460fec350aa5371b1508f9f4528ecea23c436d94b5e8fcd4f681e30a6ac00a9704a188a03
+
+# Now an additional test with the data from test 1 but using an
+# uncompressed public key.
+TST: 1025
+SK:  9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60
+PK:  0455d0e09a2b9d34292297e08d60d0f620c513d47253187c24b12786bd777645ce1a5107f7681a02af2523a6daf372e10e3a0764c9d3fe4bd5b70ab18201985ad7
+MSG:
+SIG: e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b
index 7209525..adbe6cc 100644 (file)
@@ -27,7 +27,7 @@
 #include <stdarg.h>
 #include <assert.h>
 
-#include "../src/gcrypt.h"
+#include "../src/gcrypt-int.h"
 
 #ifndef DIM
 # define DIM(v)                     (sizeof(v)/sizeof((v)[0]))
@@ -35,6 +35,7 @@
 
 /* Program option flags.  */
 static int verbose;
+static int debug;
 static int error_count;
 
 static void
@@ -917,6 +918,14 @@ check_pbkdf2 (void)
       16,
       "\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37"
       "\xd7\xf0\x34\x25\xe0\xc3"
+    },
+    { /* empty password test, not in RFC-6070 */
+      "", 0,
+      "salt", 4,
+      2,
+      20,
+      "\x13\x3a\x4c\xe8\x37\xb4\xd2\x52\x1e\xe2"
+      "\xbf\x03\xe1\x1c\x71\xca\x79\x4e\x07\x97"
     }
   };
   int tvidx;
@@ -949,11 +958,106 @@ check_pbkdf2 (void)
 }
 
 
+static void
+check_scrypt (void)
+{
+  /* Test vectors are from draft-josefsson-scrypt-kdf-01.  */
+  static struct {
+    const char *p;        /* Passphrase.  */
+    size_t plen;          /* Length of P. */
+    const char *salt;
+    size_t saltlen;
+    int parm_n;           /* CPU/memory cost.  */
+    int parm_r;           /* blocksize */
+    unsigned long parm_p; /* parallelization. */
+    int dklen;            /* Requested key length.  */
+    const char *dk;       /* Derived key.  */
+    int disabled;
+  } tv[] = {
+    {
+      "", 0,
+      "", 0,
+      16,
+      1,
+      1,
+      64,
+      "\x77\xd6\x57\x62\x38\x65\x7b\x20\x3b\x19\xca\x42\xc1\x8a\x04\x97"
+      "\xf1\x6b\x48\x44\xe3\x07\x4a\xe8\xdf\xdf\xfa\x3f\xed\xe2\x14\x42"
+      "\xfc\xd0\x06\x9d\xed\x09\x48\xf8\x32\x6a\x75\x3a\x0f\xc8\x1f\x17"
+      "\xe8\xd3\xe0\xfb\x2e\x0d\x36\x28\xcf\x35\xe2\x0c\x38\xd1\x89\x06"
+    },
+    {
+      "password", 8,
+      "NaCl", 4,
+      1024,
+      8,
+      16,
+      64,
+      "\xfd\xba\xbe\x1c\x9d\x34\x72\x00\x78\x56\xe7\x19\x0d\x01\xe9\xfe"
+      "\x7c\x6a\xd7\xcb\xc8\x23\x78\x30\xe7\x73\x76\x63\x4b\x37\x31\x62"
+      "\x2e\xaf\x30\xd9\x2e\x22\xa3\x88\x6f\xf1\x09\x27\x9d\x98\x30\xda"
+      "\xc7\x27\xaf\xb9\x4a\x83\xee\x6d\x83\x60\xcb\xdf\xa2\xcc\x06\x40"
+    },
+    {
+      "pleaseletmein", 13,
+      "SodiumChloride", 14,
+      16384,
+      8,
+      1,
+      64,
+      "\x70\x23\xbd\xcb\x3a\xfd\x73\x48\x46\x1c\x06\xcd\x81\xfd\x38\xeb"
+      "\xfd\xa8\xfb\xba\x90\x4f\x8e\x3e\xa9\xb5\x43\xf6\x54\x5d\xa1\xf2"
+      "\xd5\x43\x29\x55\x61\x3f\x0f\xcf\x62\xd4\x97\x05\x24\x2a\x9a\xf9"
+      "\xe6\x1e\x85\xdc\x0d\x65\x1e\x40\xdf\xcf\x01\x7b\x45\x57\x58\x87"
+    },
+    {
+      "pleaseletmein", 13,
+      "SodiumChloride", 14,
+      1048576,
+      8,
+      1,
+      64,
+      "\x21\x01\xcb\x9b\x6a\x51\x1a\xae\xad\xdb\xbe\x09\xcf\x70\xf8\x81"
+      "\xec\x56\x8d\x57\x4a\x2f\xfd\x4d\xab\xe5\xee\x98\x20\xad\xaa\x47"
+      "\x8e\x56\xfd\x8f\x4b\xa5\xd0\x9f\xfa\x1c\x6d\x92\x7c\x40\xf4\xc3"
+      "\x37\x30\x40\x49\xe8\xa9\x52\xfb\xcb\xf4\x5c\x6f\xa7\x7a\x41\xa4",
+      2 /* Only in debug mode.  */
+    }
+  };
+  int tvidx;
+  gpg_error_t err;
+  unsigned char outbuf[64];
+  int i;
+
+  for (tvidx=0; tvidx < DIM(tv); tvidx++)
+    {
+      if (tv[tvidx].disabled && !(tv[tvidx].disabled == 2 && debug))
+        continue;
+      if (verbose)
+        fprintf (stderr, "checking SCRYPT test vector %d\n", tvidx);
+      assert (tv[tvidx].dklen <= sizeof outbuf);
+      err = gcry_kdf_derive (tv[tvidx].p, tv[tvidx].plen,
+                             tv[tvidx].parm_r == 1 ? 41 : GCRY_KDF_SCRYPT,
+                             tv[tvidx].parm_n,
+                             tv[tvidx].salt, tv[tvidx].saltlen,
+                             tv[tvidx].parm_p, tv[tvidx].dklen, outbuf);
+      if (err)
+        fail ("scrypt test %d failed: %s\n", tvidx, gpg_strerror (err));
+      else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen))
+        {
+          fail ("scrypt test %d failed: mismatch\n", tvidx);
+          fputs ("got:", stderr);
+          for (i=0; i < tv[tvidx].dklen; i++)
+            fprintf (stderr, " %02x", outbuf[i]);
+          putc ('\n', stderr);
+        }
+    }
+}
+
+
 int
 main (int argc, char **argv)
 {
-  int debug = 0;
-
   if (argc > 1 && !strcmp (argv[1], "--verbose"))
     verbose = 1;
   else if (argc > 1 && !strcmp (argv[1], "--debug"))
@@ -969,6 +1073,7 @@ main (int argc, char **argv)
 
   check_openpgp ();
   check_pbkdf2 ();
+  check_scrypt ();
 
   return error_count ? 1 : 0;
 }
diff --git a/tests/t-lock.c b/tests/t-lock.c
new file mode 100644 (file)
index 0000000..e370f3e
--- /dev/null
@@ -0,0 +1,463 @@
+/* t-lock.c - Check the lock functions
+ * 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/>.
+ */
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <errno.h>
+#include <unistd.h>
+#if USE_POSIX_THREADS
+# include <pthread.h>
+#endif
+
+#define PGM "t-lock"
+
+#include "t-common.h"
+
+/* Mingw requires us to include windows.h after winsock2.h which is
+   included by gcrypt.h.  */
+#ifdef _WIN32
+# include <windows.h>
+#endif
+
+#ifdef _WIN32
+# define THREAD_RET_TYPE  DWORD WINAPI
+# define THREAD_RET_VALUE 0
+#else
+# define THREAD_RET_TYPE  void *
+# 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
+/* Number of interations.  */
+#define N_NONCE_ITERATIONS 1000
+/* Requested nonce size.  */
+#define NONCE_SIZE  11
+
+
+/* This tests works by having a a couple of accountant threads which do
+   random transactions between accounts and a revision threads which
+   checks that the balance of all accounts is invariant.  The idea for
+   this check is due to Bruno Haible.  */
+#define N_ACCOUNT 8
+#define ACCOUNT_VALUE 42
+static int account[N_ACCOUNT];
+
+/* Number of transactions done by each accountant.  */
+#define N_TRANSACTIONS 1000
+
+/* Number of accountants to run.  */
+#define N_ACCOUNTANTS 5
+
+/* Maximum transaction value.  A quite low value is used so that we
+   would get an integer overflow.  */
+#define MAX_TRANSACTION_VALUE 50
+
+/* Flag to tell the revision thread to finish.  */
+static volatile int stop_revision_thread;
+
+
+struct thread_arg_s
+{
+  int no;
+};
+
+
+
+\f
+/* Wrapper functions to access Libgcrypt's internal test lock.  */
+static void
+external_lock_test_init (int line)
+{
+  gpg_error_t err;
+
+  err = gcry_control (PRIV_CTL_EXTERNAL_LOCK_TEST, EXTERNAL_LOCK_TEST_INIT);
+  if (err)
+    fail ("init lock failed at %d: %s", line, gpg_strerror (err));
+}
+
+static void
+external_lock_test_lock (int line)
+{
+  gpg_error_t err;
+
+  err = gcry_control (PRIV_CTL_EXTERNAL_LOCK_TEST, EXTERNAL_LOCK_TEST_LOCK);
+  if (err)
+    fail ("taking lock failed at %d: %s", line, gpg_strerror (err));
+}
+
+static void
+external_lock_test_unlock (int line)
+{
+  gpg_error_t err;
+
+  err = gcry_control (PRIV_CTL_EXTERNAL_LOCK_TEST, EXTERNAL_LOCK_TEST_UNLOCK);
+  if (err)
+    fail ("releasing lock failed at %d: %s", line, gpg_strerror (err));
+
+}
+
+static void
+external_lock_test_destroy (int line)
+{
+  gpg_error_t err;
+
+  err = gcry_control (PRIV_CTL_EXTERNAL_LOCK_TEST, EXTERNAL_LOCK_TEST_DESTROY);
+  if (err)
+    fail ("destroying lock failed at %d: %s", line, gpg_strerror (err));
+}
+
+
+
+\f
+/* The nonce thread.  We simply request a couple of nonces and
+   return.  */
+static THREAD_RET_TYPE
+nonce_thread (void *argarg)
+{
+  struct thread_arg_s *arg = argarg;
+  int i;
+  char nonce[NONCE_SIZE];
+
+  for (i = 0; i < N_NONCE_ITERATIONS; i++)
+    {
+      gcry_create_nonce (nonce, sizeof nonce);
+      if (i && !(i%100))
+        show ("thread %d created %d nonces so far", arg->no, i);
+    }
+
+  gcry_free (arg);
+  return THREAD_RET_VALUE;
+}
+
+
+/* To check our locking function we run several threads all accessing
+   the nonce functions.  If this function returns we know that there
+   are no obvious deadlocks or failed lock initialization.  */
+static void
+check_nonce_lock (void)
+{
+  struct thread_arg_s *arg;
+#ifdef _WIN32
+  HANDLE threads[N_NONCE_THREADS];
+  int i;
+  int rc;
+
+  for (i=0; i < N_NONCE_THREADS; i++)
+    {
+      arg = gcry_xmalloc (sizeof *arg);
+      arg->no = i;
+      threads[i] = CreateThread (NULL, 0, nonce_thread, arg, 0, NULL);
+      if (!threads[i])
+        die ("error creating nonce thread %d: rc=%d",
+             i, (int)GetLastError ());
+    }
+
+  for (i=0; i < N_NONCE_THREADS; i++)
+    {
+      rc = WaitForSingleObject (threads[i], INFINITE);
+      if (rc == WAIT_OBJECT_0)
+        show ("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
+  pthread_t threads[N_NONCE_THREADS];
+  int rc, i;
+
+  for (i=0; i < N_NONCE_THREADS; i++)
+    {
+      arg = gcry_xmalloc (sizeof *arg);
+      arg->no = i;
+      pthread_create (&threads[i], NULL, nonce_thread, arg);
+    }
+
+  for (i=0; i < N_NONCE_THREADS; i++)
+    {
+      rc = pthread_join (threads[i], NULL);
+      if (rc)
+        fail ("pthread_join failed for nonce thread %d: %s",
+              i, strerror (errno));
+      else
+        show ("nonce thread %d has terminated", i);
+    }
+
+#endif /*!_WIN32*/
+}
+
+
+/* Initialze all accounts.  */
+static void
+init_accounts (void)
+{
+  int i;
+
+  for (i=0; i < N_ACCOUNT; i++)
+    account[i] = ACCOUNT_VALUE;
+}
+
+
+/* Check that the sum of all accounts matches the intial sum.  */
+static void
+check_accounts (void)
+{
+  int i, sum;
+
+  sum = 0;
+  for (i = 0; i < N_ACCOUNT; i++)
+    sum += account[i];
+  if (sum != N_ACCOUNT * ACCOUNT_VALUE)
+    die ("accounts out of balance");
+}
+
+
+static void
+print_accounts (void)
+{
+  int i;
+
+  for (i=0; i < N_ACCOUNT; i++)
+    printf ("account %d: %6d\n", i, account[i]);
+}
+
+
+/* Get a a random integer value in the range 0 to HIGH.  */
+static unsigned int
+get_rand (int high)
+{
+  return (unsigned int)(1+(int)((double)(high+1)*rand ()/(RAND_MAX+1.0))) - 1;
+}
+
+
+/* Pick a random account.  Note that this fucntion is not
+   thread-safe. */
+static int
+pick_account (void)
+{
+  return get_rand (N_ACCOUNT - 1);
+}
+
+
+/* Pick a random value for a transaction.  This is not thread-safe.  */
+static int
+pick_value (void)
+{
+  return get_rand (MAX_TRANSACTION_VALUE);
+}
+
+
+/* This is the revision department.  */
+static THREAD_RET_TYPE
+revision_thread (void *arg)
+{
+  (void)arg;
+
+  while (!stop_revision_thread)
+    {
+      external_lock_test_lock (__LINE__);
+      check_accounts ();
+      external_lock_test_unlock (__LINE__);
+    }
+  return THREAD_RET_VALUE;
+}
+
+
+/* This is one of our accountants.  */
+static THREAD_RET_TYPE
+accountant_thread (void *arg)
+{
+  int i;
+  int acc1, acc2;
+  int value;
+
+  (void)arg;
+
+  for (i = 0; i < N_TRANSACTIONS; i++)
+    {
+      external_lock_test_lock (__LINE__);
+      acc1 = pick_account ();
+      acc2 = pick_account ();
+      value = pick_value ();
+      account[acc1] += value;
+      account[acc2] -= value;
+      external_lock_test_unlock (__LINE__);
+    }
+  return THREAD_RET_VALUE;
+}
+
+
+static void
+run_test (void)
+{
+#ifdef _WIN32
+  HANDLE rthread;
+  HANDLE athreads[N_ACCOUNTANTS];
+  int i;
+  int rc;
+
+  external_lock_test_init (__LINE__);
+  stop_revision_thread = 0;
+  rthread = CreateThread (NULL, 0, revision_thread, NULL, 0, NULL);
+  if (!rthread)
+    die ("error creating revision thread: rc=%d", (int)GetLastError ());
+
+  for (i=0; i < N_ACCOUNTANTS; i++)
+    {
+      athreads[i] = CreateThread (NULL, 0, accountant_thread, NULL, 0, NULL);
+      if (!athreads[i])
+        die ("error creating accountant thread %d: rc=%d",
+             i, (int)GetLastError ());
+    }
+
+  for (i=0; i < N_ACCOUNTANTS; i++)
+    {
+      rc = WaitForSingleObject (athreads[i], INFINITE);
+      if (rc == WAIT_OBJECT_0)
+        show ("accountant thread %d has terminated", i);
+      else
+        fail ("waiting for accountant thread %d failed: %d",
+              i, (int)GetLastError ());
+      CloseHandle (athreads[i]);
+    }
+  stop_revision_thread = 1;
+
+  rc = WaitForSingleObject (rthread, INFINITE);
+  if (rc == WAIT_OBJECT_0)
+    show ("revision thread has terminated");
+  else
+    fail ("waiting for revision thread failed: %d", (int)GetLastError ());
+  CloseHandle (rthread);
+
+#elif USE_POSIX_THREADS
+  pthread_t rthread;
+  pthread_t athreads[N_ACCOUNTANTS];
+  int rc, i;
+
+  external_lock_test_init (__LINE__);
+  stop_revision_thread = 0;
+  pthread_create (&rthread, NULL, revision_thread, NULL);
+
+  for (i=0; i < N_ACCOUNTANTS; i++)
+    pthread_create (&athreads[i], NULL, accountant_thread, NULL);
+
+  for (i=0; i < N_ACCOUNTANTS; i++)
+    {
+      rc = pthread_join (athreads[i], NULL);
+      if (rc)
+        fail ("pthread_join failed for accountant thread %d: %s",
+              i, strerror (errno));
+      else
+        show ("accountant thread %d has terminated", i);
+    }
+
+  stop_revision_thread = 1;
+  rc = pthread_join (rthread, NULL);
+  if (rc)
+    fail ("pthread_join failed for the revision thread: %s", strerror (errno));
+  else
+    show ("revision thread has terminated");
+
+#endif /*USE_POSIX_THREADS*/
+
+  external_lock_test_destroy (__LINE__);
+}
+
+
+
+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, "--help"))
+        {
+          puts (
+"usage: ./t-lock [options]\n"
+"\n"
+"Options:\n"
+"  --verbose      Show what is going on\n"
+"  --debug        Flyswatter\n"
+);
+          exit (0);
+        }
+      if (!strcmp (*argv, "--verbose"))
+        {
+          verbose = 1;
+          argc--; argv++;
+        }
+      else if (!strcmp (*argv, "--debug"))
+        {
+          verbose = debug = 1;
+          argc--; argv++;
+        }
+    }
+
+  srand (time(NULL)*getpid());
+
+  if (debug)
+    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+  if (!gcry_check_version (GCRYPT_VERSION))
+    die ("version mismatch");
+  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 ();
+  check_accounts ();
+
+  run_test ();
+  check_accounts ();
+
+  /* Run a second time to check deinit code.  */
+  run_test ();
+  check_accounts ();
+
+  if (verbose)
+    print_accounts ();
+
+  return errorcount ? 1 : 0;
+}
index 85bd32e..b1c999e 100644 (file)
@@ -28,7 +28,7 @@
 #include <assert.h>
 #include <stdarg.h>
 
-#include "../src/gcrypt.h"
+#include "../src/gcrypt-int.h"
 
 #define PGM "t-mpi-bit"
 
diff --git a/tests/t-mpi-point.c b/tests/t-mpi-point.c
new file mode 100644 (file)
index 0000000..5ab0598
--- /dev/null
@@ -0,0 +1,1110 @@
+/* t-mpi-point.c  - Tests for mpi point functions
+ * Copyright (C) 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/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdarg.h>
+
+#include "../src/gcrypt-int.h"
+
+#define PGM "t-mpi-point"
+
+static const char *wherestr;
+static int verbose;
+static int debug;
+static int error_count;
+
+
+#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 xfree(a)      gcry_free ((a))
+#define pass() do { ; } while (0)
+
+
+static struct
+{
+  const char *desc;           /* Description of the curve.  */
+  const char *p;              /* Order of the prime field.  */
+  const char *a, *b;          /* The coefficients. */
+  const char *n;              /* The order of the base point.  */
+  const char *g_x, *g_y;      /* Base point.  */
+} test_curve[] =
+  {
+    {
+      "NIST P-192",
+      "0xfffffffffffffffffffffffffffffffeffffffffffffffff",
+      "0xfffffffffffffffffffffffffffffffefffffffffffffffc",
+      "0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1",
+      "0xffffffffffffffffffffffff99def836146bc9b1b4d22831",
+
+      "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012",
+      "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811"
+    },
+    {
+      "NIST P-224",
+      "0xffffffffffffffffffffffffffffffff000000000000000000000001",
+      "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe",
+      "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4",
+      "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" ,
+
+      "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21",
+      "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34"
+    },
+    {
+      "NIST P-256",
+      "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff",
+      "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc",
+      "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b",
+      "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551",
+
+      "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296",
+      "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5"
+    },
+    {
+      "NIST P-384",
+      "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
+      "ffffffff0000000000000000ffffffff",
+      "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe"
+      "ffffffff0000000000000000fffffffc",
+      "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a"
+      "c656398d8a2ed19d2a85c8edd3ec2aef",
+      "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf"
+      "581a0db248b0a77aecec196accc52973",
+
+      "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38"
+      "5502f25dbf55296c3a545e3872760ab7",
+      "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0"
+      "0a60b1ce1d7e819d7a431d7c90ea0e5f"
+    },
+    {
+      "NIST P-521",
+      "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+      "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
+      "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+      "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc",
+      "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10"
+      "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00",
+      "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
+      "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409",
+
+      "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d"
+      "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66",
+      "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6"
+      "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650"
+    },
+    {
+      "Ed25519",
+      "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED",
+      "-0x01",
+      "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A",
+      "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED",
+      "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A",
+      "0x6666666666666666666666666666666666666666666666666666666666666658"
+    },
+    { NULL, NULL, NULL, NULL, NULL }
+  };
+
+/* A sample public key for NIST P-256.  */
+static const char sample_p256_q[] =
+  "04"
+  "42B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146E"
+  "E86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E";
+static const char sample_p256_q_x[] =
+  "42B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146E";
+static const char sample_p256_q_y[] =
+  "00E86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E";
+
+
+/* A sample public key for Ed25519.  */
+static const char sample_ed25519_q[] =
+  "04"
+  "55d0e09a2b9d34292297e08d60d0f620c513d47253187c24b12786bd777645ce"
+  "1a5107f7681a02af2523a6daf372e10e3a0764c9d3fe4bd5b70ab18201985ad7";
+static const char sample_ed25519_q_x[] =
+  "55d0e09a2b9d34292297e08d60d0f620c513d47253187c24b12786bd777645ce";
+static const char sample_ed25519_q_y[] =
+  "1a5107f7681a02af2523a6daf372e10e3a0764c9d3fe4bd5b70ab18201985ad7";
+static const char sample_ed25519_q_eddsa[] =
+  "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a";
+static const char sample_ed25519_d[] =
+  "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60";
+
+
+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);
+  va_end (arg_ptr);
+}
+
+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);
+  error_count++;
+}
+
+static void
+die (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);
+  exit (1);
+}
+
+
+static void
+print_mpi_2 (const char *text, const char *text2, 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%s: [error printing number: %s]\n",
+             text, text2? text2:"", gpg_strerror (err));
+  else
+    {
+      fprintf (stderr, "%s%s: %s\n", text, text2? text2:"", buf);
+      gcry_free (buf);
+    }
+}
+
+
+static void
+print_mpi (const char *text, gcry_mpi_t a)
+{
+  print_mpi_2 (text, NULL, a);
+}
+
+
+static void
+print_point (const char *text, gcry_mpi_point_t a)
+{
+  gcry_mpi_t x, y, z;
+
+  x = gcry_mpi_new (0);
+  y = gcry_mpi_new (0);
+  z = gcry_mpi_new (0);
+  gcry_mpi_point_get (x, y, z, a);
+  print_mpi_2 (text, ".x", x);
+  print_mpi_2 (text, ".y", y);
+  print_mpi_2 (text, ".z", z);
+  gcry_mpi_release (x);
+  gcry_mpi_release (y);
+  gcry_mpi_release (z);
+}
+
+
+static void
+print_sexp (const char *prefix, gcry_sexp_t a)
+{
+  char *buf;
+  size_t size;
+
+  if (prefix)
+    fputs (prefix, stderr);
+  size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0);
+  buf = gcry_xmalloc (size);
+
+  gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size);
+  fprintf (stderr, "%.*s", (int)size, buf);
+  gcry_free (buf);
+}
+
+
+static gcry_mpi_t
+hex2mpi (const char *string)
+{
+  gpg_error_t err;
+  gcry_mpi_t val;
+
+  err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
+  if (err)
+    die ("hex2mpi '%s' failed: %s\n", string, gpg_strerror (err));
+  return val;
+}
+
+
+/* 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 gcry_mpi_t
+hex2mpiopa (const char *string)
+{
+  char *buffer;
+  size_t buflen;
+  gcry_mpi_t val;
+
+  buffer = hex2buffer (string, &buflen);
+  if (!buffer)
+    die ("hex2mpiopa '%s' failed: parser error\n", string);
+  val = gcry_mpi_set_opaque (NULL, buffer, buflen*8);
+  if (!buffer)
+    die ("hex2mpiopa '%s' failed: set_opaque error%s\n", string);
+  return val;
+}
+
+
+/* Compare A to B, where B is given as a hex string.  */
+static int
+cmp_mpihex (gcry_mpi_t a, const char *b)
+{
+  gcry_mpi_t bval;
+  int res;
+
+  if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
+    bval = hex2mpiopa (b);
+  else
+    bval = hex2mpi (b);
+  res = gcry_mpi_cmp (a, bval);
+  gcry_mpi_release (bval);
+  return res;
+}
+
+
+/* Wrapper to emulate the libgcrypt internal EC context allocation
+   function.  */
+static gpg_error_t
+ec_p_new (gcry_ctx_t *r_ctx, gcry_mpi_t p, gcry_mpi_t a)
+{
+  gpg_error_t err;
+  gcry_sexp_t sexp;
+
+  if (p && a)
+    err = gcry_sexp_build (&sexp, NULL, "(ecdsa (p %m)(a %m))", p, a);
+  else if (p)
+    err = gcry_sexp_build (&sexp, NULL, "(ecdsa (p %m))", p);
+  else if (a)
+    err = gcry_sexp_build (&sexp, NULL, "(ecdsa (a %m))", a);
+  else
+    err = gcry_sexp_build (&sexp, NULL, "(ecdsa)");
+  if (err)
+    return err;
+  err = gcry_mpi_ec_new (r_ctx, sexp, NULL);
+  gcry_sexp_release (sexp);
+  return err;
+}
+
+
+\f
+static void
+set_get_point (void)
+{
+  gcry_mpi_point_t point;
+  gcry_mpi_t x, y, z;
+
+  wherestr = "set_get_point";
+  show ("checking point setting functions\n");
+
+  point = gcry_mpi_point_new (0);
+  x = gcry_mpi_set_ui (NULL, 17);
+  y = gcry_mpi_set_ui (NULL, 42);
+  z = gcry_mpi_set_ui (NULL, 11371);
+  gcry_mpi_point_get (x, y, z, point);
+  if (gcry_mpi_cmp_ui (x, 0)
+      || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0))
+    fail ("new point not initialized to (0,0,0)\n");
+  gcry_mpi_point_snatch_get (x, y, z, point);
+  point = NULL;
+  if (gcry_mpi_cmp_ui (x, 0)
+      || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0))
+    fail ("snatch_get failed\n");
+  gcry_mpi_release (x);
+  gcry_mpi_release (y);
+  gcry_mpi_release (z);
+
+  point = gcry_mpi_point_new (0);
+  x = gcry_mpi_set_ui (NULL, 17);
+  y = gcry_mpi_set_ui (NULL, 42);
+  z = gcry_mpi_set_ui (NULL, 11371);
+  gcry_mpi_point_set (point, x, y, z);
+  gcry_mpi_set_ui (x, 23);
+  gcry_mpi_set_ui (y, 24);
+  gcry_mpi_set_ui (z, 25);
+  gcry_mpi_point_get (x, y, z, point);
+  if (gcry_mpi_cmp_ui (x, 17)
+      || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371))
+    fail ("point_set/point_get failed\n");
+  gcry_mpi_point_snatch_set (point, x, y, z);
+  x = gcry_mpi_new (0);
+  y = gcry_mpi_new (0);
+  z = gcry_mpi_new (0);
+  gcry_mpi_point_get (x, y, z, point);
+  if (gcry_mpi_cmp_ui (x, 17)
+      || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371))
+    fail ("point_snatch_set/point_get failed\n");
+
+  gcry_mpi_point_release (point);
+  gcry_mpi_release (x);
+  gcry_mpi_release (y);
+  gcry_mpi_release (z);
+}
+
+
+static void
+context_alloc (void)
+{
+  gpg_error_t err;
+  gcry_ctx_t ctx;
+  gcry_mpi_t p, a;
+
+  wherestr = "context_alloc";
+  show ("checking context functions\n");
+
+  p = gcry_mpi_set_ui (NULL, 1);
+  a = gcry_mpi_set_ui (NULL, 1);
+  err = ec_p_new (&ctx, p, a);
+  if (err)
+    die ("ec_p_new returned an error: %s\n", gpg_strerror (err));
+  gcry_mpi_release (p);
+  gcry_mpi_release (a);
+  gcry_ctx_release (ctx);
+
+  p = gcry_mpi_set_ui (NULL, 0);
+  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");
+
+  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");
+
+}
+
+
+static int
+get_and_cmp_mpi (const char *name, const char *mpistring, const char *desc,
+                 gcry_ctx_t ctx)
+{
+  gcry_mpi_t mpi;
+
+  mpi = gcry_mpi_ec_get_mpi (name, ctx, 1);
+  if (!mpi)
+    {
+      fail ("error getting parameter '%s' of curve '%s'\n", name, desc);
+      return 1;
+    }
+  if (debug)
+    print_mpi (name, mpi);
+  if (cmp_mpihex (mpi, mpistring))
+    {
+      fail ("parameter '%s' of curve '%s' does not match\n", name, desc);
+      gcry_mpi_release (mpi);
+      return 1;
+    }
+  gcry_mpi_release (mpi);
+  return 0;
+}
+
+
+static int
+get_and_cmp_point (const char *name,
+                   const char *mpi_x_string, const char *mpi_y_string,
+                   const char *desc, gcry_ctx_t ctx)
+{
+  gcry_mpi_point_t point;
+  gcry_mpi_t x, y, z;
+  int result = 0;
+
+  point = gcry_mpi_ec_get_point (name, ctx, 1);
+  if (!point)
+    {
+      fail ("error getting point parameter '%s' of curve '%s'\n", name, desc);
+      return 1;
+    }
+  if (debug)
+    print_point (name, point);
+
+  x = gcry_mpi_new (0);
+  y = gcry_mpi_new (0);
+  z = gcry_mpi_new (0);
+  gcry_mpi_point_snatch_get (x, y, z, point);
+  if (cmp_mpihex (x, mpi_x_string))
+    {
+      fail ("x coordinate of '%s' of curve '%s' does not match\n", name, desc);
+      result = 1;
+    }
+  if (cmp_mpihex (y, mpi_y_string))
+    {
+      fail ("y coordinate of '%s' of curve '%s' does not match\n", name, desc);
+      result = 1;
+    }
+  if (cmp_mpihex (z, "01"))
+    {
+      fail ("z coordinate of '%s' of curve '%s' is not 1\n", name, desc);
+      result = 1;
+    }
+  gcry_mpi_release (x);
+  gcry_mpi_release (y);
+  gcry_mpi_release (z);
+  return result;
+}
+
+
+static void
+context_param (void)
+{
+  gpg_error_t err;
+  int idx;
+  gcry_ctx_t ctx = NULL;
+  gcry_mpi_t q, d;
+  gcry_sexp_t keyparam;
+
+  wherestr = "context_param";
+
+  show ("checking standard curves\n");
+  for (idx=0; test_curve[idx].desc; idx++)
+    {
+      gcry_ctx_release (ctx);
+      err = gcry_mpi_ec_new (&ctx, NULL, test_curve[idx].desc);
+      if (err)
+        {
+          fail ("can't create context for curve '%s': %s\n",
+                test_curve[idx].desc, gpg_strerror (err));
+          continue;
+        }
+      if (get_and_cmp_mpi ("p", test_curve[idx].p, test_curve[idx].desc, ctx))
+        continue;
+      if (get_and_cmp_mpi ("a", test_curve[idx].a, test_curve[idx].desc, ctx))
+        continue;
+      if (get_and_cmp_mpi ("b", test_curve[idx].b, test_curve[idx].desc, ctx))
+        continue;
+      if (get_and_cmp_mpi ("g.x",test_curve[idx].g_x, test_curve[idx].desc,ctx))
+        continue;
+      if (get_and_cmp_mpi ("g.y",test_curve[idx].g_y, test_curve[idx].desc,ctx))
+        continue;
+      if (get_and_cmp_mpi ("n", test_curve[idx].n, test_curve[idx].desc, ctx))
+        continue;
+      if (get_and_cmp_point ("g", test_curve[idx].g_x, test_curve[idx].g_y,
+                             test_curve[idx].desc, ctx))
+        continue;
+
+    }
+
+  show ("checking sample public key (nistp256)\n");
+  q = hex2mpi (sample_p256_q);
+  err = gcry_sexp_build (&keyparam, NULL,
+                        "(public-key(ecc(curve %s)(q %m)))",
+                        "NIST P-256", q);
+  if (err)
+    die ("gcry_sexp_build failed: %s\n", gpg_strerror (err));
+  gcry_mpi_release (q);
+
+  /* We can't call gcry_pk_testkey because it is only implemented for
+     private keys.  */
+  /* err = gcry_pk_testkey (keyparam); */
+  /* if (err) */
+  /*   fail ("gcry_pk_testkey failed for sample public key: %s\n", */
+  /*         gpg_strerror (err)); */
+
+  gcry_ctx_release (ctx);
+  err = gcry_mpi_ec_new (&ctx, keyparam, NULL);
+  if (err)
+    fail ("gcry_mpi_ec_new failed for sample public key (nistp256): %s\n",
+          gpg_strerror (err));
+  else
+    {
+      gcry_sexp_t sexp;
+
+      get_and_cmp_mpi ("q", sample_p256_q, "nistp256", ctx);
+      get_and_cmp_point ("q", sample_p256_q_x, sample_p256_q_y, "nistp256",
+                         ctx);
+
+      /* Delete Q.  */
+      err = gcry_mpi_ec_set_mpi ("q", NULL, ctx);
+      if (err)
+        fail ("clearing Q for nistp256 failed: %s\n", gpg_strerror (err));
+      if (gcry_mpi_ec_get_mpi ("q", ctx, 0))
+        fail ("clearing Q for nistp256 did not work\n");
+
+      /* Set Q again.  */
+      q = hex2mpi (sample_p256_q);
+      err = gcry_mpi_ec_set_mpi ("q", q, ctx);
+      if (err)
+        fail ("setting Q for nistp256 failed: %s\n", gpg_strerror (err));
+      get_and_cmp_mpi ("q", sample_p256_q, "nistp256(2)", ctx);
+      gcry_mpi_release (q);
+
+      /* Get as s-expression.  */
+      err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
+      if (err)
+        fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err));
+      else if (debug)
+        print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp);
+      gcry_sexp_release (sexp);
+
+      err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx);
+      if (err)
+        fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n",
+              gpg_strerror (err));
+      else if (debug)
+        print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp);
+      gcry_sexp_release (sexp);
+
+      err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx);
+      if (gpg_err_code (err) != GPG_ERR_NO_SECKEY)
+        fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n",
+              gpg_strerror (err));
+      gcry_sexp_release (sexp);
+    }
+
+  show ("checking sample public key (Ed25519)\n");
+  q = hex2mpi (sample_ed25519_q);
+  gcry_sexp_release (keyparam);
+  err = gcry_sexp_build (&keyparam, NULL,
+                        "(public-key(ecc(curve %s)(flags eddsa)(q %m)))",
+                        "Ed25519", q);
+  if (err)
+    die ("gcry_sexp_build failed: %s\n", gpg_strerror (err));
+  gcry_mpi_release (q);
+
+  /* We can't call gcry_pk_testkey because it is only implemented for
+     private keys.  */
+  /* err = gcry_pk_testkey (keyparam); */
+  /* if (err) */
+  /*   fail ("gcry_pk_testkey failed for sample public key: %s\n", */
+  /*         gpg_strerror (err)); */
+
+  gcry_ctx_release (ctx);
+  err = gcry_mpi_ec_new (&ctx, keyparam, NULL);
+  if (err)
+    fail ("gcry_mpi_ec_new failed for sample public key: %s\n",
+          gpg_strerror (err));
+  else
+    {
+      gcry_sexp_t sexp;
+
+      get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519", ctx);
+      get_and_cmp_point ("q", sample_ed25519_q_x, sample_ed25519_q_y,
+                         "Ed25519", ctx);
+      get_and_cmp_mpi ("q@eddsa", sample_ed25519_q_eddsa, "Ed25519", ctx);
+
+      /* Set d to see whether Q is correctly re-computed.  */
+      d = hex2mpi (sample_ed25519_d);
+      err = gcry_mpi_ec_set_mpi ("d", d, ctx);
+      if (err)
+        fail ("setting d for Ed25519 failed: %s\n", gpg_strerror (err));
+      gcry_mpi_release (d);
+      get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519(recompute Q)", ctx);
+
+      /* Delete Q by setting d and then clearing d.  The clearing is
+         required so that we can check whether Q has been cleared and
+         because further tests only expect a public key.  */
+      d = hex2mpi (sample_ed25519_d);
+      err = gcry_mpi_ec_set_mpi ("d", d, ctx);
+      if (err)
+        fail ("setting d for Ed25519 failed: %s\n", gpg_strerror (err));
+      gcry_mpi_release (d);
+      err = gcry_mpi_ec_set_mpi ("d", NULL, ctx);
+      if (err)
+        fail ("setting d for Ed25519 failed(2): %s\n", gpg_strerror (err));
+      if (gcry_mpi_ec_get_mpi ("q", ctx, 0))
+        fail ("setting d for Ed25519 did not reset Q\n");
+
+      /* Set Q again.  We need to use an opaque MPI here because
+         sample_ed25519_q is in uncompressed format which can only be
+         auto-detected if passed opaque.  */
+      q = hex2mpiopa (sample_ed25519_q);
+      err = gcry_mpi_ec_set_mpi ("q", q, ctx);
+      if (err)
+        fail ("setting Q for Ed25519 failed: %s\n", gpg_strerror (err));
+      gcry_mpi_release (q);
+      get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519(2)", ctx);
+
+      /* Get as s-expression.  */
+      err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
+      if (err)
+        fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err));
+      else if (debug)
+        print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp);
+      gcry_sexp_release (sexp);
+
+      err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx);
+      if (err)
+        fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n",
+              gpg_strerror (err));
+      else if (debug)
+        print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp);
+      gcry_sexp_release (sexp);
+
+      err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx);
+      if (gpg_err_code (err) != GPG_ERR_NO_SECKEY)
+        fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n",
+              gpg_strerror (err));
+      gcry_sexp_release (sexp);
+
+    }
+
+  gcry_ctx_release (ctx);
+  gcry_sexp_release (keyparam);
+}
+
+
+
+
+/* Create a new point from (X,Y,Z) given as hex strings.  */
+gcry_mpi_point_t
+make_point (const char *x, const char *y, const char *z)
+{
+  gcry_mpi_point_t point;
+
+  point = gcry_mpi_point_new (0);
+  gcry_mpi_point_snatch_set (point, hex2mpi (x), hex2mpi (y), hex2mpi (z));
+
+  return point;
+}
+
+
+/* This tests checks that the low-level EC API yields the same result
+   as using the high level API.  The values have been taken from a
+   test run using the high level API.  */
+static void
+basic_ec_math (void)
+{
+  gpg_error_t err;
+  gcry_ctx_t ctx;
+  gcry_mpi_t P, A;
+  gcry_mpi_point_t G, Q;
+  gcry_mpi_t d;
+  gcry_mpi_t x, y, z;
+
+  wherestr = "basic_ec_math";
+  show ("checking basic math functions for EC\n");
+
+  P = hex2mpi ("0xfffffffffffffffffffffffffffffffeffffffffffffffff");
+  A = hex2mpi ("0xfffffffffffffffffffffffffffffffefffffffffffffffc");
+  G = make_point ("188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012",
+                  "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811",
+                  "1");
+  d = hex2mpi ("D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D");
+  Q = gcry_mpi_point_new (0);
+
+  err = ec_p_new (&ctx, P, A);
+  if (err)
+    die ("ec_p_new failed: %s\n", gpg_strerror (err));
+
+  x = gcry_mpi_new (0);
+  y = gcry_mpi_new (0);
+  z = gcry_mpi_new (0);
+
+  {
+    /* A quick check that multiply by zero works.  */
+    gcry_mpi_t tmp;
+
+    tmp = gcry_mpi_new (0);
+    gcry_mpi_ec_mul (Q, tmp, G, ctx);
+    gcry_mpi_release (tmp);
+    gcry_mpi_point_get (x, y, z, Q);
+    if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 0)
+        || gcry_mpi_cmp_ui (z, 0))
+      fail ("multiply a point by zero failed\n");
+  }
+
+  gcry_mpi_ec_mul (Q, d, G, ctx);
+  gcry_mpi_point_get (x, y, z, Q);
+  if (cmp_mpihex (x, "222D9EC717C89D047E0898C9185B033CD11C0A981EE6DC66")
+      || cmp_mpihex (y, "605DE0A82D70D3E0F84A127D0739ED33D657DF0D054BFDE8")
+      || cmp_mpihex (z, "00B06B519071BC536999AC8F2D3934B3C1FC9EACCD0A31F88F"))
+    fail ("computed public key does not match\n");
+  if (debug)
+    {
+      print_mpi ("Q.x", x);
+      print_mpi ("Q.y", y);
+      print_mpi ("Q.z", z);
+    }
+
+  if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
+    fail ("failed to get affine coordinates\n");
+  if (cmp_mpihex (x, "008532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE")
+      || cmp_mpihex (y, "00C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966"))
+    fail ("computed affine coordinates of public key do not match\n");
+  if (debug)
+    {
+      print_mpi ("q.x", x);
+      print_mpi ("q.y", y);
+    }
+
+  gcry_mpi_release (z);
+  gcry_mpi_release (y);
+  gcry_mpi_release (x);
+  gcry_mpi_point_release (Q);
+  gcry_mpi_release (d);
+  gcry_mpi_point_release (G);
+  gcry_mpi_release (A);
+  gcry_mpi_release (P);
+  gcry_ctx_release (ctx);
+}
+
+
+/* This is the same as basic_ec_math but uses more advanced
+   features.  */
+static void
+basic_ec_math_simplified (void)
+{
+  gpg_error_t err;
+  gcry_ctx_t ctx;
+  gcry_mpi_point_t G, Q;
+  gcry_mpi_t d;
+  gcry_mpi_t x, y, z;
+  gcry_sexp_t sexp;
+
+  wherestr = "basic_ec_math_simplified";
+  show ("checking basic math functions for EC (variant)\n");
+
+  d = hex2mpi ("D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D");
+  Q = gcry_mpi_point_new (0);
+
+  err = gcry_mpi_ec_new (&ctx, NULL, "NIST P-192");
+  if (err)
+    die ("gcry_mpi_ec_new failed: %s\n", gpg_strerror (err));
+  G = gcry_mpi_ec_get_point ("g", ctx, 1);
+  if (!G)
+    die ("gcry_mpi_ec_get_point(G) failed\n");
+  gcry_mpi_ec_mul (Q, d, G, ctx);
+
+  x = gcry_mpi_new (0);
+  y = gcry_mpi_new (0);
+  z = gcry_mpi_new (0);
+  gcry_mpi_point_get (x, y, z, Q);
+  if (cmp_mpihex (x, "222D9EC717C89D047E0898C9185B033CD11C0A981EE6DC66")
+      || cmp_mpihex (y, "605DE0A82D70D3E0F84A127D0739ED33D657DF0D054BFDE8")
+      || cmp_mpihex (z, "00B06B519071BC536999AC8F2D3934B3C1FC9EACCD0A31F88F"))
+    fail ("computed public key does not match\n");
+  if (debug)
+    {
+      print_mpi ("Q.x", x);
+      print_mpi ("Q.y", y);
+      print_mpi ("Q.z", z);
+    }
+
+  if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
+    fail ("failed to get affine coordinates\n");
+  if (cmp_mpihex (x, "008532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE")
+      || cmp_mpihex (y, "00C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966"))
+    fail ("computed affine coordinates of public key do not match\n");
+  if (debug)
+    {
+      print_mpi ("q.x", x);
+      print_mpi ("q.y", y);
+    }
+
+  gcry_mpi_release (z);
+  gcry_mpi_release (y);
+  gcry_mpi_release (x);
+
+  /* Let us also check whether we can update the context.  */
+  err = gcry_mpi_ec_set_point ("g", G, ctx);
+  if (err)
+    die ("gcry_mpi_ec_set_point(G) failed\n");
+  err = gcry_mpi_ec_set_mpi ("d", d, ctx);
+  if (err)
+    die ("gcry_mpi_ec_set_mpi(d) failed\n");
+
+  /* FIXME: Below we need to check that the returned S-expression is
+     as requested.  For now we use manual inspection using --debug.  */
+
+  /* Does get_sexp return the private key?  */
+  err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
+  if (err)
+    fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err));
+  else if (debug)
+    print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp);
+  gcry_sexp_release (sexp);
+
+  /* Does get_sexp return the public key if requested?  */
+  err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx);
+  if (err)
+    fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n", gpg_strerror (err));
+  else if (debug)
+    print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp);
+  gcry_sexp_release (sexp);
+
+  /* Does get_sexp return the public key after d has been deleted?  */
+  err = gcry_mpi_ec_set_mpi ("d", NULL, ctx);
+  if (err)
+    die ("gcry_mpi_ec_set_mpi(d=NULL) failed\n");
+  err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
+  if (err)
+    fail ("gcry_pubkey_get_sexp(0 w/o d) failed: %s\n", gpg_strerror (err));
+  else if (debug)
+    print_sexp ("Result of gcry_pubkey_get_sexp (0 w/o d):\n", sexp);
+  gcry_sexp_release (sexp);
+
+  /* Does get_sexp return an error after d has been deleted?  */
+  err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx);
+  if (gpg_err_code (err) != GPG_ERR_NO_SECKEY)
+    fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n",
+          gpg_strerror (err));
+  gcry_sexp_release (sexp);
+
+  /* Does get_sexp return an error after d and Q have been deleted?  */
+  err = gcry_mpi_ec_set_point ("q", NULL, ctx);
+  if (err)
+    die ("gcry_mpi_ec_set_point(q=NULL) failed\n");
+  err = gcry_pubkey_get_sexp (&sexp, 0, ctx);
+  if (gpg_err_code (err) != GPG_ERR_BAD_CRYPT_CTX)
+    fail ("gcry_pubkey_get_sexp(0 w/o Q,d) returned wrong error: %s\n",
+          gpg_strerror (err));
+  gcry_sexp_release (sexp);
+
+
+  gcry_mpi_point_release (Q);
+  gcry_mpi_release (d);
+  gcry_mpi_point_release (G);
+  gcry_ctx_release (ctx);
+}
+
+
+/* Check the math used with Twisted Edwards curves.  */
+static void
+twistededwards_math (void)
+{
+  gpg_error_t err;
+  gcry_ctx_t ctx;
+  gcry_mpi_point_t G, Q;
+  gcry_mpi_t k;
+  gcry_mpi_t w, a, x, y, z, p, n, b, I;
+
+  wherestr = "twistededwards_math";
+  show ("checking basic Twisted Edwards math\n");
+
+  err = gcry_mpi_ec_new (&ctx, NULL, "Ed25519");
+  if (err)
+    die ("gcry_mpi_ec_new failed: %s\n", gpg_strerror (err));
+
+  k = hex2mpi
+    ("2D3501E723239632802454EE5DDC406EFB0BDF18486A5BDE9C0390A9C2984004"
+     "F47252B628C953625B8DEB5DBCB8DA97AA43A1892D11FA83596F42E0D89CB1B6");
+  G = gcry_mpi_ec_get_point ("g", ctx, 1);
+  if (!G)
+    die ("gcry_mpi_ec_get_point(G) failed\n");
+  Q = gcry_mpi_point_new (0);
+
+
+  w = gcry_mpi_new (0);
+  a = gcry_mpi_new (0);
+  x = gcry_mpi_new (0);
+  y = gcry_mpi_new (0);
+  z = gcry_mpi_new (0);
+  I = gcry_mpi_new (0);
+  p = gcry_mpi_ec_get_mpi ("p", ctx, 1);
+  n = gcry_mpi_ec_get_mpi ("n", ctx, 1);
+  b = gcry_mpi_ec_get_mpi ("b", ctx, 1);
+
+  /* Check: 2^{p-1} mod p == 1 */
+  gcry_mpi_sub_ui (a, p, 1);
+  gcry_mpi_powm (w, GCRYMPI_CONST_TWO, a, p);
+  if (gcry_mpi_cmp_ui (w, 1))
+    fail ("failed assertion: 2^{p-1} mod p == 1\n");
+
+  /* Check: p % 4 == 1 */
+  gcry_mpi_mod (w, p, GCRYMPI_CONST_FOUR);
+  if (gcry_mpi_cmp_ui (w, 1))
+    fail ("failed assertion: p % 4 == 1\n");
+
+  /* Check: 2^{n-1} mod n == 1 */
+  gcry_mpi_sub_ui (a, n, 1);
+  gcry_mpi_powm (w, GCRYMPI_CONST_TWO, a, n);
+  if (gcry_mpi_cmp_ui (w, 1))
+    fail ("failed assertion: 2^{n-1} mod n == 1\n");
+
+  /* Check: b^{(p-1)/2} mod p == p-1 */
+  gcry_mpi_sub_ui (a, p, 1);
+  gcry_mpi_div (x, NULL, a, GCRYMPI_CONST_TWO, -1);
+  gcry_mpi_powm (w, b, x, p);
+  gcry_mpi_abs (w);
+  if (gcry_mpi_cmp (w, a))
+    fail ("failed assertion: b^{(p-1)/2} mod p == p-1\n");
+
+  /* I := 2^{(p-1)/4} mod p */
+  gcry_mpi_sub_ui (a, p, 1);
+  gcry_mpi_div (x, NULL, a, GCRYMPI_CONST_FOUR, -1);
+  gcry_mpi_powm (I, GCRYMPI_CONST_TWO, x, p);
+
+  /* Check: I^2 mod p == p-1 */
+  gcry_mpi_powm (w, I, GCRYMPI_CONST_TWO, p);
+  if (gcry_mpi_cmp (w, a))
+    fail ("failed assertion: I^2 mod p == p-1\n");
+
+  /* Check: G is on the curve */
+  if (!gcry_mpi_ec_curve_point (G, ctx))
+    fail ("failed assertion: G is on the curve\n");
+
+  /* Check: nG == (0,1) */
+  gcry_mpi_ec_mul (Q, n, G, ctx);
+  if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
+    fail ("failed to get affine coordinates\n");
+  if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 1))
+    fail ("failed assertion: nG == (0,1)\n");
+
+  /* Now two arbitrary point operations taken from the ed25519.py
+     sample data.  */
+  gcry_mpi_release (a);
+  a = hex2mpi
+    ("4f71d012df3c371af3ea4dc38385ca5bb7272f90cb1b008b3ed601c76de1d496"
+     "e30cbf625f0a756a678d8f256d5325595cccc83466f36db18f0178eb9925edd3");
+  gcry_mpi_ec_mul (Q, a, G, ctx);
+  if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
+    fail ("failed to get affine coordinates\n");
+  if (cmp_mpihex (x, ("157f7361c577aad36f67ed33e38dc7be"
+                      "00014fecc2165ca5cee9eee19fe4d2c1"))
+      || cmp_mpihex (y, ("5a69dbeb232276b38f3f5016547bb2a2"
+                         "4025645f0b820e72b8cad4f0a909a092")))
+    {
+      fail ("sample point multiply failed:\n");
+      print_mpi ("r", a);
+      print_mpi ("Rx", x);
+      print_mpi ("Ry", y);
+    }
+
+  gcry_mpi_release (a);
+  a = hex2mpi
+    ("2d3501e723239632802454ee5ddc406efb0bdf18486a5bde9c0390a9c2984004"
+     "f47252b628c953625b8deb5dbcb8da97aa43a1892d11fa83596f42e0d89cb1b6");
+  gcry_mpi_ec_mul (Q, a, G, ctx);
+  if (gcry_mpi_ec_get_affine (x, y, Q, ctx))
+    fail ("failed to get affine coordinates\n");
+  if (cmp_mpihex (x, ("6218e309d40065fcc338b3127f468371"
+                      "82324bd01ce6f3cf81ab44e62959c82a"))
+      || cmp_mpihex (y, ("5501492265e073d874d9e5b81e7f8784"
+                         "8a826e80cce2869072ac60c3004356e5")))
+    {
+      fail ("sample point multiply failed:\n");
+      print_mpi ("r", a);
+      print_mpi ("Rx", x);
+      print_mpi ("Ry", y);
+    }
+
+
+  gcry_mpi_release (I);
+  gcry_mpi_release (b);
+  gcry_mpi_release (n);
+  gcry_mpi_release (p);
+  gcry_mpi_release (w);
+  gcry_mpi_release (a);
+  gcry_mpi_release (x);
+  gcry_mpi_release (y);
+  gcry_mpi_release (z);
+  gcry_mpi_point_release (Q);
+  gcry_mpi_point_release (G);
+  gcry_mpi_release (k);
+  gcry_ctx_release (ctx);
+}
+
+
+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;
+
+  if (!gcry_check_version (GCRYPT_VERSION))
+    die ("version mismatch\n");
+
+  gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+  gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+  if (debug)
+    gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
+  gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
+
+  set_get_point ();
+  context_alloc ();
+  context_param ();
+  basic_ec_math ();
+  basic_ec_math_simplified ();
+  twistededwards_math ();
+
+  show ("All tests completed. Errors: %d\n", error_count);
+  return error_count ? 1 : 0;
+}
index e14ae7b..0dc9092 100644 (file)
@@ -44,18 +44,21 @@ test_sexp ( int argc, char **argv )
     size_t n;
     char *buf;
 
-    if ( gcry_mpi_scan( &key[0], GCRYMPI_FMT_HEX, elg_testkey1.p, NULL ) )
+    (void)argc;
+    (void)argv;
+
+    if ( gcry_mpi_scan( &key[0], GCRYMPI_FMT_HEX, elg_testkey1.p, 0, NULL ) )
        BUG();
-    if ( gcry_mpi_scan( &key[1], GCRYMPI_FMT_HEX, elg_testkey1.g, NULL ) )
+    if ( gcry_mpi_scan( &key[1], GCRYMPI_FMT_HEX, elg_testkey1.g, 0, NULL ) )
        BUG();
-    if ( gcry_mpi_scan( &key[2], GCRYMPI_FMT_HEX, elg_testkey1.y, NULL ) )
+    if ( gcry_mpi_scan( &key[2], GCRYMPI_FMT_HEX, elg_testkey1.y, 0, NULL ) )
        BUG();
 
     /* get nbits from a key */
     rc = gcry_sexp_build ( &sexp, NULL,
                           "(public-key(elg(p%m)(g%m)(y%m)))",
                                  key[0], key[1], key[2] );
-    fputs ( "DUMP of PK:\n", stderr );
+    fprintf (stderr, "DUMP of PK (rc=%d):\n", rc);
     gcry_sexp_dump ( sexp );
     {  gcry_sexp_t x;
        x = gcry_sexp_cdr ( sexp );
@@ -80,6 +83,9 @@ test_genkey ( int argc, char **argv )
     int rc, nbits = 1024;
     gcry_sexp_t s_parms, s_key;
 
+    (void)argc;
+    (void)argv;
+
     gcry_control( GCRYCTL_INIT_SECMEM, 16384, 0 );
     rc = gcry_sexp_build ( &s_parms, NULL, "(genkey(dsa(nbits %d)))", nbits );
     rc = gcry_pk_genkey( &s_key, s_parms );
@@ -95,18 +101,26 @@ test_genkey ( int argc, char **argv )
 int
 main( int argc, char **argv )
 {
-    if ( argc < 2 )
-       printf("%s\n", gcry_check_version ( NULL ) );
-    else if ( !strcmp ( argv[1], "version") )
-       printf("%s\n", gcry_check_version ( argc > 2 ? argv[2] : NULL ) );
-    else if ( !strcmp ( argv[1], "sexp" ) )
-       test_sexp ( argc-2, argv+2 );
-    else if ( !strcmp ( argv[1], "genkey" ) )
-       test_genkey ( argc-2, argv+2 );
-    else {
-       fprintf (stderr, "usage: testapi mode-string [mode-args]\n");
-       return 1;
+  const char *s;
+
+  if ( argc < 2 )
+    {
+      s = gcry_check_version (NULL);
+      printf("%s\n", s? s : "(null)");
+    }
+  else if ( !strcmp ( argv[1], "version") )
+    {
+      s = gcry_check_version (argc > 2 ? argv[2] : NULL );
+      printf("%s\n", s? s : "(null)");
     }
+  else if ( !strcmp ( argv[1], "sexp" ) )
+    test_sexp ( argc-2, argv+2 );
+  else if ( !strcmp ( argv[1], "genkey" ) )
+    test_genkey ( argc-2, argv+2 );
+  else {
+    fprintf (stderr, "usage: testapi mode-string [mode-args]\n");
+    return 1;
+  }
 
-    return 0;
+  return 0;
 }
index 73d3d6e..5a02c26 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
-#include "../src/gcrypt.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;
@@ -42,6 +76,8 @@ info (const char *format, ...)
       va_start( arg_ptr, format ) ;
       vfprintf (stderr, format, arg_ptr );
       va_end(arg_ptr);
+      if (*format && format[strlen(format)-1] != '\n')
+        putc ('\n', stderr);
     }
 }
 
@@ -54,10 +90,110 @@ fail ( const char *format, ... )
     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++;
 }
 
 
+
+/* 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 gcry_mpi_t
+hex2mpi (const char *string)
+{
+  gpg_error_t err;
+  gcry_mpi_t val;
+
+  err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
+  if (err)
+    die ("hex2mpi '%s' failed: %s\n", string, gpg_strerror (err));
+  return val;
+}
+
+static gcry_mpi_t
+hex2mpiopa (const char *string)
+{
+  char *buffer;
+  size_t buflen;
+  gcry_mpi_t val;
+
+  buffer = hex2buffer (string, &buflen);
+  if (!buffer)
+    die ("hex2mpiopa '%s' failed: parser error\n", string);
+  val = gcry_mpi_set_opaque (NULL, buffer, buflen*8);
+  if (!buffer)
+    die ("hex2mpiopa '%s' failed: set_opaque error%s\n", string);
+  return val;
+}
+
+
+/* Compare A to B, where B is given as a hex string.  */
+static int
+cmp_mpihex (gcry_mpi_t a, const char *b)
+{
+  gcry_mpi_t bval;
+  int res;
+
+  if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
+    bval = hex2mpiopa (b);
+  else
+    bval = hex2mpi (b);
+  res = gcry_mpi_cmp (a, bval);
+  gcry_mpi_release (bval);
+  return res;
+}
+
+/* Compare A to B, where A is a buffer and B a hex string.  */
+static int
+cmp_bufhex (const void *a, size_t alen, const char *b)
+{
+  void *bbuf;
+  size_t blen;
+  int res;
+
+  if (!a && !b)
+    return 0;
+  if (a && !b)
+    return 1;
+  if (!a && b)
+    return -1;
+
+  bbuf = hex2buffer (b, &blen);
+  if (!bbuf)
+    die ("cmp_bufhex: error converting hex string\n");
+  if (alen != blen)
+    return alen < blen? -1 : 1;
+  res = memcmp (a, bbuf, alen);
+  xfree (bbuf);
+  return res;
+}
+
+
+\f
 /* fixme: we need better tests */
 static void
 basic (void)
@@ -89,44 +225,52 @@ basic (void)
 
   for (pass=0;;pass++)
     {
+      gcry_mpi_t m;
+
       switch (pass)
         {
         case 0:
           string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
                     "(q #61626364656667#) (g %m)))");
 
-          if ( gcry_sexp_build (&sexp, NULL, string,
-                                gcry_mpi_set_ui (NULL, 42)) )
+          m = gcry_mpi_set_ui (NULL, 42);
+          if ( gcry_sexp_build (&sexp, NULL, string, m ) )
             {
+              gcry_mpi_release (m);
               fail (" scanning `%s' failed\n", string);
               return;
             }
+          gcry_mpi_release (m);
           break;
 
         case 1:
           string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
                     "(q %b) (g %m)))");
 
+          m = gcry_mpi_set_ui (NULL, 42);
           if ( gcry_sexp_build (&sexp, NULL, string,
-                                15, "foo\0\x01\0x02789012345",
-                                gcry_mpi_set_ui (NULL, 42)) )
+                                15, "foo\0\x01\0x02789012345", m) )
             {
+              gcry_mpi_release (m);
               fail (" scanning `%s' failed\n", string);
               return;
             }
+          gcry_mpi_release (m);
           break;
 
         case 2:
           string = ("(public-key (dsa (p #41424344#) (y silly_y_value) "
                     "(q %b) (g %m)))");
 
+          m = gcry_mpi_set_ui (NULL, 17);
           if ( gcry_sexp_build (&sexp, NULL, string,
-                                secure_buffer_len, secure_buffer,
-                                gcry_mpi_set_ui (NULL, 17)) )
+                                secure_buffer_len, secure_buffer, m) )
             {
+              gcry_mpi_release (m);
               fail (" scanning `%s' failed\n", string);
               return;
             }
+          gcry_mpi_release (m);
           if (!gcry_is_secure (sexp))
             fail ("gcry_sexp_build did not switch to secure memory\n");
           break;
@@ -144,13 +288,15 @@ basic (void)
 
             string = ("(public-key (dsa (p #41424344#) (parm %S) "
                       "(y dummy)(q %b) (g %m)))");
+            m = gcry_mpi_set_ui (NULL, 17);
             if ( gcry_sexp_build (&sexp, NULL, string, help_sexp,
-                                  secure_buffer_len, secure_buffer,
-                                  gcry_mpi_set_ui (NULL, 17)) )
+                                  secure_buffer_len, secure_buffer, m) )
               {
+                gcry_mpi_release (m);
                 fail (" scanning `%s' failed\n", string);
                 return;
               }
+            gcry_mpi_release (m);
             gcry_sexp_release (help_sexp);
           }
           break;
@@ -181,21 +327,25 @@ basic (void)
           p = gcry_sexp_nth_data (s1, 0, &n);
           if (!p)
             {
+              gcry_sexp_release (s1);
               fail ("no car for `%s'\n", token);
               continue;
             }
-          info ("car=`%.*s'\n", (int)n, p);
+          /* info ("car=`%.*s'\n", (int)n, p); */
 
           s2 = gcry_sexp_cdr (s1);
           if (!s2)
             {
+              gcry_sexp_release (s1);
               fail ("no cdr for `%s'\n", token);
               continue;
             }
 
           p = gcry_sexp_nth_data (s2, 0, &n);
+          gcry_sexp_release (s2);
           if (p)
             {
+              gcry_sexp_release (s1);
               fail ("data at car of `%s'\n", token);
               continue;
             }
@@ -203,6 +353,7 @@ basic (void)
           if (parm)
             {
               s2 = gcry_sexp_find_token (s1, parm, strlen (parm));
+              gcry_sexp_release (s1);
               if (!s2)
                 {
                   fail ("didn't found `%s'\n", parm);
@@ -211,25 +362,31 @@ basic (void)
               p = gcry_sexp_nth_data (s2, 0, &n);
               if (!p)
                 {
+                  gcry_sexp_release (s2);
                   fail("no car for `%s'\n", parm );
                   continue;
                 }
-              info ("car=`%.*s'\n", (int)n, p);
+              /* info ("car=`%.*s'\n", (int)n, p); */
               p = gcry_sexp_nth_data (s2, 1, &n);
               if (!p)
                 {
+                  gcry_sexp_release (s2);
                   fail("no cdr for `%s'\n", parm );
                   continue;
                 }
-              info ("cdr=`%.*s'\n", (int)n, p);
+              /* info ("cdr=`%.*s'\n", (int)n, p); */
 
               a = gcry_sexp_nth_mpi (s2, 0, GCRYMPI_FMT_USG);
+              gcry_sexp_release (s2);
               if (!a)
                 {
                   fail("failed to cdr the mpi for `%s'\n", parm);
                   continue;
                 }
+              gcry_mpi_release (a);
             }
+          else
+            gcry_sexp_release (s1);
         }
 
       gcry_sexp_release (sexp);
@@ -436,6 +593,524 @@ check_sscan (void)
 }
 
 
+static void
+check_extract_param (void)
+{
+  /* This sample data is a real key but with some parameters of the
+     public key modified.  */
+  static char sample1[] =
+    "(key-data"
+    " (public-key"
+    "  (ecc"
+    "   (curve Ed25519)"
+    "   (p #6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED#)"
+    "   (a #EF#)"
+    "   (b #C2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6#)"
+    "   (g #14"
+    "       216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
+    "       6666666666666666666666666666666666666666666666666666666666666658#)"
+    "   (n #0000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED#)"
+    "   (q #20B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62#)"
+    "))"
+    " (private-key"
+    "  (ecc"
+    "   (curve Ed25519)"
+    "   (p #7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED#)"
+    "   (a #FF#)"
+    "   (b #D2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6#)"
+    "   (g #04"
+    "       216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
+    "       6666666666666666666666666666666666666666666666666666666666666658#)"
+    "   (n #1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED#)"
+    "   (q #30B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62#)"
+    "   (d #56BEA284A22F443A7AEA8CEFA24DA5055CDF1D490C94D8C568FE0802C9169276#)"
+    ")))";
+
+  static char sample1_p[] =
+    "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED";
+  static char sample1_px[] =
+    "6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED";
+  static char sample1_a[] = "FF";
+  static char sample1_ax[] = "EF";
+  static char sample1_b[] =
+    "D2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6";
+  static char sample1_bx[] =
+    "C2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6";
+  static char sample1_g[] =
+    "04"
+    "216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
+    "6666666666666666666666666666666666666666666666666666666666666658";
+  static char sample1_gx[] =
+    "14"
+    "216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
+    "6666666666666666666666666666666666666666666666666666666666666658";
+  static char sample1_n[] =
+    "1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED";
+  static char sample1_nx[] =
+    "0000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED";
+  static char sample1_q[] =
+    "30B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62";
+  static char sample1_qx[] =
+    "20B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62";
+  static char sample1_d[] =
+    "56BEA284A22F443A7AEA8CEFA24DA5055CDF1D490C94D8C568FE0802C9169276";
+
+  static struct {
+    const char *sexp_str;
+    const char *path;
+    const char *list;
+    int nparam;
+    gpg_err_code_t expected_err;
+    const char *exp_p;
+    const char *exp_a;
+    const char *exp_b;
+    const char *exp_g;
+    const char *exp_n;
+    const char *exp_q;
+    const char *exp_d;
+  } tests[] = {
+    {
+      sample1,
+      NULL,
+      "pabgnqd", 6,
+      GPG_ERR_MISSING_VALUE,
+    },
+    {
+      sample1,
+      NULL,
+      "pabgnq", 7,
+      GPG_ERR_INV_ARG
+    },
+    {
+      sample1,
+      NULL,
+      "pab'gnq", 7,
+      GPG_ERR_SYNTAX
+    },
+    {
+      sample1,
+      NULL,
+      "pab''gnq", 7,
+      GPG_ERR_SYNTAX
+    },
+    {
+      sample1,
+      NULL,
+      "pabgnqd", 7,
+      0,
+      sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
+      sample1_qx, sample1_d
+    },
+    {
+      sample1,
+      NULL,
+      "  pab\tg nq\nd  ", 7,
+      0,
+      sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
+      sample1_qx, sample1_d
+    },
+    {
+      sample1,
+      NULL,
+      "abg", 3,
+      0,
+      sample1_ax, sample1_bx, sample1_gx
+    },
+    {
+      sample1,
+      NULL,
+      "ab'g'", 3,
+      0,
+      sample1_ax, sample1_bx, sample1_gx
+    },
+    {
+      sample1,
+      NULL,
+      "x?abg", 4,
+      0,
+      NULL, sample1_ax, sample1_bx, sample1_gx
+    },
+    {
+      sample1,
+      NULL,
+      "p?abg", 4,
+      GPG_ERR_USER_1,
+      NULL, sample1_ax, sample1_bx, sample1_gx
+    },
+    {
+      sample1,
+      NULL,
+      "pax?gnqd", 7,
+      0,
+      sample1_px, sample1_ax, NULL, sample1_gx, sample1_nx,
+      sample1_qx, sample1_d
+    },
+    {
+      sample1,
+      "public-key",
+      "pabgnqd", 7,
+      GPG_ERR_NO_OBJ,  /* d is not in public key.  */
+      sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
+      sample1_qx, sample1_d
+    },
+    {
+      sample1,
+      "private-key",
+      "pabgnqd", 7,
+      0,
+      sample1_p, sample1_a, sample1_b, sample1_g, sample1_n,
+      sample1_q, sample1_d
+    },
+    {
+      sample1,
+      "public-key!ecc",
+      "pabgnq", 6,
+      0,
+      sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
+      sample1_qx
+    },
+    {
+      sample1,
+      "public-key!ecc!foo",
+      "pabgnq", 6,
+      GPG_ERR_NOT_FOUND
+    },
+    {
+      sample1,
+      "public-key!!ecc",
+      "pabgnq", 6,
+      GPG_ERR_NOT_FOUND
+    },
+    {
+      sample1,
+      "private-key",
+      "pa/bgnqd", 7,
+      0,
+      sample1_p, sample1_a, sample1_b, sample1_g, sample1_n,
+      sample1_q, sample1_d
+    },
+    {
+      sample1,
+      "private-key",
+      "p-a+bgnqd", 7,
+      0,
+      sample1_p, "-01", sample1_b, sample1_g, sample1_n,
+      sample1_q, sample1_d
+    },
+    {NULL}
+  };
+  int idx, i;
+  const char *paramstr;
+  int paramidx;
+  gpg_error_t err;
+  gcry_sexp_t sxp;
+  gcry_mpi_t mpis[7];
+  gcry_buffer_t ioarray[7];
+  char iobuffer[200];
+
+  info ("checking gcry_sexp_extract_param\n");
+  for (idx=0; tests[idx].sexp_str; idx++)
+    {
+      err = gcry_sexp_new (&sxp, tests[idx].sexp_str, 0, 1);
+      if (err)
+        die ("converting string to sexp failed: %s", gpg_strerror (err));
+
+      memset (mpis, 0, sizeof mpis);
+      switch (tests[idx].nparam)
+        {
+        case 0:
+          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
+                                         NULL);
+          break;
+        case 1:
+          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
+                                         mpis+0, NULL);
+          break;
+        case 2:
+          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
+                                         mpis+0, mpis+1, NULL);
+          break;
+        case 3:
+          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
+                                         mpis+0, mpis+1, mpis+2, NULL);
+          break;
+        case 4:
+          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
+                                         mpis+0, mpis+1, mpis+2, mpis+3, NULL);
+          break;
+        case 5:
+          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
+                                         mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
+                                         NULL);
+          break;
+        case 6:
+          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
+                                         mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
+                                         mpis+5, NULL);
+          break;
+        case 7:
+          err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
+                                         mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
+                                         mpis+5, mpis+6, NULL);
+          break;
+        default:
+          die ("test %d: internal error", idx);
+        }
+
+      if (tests[idx].expected_err
+          && tests[idx].expected_err != GPG_ERR_USER_1)
+        {
+          if (tests[idx].expected_err != gpg_err_code (err))
+            fail ("gcry_sexp_extract_param test %d failed: "
+                  "expected error '%s' - got '%s'", idx,
+                  gpg_strerror (tests[idx].expected_err),gpg_strerror (err));
+
+        }
+      else if (err)
+        {
+          fail ("gcry_sexp_extract_param test %d failed: %s",
+                idx, gpg_strerror (err));
+        }
+      else /* No error - check the extracted values.  */
+        {
+          for (paramidx=0; paramidx < DIM (mpis); paramidx++)
+            {
+              switch (paramidx)
+                {
+                case 0: paramstr = tests[idx].exp_p; break;
+                case 1: paramstr = tests[idx].exp_a; break;
+                case 2: paramstr = tests[idx].exp_b; break;
+                case 3: paramstr = tests[idx].exp_g; break;
+                case 4: paramstr = tests[idx].exp_n; break;
+                case 5: paramstr = tests[idx].exp_q; break;
+                case 6: paramstr = tests[idx].exp_d; break;
+                default:
+                  die ("test %d: internal error: bad param %d",
+                       idx, paramidx);
+                }
+
+              if (tests[idx].expected_err == GPG_ERR_USER_1
+                  && mpis[paramidx] && !paramstr && paramidx == 0)
+                ; /* Okay  Special case error for param 0.  */
+              else if (!mpis[paramidx] && !paramstr)
+                ; /* Okay.  */
+              else if (!mpis[paramidx] && paramstr)
+                fail ("test %d: value for param %d expected but not returned",
+                      idx, paramidx);
+              else if (mpis[paramidx] && !paramstr)
+                fail ("test %d: value for param %d not expected",
+                      idx, paramidx);
+              else if (cmp_mpihex (mpis[paramidx], paramstr))
+                {
+                  fail ("test %d: param %d mismatch", idx, paramidx);
+                  gcry_log_debug    ("expected: %s\n", paramstr);
+                  gcry_log_debugmpi ("     got", mpis[paramidx]);
+                }
+              else if (tests[idx].expected_err && paramidx == 0)
+                fail ("test %d: param %d: expected error '%s' - got 'Success'",
+                      idx, paramidx, gpg_strerror (tests[idx].expected_err));
+            }
+
+        }
+
+      for (i=0; i < DIM (mpis); i++)
+        gcry_mpi_release (mpis[i]);
+      gcry_sexp_release (sxp);
+    }
+
+  info ("checking gcry_sexp_extract_param/desc\n");
+
+  memset (ioarray, 0, sizeof ioarray);
+
+  err = gcry_sexp_new (&sxp, sample1, 0, 1);
+  if (err)
+    die ("converting string to sexp failed: %s", gpg_strerror (err));
+
+  ioarray[1].size = sizeof iobuffer;
+  ioarray[1].data = iobuffer;
+  ioarray[1].off  = 0;
+  ioarray[2].size = sizeof iobuffer;
+  ioarray[2].data = iobuffer;
+  ioarray[2].off  = 50;
+  assert (ioarray[2].off < sizeof iobuffer);
+  err = gcry_sexp_extract_param (sxp, "key-data!private-key", "&pab",
+                                 ioarray+0, ioarray+1, ioarray+2, NULL);
+  if (err)
+    fail ("gcry_sexp_extract_param with desc failed: %s", gpg_strerror (err));
+  else
+    {
+      if (!ioarray[0].data)
+        fail ("gcry_sexp_extract_param/desc failed: no P");
+      else if (ioarray[0].size != 32)
+        fail ("gcry_sexp_extract_param/desc failed: P has wrong size");
+      else if (ioarray[0].len != 32)
+        fail ("gcry_sexp_extract_param/desc failed: P has wrong length");
+      else if (ioarray[0].off)
+        fail ("gcry_sexp_extract_param/desc failed: P has OFF set");
+      else if (cmp_bufhex (ioarray[0].data, ioarray[0].len, sample1_p))
+        {
+          fail ("gcry_sexp_extract_param/desc failed: P mismatch");
+          gcry_log_debug    ("expected: %s\n", sample1_p);
+          gcry_log_debughex ("     got", ioarray[0].data, ioarray[0].len);
+        }
+
+      if (!ioarray[1].data)
+        fail ("gcry_sexp_extract_param/desc failed: A buffer lost");
+      else if (ioarray[1].size != sizeof iobuffer)
+        fail ("gcry_sexp_extract_param/desc failed: A size changed");
+      else if (ioarray[1].off != 0)
+        fail ("gcry_sexp_extract_param/desc failed: A off changed");
+      else if (ioarray[1].len != 1)
+        fail ("gcry_sexp_extract_param/desc failed: A has wrong length");
+      else if (cmp_bufhex ((char *)ioarray[1].data + ioarray[1].off,
+                           ioarray[1].len, sample1_a))
+        {
+          fail ("gcry_sexp_extract_param/desc failed: A mismatch");
+          gcry_log_debug    ("expected: %s\n", sample1_a);
+          gcry_log_debughex ("     got",
+                             (char *)ioarray[1].data + ioarray[1].off,
+                             ioarray[1].len);
+        }
+
+      if (!ioarray[2].data)
+        fail ("gcry_sexp_extract_param/desc failed: B buffer lost");
+      else if (ioarray[2].size != sizeof iobuffer)
+        fail ("gcry_sexp_extract_param/desc failed: B size changed");
+      else if (ioarray[2].off != 50)
+        fail ("gcry_sexp_extract_param/desc failed: B off changed");
+      else if (ioarray[2].len != 32)
+        fail ("gcry_sexp_extract_param/desc failed: B has wrong length");
+      else if (cmp_bufhex ((char *)ioarray[2].data + ioarray[2].off,
+                           ioarray[2].len, sample1_b))
+        {
+          fail ("gcry_sexp_extract_param/desc failed: B mismatch");
+          gcry_log_debug    ("expected: %s\n", sample1_b);
+          gcry_log_debughex ("     got",
+                             (char *)ioarray[2].data + ioarray[2].off,
+                             ioarray[2].len);
+        }
+
+      xfree (ioarray[0].data);
+    }
+
+  gcry_sexp_release (sxp);
+
+  info ("checking gcry_sexp_extract_param long name\n");
+
+  memset (ioarray, 0, sizeof ioarray);
+  memset (mpis, 0, sizeof mpis);
+
+  err = gcry_sexp_new (&sxp, sample1, 0, 1);
+  if (err)
+    die ("converting string to sexp failed: %s", gpg_strerror (err));
+
+  err = gcry_sexp_extract_param (sxp, "key-data!private-key",
+                                 "&'curve'+p",
+                                 ioarray+0, mpis+0, NULL);
+  if (err)
+    fail ("gcry_sexp_extract_param long name failed: %s", gpg_strerror (err));
+
+  if (!ioarray[0].data)
+    fail ("gcry_sexp_extract_param long name failed: no curve");
+  else if (ioarray[0].size != 7)
+    fail ("gcry_sexp_extract_param long name failed: curve has wrong size");
+  else if (ioarray[0].len != 7)
+    fail ("gcry_sexp_extract_param long name failed: curve has wrong length");
+  else if (ioarray[0].off)
+    fail ("gcry_sexp_extract_param long name failed: curve has OFF set");
+  else if (strncmp (ioarray[0].data, "Ed25519", 7))
+    {
+      fail ("gcry_sexp_extract_param long name failed: curve mismatch");
+      gcry_log_debug ("expected: %s\n", "Ed25519");
+      gcry_log_debug ("     got: %.*s\n",
+                      (int)ioarray[0].len, (char*)ioarray[0].data);
+    }
+
+  if (!mpis[0])
+    fail ("gcry_sexp_extract_param long name failed: p not returned");
+  else if (cmp_mpihex (mpis[0], sample1_p))
+    {
+      fail ("gcry_sexp_extract_param long name failed: p mismatch");
+      gcry_log_debug    ("expected: %s\n", sample1_p);
+      gcry_log_debugmpi ("     got", mpis[0]);
+    }
+
+  gcry_free (ioarray[0].data);
+  gcry_mpi_release (mpis[0]);
+
+  gcry_sexp_release (sxp);
+
+}
+
+
+/* A test based on bug 1594.  */
+static void
+bug_1594 (void)
+{
+static char thing[] =
+  "(signature"
+  " (public-key"
+  "  (rsa"
+  "   (n #00A53A6B3A50BE571F805BD98ECE1FCE4CE291C3D4D3E971740E1EE6D447F526"
+  "       6AC8973DDC82F0ADD234CC82E0A0A3F48B81ACC8B038DB8ACC3E78DC2ED2642F"
+  "       6BA353FCA60F47C2801DEB477B37FB8B2F5508AA1C6D922780DB142DEA19B812"
+  "       C4E64F1138AD3BD61C58DB2D2591BE0BF36A1AC588AA45763BCDFF581050ABA8"
+  "       CA47BD9723ADD6A308AE28471EDD2B16D03C941D4F2B7E019C43AF8972880633"
+  "       54E97B7E19F1677D84B69A26B184A77B719DD72C48E0EE36107046F786566A9D"
+  "       13BAD724D6D78F24700FC22FC000E1B2A8C1B08ED62008395B0764CD9B55E80D"
+  "       A0A2B61C698DC27EA98E68BB576ACFC2B91B4D7283E7D960948D049D6E3C4CB1"
+  "       F489B460A120A4BB6C04A843FD3A67454136DE61CF68A927871EFFA9141BD372"
+  "       A748593C703E0301F039A9E674C50301BFC385BABE5B154250E7D57B82DB31F1"
+  "       E1AC696F870DCD8FE8DEC75608B988FCA3B484F1FD7755BF452F99597269AF02"
+  "       E8AF87D0F93DB427291659183D077254C835BFB6DDFD87CD0B5E0738682FCD34"
+  "       923F22551F73944E6CBE3ED6879B4414676B5DA0F30ED21DFA12BD2230C3C5D2"
+  "       EA116A3EFEB4AEC21C58E63FAFA549A63190F01859445E9B80F427B80FD4C884"
+  "       2AD41FE760A3E9DEDFB56CEBE8EA783838B2B392CACDDC760CCE212E388AFBC1"
+  "       95DC6D0ED87E9091F82A82CE372738C8DE8ABD76ACD06AC8B80AA0597162DF59"
+  "       67#)"
+  "   (e #010001#))))";
+  gcry_sexp_t sig, pubkey, n, n_val;
+
+  info ("checking fix for bug 1594\n");
+
+  if (gcry_sexp_new (&sig, thing, 0, 1))
+    die ("scanning fixed string failed\n");
+  pubkey = gcry_sexp_find_token (sig, "public-key", 0);
+  gcry_sexp_release (sig);
+  if (!pubkey)
+    {
+      fail ("'public-key' token not found");
+      return;
+    }
+  n = gcry_sexp_find_token (pubkey, "n", 0);
+  if (!n)
+    {
+      fail ("'n' token not found");
+      gcry_sexp_release (pubkey);
+      return;
+    }
+  n_val = gcry_sexp_nth (n, 1);
+  /* Bug 1594 would require the following test:
+   *   if (n_val)
+   *     fail ("extracting 1-th of 'n' list did not fail");
+   * However, we meanwhile modified the S-expression functions to
+   * behave like Scheme to allow the access of any element of a list.
+   */
+  if (!n_val)
+    fail ("extracting 1-th of 'n' list failed");
+  /*gcry_log_debugsxp ("1-th", n_val); => "(#00A5...#)"  */
+  gcry_sexp_release (n_val);
+  n_val = gcry_sexp_nth (n, 2);
+  if (n_val)
+    fail ("extracting 2-th of 'n' list did not fail");
+  n_val = gcry_sexp_nth (n, 0);
+  if (!n_val)
+    fail ("extracting 0-th of 'n' list failed");
+  /*gcry_log_debugsxp ("0-th", n_val); => "(n)"  */
+  if (gcry_sexp_nth (n_val, 1))
+    fail ("extracting 1-th of car of 'n' list did not fail");
+  gcry_sexp_release (n_val);
+}
 
 
 int
@@ -451,6 +1126,8 @@ main (int argc, char **argv)
   canon_len ();
   back_and_forth ();
   check_sscan ();
+  check_extract_param ();
+  bug_1594 ();
 
   return error_count? 1:0;
 }
index af3c4c3..1332c7c 100644 (file)
@@ -33,7 +33,7 @@
 #include <string.h>
 #include <stdarg.h>
 
-#include "../src/gcrypt.h"
+#include "../src/gcrypt-int.h"
 
 #define PGM "version"